mirror of
https://github.com/restoreddev/phpapprentice.git
synced 2025-08-12 01:34:23 +02:00
Initial commit for public repo
This commit is contained in:
22
src/App.php
Normal file
22
src/App.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
use Apprentice\Command;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class App
|
||||
{
|
||||
/**
|
||||
* Runs cli application
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main(): void
|
||||
{
|
||||
$cli = new Application;
|
||||
$cli->add(new Command\BuildCommand);
|
||||
$cli->add(new Command\ServerCommand);
|
||||
$cli->run();
|
||||
}
|
||||
}
|
104
src/Build.php
Normal file
104
src/Build.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
/**
|
||||
* Handles building pages in public folder
|
||||
* using configuration based on Page classes
|
||||
*/
|
||||
class Build
|
||||
{
|
||||
/**
|
||||
* Builds all pages in config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildAll(): void
|
||||
{
|
||||
$this->cleanPublicFolder();
|
||||
|
||||
$pages = config('pages');
|
||||
foreach ($pages as $page) {
|
||||
$this->buildPage($page);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds single page in config
|
||||
*
|
||||
* @param string $name Name of page to build
|
||||
* @return string Contents of built page
|
||||
*/
|
||||
public function runSingleBuild(string $name): string
|
||||
{
|
||||
$pages = config('pages');
|
||||
|
||||
foreach ($pages as $page) {
|
||||
if ($page->name == $name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildPage($page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all html files in public folder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cleanPublicFolder(): void
|
||||
{
|
||||
$files = glob(config('output_dir') . '/*.html');
|
||||
foreach ($files as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds single Page into html and
|
||||
* outputs to public directory
|
||||
*
|
||||
* @param Page $page Page from config to be built
|
||||
* @return void Contents of built page
|
||||
*/
|
||||
private function buildPage(Page $page): string
|
||||
{
|
||||
if (!empty($page->code)) {
|
||||
$code = file_get_contents(config('code_dir') . '/' . $page->code);
|
||||
$page->variables['code'] = $code;
|
||||
}
|
||||
|
||||
if ($page->template) {
|
||||
$template = config('templates_dir') . '/' . $page->template;
|
||||
} else {
|
||||
$template = config('templates_dir') . '/default.phtml';
|
||||
}
|
||||
$output = $this->getOutput($template, $page->variables);
|
||||
|
||||
file_put_contents(config('output_dir') . '/' . $page->name . '.html', $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads template file with scoped
|
||||
* variables
|
||||
*
|
||||
* @param string $path Path to template in templates folder
|
||||
* @param array $vars Array of variables to be loaded in template
|
||||
* @return string Output of template
|
||||
*/
|
||||
private function getOutput(string $path, array $vars = []): string {
|
||||
if ($vars) {
|
||||
extract($vars);
|
||||
}
|
||||
|
||||
ob_start();
|
||||
require $path;
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
24
src/Command/BuildCommand.php
Normal file
24
src/Command/BuildCommand.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice\Command;
|
||||
|
||||
use Apprentice\Build;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class BuildCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('build')
|
||||
->setDescription('Builds PHP templates into HTML files.')
|
||||
->setHelp('Help!');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$build = new Build;
|
||||
$build->buildAll();
|
||||
}
|
||||
}
|
23
src/Command/ServerCommand.php
Normal file
23
src/Command/ServerCommand.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ServerCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('server')
|
||||
->setDescription('Runs PHP server that automatically builds files')
|
||||
->setHelp('Help!');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('Starting development server on localhost:8080');
|
||||
system('php -S localhost:8080 -t docs src/util/router.php');
|
||||
}
|
||||
}
|
77
src/Page.php
Normal file
77
src/Page.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
/**
|
||||
* A class representing a single page in the build process
|
||||
*/
|
||||
class Page
|
||||
{
|
||||
/**
|
||||
* Name of page, used in filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Name of template to use
|
||||
* If none is provided, a default will be used
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $template;
|
||||
|
||||
/**
|
||||
* Name of code file to load as table
|
||||
* Will be skipped if none is provided
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* Map of data to passed to template
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $variables;
|
||||
|
||||
/**
|
||||
* Creates new page
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $template
|
||||
* @param string|null $code
|
||||
* @param array $variables
|
||||
*/
|
||||
public function __construct(
|
||||
string $name,
|
||||
?string $template = null,
|
||||
?string $code = null,
|
||||
?array $variables = []
|
||||
) {
|
||||
$this->name = $name;
|
||||
$this->template = $template;
|
||||
$this->code = $code;
|
||||
$this->variables = $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static constructor
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $template
|
||||
* @param string|null $code
|
||||
* @param array $variables
|
||||
* @return Apprentice\Page
|
||||
*/
|
||||
public static function create(
|
||||
string $name,
|
||||
?string $template = null,
|
||||
?string $code = null,
|
||||
?array $variables = []
|
||||
): Page {
|
||||
return new static($name, $template, $code, $variables);
|
||||
}
|
||||
}
|
149
src/util/functions.php
Normal file
149
src/util/functions.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runs a scoped require on a partial
|
||||
*
|
||||
* The filename must start with an underscore
|
||||
* and end with .php or .phtml
|
||||
*
|
||||
* @param string $path Name of partial
|
||||
* @param array $vars Variables to use for the partial
|
||||
* @return void
|
||||
*/
|
||||
function partial(string $path, array $vars = []) {
|
||||
$dir = config('templates_dir');
|
||||
if (file_exists($dir. '/' . "_$path.php")) {
|
||||
$file = $dir. '/' . "_$path.php";
|
||||
} elseif (file_exists($dir . '/' . "_$path.phtml")) {
|
||||
$file = $dir. '/' . "_$path.phtml";
|
||||
} else {
|
||||
throw new Exception('Partial could not be found: ' . $dir . '/' . "_$path.php");
|
||||
}
|
||||
|
||||
extract($vars);
|
||||
|
||||
require $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url path to page
|
||||
*
|
||||
* @param string $page Name of page
|
||||
* @return string
|
||||
*/
|
||||
function page_path(string $page): string {
|
||||
return '/' . $page . '.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely escapes text for display in html
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function escape(string $text): string {
|
||||
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads content of svg icon from assets folder
|
||||
*
|
||||
* @param string $name Name of icon without extension
|
||||
* @return string Contents of file
|
||||
*/
|
||||
function icon(string $name): string {
|
||||
$dir = config('icon_dir');
|
||||
$path = $dir . '/' . $name . '.svg';
|
||||
if (file_exists($path)) {
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes string of PHP code and converts it into html for display
|
||||
*
|
||||
* @param string $code
|
||||
* @return string
|
||||
*/
|
||||
function code_table(string $code): string {
|
||||
$tokens = token_get_all($code);
|
||||
$output = '<div class="grid-code">' .
|
||||
'<div class="doc"></div>' .
|
||||
'<div class="code">' .
|
||||
'<pre>' .
|
||||
'<code class="language-php">';
|
||||
|
||||
$previousTokenWasComment = false;
|
||||
foreach ($tokens as $token) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $token[0];
|
||||
$text = $token[1];
|
||||
|
||||
if ($id == T_COMMENT || $id == T_DOC_COMMENT) {
|
||||
$text = htmlspecialchars(trim(str_replace('/', '', $text)));
|
||||
|
||||
if ($previousTokenWasComment) {
|
||||
$output .= ' ' . $text;
|
||||
} else {
|
||||
$output .= '</code>' .
|
||||
'</pre>' .
|
||||
'</div>' .
|
||||
'<div class="doc">' .
|
||||
$text;
|
||||
}
|
||||
|
||||
$previousTokenWasComment = true;
|
||||
} else {
|
||||
if ($previousTokenWasComment) {
|
||||
$output .= '</div>' .
|
||||
'<div class="code">' .
|
||||
'<pre>' .
|
||||
'<code class="language-php">';
|
||||
}
|
||||
|
||||
$output .= htmlspecialchars($text);
|
||||
$previousTokenWasComment = false;
|
||||
}
|
||||
}
|
||||
|
||||
$output .= '</code>' .
|
||||
'</pre>' .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads config file into a global
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
function load_config(string $path) {
|
||||
$config = require $path;
|
||||
|
||||
if (!is_array($config)) {
|
||||
throw new \Exception('Config file does not return an array.');
|
||||
}
|
||||
|
||||
$GLOBALS['APPRENTICE_CONFIG'] = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config value
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
function config(string $key) {
|
||||
$config = $GLOBALS['APPRENTICE_CONFIG'] ?? [];
|
||||
|
||||
return $config[$key] ?? null;
|
||||
}
|
27
src/util/router.php
Normal file
27
src/util/router.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Router file used for development server
|
||||
* to create html files on demand
|
||||
*/
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
load_config(__DIR__ . '/../../config.php');
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$pathinfo = pathinfo($uri);
|
||||
|
||||
if ($pathinfo['dirname'] == '/' && !isset($pathinfo['extension'])) {
|
||||
$pathinfo['extension'] = 'html';
|
||||
$pathinfo['filename'] = 'index';
|
||||
}
|
||||
|
||||
if ($pathinfo['extension'] == 'html') {
|
||||
$build = new Apprentice\Build;
|
||||
$output = $build->runSingleBuild($pathinfo['filename']);
|
||||
|
||||
echo $output;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
Reference in New Issue
Block a user