From c566972160b47696912c8e24a0e1b738a1d7b9f5 Mon Sep 17 00:00:00 2001 From: "nisch.codes" Date: Tue, 22 Jul 2025 23:12:41 +0200 Subject: [PATCH] Initial Code commit --- .../HomeController.php} | 13 +- app/Model/HomeModel.php | 37 ++ .../layout => Resources/Layout}/index.html | 2 +- .../Template}/index.html | 0 app/View/HomeView.php | 31 ++ composer.json | 3 +- public/.htaccess | 356 ++++++++++++++++++ src/Application.php | 49 ++- src/Attributes/Route.php | 33 ++ src/HTTP.php | 4 +- .../MVC/BaseController.php | 18 +- src/{Controller.php => MVC/BaseModel.php} | 15 +- src/{Repository.php => MVC/BaseView.php} | 13 +- src/MiddlewareHandler.php | 0 src/Request.php | 35 ++ src/Router.php | 40 ++ 16 files changed, 618 insertions(+), 31 deletions(-) rename app/{controller/Controller.php => Controller/HomeController.php} (67%) create mode 100644 app/Model/HomeModel.php rename app/{resources/layout => Resources/Layout}/index.html (97%) rename app/{resources/template => Resources/Template}/index.html (100%) create mode 100644 app/View/HomeView.php create mode 100644 public/.htaccess create mode 100644 src/Attributes/Route.php rename app/model/Repository.php => src/MVC/BaseController.php (61%) rename src/{Controller.php => MVC/BaseModel.php} (71%) rename src/{Repository.php => MVC/BaseView.php} (76%) create mode 100644 src/MiddlewareHandler.php create mode 100644 src/Request.php create mode 100644 src/Router.php diff --git a/app/controller/Controller.php b/app/Controller/HomeController.php similarity index 67% rename from app/controller/Controller.php rename to app/Controller/HomeController.php index 2147aab..2d77ac6 100644 --- a/app/controller/Controller.php +++ b/app/Controller/HomeController.php @@ -3,7 +3,7 @@ namespace Nischcodes\Shiftcalc\App\Controller; /** - * Controller + * HomeController * * main controller for this application * @@ -19,6 +19,15 @@ namespace Nischcodes\Shiftcalc\App\Controller; * @link https://projects.nisch.codes/nischcodes/shiftcalc */ -class Controller extends Nischcodes\ShiftCalc\Controller { +use Nischcodes\Shiftcalc\Attributes\Route; +use Nischcodes\Shiftcalc\MVC\BaseController; + +class HomeController extends BaseController { + + #[Route('GET', '/')] + public function index() { + echo "Homepage"; + } + //TODO } \ No newline at end of file diff --git a/app/Model/HomeModel.php b/app/Model/HomeModel.php new file mode 100644 index 0000000..395d722 --- /dev/null +++ b/app/Model/HomeModel.php @@ -0,0 +1,37 @@ + + * @copyright 2021 nisch.codes + * @license https://projects.nisch.codes/nischcodes/shiftcalc/src/branch/main/LICENSE GPL-3 + * @version 1.0.0 + * @link https://projects.nisch.codes/nischcodes/shiftcalc + */ + +use Nischcodes\Shiftcalc\MVC\BaseModel; + +class HomeModel implements BaseModel { + + // implement the init function + public function init() { + echo "HomeModel init"; + } + + // implement the getAll function + public function getAll() { + return []; + } + + public function get($index){} +} \ No newline at end of file diff --git a/app/resources/layout/index.html b/app/Resources/Layout/index.html similarity index 97% rename from app/resources/layout/index.html rename to app/Resources/Layout/index.html index 070b779..320f6f7 100644 --- a/app/resources/layout/index.html +++ b/app/Resources/Layout/index.html @@ -19,6 +19,6 @@ - + \ No newline at end of file diff --git a/app/resources/template/index.html b/app/Resources/Template/index.html similarity index 100% rename from app/resources/template/index.html rename to app/Resources/Template/index.html diff --git a/app/View/HomeView.php b/app/View/HomeView.php new file mode 100644 index 0000000..96842d6 --- /dev/null +++ b/app/View/HomeView.php @@ -0,0 +1,31 @@ + + * @copyright 2021 nisch.codes + * @license https://projects.nisch.codes/nischcodes/shiftcalc/src/branch/main/LICENSE GPL-3 + * @version 1.0.0 + * @link https://projects.nisch.codes/nischcodes/shiftcalc + */ + +use Nischcodes\Shiftcalc\MVC\BaseView; + +class HomeView implements BaseView { + + // implement the render function + public function render($data) { + echo "HomeView render"; + } + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 26ab771..605b91b 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,8 @@ "license": "GPL-3.0", "autoload": { "psr-4": { - "Nischcodes\\Shiftcalc\\": "src/" + "Nischcodes\\Shiftcalc\\": "src/", + "Nischcodes\\Shiftcalc\\App\\": "app/" } }, "authors": [ diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..7689aa1 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,356 @@ +##### +# +# .htaccess file for use with Apache Webserver +# +# This file includes settings for the following configuration options: +# +# - Compression +# - Caching +# - MIME types +# - Cross Origin requests +# - Rewriting and Access +# - Miscellaneous +# - PHP optimisation +# +# Consider adding this file's content to your webserver's configuration directly for speed improvement +# +# Lots of the options are taken from https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess +# +#### + +### Begin: Compression ### + +# Compressing resource files will save bandwidth and so improve loading speed especially for users +# with slower internet connections compress the .js and .css files. + + + AddType "text/javascript" .gzip + + + AddType "text/css" .gzip + +AddEncoding gzip .gzip + + + # Force compression for mangled `Accept-Encoding` request headers + + + SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding + RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding + + + + # Compress all output labeled with one of the following media types. + # + # (!) For Apache versions below version 2.3.7 you don't need to + # enable `mod_filter` and can remove the `` + # and `` lines as `AddOutputFilterByType` is still in + # the core directives. + # + # https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype + + + AddOutputFilterByType DEFLATE application/atom+xml \ + application/javascript \ + application/json \ + application/ld+json \ + application/manifest+json \ + application/rdf+xml \ + application/rss+xml \ + application/schema+json \ + application/vnd.geo+json \ + application/vnd.ms-fontobject \ + application/x-font-ttf \ + application/x-javascript \ + application/x-web-app-manifest+json \ + application/xhtml+xml \ + application/xml \ + font/eot \ + font/opentype \ + image/bmp \ + image/svg+xml \ + image/vnd.microsoft.icon \ + image/x-icon \ + text/cache-manifest \ + text/css \ + text/html \ + text/javascript \ + text/plain \ + text/vcard \ + text/vnd.rim.location.xloc \ + text/vtt \ + text/x-component \ + text/x-cross-domain-policy \ + text/xml + + + + AddEncoding gzip svgz + + + +### End: Compression ### + +### Begin: Browser caching of resource files ### + +# This affects Frontend and Backend and increases performance. + + + ExpiresActive on + ExpiresDefault "access plus 1 month" + + ExpiresByType text/css "access plus 1 year" + + ExpiresByType application/json "access plus 0 seconds" + ExpiresByType application/ld+json "access plus 0 seconds" + ExpiresByType application/schema+json "access plus 0 seconds" + ExpiresByType application/vnd.geo+json "access plus 0 seconds" + ExpiresByType application/xml "access plus 0 seconds" + ExpiresByType text/xml "access plus 0 seconds" + + ExpiresByType image/vnd.microsoft.icon "access plus 1 week" + ExpiresByType image/x-icon "access plus 1 week" + + ExpiresByType text/x-component "access plus 1 month" + + ExpiresByType text/html "access plus 0 seconds" + + ExpiresByType application/javascript "access plus 1 year" + ExpiresByType application/x-javascript "access plus 1 year" + ExpiresByType text/javascript "access plus 1 year" + + ExpiresByType application/manifest+json "access plus 1 week" + ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" + ExpiresByType text/cache-manifest "access plus 0 seconds" + + ExpiresByType audio/ogg "access plus 1 month" + ExpiresByType image/bmp "access plus 1 month" + ExpiresByType image/gif "access plus 1 month" + ExpiresByType image/jpeg "access plus 1 month" + ExpiresByType image/png "access plus 1 month" + ExpiresByType image/svg+xml "access plus 1 month" + ExpiresByType image/webp "access plus 1 month" + ExpiresByType video/mp4 "access plus 1 month" + ExpiresByType video/ogg "access plus 1 month" + ExpiresByType video/webm "access plus 1 month" + + ExpiresByType application/atom+xml "access plus 1 hour" + ExpiresByType application/rdf+xml "access plus 1 hour" + ExpiresByType application/rss+xml "access plus 1 hour" + + ExpiresByType application/vnd.ms-fontobject "access plus 1 month" + ExpiresByType font/eot "access plus 1 month" + ExpiresByType font/opentype "access plus 1 month" + ExpiresByType application/x-font-ttf "access plus 1 month" + ExpiresByType application/font-woff "access plus 1 month" + ExpiresByType application/x-font-woff "access plus 1 month" + ExpiresByType font/woff "access plus 1 month" + ExpiresByType application/font-woff2 "access plus 1 month" + + ExpiresByType text/x-cross-domain-policy "access plus 1 week" + + + +### End: Browser caching of resource files ### + +### Begin: MIME types ### + +# Proper MIME types for all files + + + # Data interchange + AddType application/atom+xml atom + AddType application/json json map topojson + AddType application/ld+json jsonld + AddType application/rss+xml rss + AddType application/vnd.geo+json geojson + AddType application/xml rdf xml + + # JavaScript + AddType application/javascript js + + # Manifest files + AddType application/manifest+json webmanifest + AddType application/x-web-app-manifest+json webapp + AddType text/cache-manifest appcache + + # Media files + + AddType audio/mp4 f4a f4b m4a + AddType audio/ogg oga ogg opus + AddType image/bmp bmp + AddType image/svg+xml svg svgz + AddType image/webp webp + AddType video/mp4 f4v f4p m4v mp4 + AddType video/ogg ogv + AddType video/webm webm + AddType video/x-flv flv + AddType image/x-icon cur ico + + # Web fonts + AddType application/font-woff woff + AddType application/font-woff2 woff2 + AddType application/vnd.ms-fontobject eot + AddType application/x-font-ttf ttc ttf + AddType font/opentype otf + + # Other + AddType application/octet-stream safariextz + AddType application/x-bb-appworld bbaw + AddType application/x-chrome-extension crx + AddType application/x-opera-extension oex + AddType application/x-xpinstall xpi + AddType text/vcard vcard vcf + AddType text/vnd.rim.location.xloc xloc + AddType text/vtt vtt + AddType text/x-component htc + + + +# UTF-8 encoding +AddDefaultCharset utf-8 + + AddCharset utf-8 .atom .css .js .json .manifest .rdf .rss .vtt .webapp .webmanifest .xml + + +### End: MIME types ### + +### Begin: Cross Origin ### + +# Send the CORS header for images when browsers request it. + + + + SetEnvIf Origin ":" IS_CORS + Header set Access-Control-Allow-Origin "*" env=IS_CORS + + + + +# Allow cross-origin access to web fonts. + + + Header set Access-Control-Allow-Origin "*" + + + +### End: Cross Origin ### + +### Begin: Rewriting and Access ### + + + # Enable URL rewriting + RewriteEngine On + + # Store the current location in an environment variable CWD to use + # mod_rewrite in .htaccess files without knowing the RewriteBase + RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$ + RewriteRule ^.*$ - [E=CWD:%2] + + # Rules to set ApplicationContext based on hostname + #RewriteCond %{HTTP_HOST} ^dev\.example\.com$ + #RewriteRule .? - [E=WORKBENCH_CONTEXT:Development] + #RewriteCond %{HTTP_HOST} ^staging\.example\.com$ + #RewriteRule .? - [E=WORKBENCH_CONTEXT:Production/Staging] + #RewriteCond %{HTTP_HOST} ^www\.example\.com$ + #RewriteRule .? - [E=WORKBENCH_CONTEXT:Production] + + # Rule for versioned static files, configured through: + # IMPORTANT: This rule has to be the very first RewriteCond in order to work! + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ %{ENV:CWD}$1.$3 [L] + + # Block access to all hidden files and directories with the exception of + # the visible content from within the `/.well-known/` hidden directory (RFC 5785). + RewriteCond %{REQUEST_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC] + RewriteCond %{SCRIPT_FILENAME} -d [OR] + RewriteCond %{SCRIPT_FILENAME} -f + RewriteRule (?:^|/)\. - [F] + + # Stop rewrite processing, if we are in known directories + # NOTE: Add your additional local storages here + RewriteRule ^(?:assets/|files/|uploads/|favicon\.ico) - [L] + + # If the file/symlink/directory does not exist => Redirect to index.php. + # For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'. + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-l + RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L] + + + +# Access block for files +# Apache < 2.3 + + + Order allow,deny + Deny from all + Satisfy All + + +# Apache ≥ 2.3 + + + Require all denied + + + +# Block access to vcs directories + + RedirectMatch 404 /\.(?:git|svn|hg)/ + + +### End: Rewriting and Access ### + +### Begin: Miscellaneous ### + +# 404 error prevention for non-existing redirected folders +Options -MultiViews + +# Make sure that directory listings are disabled. + + Options -Indexes + + + + # Force IE to render pages in the highest available mode + Header set X-UA-Compatible "IE=edge" + + Header unset X-UA-Compatible + + + # Reducing MIME type security risks + Header set X-Content-Type-Options "nosniff" + + +# ETag removal + + Header unset ETag + +FileETag None + +### End: Miscellaneous ### + + + header set x-robots-tag: noindex + + +### Security Settings ### + +### Content Security Policy - CSP-HEADER +Header set Content-Security-Policy "default-src 'self' data: 'unsafe-inline'; frame-src 'self'; font-src 'self'; img-src 'self' data: 'unsafe-inline'; object-src 'self'; script-src 'self' data: 'unsafe-inline' 'unsafe-eval'; style-src 'self' data: 'unsafe-inline';" + +### X-Content-Type-Options +# Header always set X-Content-Type-Options "nosniff" +# Already set, see above + +### X-Frame-Options +Header always set X-Frame-Options "SAMEORIGIN" + +### X-Xss-Protection +Header always set X-Xss-Protection "1; mode=block" + +### Referrer-Policy +Header set Referrer-Policy "strict-origin" \ No newline at end of file diff --git a/src/Application.php b/src/Application.php index a05c59f..08472f7 100644 --- a/src/Application.php +++ b/src/Application.php @@ -20,9 +20,16 @@ namespace Nischcodes\Shiftcalc; */ use Nischcodes\Shiftcalc\DotEnv; +use Nischcodes\Shiftcalc\Router; +use Nischcodes\Shiftcalc\Request; class Application { + static $router; + + static $basenamespace = "Nischcodes\\Shiftcalc\\App\\"; + static $controllernamespace = "Nischcodes\\Shiftcalc\\App\\Controller\\"; + static function init() { // get the current root directory @@ -36,11 +43,49 @@ class Application { // load .env file DotEnv::load("$projectRoot/.env"); } + + // initilise the router object + self::$router = new Router(); + + // get all controller from the application directory + $appControllers = glob("$projectRoot/app/Controller/*.php"); + + // iterate over all application controller and register the routes with model + foreach($appControllers as $appController) { + + // extract the class name + $controllerClassName = basename($appController, '.php'); + // construct the namespaces + $controllerFQN = self::$controllernamespace.$controllerClassName; + $modelFQN = str_replace("Controller", "Model", $controllerFQN); + $viewFQN = str_replace("Controller", "View", $controllerFQN); + + // check if classes exists + $controllerClass = (class_exists($controllerFQN) ? $controllerFQN : false); + $modelClass = (class_exists($modelFQN) ? $modelFQN : ''); + $viewClass = (class_exists($viewFQN) ? $viewFQN : ''); + + // check if the current classname is loaded + if($controllerClass) { + + // register controller for routing with model + self::$router->registerRoutesFromController( + $controllerClass, + $modelClass, + $viewClass + ); + } + } } static function run() { - //echo "run application"; + // call the route for the requested path + self::$router->dispatch( + Request::uri(), + Request::method(), + Request::parameters() + ); } @@ -61,6 +106,6 @@ class Application { $dir = $parent; } - throw new RuntimeException('Project root folder not found.'); + throw new \RuntimeException('Project root folder not found.'); } } \ No newline at end of file diff --git a/src/Attributes/Route.php b/src/Attributes/Route.php new file mode 100644 index 0000000..c42d7f5 --- /dev/null +++ b/src/Attributes/Route.php @@ -0,0 +1,33 @@ + + * @copyright 2021 nisch.codes + * @license https://projects.nisch.codes/nischcodes/shiftcalc/src/branch/main/LICENSE GPL-3 + * @version 1.0.0 + * @link https://projects.nisch.codes/nischcodes/shiftcalc + */ + +use Attribute; + +#[Attribute(Attribute::TARGET_METHOD)] +class Route { + + public function __construct( + public string $method, + public string $path, + public array $middleware = [] + ) {} + +} \ No newline at end of file diff --git a/src/HTTP.php b/src/HTTP.php index 32c29b8..915d45f 100644 --- a/src/HTTP.php +++ b/src/HTTP.php @@ -21,7 +21,7 @@ namespace Nischcodes\Shiftcalc; class HTTP { - static function fetch(string $url, ?Array $headers = []): Mixed { + static function fetch(string $url, ?Array $headers = []): string|bool { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if(!empty($headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); @@ -31,7 +31,7 @@ class HTTP { curl_close($ch); if(curl_errno($ch)) { - throw new Exception('Curl-Error: ' . curl_error($ch)); + throw new \Exception('Curl-Error: ' . curl_error($ch)); exit; } // returns the raw response of the curl request diff --git a/app/model/Repository.php b/src/MVC/BaseController.php similarity index 61% rename from app/model/Repository.php rename to src/MVC/BaseController.php index 3171fae..eb15d58 100644 --- a/app/model/Repository.php +++ b/src/MVC/BaseController.php @@ -1,11 +1,9 @@ init(); + } } \ No newline at end of file diff --git a/src/Controller.php b/src/MVC/BaseModel.php similarity index 71% rename from src/Controller.php rename to src/MVC/BaseModel.php index 19cef1f..4dac8d4 100644 --- a/src/Controller.php +++ b/src/MVC/BaseModel.php @@ -1,11 +1,9 @@ + * @copyright 2021 nisch.codes + * @license https://projects.nisch.codes/nischcodes/shiftcalc/src/branch/main/LICENSE GPL-3 + * @version 1.0.0 + * @link https://projects.nisch.codes/nischcodes/shiftcalc + */ + +class Request { + + public static function uri(): Mixed { + return parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + } + + public static function method(): string { + return $_SERVER['REQUEST_METHOD']; + } + + public static function parameters(): array { + return $_REQUEST ?? []; + } +} \ No newline at end of file diff --git a/src/Router.php b/src/Router.php new file mode 100644 index 0000000..10ce0db --- /dev/null +++ b/src/Router.php @@ -0,0 +1,40 @@ + + * @copyright 2021 nisch.codes + * @license https://projects.nisch.codes/nischcodes/shiftcalc/src/branch/main/LICENSE GPL-3 + * @version 1.0.0 + * @link https://projects.nisch.codes/nischcodes/shiftcalc + */ + +class Router { + + protected array $routes = []; + + public function dispatch(string $uri, string $method, ?array $parameter = []) { + //TODO + + var_dump($uri); + var_dump($method); + var_dump($parameter); + } + + public function registerRoutesFromController(string $controller, string $model = '', string $view = '') { + + var_dump($controller); + var_dump($model); + var_dump($view); + } +} \ No newline at end of file