From 4a86e0f14af70011b921e9d639ba51306129dd2a Mon Sep 17 00:00:00 2001 From: Langur Date: Thu, 5 Jan 2023 22:32:11 +0900 Subject: [PATCH] Initial commit --- .htaccess | 7 + LICENSE | 2 +- README.md | 21 ++ VERSION | 1 + changelog.md | 4 + config.php | 57 ++++ controler/sample/index.php | 19 ++ controler/sample/sub/index.php | 19 ++ images/thumbnail.png | Bin 0 -> 1373 bytes index.php | 12 + libs/.gitkeep | 0 modules/kernel/class.php | 563 +++++++++++++++++++++++++++++++ modules/kernel/main.php | 88 +++++ modules/templateengine/class.php | 97 ++++++ modules/templateengine/main.php | 22 ++ public/.htaccess | 7 + public/index.php | 52 +++ view/error/400.tpl | 11 + view/error/403.tpl | 11 + view/error/404.tpl | 11 + view/sample/index.tpl | 83 +++++ view/sample/sub/index.tpl | 83 +++++ 22 files changed, 1169 insertions(+), 1 deletion(-) create mode 100644 .htaccess create mode 100644 README.md create mode 100644 VERSION create mode 100644 changelog.md create mode 100644 config.php create mode 100644 controler/sample/index.php create mode 100644 controler/sample/sub/index.php create mode 100644 images/thumbnail.png create mode 100644 index.php create mode 100644 libs/.gitkeep create mode 100644 modules/kernel/class.php create mode 100644 modules/kernel/main.php create mode 100644 modules/templateengine/class.php create mode 100644 modules/templateengine/main.php create mode 100644 public/.htaccess create mode 100644 public/index.php create mode 100644 view/error/400.tpl create mode 100644 view/error/403.tpl create mode 100644 view/error/404.tpl create mode 100644 view/sample/index.tpl create mode 100644 view/sample/sub/index.tpl diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..048c945 --- /dev/null +++ b/.htaccess @@ -0,0 +1,7 @@ + +RewriteEngine On +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . index.php [L] + diff --git a/LICENSE b/LICENSE index 08aa8ef..a95faff 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Langur +Copyright (c) 2017-2023 Akihisa ONODA Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..f10a9ac --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Macaca - A simple contents management system for PHP + +## Overview +Macaca is a content management system that provides a simple MVC framework. +You can deploy a public directory or under a specific directory. +Of course, you can also be extended using composer. + +## Deploy +You have a choice of two methods. +### Deploy a public directory +The following files will be made available to the public. +All files should then be routed to *public/index.php* . +- public/index.php + +### Deploy under a specific directory +The following files will be made available to the public. +All files should then be routed to *index.php* . +- index.php + +## License +This software is distributed under the MIT License. Please read LICENSE for information on the software availability and distribution. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..8a9ecc2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..6e8d992 --- /dev/null +++ b/changelog.md @@ -0,0 +1,4 @@ +# Macaca Change Log + +## Version 0.0.1 (Thr, Jan 5 2023) +- Initial public release diff --git a/config.php b/config.php new file mode 100644 index 0000000..512d5c3 --- /dev/null +++ b/config.php @@ -0,0 +1,57 @@ + + */ + +/* ------------------------------------------------------------- + * Macaca用定義 + * ------------------------------------------------------------- */ +define('LOADED_CONFIG', true); + +/* ------------------------------------------------------------- + * PATH設定 + * ------------------------------------------------------------- */ +define('ROOT_URI', '/'); +define('__ABSPATH__', dirname(__FILE__) . '/'); +define('LIBPATH', __ABSPATH__ . 'libs/'); +define('MODPATH', __ABSPATH__ . 'modules/'); +define('ERROR_VIEW_PATH', __ABSPATH__ . 'view/error'); + +/* ------------------------------------------------------------- + * PHPの設定変更 + * ------------------------------------------------------------- */ +ini_set("include_path", get_include_path() . PATH_SEPARATOR . LIBPATH); + +/* ------------------------------------------------------------- + * 環境設定 + * ------------------------------------------------------------- */ +# SiteName +define('SITE_NAME', 'Macaca'); +define('SITE_EMAIL', 'webmaster@localhost'); +define('SITE_USE_OGP', false); +define('SITE_CACHE', '20230105'); + +# ERROR +ini_set('display_errors', false); +ini_set('error_reporting', E_ALL & ~E_STRICT & ~E_NOTICE & ~E_DEPRECATED); + +# DEBUG +define('DEBUG_SITE', false); + +/* ------------------------------------------------------------- + * 各種ロード + * ------------------------------------------------------------- */ +foreach (glob(LIBPATH . '*/*.php') as $path) { + include $path; +} +foreach (glob(MODPATH . '*/class.php') as $path) { + require_once $path; +} +foreach (glob(MODPATH . '*/main.php') as $path) { + include $path; +} diff --git a/controler/sample/index.php b/controler/sample/index.php new file mode 100644 index 0000000..884af7b --- /dev/null +++ b/controler/sample/index.php @@ -0,0 +1,19 @@ + + */ + +$argv = $this->getARGV(); +$view_engine = $this->getViewEngine(); + +# setString(文字列)で保持したデータはgetString()で読み出すことができる。 +# StringはFoobarのように任意の文字列に置換可能。 +$view_engine['templateengine']->setString("main"); \ No newline at end of file diff --git a/controler/sample/sub/index.php b/controler/sample/sub/index.php new file mode 100644 index 0000000..1879779 --- /dev/null +++ b/controler/sample/sub/index.php @@ -0,0 +1,19 @@ + + */ + +$argv = $this->getARGV(); +$view_engine = $this->getViewEngine(); + +# setString(文字列)で保持したデータはgetString()で読み出すことができる。 +# StringはFoobarのように任意の文字列に置換可能。 +$view_engine['templateengine']->setString("sub"); \ No newline at end of file diff --git a/images/thumbnail.png b/images/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..283bc531a38e9d1225e64b659baa4d4316eb3311 GIT binary patch literal 1373 zcmbVLYfzF26#X>KMA2T3CM7j3?QSOfp`zs@*V0r>Eu};%3l&KTLsKFi*_P6@V^KQb z=DJ#&x|%F03g&|zlC>uJpnSKOu0lrQuBiDSSepIS?7!~JojdoOIcLt?nS13xWC#@E z3;_TD8WtK94FKji05J2lSYbkRkH$ErVL=Lv2n2vyu8p2xY1%g@hDJvK0Am{fT*v`{ zB@=YvEdXSJ0PyYv0Qmd_0FKn+rh|Sa!v4U1Y_P##crhlYGg+2qmPVtoMqcb{qRbM) zLxL>0CkGFj7Heu~+!+9{lYMHlXQwNZOrTX}SVXXu+RSq08o1+GNR%mxS6EOWmOeB! zNTK}tOIDEF!gp16!$bE9Z==|YcPYh>+%<%zLE4tv9pQYz`sAr=y!3M1^)hcFRcZPWxD z`D)u_Z+Ff|t(g4~ecaZ@1M{S}=pTdVCiR_vK8xzPrE}5vC}7s+W73^I43x}2=HOAU zV@q8Xr3KhAtBF)6uD5lgR9NotYeQ}%@{*z>(-t;C`zE)py{oO8(T*2#q*$!J*loaT zwj%!29eA1JAmm6B-kpfOUg6D`)1b}Liiy7bzGT@uT^@MS*uQN&mHV8x6|rr&CZ|^w zblOKO-HyRUD(#}fkmEH+s|33X@w@F5BKe}^m127}jDIM^oI`>#Y5_p}OZeX{~p8;`Vdi8(U|l^-HTPNMSHUa0!Eex&%sl0tPAdf@S>x! zY~@bcKyfPZ7g@#x4tW7Bm|yv!l^2`R^vd9dn3zp{n|6rbZ=c3ciZ}IT*oKG8!f*_9 z-gh)8dGb7L(|C*0S@NxbNI?mzPWh%B9#xr+M1s!Kep{bhAlyW9C*;o5pSa)iM#>?| zU}T)(?>A!q+VvUuy(NX7f|yGI@;DJRrVFym#Xq2^0$tC?pLcOcQVh+h%Ki3tQ|Kji z7#UpNrRg8P&R1dNuQg?wk`7trOQuYzge^HAR0H+${k;c#vCJgzog7WpcI=>4@_75M1muW^bt;?TYQbpz&PKwbdlV+TYo}9{l>RW|c>Vu~vL&!W9&K|028fY8tAt*o=)RhZK>lMgL zr`d*=2MX-#w20f+uJSv>^CITU95=u=LgP6Ux|L*fggiHW@m?VA>}G*)cb)coqS=?d z@xt+s=E2Ko){!6C7A6NoW-u-@iI7S3Nz5Rc2H+05d$@rpHxP{ly?jt8A5YK~1bsj- lzeR`mOh7rEl#+bz{{qnKKY<048uuw + */ +session_start(); +include_once('./config.php'); +require_once('./public/index.php'); diff --git a/libs/.gitkeep b/libs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/modules/kernel/class.php b/modules/kernel/class.php new file mode 100644 index 0000000..bc2de93 --- /dev/null +++ b/modules/kernel/class.php @@ -0,0 +1,563 @@ + + */ + +namespace Kernel; + +define('ALL_BITS', -1); + +// フラグ管理用の定義 +define('KERNEL_FLAG_CONTROLER_IS_UNNECESSARY', 1 << 0); +define('KERNEL_FLAG_URI_IS_ARTICLES', 1 << 1); + +// URI分離のための定義 +define('KERNEL_PARAM_DIVIDE_URI', 2); +define('KERNEL_PARAM_DIVIDE_URI_PATH', 0); +define('KERNEL_PARAM_DIVIDE_URI_PARAM', 1); + +// QUERY分離のための定義 +define('KERNEL_PARAM_DIVIDE_QUERY', 2); +define('KERNEL_PARAM_DIVIDE_QUERY_NAME', 0); +define('KERNEL_PARAM_DIVIDE_QUERY_VALUE', 1); + +// ファイル読出しのための定義 +define('KERNEL_READ_BYTES', 1024); + +// ファイルの拡張子指定のための定義 +define('KERNEL_PARAM_DIVIDE_FILENAME_EXTENTION', 1); + +/** + * EnumViewEngineクラス + * + * ViewEngineの種別をEnum的に扱うためのクラス。 + * + * @category Enum + * @package Kernel + */ +class EnumViewEngine +{ + const NONE = 0; + const RAW = 1; + const TEMPLATEENGINE = 2; +} + + +/** + * Kernelクラス + * + * Macacaにおける処理のコアとなります。 + * 引数の監理やMVCの紐付けを行います。 + * + * @category Kernel + * @package Kernel + */ +class Kernel +{ + // 各種パラメータの保持 + private $parameter; + + // コントローラを使用しないファイルの拡張子を指定 + private $controlerless_filename_extension = ['css', 'js', 'jpg', 'png']; + + // HTTPのステータスコード + private $http_status_code = array( + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 204 => 'No Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Moved Temporarily', + 304 => 'Not Modified', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 403 => 'Forbidden', + 404 => 'Not Found', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 506 => 'Variant Also Negotiates', + ); + + + public function __construct() + { + $this->parameter = []; + $this->parameter['flag'] = 0; + $this->parameter['PathControler'] = __ABSPATH__ . 'controler'; + $this->parameter['PathView'] = __ABSPATH__ . 'view'; + $this->parameter['PathViewc'] = __ABSPATH__ . 'view_c'; + } + + // クラスを拡張するための処理 + public function __call($name, $args) + { + if (strncmp($name, 'get', 3) === 0) { + return $this->get(substr($name, 3), reset($args)); + } + elseif (strncmp($name, 'set', 3) === 0) { + return $this->set(substr($name, 3), reset($args)); + } + elseif (strncmp($name, 'exec', 4) === 0) { + return $this->exec(substr($name, 4), reset($args)); + } + else { + } + + throw new \BadMethodCallException('Method "' . $name . '" does not exist.'); + } + + // クラスを拡張するための処理 + public function __set($key, $value) + { + $this->set($key, $value); + } + + // クラスを拡張するための処理 + public function get($key, $default = null) + { + if (array_key_exists($key, $this->parameter)) { + return $this->parameter[$key]; + } + + return $default; + } + + // クラスを拡張するための処理 + public function set($key, $value) + { + $this->parameter[$key] = $value; + } + + // クラスを拡張するための処理 + public function exec($key, $func = null) + { + $func(); + } + + /** + * Subディレクトリの設定。 + * + * @param array $param + * @return string | null + */ + public function setSubDir($param) + { + $this->parameter['SubDir'] = (isset($param['sub_dir'])) ? $param['sub_dir'] : null; + } + + /** + * URIの抽出。 + * + * @param array $param + * @return string + */ + public function setURI($param) + { + $uri = explode('?', + $_SERVER["REQUEST_URI"], + KERNEL_PARAM_DIVIDE_URI)[KERNEL_PARAM_DIVIDE_URI_PATH]; + if (isset($param['sub_dir'])) { + $uri = preg_replace("/^\\" . $param['sub_dir'] ."/", '', $uri); + } + $this->parameter['URI'] = htmlspecialchars($uri, ENT_QUOTES, 'UTF-8'); + } + + /** + * 引数の抽出。 + * + * @param void + * @return array + */ + public function setARGV() + { + if ($_SERVER['REQUEST_METHOD'] !== "POST") { + if ($_SERVER['QUERY_STRING'] === "") { + $argv = array(); + } else { + $ary = explode('&', $_SERVER['QUERY_STRING']); + foreach ($ary as $equation) { + $parameters = explode('=', $equation, KERNEL_PARAM_DIVIDE_QUERY); + // 先勝ちで値を格納する + if (!isset($argv[$parameters[KERNEL_PARAM_DIVIDE_QUERY_NAME]]) && + count($parameters) > 1) { + $argv[$parameters[KERNEL_PARAM_DIVIDE_QUERY_NAME]] = $parameters[KERNEL_PARAM_DIVIDE_QUERY_VALUE]; + } + } + } + } else { + $argv = $_POST; + } + $this->parameter['ARGV'] = isset($argv) ? $argv : array(); + } + + /** + * メソッドの抽出。 + * + * @param Kernel $kernel + * @return string + */ + public function setMethod() + { + // '_method'でメソッド名が定義されていたら当該メソッドとして扱う + $method = (isset($this->parameter['ARGV']['_method'])) ? $this->parameter['ARGV']['_method'] : null; + if (is_null($method)) { + $method = $_SERVER['REQUEST_METHOD']; + } else { + $method = strtoupper(htmlspecialchars($method, ENT_QUOTES, 'UTF-8')); + } + + $this->parameter['Method'] = $method; + } + + /** + * 引数の数を抽出。 + * + * @param Kernel $kernel + * @return int + */ + public function setARGC() + { + $this->parameter['ARGC'] = count($this->getARGV()); + } + + /** + * フラグのビットを立てる。 + * + * @param int $value + * @param int $bits + * @return int | null + */ + private function setBits($value, $bits) + { + return is_int($value) ? ($value | $bits) : null; + } + + /** + * フラグのビットを削除する。 + * + * @param int $value + * @param int $bits + * @return int | null + */ + private function unsetBits($value, $bits) + { + return is_int($value) ? ($value & (ALL_BITS ^ $bits)) : null; + } + + /** + * コントローラを探す。 + * + * @param void + * @return int | null + */ + public function findControler() + { + $controler = ''; + + if (mb_substr($this->getURI(), -1) !== '/') { + // URIがファイルを示していればそのまま処理する。 + $ary = explode('/', $this->getURI()); + $ary_keys = array_keys($ary); + $ary_last_key = end($ary_keys); + $file = explode('.', $ary[$ary_last_key]); + if (count($file) > 1) { + $file_keys = array_keys($file); + $file_extension_key = end($file_keys); + if (in_array($file[$file_extension_key], + $this->controlerless_filename_extension)) { + // コントローラを使用しないファイルであれば、 + // KERNEL_FLAG_CONTROLER_IS_UNNECESSARYフラグを立てる + $this->set('flag', + $this->setBits($this->get('flag'), + KERNEL_FLAG_CONTROLER_IS_UNNECESSARY)); + } else { + // コントローラを使用するファイルであれば、 + // 拡張子をPHPに変更する + $file[$file_extension_key] = 'php'; + $this->set('flag', + $this->unsetBits($this->get('flag'), + KERNEL_FLAG_CONTROLER_IS_UNNECESSARY)); + } + } else { + // URIが拡張子を持っていなければ、当該名のコント + // ローラとして扱う + $file[KERNEL_PARAM_DIVIDE_FILENAME_EXTENTION] = 'php'; + $this->set('flag', + $this->unsetBits($this->get('flag'), + KERNEL_FLAG_CONTROLER_IS_UNNECESSARY)); + } + + if (($this->get('flag') & KERNEL_FLAG_CONTROLER_IS_UNNECESSARY) === 0) { + // コントローラを必要とするのであれば、コントローラのファイル名を + // 再生成する + $ary[$ary_last_key] = implode('.', $file); + $controler = implode('/', $ary); + } else { + $controler = null; + } + } else { + // URIがディレクトリを示していればindexを参照したと判断して処理する。 + $controler = $this->getURI() . 'index.php'; + } + + // ルートディレクトリが異なる場合はコントローラのパスを補正する。 + if (!empty($this->getRootDirectory())) { + $controler = $this->convertRootUri($controler); + } + + // 最終的なコントローラを決定する。 + if (($this->get('flag') & KERNEL_FLAG_CONTROLER_IS_UNNECESSARY) === 0 && + file_exists($this->getPathControler() . $controler)) { + $this->setControler($this->getPathControler() . $controler); + } else { + $this->setControler(null); + } + } + + /** + * コントローラを実行する。 + * + * @param void + * @return void + */ + public function execControler() + { + $this->findControler(); + + if (!is_null($this->getControler())) { + include($this->getControler()); + } + } + + public function findView() + { + $view = ''; + + if (mb_substr($this->getURI(), -1) !== '/') { + $ary = explode('/', $this->getURI()); + $ary_keys = array_keys($ary); + $ary_last_key = end($ary_keys); + $file = explode('.', $ary[$ary_last_key]); + if (count($file) > 1) { + $file_keys = array_keys($file); + $file_extension_key = end($file_keys); + $this->setViewFilenameExtention($file[$file_extension_key]); + switch ($file[$file_extension_key]) { + case 'html': + case 'htm': + case 'tpl': + $file[$file_extension_key] = 'tpl'; + $this->setEngine(EnumViewEngine::TEMPLATEENGINE); + break; + case 'php': + $this->setEngine(EnumViewEngine::NONE); + break; + default: + $this->setEngine(EnumViewEngine::RAW); + break; + } + } else { + $file[1] = 'tpl'; + $this->setViewFilenameExtention($file[1]); + $this->setEngine(EnumViewEngine::TEMPLATEENGINE); + } + + if ($this->getEngine() !== EnumViewEngine::NONE) { + $ary[$ary_last_key] = implode('.', $file); + $view = implode('/', $ary); + } else { + $view = null; + } + } + else { + $view = $this->getURI() . 'index.tpl'; + $this->setViewFilenameExtention('tpl'); + $this->setEngine(EnumViewEngine::TEMPLATEENGINE); + } + + if (!empty($this->getRootDirectory())) { + $view = $this->convertRootUri($view); + } + + if ($this->getEngine() === EnumViewEngine::RAW && + file_exists($this->getPathRoot() . $view)) { + $this->setView($this->getPathRoot() . $view); + } elseif (file_exists($this->getPathView() . $view)) { + $this->setView($this->getPathView() . $view); + } else { + $this->setView(null); + $this->setEngine(EnumViewEngine::NONE); + } + } + + public function execViewEngine() + { + $this->findView(); + if (is_null($this->getView())) { + if ($this->getEngine() === EnumViewEngine::NONE && + $this->getViewFilenameExtention() !== 'php') { + $this->execViewError(404); + exit; + } + return; + } + switch ($this->getEngine()) { + case EnumViewEngine::NONE: + if ($this->setViewFilenameExtention !== 'php') { + $this->execViewError(404); + exit; + } + break; + case EnumViewEngine::RAW: + $this->execViewEngineRaw(); + break; + case EnumViewEngine::TEMPLATEENGINE: + $this->getViewEngine()['templateengine']->display($this->getView()); + break; + default: + break; + } + } + + private function execViewEngineRaw() + { + $content_type = ''; + switch ($this->getViewFilenameExtention()) { + case 'txt': + $content_type = 'text/plain'; + break; + case 'csv': + $content_type = 'text/csv'; + break; + case 'css': + $content_type = 'text/css'; + break; + case 'js': + $content_type = 'text/javascript'; + break; + case 'pdf': + $content_type = 'application/pdf'; + break; + case 'xls': + case 'xlsx': + $content_type = 'application/vnd.ms-excel'; + break; + case 'ppt': + case 'pptx': + $content_type = 'application/vnd.ms-powerpoint'; + break; + case 'doc': + case 'docx': + $content_type = 'application/vnd.msword'; + break; + case 'jpg': + case 'jpeg': + case 'JPG': + case 'JPEG': + $content_type = 'image/jpeg'; + break; + case 'png': + case 'PNG': + $content_type = 'image/png'; + break; + case 'gif': + case 'GIF': + $content_type = 'image/gif'; + break; + case 'bmp': + case 'BMP': + $content_type = 'image/bmp'; + break; + case 'zip': + $content_type = 'application/zip'; + break; + case 'lzh': + $content_type = 'application/x-lzh'; + break; + case 'tar': + case 'gz': + $content_type = 'application/x-tar'; + break; + case 'mp3': + $content_type = 'audio/mpeg'; + break; + case 'mp4': + $content_type = 'audio/mp4'; + break; + case 'mpeg': + case 'mpg': + $content_type = 'video/mpeg'; + break; + default: + $content_type = 'application/octet-stream'; + break; + } + header('Content-Type: ' . $content_type); + + $fp = fopen($this->getView(), 'r'); + for ($offset = 0; ($data = stream_get_contents($fp, KERNEL_READ_BYTES, $offset)) != false; $offset += KERNEL_READ_BYTES) { + print($data); + } + fclose($fp); + } + + public function execViewError($code) { + if (isset($this->http_status_code[$code])) { + header("HTTP/1.0 $code " . $this->http_status_code[$code]); + if (file_exists(ERROR_VIEW_PATH . "/{$code}.tpl") && + isset($this->getViewEngine()['Error'])) { + $uri = $this->getViewEngine()['Error']->template_dir . "{$code}.tpl"; + $this->getViewEngine()['Error']->display($uri); + } else { + echo($this->http_status_code[$code] . '.'); + } + } else { + header("HTTP/1.0 400 Bad Request"); + if (file_exists(ERROR_VIEW_PATH . '/400.tpl') && + isset($this->getViewEngine()['Error'])) { + $uri = $this->getViewEngine()['Error']->template_dir . '400.tpl'; + $this->getViewEngine()['Error']->display($uri); + } else { + echo('Bad Request.'); + } + } + } + + public function convertDirectoryPath($key, $kind) { + if (empty($kind) || empty($key)) { + return ''; + } + + switch ($kind) { + case 'view': + $result = __ABSPATH__ . 'view/' . $key; + break; + case 'viewc': + $result = __ABSPATH__ . 'view_c/' . $key; + break; + case 'controler': + $result = __ABSPATH__ . 'controler/' . $key; + break; + default: + $result = ''; + break; + } + + return $result; + } + + private function convertRootUri($uri) { + return (!empty($uri)) ? implode('', explode($this->getRootDirectory(), $uri, 2)) : ''; + } +} diff --git a/modules/kernel/main.php b/modules/kernel/main.php new file mode 100644 index 0000000..8699476 --- /dev/null +++ b/modules/kernel/main.php @@ -0,0 +1,88 @@ + + */ + +namespace Kernel; + +/** + * Kernelオブジェクトへの初期化処理。 + * + * @param Kernel $kernel + * @param array $param + * @return void + */ +function init($kernel, $param = null) { + /** + * セッションを保存。 + */ + $kernel->setSession($_SESSION); + + /** + * Subディレクトリの設定。 + * + * @param array $param + * @return string | null + */ + $kernel->setSubDir($param); + + /** + * URIの抽出。 + * + * @param array $param + * @return string + */ + $kernel->setURI($param); + + /** + * 引数の抽出。 + * + * @param void + * @return array + */ + $kernel->setARGV(); + + /** + * メソッドの抽出。 + * + * @param Kernel $kernel + * @return string + */ + $kernel->setMethod(); + + /** + * 引数の数を抽出。 + * + * @param Kernel $kernel + * @return int + */ + $kernel->setARGC(); + + /** + * アクセスされたポート番号を抽出。 + */ + $kernel->setServerPort(intval($_SERVER['SERVER_PORT'])); + + + /** + * 各種パスの抽出。 + */ + $kernel->setPathRoot(substr(__ABSPATH__, 0, -1) . (isset($param['root_directory']) ? $param['root_directory'] : '')); + + $kernel->setPathView($kernel->convertDirectoryPath($param['path_site_key'], 'view')); + + $kernel->setPathViewc($kernel->convertDirectoryPath($param['path_site_key'], 'viewc')); + + $kernel->setPathControler($kernel->convertDirectoryPath($param['path_site_key'], 'controler')); + + $kernel->setPathErrorView($kernel->convertDirectoryPath($param['path_error_key'], 'view')); + + $kernel->setPathErrorViewc($kernel->convertDirectoryPath($param['path_error_key'], 'viewc')); + + $kernel->setRootDirectory((isset($param['root_directory'])) ? $param['root_directory'] : null); +} diff --git a/modules/templateengine/class.php b/modules/templateengine/class.php new file mode 100644 index 0000000..c99aa92 --- /dev/null +++ b/modules/templateengine/class.php @@ -0,0 +1,97 @@ + + */ + +namespace TemplateEngine; + +/** + * TemplateEngineクラス + * + * Macacaにおける処理のコアとなります。 + * 引数の監理やMVCの紐付けを行います。 + * + * @category TemplateEngine + * @package TemplateEngine + */ +class TemplateEngine +{ + // 各種パラメータの保持 + private $parameter; + public $template_dir = ''; + public $compile_dir = ''; + + public function __construct() + { + $this->parameter = []; + $this->parameter['flag'] = 0; + $this->parameter['PathView'] = __ABSPATH__ . 'view'; + $this->template_dir = ''; + } + + // クラスを拡張するための処理 + public function __call($name, $args) + { + if (strncmp($name, 'get', 3) === 0) { + return $this->get(substr($name, 3), reset($args)); + } + elseif (strncmp($name, 'set', 3) === 0) { + return $this->set(substr($name, 3), reset($args)); + } + elseif (strncmp($name, 'exec', 4) === 0) { + return $this->exec(substr($name, 4), reset($args)); + } + else { + } + + throw new \BadMethodCallException('Method "' . $name . '" does not exist.'); + } + + // クラスを拡張するための処理 + public function __set($key, $value) + { + $this->set($key, $value); + } + + // クラスを拡張するための処理 + public function get($key, $default = null) + { + if (array_key_exists($key, $this->parameter)) { + return $this->parameter[$key]; + } + + return $default; + } + + // クラスを拡張するための処理 + public function set($key, $value) + { + $this->parameter[$key] = $value; + } + + // クラスを拡張するための処理 + public function exec($key, $func = null) + { + $func(); + } + + /** + * Viewを表示する。 + * + * @param int $value + */ + public function display($value) + { + if (file_exists($value)) { + include($value); + } + } +} diff --git a/modules/templateengine/main.php b/modules/templateengine/main.php new file mode 100644 index 0000000..b2f018d --- /dev/null +++ b/modules/templateengine/main.php @@ -0,0 +1,22 @@ + + */ + +namespace TemplateEngine; + +/** + * TemplateEngineオブジェクトへの初期化処理。 + * + * @param TemplateEngine $template_enagine + * @param array $param + * @return void + */ +function init($template_enagine, $param = null) { + ; +} diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..048c945 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,7 @@ + +RewriteEngine On +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . index.php [L] + diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..1a457fe --- /dev/null +++ b/public/index.php @@ -0,0 +1,52 @@ + + */ + +/* + * 初期化 + * -------------- */ +if (!defined('LOADED_CONFIG')) { + session_start(); + include_once('../config.php'); +} + +# URI +# protocol://***.***.***/ の形式で記載すること +define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/'); + +$kernel = new Kernel\Kernel(); +$param = array('root_directory' => ROOT_URI, + 'path_site_key' => 'sample', + 'path_error_key' => 'error'); +Kernel\init($kernel, $param); + +/* + * Object生成 + * -------------- */ +$view_engine['templateengine'] = new TemplateEngine\TemplateEngine; +$view_engine['templateengine']->template_dir = $kernel->getPathView() . '/'; +$view_engine['Error'] = new TemplateEngine\TemplateEngine; +$view_engine['Error']->template_dir = $kernel->getPathErrorView() . '/'; +$kernel->setViewEngine($view_engine); + +$_SERVER['SERVER_SOFTWARE'] = 'Macaca'; +$_SERVER['SERVER_SIGNATURE'] = "
" . $_SERVER['SERVER_SOFTWARE'] . " at " . $_SERVER['SERVER_NAME'] . " Port " . $_SERVER['SERVER_PORT'] . "
"; + +$parser = array(); +$kernel->setParser($parser); + +/* + * Controler実行 + * -------------- */ +$kernel->execControler(); + +/* + * View実行 + * -------------- */ +$kernel->execViewEngine(); diff --git a/view/error/400.tpl b/view/error/400.tpl new file mode 100644 index 0000000..e3e804a --- /dev/null +++ b/view/error/400.tpl @@ -0,0 +1,11 @@ + + + + + Error 400 + + + +

