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 0000000..283bc53
Binary files /dev/null and b/images/thumbnail.png differ
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..c57fe63
--- /dev/null
+++ b/index.php
@@ -0,0 +1,12 @@
+
+ */
+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");
+}
+?>
+
+ 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");
+}
+?>
+
+ 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