Error 400

+ + \ No newline at end of file diff --git a/view/error/403.tpl b/view/error/403.tpl new file mode 100644 index 0000000..c65f755 --- /dev/null +++ b/view/error/403.tpl @@ -0,0 +1,11 @@ + + + + + Error 403 + + + +

Error 403

+ + \ No newline at end of file diff --git a/view/error/404.tpl b/view/error/404.tpl new file mode 100644 index 0000000..af7a93b --- /dev/null +++ b/view/error/404.tpl @@ -0,0 +1,11 @@ + + + + + Error 404 + + + +

Error 404

+ + \ No newline at end of file diff --git a/view/sample/index.tpl b/view/sample/index.tpl new file mode 100644 index 0000000..5aebb35 --- /dev/null +++ b/view/sample/index.tpl @@ -0,0 +1,83 @@ + + + + */ +if (SITE_USE_OGP) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +?> + + <?php +if (!empty($this->title)) { + echo($this->title . ' | '); +} +echo(SITE_NAME); +?> +keywords)) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +if (!empty($this->description)) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +?> + + +' . "\n"); + if (!empty($this->description)) { + echo(' ' ."\n"); + } + else { + echo(' ' . "\n"); + } + echo(' ' . "\n"); + if (defined('SITE_CACHE')) { + echo(' ' . "\n"); + } + else { + echo(' ' . "\n"); + } + echo(' ' . "\n"); + if (!empty($this->title)) { + echo(' ' ."\n"); + } + else { + echo(' ' ."\n"); + } + if (defined('SITE_EMAIL')) { + echo(' ' ."\n"); + } +} + +if (defined('SITE_CACHE')) { + echo(' ' ."\n"); +} else { + echo(' ' ."\n"); +} +?> + + + +getString()); +?>
+ + \ No newline at end of file diff --git a/view/sample/sub/index.tpl b/view/sample/sub/index.tpl new file mode 100644 index 0000000..7420310 --- /dev/null +++ b/view/sample/sub/index.tpl @@ -0,0 +1,83 @@ + + + + */ +if (SITE_USE_OGP) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +?> + + <?php +if (!empty($this->title)) { + echo($this->title . ' | '); +} +echo(SITE_NAME); +?> +keywords)) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +if (!empty($this->description)) { + echo(' ' . "\n"); +} +else { + echo(' ' . "\n"); +} +?> + + +' . "\n"); + if (!empty($this->description)) { + echo(' ' ."\n"); + } + else { + echo(' ' . "\n"); + } + echo(' ' . "\n"); + if (defined('SITE_CACHE')) { + echo(' ' . "\n"); + } + else { + echo(' ' . "\n"); + } + echo(' ' . "\n"); + if (!empty($this->title)) { + echo(' ' ."\n"); + } + else { + echo(' ' ."\n"); + } + if (defined('SITE_EMAIL')) { + echo(' ' ."\n"); + } +} + +if (defined('SITE_CACHE')) { + echo(' ' ."\n"); +} else { + echo(' ' ."\n"); +} +?> + + + +getString()); +?>
+ + \ No newline at end of file