From 12f4a9a142c7f0507bfaf4e10cf5e0d1c4aa97dd Mon Sep 17 00:00:00 2001 From: Pentagonal Date: Wed, 5 Apr 2017 18:06:09 +0700 Subject: [PATCH 001/142] Initial commit --- LICENSE | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..abf1a59 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, PentagonalProject +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From d471093fac4f88a0c0207f8f8b73001924d9477b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Wed, 5 Apr 2017 18:13:33 +0700 Subject: [PATCH 002/142] =?UTF-8?q?singing=20=F0=9F=8E=A4=20=20with=20a=20?= =?UTF-8?q?cup=20of=20=E2=98=95=20coffee?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 175 +++++++++++++++++++ App/.htaccess | 1 + App/Classes/AutoLoaderClass.php | 300 ++++++++++++++++++++++++++++++++ App/Functions/Utilities.php | 4 + App/loader.php | 16 ++ LICENSE | 2 +- Modules/.htaccess | 1 + Modules/index.php | 2 + README.md | 7 + Storage/.htaccess | 1 + bootstrap.php | 10 ++ composer.json | 30 ++++ config.php | 30 ++++ phpcs.xml | 19 ++ site_api/.htaccess | 40 +++++ site_api/index.php | 11 ++ site_web/.htaccess | 40 +++++ site_web/index.php | 11 ++ 18 files changed, 699 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 App/.htaccess create mode 100644 App/Classes/AutoLoaderClass.php create mode 100644 App/Functions/Utilities.php create mode 100644 App/loader.php create mode 100644 Modules/.htaccess create mode 100644 Modules/index.php create mode 100644 README.md create mode 100644 Storage/.htaccess create mode 100644 bootstrap.php create mode 100644 composer.json create mode 100644 config.php create mode 100644 phpcs.xml create mode 100644 site_api/.htaccess create mode 100644 site_api/index.php create mode 100644 site_web/.htaccess create mode 100644 site_web/index.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a00957d --- /dev/null +++ b/.gitignore @@ -0,0 +1,175 @@ +# ####################################################################### +# Gitignore +# Add Some Common OS and Code Editor +# ####################################################################### + +# +# ================================= +# Gitignore For Mac +# ================================= +# + +# Apple Default hidden +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# +# ================================= +# Gitignore For Windows +# ================================= +# + +# Windows image file caches +Thumbs.db +thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# System Volumes Information used on file shares +System Volume Information/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp +*.exe + +# Windows shortcuts +*.lnk + +# +# ================================= +# Gitignore For Linux OS +# ================================= + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# +# ================================= +# Gitignore For SublimeText +# ================================= + +# cache files for sublime text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# workspace files are user-specific +*.sublime-workspace + +# project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using SublimeText +# *.sublime-project + +# sftp configuration file +sftp-config.json + +# +# ================================= +# Gitignore For Jetbrain +# ================================= +# + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# .idea/shelf + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Gitignore For Composer +# ================================= +# + +# ignore all lock file +*.lock + +# ignore all log file +*.log + +# ignore composer phar file +composer.phar + +# add exclude vendor +vendor + +# Ignore Sublime .phpintel +.phpintel + +# Ignore Visual Studio code +.vscode + diff --git a/App/.htaccess b/App/.htaccess new file mode 100644 index 0000000..31f17f9 --- /dev/null +++ b/App/.htaccess @@ -0,0 +1 @@ +Deny From All diff --git a/App/Classes/AutoLoaderClass.php b/App/Classes/AutoLoaderClass.php new file mode 100644 index 0000000..21d6326 --- /dev/null +++ b/App/Classes/AutoLoaderClass.php @@ -0,0 +1,300 @@ +nameSpace = $this->resolveNameSpace($nameSpace); + $this->baseDirectory = (array) $directory; + } + + /** + * @return array + */ + public static function getReferences() + { + return AutoLoaderClass::$references; + } + + /** + * Resolve Name Space + * + * @param string $string + * @return string + */ + protected function resolveNameSpace($string) + { + return preg_replace( + '`(\\\)+`', + '\\', + trim($string, '\\') + ); + } + + /** + * Resolve Name Space To Lower + * + * @param string $string + * @return string + */ + protected function resolveNameSpaceLower($string) + { + return $this->toLower($this->resolveNameSpace($string)); + } + + /** + * To Lower Case + * + * @param string $string + * @return string + */ + protected function toLower($string) + { + // sanity case insensitive class + return strtolower($string); + } + + /** + * Push Into Reference + * + * @param string $group the group / Name Space + * @param string $class the class Name + * @param string $file the absolute file + * @return bool|string + */ + private function pushReference($group, $class, $file) + { + if ($file = stream_resolve_include_path($file)) { + $ref =& AutoLoaderClass::$references; + // references name space + $nameSpace = $this->resolveNameSpace($group); + $group = $this->toLower($nameSpace); + if ($this->hasGroupReference($group)) { + $ref[$group] = []; + } + + return $ref[$group][$this->resolveNameSpaceLower($class)] = $file; + } + + return false; + } + + /** + * @param string $class + * @return bool + */ + public function load($class) + { + if (!is_string($class)) { + return false; + } + + if ($file = $this->findFileFor($class)) { + // prevent multiple call instance of class + if (class_exists($class)) { + return true; + } + + IncludeFileOnce($file); + return true; + } + + return false; + } + + /** + * Create Instance + * + * @param string $nameSpace + * @param string|array $directory + * @return static + */ + public static function create($nameSpace, $directory) + { + return new static($nameSpace, $directory); + } + + /** + * Create Object & Register + * + * @param string $nameSpace the name space + * @param string|array $directory directory to scan + * @return bool + */ + public static function createRegister($nameSpace, $directory) + { + return (new static($nameSpace, $directory))->register(); + } + + /** + * Register Auto load + * + * @param bool $prepend + * @return bool + */ + public function register($prepend = false) + { + return spl_autoload_register([$this, 'load'], true, $prepend); + } + + /** + * Un-Registers this instance as an autoloader. + */ + public function unRegister() + { + spl_autoload_unregister([$this, 'load']); + } + + /** + * Get File For Class + * + * @param string $class + * @return bool|string + */ + protected function findFileFor($class) + { + $class = $this->resolveNameSpaceLower($class); + if (isset(self::$classLoadedRef[$class])) { + return self::$classLoadedRef[$class]; + } + + if (false !== $file = $this->getClassReference($class)) { + return $file; + } + + foreach ($this->baseDirectory as $directory) { + if (!is_string($directory) || ! ($directory = realpath($directory))) { + continue; + } + + if (false !== $pos = strpos($class, $this->nameSpace)) { + $class = substr($class, $pos+1); + } + + $file = $this->pushReference( + $this->nameSpace, + $class, + $directory . DIRECTORY_SEPARATOR . $class . '.php' + ); + + if ($file) { + self::$classLoadedRef[$this->resolveNameSpaceLower($class)] = $file; + break; + } + } + + return $file; + } + + /** + * Split Name Space Key + * + * @param string $class + * @return array + */ + protected function splitClassNameSpace($class) + { + $class = $this->resolveNameSpace($class); + $nameSpaceArray = explode('\\', $class); + $nameSpace = ''; + $class = end($nameSpaceArray); + array_shift($nameSpaceArray); + if (count($nameSpaceArray) > 1) { + $nameSpace = implode('\\', $nameSpaceArray); + } + return [ + self::NAME_SPACE_KEY => $nameSpace, + self::CLASS_NAME_KEY => $class, + ]; + } + + /** + * Get Reference + * @param string $class + * @return bool|array + */ + protected function getClassReference($class) + { + // check if not as a class + if (!$class || substr($class, -1) == '\\') { + return false; + } + + $splitClass = $this->splitClassNameSpace($class); + $group = $this->getGroupReference($splitClass[self::NAME_SPACE_KEY]); + + return $group && isset($group[$splitClass[self::CLASS_NAME_KEY]]) + ? $group[$splitClass[self::CLASS_NAME_KEY]] + : false; + } + + /** + * Getting References + * + * @param string $group + * @return bool|mixed + */ + protected function getGroupReference($group) + { + if ($this->hasGroupReference($group)) { + return AutoLoaderClass::$references[$this->resolveNameSpace($group)]; + } + + return false; + } + + /** + * Has Group reference + * + * @param string $group + * @return bool + */ + protected function hasGroupReference($group) + { + $group = $this->resolveNameSpaceLower($group); + return isset(AutoLoaderClass::$references[$group]); + } +} + +/** + * @param string $file + */ +function IncludeFileOnce($file) +{ + /** @noinspection PhpIncludeInspection */ + include_once $file; +} diff --git a/App/Functions/Utilities.php b/App/Functions/Utilities.php new file mode 100644 index 0000000..800a729 --- /dev/null +++ b/App/Functions/Utilities.php @@ -0,0 +1,4 @@ += 5.6", + "apatis/array-storage": "^1", + "apatis/exceptions": "^1", + "apatis/transporter": "dev-master", + "aura/session": "^2.1", + "doctrine/dbal": "^2.5", + "guzzlehttp/guzzle": "~6", + "pentagonal/phpass": "^1", + "pentagonal/simple_encrypt": "^1", + "slim/slim": "^2", + "wa72/htmlpagedom": "^1.3" + }, + "require-dev": { + "squizlabs/php_codesniffer": "2.*", + "phpunit/phpunit": "^5" + }, + "license": "BSD", + "authors": [ + { + "name": "nawa", + "email": "nawa@yahoo.com" + } + ] +} diff --git a/config.php b/config.php new file mode 100644 index 0000000..a75dee6 --- /dev/null +++ b/config.php @@ -0,0 +1,30 @@ + [ + 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', + 'app' => __DIR__ . DIRECTORY_SEPARATOR . 'App', + 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', + ], + 'database' => [ + 'host' => 'localhost', + 'user' => '', + 'password' => '', + 'name' => '', + 'port' => 3306, + 'charset' => 'utf-8', + ], + 'environment' => [ + 'debug' => true, + 'error' => true, + 'log' => true, + ], + 'session' => [ + 'path' => '/', + 'save_path' => null, + 'expire' => null, + 'domain' => '*', + ], +]; diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..2d6df1c --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,19 @@ + + + Coding Standard + + + + + + + + + + + + + + App + Modules + diff --git a/site_api/.htaccess b/site_api/.htaccess new file mode 100644 index 0000000..c04d6cc --- /dev/null +++ b/site_api/.htaccess @@ -0,0 +1,40 @@ +# ---------------------------------------------------------------- +# CONF - htaccess (Apache) +# --------------------------------------------------------------- + +# Don't Allow directory indexing +Options Indexes FollowSymLinks Multiviews + +# ---------------------------------------------------------------- +# SECURITY ENGAGEMENT +# ---------------------------------------------------------------- + +# prevent all accesed start with +# dot(.) to accesed by external +# ------------------------------- + + Deny From All + + +# set default 403 forbidden into +# Current url - best experience +# Routes +# ------------------------------- +ErrorDocument 403 / + +# ---------------------------------------------------------------- +# ROUTES HANDLER +# ---------------------------------------------------------------- + +# Handle Index base URI '/' With +# ------------------------------- + + + RewriteEngine on + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + # use index.php as base URL + RewriteRule ^(.*)$ index.php [QSA,L] + # handle index.html & index.php to solved as / + RewriteRule ^(index\.s?html)?$ index.php [QSA,L] + diff --git a/site_api/index.php b/site_api/index.php new file mode 100644 index 0000000..347a248 --- /dev/null +++ b/site_api/index.php @@ -0,0 +1,11 @@ + + Deny From All + + +# set default 403 forbidden into +# Current url - best experience +# Routes +# ------------------------------- +ErrorDocument 403 / + +# ---------------------------------------------------------------- +# ROUTES HANDLER +# ---------------------------------------------------------------- + +# Handle Index base URI '/' With +# ------------------------------- + + + RewriteEngine on + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + # use index.php as base URL + RewriteRule ^(.*)$ index.php [QSA,L] + # handle index.html & index.php to solved as / + RewriteRule ^(index\.s?html)?$ index.php [QSA,L] + diff --git a/site_web/index.php b/site_web/index.php new file mode 100644 index 0000000..347a248 --- /dev/null +++ b/site_web/index.php @@ -0,0 +1,11 @@ + Date: Fri, 21 Apr 2017 19:07:24 +0700 Subject: [PATCH 003/142] =?UTF-8?q?Ngopi=20(=E2=98=95)=20dulu=20juragan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + App/Classes/Application.php | 92 +++ App/Classes/AutoLoaderClass.php | 84 ++- App/Classes/Config.php | 137 ++++ App/Classes/Database.php | 828 ++++++++++++++++++++++ App/FunctionsIncludes.php | 7 + App/Includes/Constant.php | 12 + App/Includes/Environment.php | 158 +++++ App/{Functions => Includes}/Utilities.php | 0 App/loader.php | 16 - bootstrap.php | 10 - composer.json | 20 +- config.php | 2 +- {site_api => public}/.htaccess | 0 public/index.php | 113 +++ site_api/index.php | 11 - site_web/.htaccess | 40 -- site_web/index.php | 11 - 18 files changed, 1425 insertions(+), 117 deletions(-) create mode 100644 App/Classes/Application.php create mode 100644 App/Classes/Config.php create mode 100644 App/Classes/Database.php create mode 100644 App/FunctionsIncludes.php create mode 100644 App/Includes/Constant.php create mode 100644 App/Includes/Environment.php rename App/{Functions => Includes}/Utilities.php (100%) delete mode 100644 App/loader.php delete mode 100644 bootstrap.php rename {site_api => public}/.htaccess (100%) create mode 100644 public/index.php delete mode 100644 site_api/index.php delete mode 100644 site_web/.htaccess delete mode 100644 site_web/index.php diff --git a/.gitignore b/.gitignore index a00957d..dd948d7 100644 --- a/.gitignore +++ b/.gitignore @@ -173,3 +173,4 @@ vendor # Ignore Visual Studio code .vscode +Modules/*/ diff --git a/App/Classes/Application.php b/App/Classes/Application.php new file mode 100644 index 0000000..0e4485a --- /dev/null +++ b/App/Classes/Application.php @@ -0,0 +1,92 @@ +appDirectory = dirname(__DIR__); + $this->rootDirectory = dirname($this->appDirectory); + $this->init($config); + } + + /** + * @return string + */ + public function getRootDirectory() + { + return $this->rootDirectory; + } + + /** + * @return string + */ + public function getAppDirectory() + { + return $this->appDirectory; + } + + /** + * Initialize + * + * @param $config + */ + protected function init($config) + { + $config['directory'] = isset($config['directory']) ? $config['directory'] : []; + if (!is_array($config['directory'])) { + $config['directory'] = []; + } + $config['directory'] = array_merge([ + 'module' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Modules', + 'storage' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Storage' + ], $config['directory']); + + $config['httpVersion'] = isset($_SERVER['SERVER_PROTOCOL']) + && strpos($_SERVER['SERVER_PROTOCOL'], '/') !== false + ? explode('/', $_SERVER['SERVER_PROTOCOL'])[1] + : '1.1'; + + $this->config = new Config($config); + } + + public function run() + { + $this->slim = new App( + [ + 'settings' => $this->config->get() + ] + ); + return $this->slim; + } +} diff --git a/App/Classes/AutoLoaderClass.php b/App/Classes/AutoLoaderClass.php index 21d6326..a0e78b3 100644 --- a/App/Classes/AutoLoaderClass.php +++ b/App/Classes/AutoLoaderClass.php @@ -1,11 +1,11 @@ classMap; } /** @@ -99,15 +112,15 @@ protected function toLower($string) private function pushReference($group, $class, $file) { if ($file = stream_resolve_include_path($file)) { - $ref =& AutoLoaderClass::$references; // references name space $nameSpace = $this->resolveNameSpace($group); $group = $this->toLower($nameSpace); if ($this->hasGroupReference($group)) { - $ref[$group] = []; + self::$references[$group] = []; } - - return $ref[$group][$this->resolveNameSpaceLower($class)] = $file; + $class = $this->resolveNameSpaceLower($class); + $this->classMap[$class] = $file; + return self::$references[$group][$class] = $file; } return false; @@ -122,9 +135,8 @@ public function load($class) if (!is_string($class)) { return false; } - if ($file = $this->findFileFor($class)) { - // prevent multiple call instance of class + // prevent multiple call instanphpfastcachece of class if (class_exists($class)) { return true; } @@ -160,6 +172,16 @@ public static function createRegister($nameSpace, $directory) return (new static($nameSpace, $directory))->register(); } + /** + * @param array $nameSpaceAndDirectory + */ + public static function createRegisterArray(array $nameSpaceAndDirectory) + { + foreach ($nameSpaceAndDirectory as $key => $item) { + self::createRegister($key, $item); + } + } + /** * Register Auto load * @@ -168,41 +190,48 @@ public static function createRegister($nameSpace, $directory) */ public function register($prepend = false) { - return spl_autoload_register([$this, 'load'], true, $prepend); + return spl_autoload_register($this, true, $prepend); } /** - * Un-Registers this instance as an autoloader. + * Un-Registers this instance as an auto loader. */ public function unRegister() { - spl_autoload_unregister([$this, 'load']); + spl_autoload_unregister($this); } /** * Get File For Class * - * @param string $class + * @param string $Class * @return bool|string */ - protected function findFileFor($class) + protected function findFileFor($Class) { - $class = $this->resolveNameSpaceLower($class); - if (isset(self::$classLoadedRef[$class])) { - return self::$classLoadedRef[$class]; + $Class = $this->resolveNameSpace($Class); + $class = $this->toLower($Class); + if ($class) { + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if (isset(self::$classMapReference[$class])) { + return self::$classMapReference[$class]; + } } if (false !== $file = $this->getClassReference($class)) { return $file; } + $namespace= $this->resolveNameSpaceLower($this->nameSpace); foreach ($this->baseDirectory as $directory) { if (!is_string($directory) || ! ($directory = realpath($directory))) { continue; } - if (false !== $pos = strpos($class, $this->nameSpace)) { - $class = substr($class, $pos+1); + if (0 === $pos = strpos($class, $namespace)) { + $class = substr($Class, strlen($namespace)+1); } $file = $this->pushReference( @@ -210,9 +239,8 @@ protected function findFileFor($class) $class, $directory . DIRECTORY_SEPARATOR . $class . '.php' ); - if ($file) { - self::$classLoadedRef[$this->resolveNameSpaceLower($class)] = $file; + self::$classMapReference[$this->resolveNameSpaceLower($class)] = $file; break; } } @@ -286,7 +314,15 @@ protected function getGroupReference($group) protected function hasGroupReference($group) { $group = $this->resolveNameSpaceLower($group); - return isset(AutoLoaderClass::$references[$group]); + return isset(self::$references[$group]); + } + + /** + * @param $class + */ + public function __invoke($class) + { + call_user_func_array([$this, 'load'], func_get_args()); } } diff --git a/App/Classes/Config.php b/App/Classes/Config.php new file mode 100644 index 0000000..103485b --- /dev/null +++ b/App/Classes/Config.php @@ -0,0 +1,137 @@ +collection = new CollectionFetch($setting); + $this->originalCollection = clone $this->collection; + } + + /** + * Get Config + * + * @param string|null $key + * @param mixed $default + * @return mixed + */ + public function get($key = null, $default = null) + { + if (!func_num_args()) { + return $this->collection->all(); + } + + return $this->collection->fetch($key, $default); + } + + /** + * Reset Collection to default + */ + public function resetToDefault() + { + $this->lastCollection = $this->collection; + $this->collection = clone $this->originalCollection; + } + + /** + * @return CollectionFetch + */ + public function getCurrentCollection() + { + return $this->collection; + } + + /** + * @return CollectionFetch + */ + public function getDefaultCollection() + { + return $this->originalCollection; + } + + /** + * @return CollectionFetch + */ + public function getLastCollection() + { + return $this->lastCollection ?: $this->collection; + } + + /** + * @param array|string $key string + * @param mixed $values the value key name + */ + public function set($key, $values = null) + { + if (is_array($key)) { + $this->collection->replace($key); + return; + } + + if (!is_string($key) && !is_numeric($key)) { + throw new InvalidArgumentException( + 'Invalid key name given! Key config must be as a string!' + ); + } + if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $key, $matches)) > 1) { + // Does the index contain array notation + $the_key = null; + $matches[0] = array_reverse($matches[0]); + $old_key = null; + for ($i = 0; $i < $count; $i++) { + $key = trim($matches[0][$i], '[]'); + // Empty notation will return the value as array + if ($key === '') { + $the_key[] = $the_key?: $values; + if (count($the_key) > 1) { + unset($the_key[key($the_key)]); + } + continue; + } + if (!isset($the_key)) { + $the_key[$key] = $values; + continue; + } + + $the_key[$key] = $the_key; + if (count($the_key) > 1) { + unset($the_key[key($the_key)]); + } + } + + $key = key($the_key); + $values = is_array($this->collection[$key]) + ? array_merge($this->collection[$key], $the_key[$key]) + : $the_key; + unset($the_key); + } + + $this->collection->set($key, $values); + } +} diff --git a/App/Classes/Database.php b/App/Classes/Database.php new file mode 100644 index 0000000..4ae120a --- /dev/null +++ b/App/Classes/Database.php @@ -0,0 +1,828 @@ + @uses Connection + * + * @method void beginTransaction() + * + * @method void close() + * @method void commit() + * @method bool connect() + * @method mixed convertToDatabaseValue(mixed $value, $type) + * @method mixed convertToPHPValue(mixed $value, $type) + * @method QueryBuilder createQueryBuilder() + * @method void createSavepoint(string $savepoint) + * + * @method int delete(string $tableExpression, array $identifier, array $types = []) + * + * @method int errorCode() + * @method array errorInfo() + * @method void exec(string $statement) + * @method Statement executeQuery(string $query, array $params = [], array $types = [], QueryCacheProfile $qcp = null) + * @method ResultStatement executeCacheQuery(string $query, $params, $types, QueryCacheProfile $qcp) + * @method int executeUpdate(string $query, array $params = [], array $types = []) + * + * @method int insert(string $tableExpression, array $data, array $types = []) + * @method bool isAutoCommit() + * @method bool isConnected() + * @method bool isRollbackOnly() + * @method bool isTransactionActive() + * + * @method array fetchAssoc(string $statement, array $params = [], array $types = []) + * @method array fetchArray(string $statement, array $params = [], array $types = []) + * @method array fetchColumn(string $statement, array $params = [], array $types = []) + * @method array fetchAll(string $sql, array $params = array(), $types = array()) + * + * @method Configuration getConfiguration() + * @method Driver getDriver() + * @method string getDatabase() + * @method AbstractPlatform getDatabasePlatform() + * @method EventManager getEventManager() + * @method ExpressionBuilder getExpressionBuilder() + * @method string getHost() + * @method array getParams() + * @method string|null getPassword() + * @method mixed getPort() + * @method AbstractSchemaManager getSchemaManager() + * @method int getTransactionIsolation() + * @method int getTransactionNestingLevel() + * @method string|null getUsername() + * @method Connection getWrappedConnection() + * + * @method string lastInsertId(string|null $seqName) + * + * @method bool ping() + * @method Statement prepare(string $statement) + * @method array project(string $query, array $params, \Closure $function) + * + * @method void releaseSavepoint(string $savePoint) + * @method array resolveParams(array $params, array $types) + * @method bool|void rollBack() + * @method void rollbackSavepoint(string $savePoint) + * + * @method void setAutoCommit(bool $autoCommit) + * @method void setFetchMode(int $fetchMode) + * @method void setNestTransactionsWithSavePoints(bool $nestTransactionsWithSavePoints) + * @method void setRollbackOnly() + * @method int setTransactionIsolation(int $level) + * + * @method void transactional(\Closure $func) + * + * @method int update(string $tableExpression, array $data, array $identifier, array $types = []) + * + * @method string quote(mixed $input, int $type = \PDO::PARAM_STR) + * @method string quoteIdentifier(string $str) + * + * @uses \PDO::ATTR_DEFAULT_FETCH_MODE for (19) + * @method Statement query(string $sql, int $mode = 19, mixed $additionalArg = null, array $constructorArgs = []) + */ +class Database +{ + /** + * @see Connection::TRANSACTION_READ_UNCOMMITTED + */ + const TRANSACTION_READ_UNCOMMITTED = Connection::TRANSACTION_READ_UNCOMMITTED; + + /** + * @see Connection::TRANSACTION_READ_COMMITTED + */ + const TRANSACTION_READ_COMMITTED = Connection::TRANSACTION_READ_COMMITTED; + + /** + * @see Connection::TRANSACTION_REPEATABLE_READ + */ + const TRANSACTION_REPEATABLE_READ = Connection::TRANSACTION_REPEATABLE_READ; + + /** + * @see Connection::TRANSACTION_SERIALIZABLE + */ + const TRANSACTION_SERIALIZABLE = Connection::TRANSACTION_SERIALIZABLE; + + /** + * @see Connection::PARAM_INT_ARRAY + */ + const PARAM_INT_ARRAY = Connection::PARAM_INT_ARRAY; + + /** + * @see Connection::PARAM_STR_ARRAY + */ + const PARAM_STR_ARRAY = Connection::PARAM_STR_ARRAY; + + /** + * @see Connection::ARRAY_PARAM_OFFSET + */ + const ARRAY_PARAM_OFFSET = Connection::ARRAY_PARAM_OFFSET; + + /** + * @var Connection + */ + protected $currentConnection; + + /** + * @var string + */ + protected $currentSelectedDriver; + + /** + * @var array + */ + protected $currentUserParams = [ + 'charset' => 'utf8', + 'collate' => 'utf8_unicode_ci', // 'utf_general_ci' + ]; + + /** + * @var string + */ + protected $currentTablePrefix = ''; + + /** + * Column Quote Identifier + * + * @var string + */ + protected $currentQuoteIdentifier = '"'; + + /** + * Database constructor. + * @param array $configs database Configuration + * @throws DBALException + */ + public function __construct(array $configs) + { + /** + * Merge User Param + */ + $this->currentUserParams = array_merge($this->currentUserParams, $configs); + if (!isset($this->currentUserParams['driver'])) { + throw new DBALException('Driver must be declare.', E_USER_ERROR); + } + if (! is_string($this->currentUserParams['driver'])) { + throw new DBALException('Driver must as a string.', E_USER_ERROR); + } + + if (isset($this->currentUserParams['port'])) { + if ($this->currentUserParams['port']) { + if (!is_numeric($this->currentUserParams['port'])) { + throw new DBALException('Invalid database port.', E_USER_ERROR); + } + } else { + unset($this->currentUserParams['port']); + } + } + + /** + * Sanitize Selected Driver + */ + $this->currentSelectedDriver = $this + ->sanitizeSelectedAvailableDriver($this->currentUserParams['driver']); + if (!$this->currentSelectedDriver) { + throw new DBALException('Selected driver unavailable.', E_USER_ERROR); + } + + if (isset($this->currentUserParams['prefix']) && is_string($this->currentUserParams['prefix'])) { + $this->currentUserParams['prefix'] = trim($this->currentUserParams['prefix']); + $this->currentTablePrefix = (string) $this->currentUserParams['prefix']; + } + if (isset($this->currentUserParams['dbname']) && !isset($this->currentUserParams['name'])) { + $this->currentUserParams['name'] = $this->currentUserParams['dbname']; + } + + if ((!isset($this->currentUserParams['name']) || !is_string($this->currentUserParams['name'])) + && $this->currentSelectedDriver != 'pdo_sqlite' + ) { + throw new DBALException('Invalid Database Name.', E_USER_ERROR); + } + + if ($this->currentSelectedDriver == 'pdo_sqlite' && !isset($this->currentUserParams['path'])) { + if (!isset($this->currentUserParams['name']) || !is_string($this->currentUserParams['name'])) { + throw new DBALException('SQLite database path must be not empty.', E_USER_ERROR); + } + $this->currentUserParams['path'] = $this->currentUserParams['name']; + } + $this->currentUserParams['dbname'] = $this->currentUserParams['name']; + unset($this->currentUserParams['name']); + + /** + * create new parameters + */ + $this->currentUserParams['driver'] = $this->currentSelectedDriver; + + /** + * Create New Connection + */ + $this->currentConnection = DriverManager::getConnection($this->currentUserParams); + + /** + * Set Quote Identifier + */ + $this->currentQuoteIdentifier = $this-> + currentConnection + ->getDatabasePlatform() + ->getIdentifierQuoteCharacter(); + } + + /** + * Getting Doctrine Connection + * + * @return Connection + */ + public function getConnection() + { + return $this->currentConnection; + } + + /** + * Get Table Prefix + * + * @return string + */ + public function getTablePrefix() + { + return $this->currentTablePrefix; + } + + /** + * Get identifier + * + * @return string + */ + public function getQuoteIdentifier() + { + return $this->currentQuoteIdentifier; + } + + /** + * Get user params + * + * @return array + */ + public function getUserParams() + { + return $this->currentUserParams; + } + + /** + * Get Connection params + * + * @return array + */ + public function getConnectionParams() + { + return $this->getParams(); + } + + /** + * Check Database driver available for Doctrine + * and choose the best driver of sqlsrv an oci + * + * @param string $driverName + * @final + * @return bool|string return lowercase an fix database driver for Connection + */ + final public function sanitizeSelectedAvailableDriver($driverName) + { + if (is_string($driverName) && trim($driverName)) { + $driverName = trim(strtolower($driverName)); + /** + * switch to Doctrine fixed db + * Aliases + */ + $driverSchemeAliases = [ + 'db2' => 'ibm_db2', + 'drizzle' => 'drizzle_pdo_mysql', + 'mssql' => 'pdo_sqlsrv', + 'mysql' => 'pdo_mysql', + 'mysql2' => 'pdo_mysql', // Amazon RDS, for some weird reason + 'postgre' => 'pdo_pgsql', + 'postgre_sql'=> 'pdo_pgsql', + 'postgres' => 'pdo_pgsql', + 'postgresql' => 'pdo_pgsql', + 'pgsql' => 'pdo_pgsql', + 'sqlite' => 'pdo_sqlite', + 'sqlite3' => 'pdo_sqlite', + 'oci' => 'oci8', + 'pdo_oci' => 'oci8', # recommendation pdo_oci uses oci8 + 'pdo_sqlsrv' => 'sqlsrv', #recommendation pdo_sqlsrv uses sqlsrv + ]; + if (isset($driverSchemeAliases[$driverName])) { + $driverName = $driverSchemeAliases[$driverName]; + } + + if (in_array($driverName, DriverManager::getAvailableDrivers())) { + return $driverName; + } + } + + return false; + } + + /** + * Trimming table for safe usage + * + * @param mixed $table + * @return mixed + */ + public function trimTableSelector($table) + { + if (is_array($table)) { + foreach ($table as $key => $value) { + $table[$key] = $this->trimTableSelector($value); + } + return $table; + } elseif (is_object($table)) { + foreach (get_object_vars($table) as $key => $value) { + $table->{$key} = $this->trimTableSelector($value); + } + return $table; + } + if (is_string($table)) { + $tableArray = explode('.', $table); + foreach ($tableArray as $key => $value) { + $tableArray[$key] = trim( + trim( + trim($value), + $this->currentQuoteIdentifier + ) + ); + } + $table = implode('.', $tableArray); + } + + return $table; + } + + /** + * Alternative multi variable type quoted identifier + * + * @param mixed $quoteStr + * @return mixed + * @throws \InvalidArgumentException + */ + public function quoteIdentifiers($quoteStr) + { + if ($quoteStr instanceof \Closure || is_resource($quoteStr)) { + throw new \InvalidArgumentException( + "Invalid value to be quote, quote value could not be instance of `Closure` or as a `Resource`", + E_USER_ERROR + ); + } + + $quoteStr = $this->trimTableSelector($quoteStr); + if (is_array($quoteStr)) { + foreach ($quoteStr as $key => $value) { + $quoteStr[$key] = $this->quoteIdentifiers($value); + } + return $quoteStr; + } elseif (is_object($quoteStr)) { + foreach (get_object_vars($quoteStr) as $key => $value) { + $quoteStr->{$key} = $this->quoteIdentifiers($value); + } + return $quoteStr; + } + + $return = $this->quoteIdentifier($quoteStr); + + return $return; + } + + /** + * Alternative multi variable type quote string + * Nested quotable + * + * @param mixed $quoteStr + * @param int $type + * @return array|mixed|string + */ + public function quotes($quoteStr, $type = \PDO::PARAM_STR) + { + if ($quoteStr instanceof \Closure || is_resource($quoteStr)) { + throw new \InvalidArgumentException( + "Invalid value to be quote, quote value could not be instance of `Closure` or as a `Resource`", + E_USER_ERROR + ); + } + + $quoteStr = $this->trimTableSelector($quoteStr); + if (is_array($quoteStr)) { + foreach ($quoteStr as $key => $value) { + $quoteStr[$key] = $this->quotes($value, $type); + } + return $quoteStr; + } elseif (is_object($quoteStr)) { + foreach (get_object_vars($quoteStr) as $key => $value) { + $quoteStr->{$key} = $this->quotes($value, $type); + } + return $quoteStr; + } + + return $this->quote($quoteStr); + } + + /** + * Prefix CallBack + * + * @access private + * @param string $table the table + * @return string + */ + private function prefixTableCallback($table) + { + $prefix = $this->getTablePrefix(); + if (!empty($prefix) && is_string($prefix) && trim($prefix)) { + $table = (strpos($table, $prefix) === 0) + ? $table + : $prefix.$table; + } + + return $table; + } + + /** + * Prefixing table with predefined table prefix on configuration + * + * @param mixed $table + * @param bool $use_identifier + * @return array|null|string + */ + public function prefixTables($table, $use_identifier = false) + { + if ($table instanceof \Closure || is_resource($table)) { + throw new \InvalidArgumentException( + "Invalid value to be quote, table value could not be instance of `Closure` or as a `Resource`", + E_USER_ERROR + ); + } + + $prefix = $this->getTablePrefix(); + if (is_array($table)) { + foreach ($table as $key => $value) { + $table[$key] = $this->prefixTables($value, $use_identifier); + } + return $table; + } + if (is_object($table)) { + foreach (get_object_vars($table) as $key => $value) { + $table->{$key} = $this->prefixTables($value, $use_identifier); + } + return $table; + } + if (!is_string($table)) { + return null; + } + if (strpos($table, $this->currentQuoteIdentifier) !== false) { + $use_identifier = true; + } + if (!empty($prefix) && is_string($prefix) && trim($prefix)) { + $tableArray = explode('.', $table); + $tableArray = $this->trimTableSelector($tableArray); + if (count($tableArray) > 1) { + $connectionParams = $this->getConnectionParams(); + if (isset($connectionParams['db.name']) && $tableArray[0] == $connectionParams['db.name']) { + $tableArray[1] = $this->prefixTableCallback($tableArray); + } + if ($use_identifier) { + return $this->currentQuoteIdentifier + . implode("{$this->currentQuoteIdentifier}.{$this->currentQuoteIdentifier}", $tableArray) + . $this->currentQuoteIdentifier; + } else { + return implode(".", $tableArray); + } + } else { + $table = $this->prefixTableCallback($tableArray[0]); + } + } + + return $use_identifier + ? $this->currentQuoteIdentifier.$table.$this->currentQuoteIdentifier + : $table; + } + + /** + * @uses Database::prefixTables() + * + * @param mixed $tables + * @param bool $use_identifier + * @return mixed + */ + public function prefix($tables, $use_identifier = false) + { + return $this->prefixTables($tables, $use_identifier); + } + + /** + * Compile Bindings + * Take From CI 3 Database Query Builder, default string Binding use Question mark ( ? ) + * + * @param string $sql sql statement + * @param array $binds array of bind data + * @return mixed + */ + public function compileBindsQuestionMark($sql, $binds = null) + { + if (empty($binds) || strpos($sql, '?') === false) { + return $sql; + } elseif (! is_array($binds)) { + $binds = [$binds]; + $bind_count = 1; + } else { + // Make sure we're using numeric keys + $binds = array_values($binds); + $bind_count = count($binds); + } + // Make sure not to replace a chunk inside a string that happens to match the bind marker + if ($countMatches = preg_match_all("/'[^']*'/i", $sql, $matches)) { + $countMatches = preg_match_all( + '/\?/i', # regex + str_replace( + $matches[0], + str_replace('?', str_repeat(' ', 1), $matches[0]), + $sql, + $countMatches + ), + $matches, # matches + PREG_OFFSET_CAPTURE + ); + // Bind values' count must match the count of markers in the query + if ($bind_count !== $countMatches) { + return false; + } + } elseif (($countMatches = preg_match_all('/\?/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) { + return $sql; + } + + do { + $countMatches--; + $escapedValue = is_int($binds[$countMatches]) + ? $binds[$countMatches] + : $this->quote($binds[$countMatches]); + if (is_array($escapedValue)) { + $escapedValue = '('.implode(',', $escapedValue).')'; + } + $sql = substr_replace($sql, $escapedValue, $matches[0][$countMatches][1], 1); + } while ($countMatches !== 0); + + return $sql; + } + + /** + * Query using binding optionals statements + * + * @uses compileBindsQuestionMark + * @param string $sql + * @param mixed $statement array|string|null + * @return Statement + * @throws DBALException + */ + public function queryBind($sql, $statement = null) + { + $sql = $this->compileBindsQuestionMark($sql, $statement); + if ($sql === false) { + throw new DBALException( + sprintf( + 'Invalid statement binding count with sql query : %s', + $sql + ), + E_USER_WARNING + ); + } + + return $this->query($sql); + } + + /** + * -------------------------------------------------------------- + * SCHEMA + * + * Lists common additional Methods just for check & lists only + * to use more - please @uses Database::getSchemaManager() + * + * @see AbstractSchemaManager + * + * ------------------------------------------------------------ */ + + /** + * Check Table Maybe Invalid + * + * @param string $tableName + * @return string + * @throws \InvalidArgumentException + */ + protected function tableMaybeInvalid($tableName) + { + if (!is_string($tableName)) { + throw new \InvalidArgumentException( + 'Invalid table name type. Table name must be as string', + E_USER_ERROR + ); + } + + $tableName = trim($tableName); + if ($tableName == '') { + throw new \InvalidArgumentException( + 'Invalid parameter table name. Table name could not be empty.', + E_USER_ERROR + ); + } + + return $tableName; + } + + /** + * Get List Available Databases + * + * @return array + */ + public function listDatabases() + { + return $this->getSchemaManager()->listDatabases(); + } + + /** + * Returns a list of all namespaces in the current database. + * + * @return array + */ + public function listNamespaceNames() + { + return $this->getSchemaManager()->listDatabases(); + } + + /** + * Lists the available sequences for this connection. + * + * @return Sequence[] + */ + public function listSequences() + { + return $this->getSchemaManager()->listSequences(); + } + + /** + * Get Doctrine Column of table + * + * @param string $tableName + * @return Column[] + */ + public function listTableColumns($tableName) + { + $tableName = $this->tableMaybeInvalid($tableName); + return $this + ->getSchemaManager() + ->listTableColumns($tableName); + } + + /** + * Lists the indexes for a given table returning an array of Index instances. + * + * Keys of the portable indexes list are all lower-cased. + * + * @param string $tableName The name of the table. + * + * @return Index[] + */ + public function listTableIndexes($tableName) + { + $tableName = $this->tableMaybeInvalid($tableName); + return $this + ->getSchemaManager() + ->listTableIndexes($tableName); + } + + /** + * Check if table is Exists + * + * @param string $tables + * @return bool + * @throws \InvalidArgumentException + */ + public function tablesExist($tables) + { + if (! is_string($tables) && !is_array($tables)) { + throw new \InvalidArgumentException( + 'Invalid table name type. Table name must be as string or array', + E_USER_ERROR + ); + } + + $tables = $this->prefixTables($tables); + ! is_array($tables) && $tables = [$tables]; + return $this + ->getSchemaManager() + ->tablesExist($tables); + } + + /** + * Returns a list of all tables in the current Database Connection. + * + * @return array + */ + public function listTableNames() + { + return $this + ->getSchemaManager() + ->listTableNames(); + } + + /** + * Get List Table + * + * @return Table[] + */ + public function listTables() + { + return $this + ->getSchemaManager() + ->listTables(); + } + + /** + * Get Object Doctrine Table from Table Name + * + * @param string $tableName + * + * @return Table + */ + public function listTableDetails($tableName) + { + $tableName = $this->tableMaybeInvalid($tableName); + return $this->getSchemaManager()->listTableDetails($tableName); + } + + /** + * Lists the views this connection has. + * + * @return View[] + */ + public function listViews() + { + return $this->getSchemaManager()->listViews(); + } + + /** + * Lists the foreign keys for the given table. + * + * @param string $tableName The name of the table. + * + * @return ForeignKeyConstraint[] + */ + public function listTableForeignKeys($tableName) + { + $tableName = $this->tableMaybeInvalid($tableName); + return $this->getSchemaManager()->listTableForeignKeys($tableName); + } + + + /** + * Magic Method __call - calling arguments for backward compatibility + * + * @uses Connection + * + * @param string $method method object : + * @see Connection + * @param array $arguments the arguments list + * @return mixed + * @throws DBALException + */ + public function __call($method, array $arguments) + { + /** + * check if method exists on connection @see Connection ! + */ + if (method_exists($this->getConnection(), $method)) { + return call_user_func_array([$this->getConnection(), $method], $arguments); + } + throw new DBALException( + sprintf( + "Call to undefined Method %s", + $method + ), + E_USER_ERROR + ); + } +} diff --git a/App/FunctionsIncludes.php b/App/FunctionsIncludes.php new file mode 100644 index 0000000..9a2c71c --- /dev/null +++ b/App/FunctionsIncludes.php @@ -0,0 +1,7 @@ += 7) { + $type = IIS7_SERVER; + } + } + + if (! $type + && ( + function_exists('apache_get_modules') + || function_exists('apache_get_version') + ) + ) { + $type = APACHE_SERVER; + } + + return $type; +} + +/** + * Check if apache Server Base + * + * @return bool + */ +function isApache() +{ + return in_array(getWebServerSoftWare(), [APACHE_SERVER, LITESPEED_SERVER]); +} + +/** + * Check if Litespeed Web Server Base + * + * @return bool + */ +function isLitespeed() +{ + return getWebServerSoftWare() === LIGHTTPD_SERVER; +} + +/** + * Check if Nginx Web Server Base + * + * @return bool + */ +function isNginx() +{ + return getWebServerSoftWare() === NGINX_SERVER; +} + +/** + * Check if Hiawatha Web Server Base + * + * @return bool + */ +function isHiawatha() +{ + return getWebServerSoftWare() === HIAWATHA_SERVER; +} + +/** + * Check if Hiawatha Web Server Base + * + * @return bool + */ +function isLighttpd() +{ + return getWebServerSoftWare() === LIGHTTPD_SERVER; +} + +/** + * Check if IIS Web Server Base + * + * @return bool + */ +function isIIS() +{ + return in_array(getWebServerSoftWare(), [IIS_SERVER, IIS7_SERVER]); +} + +/** + * Check if IIS7 Web Server Base + * + * @return bool + */ +function isIIS7() +{ + return getWebServerSoftWare() === IIS7_SERVER; +} + +/** + * Test if the current browser runs on a mobile device (smart phone, tablet, etc.) + * + * @return bool + */ +function isMobile() { + if (empty($_SERVER['HTTP_USER_AGENT'])) { + return false; + } + + $userAgent = $_SERVER['HTTP_USER_AGENT']; + if ( strpos($userAgent, 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.) + || strpos($userAgent, 'Android') !== false + || strpos($userAgent, 'Silk/') !== false + || strpos($userAgent, 'Kindle') !== false + || strpos($userAgent, 'BlackBerry') !== false + || strpos($userAgent, 'Opera Mini') !== false + || strpos($userAgent, 'Opera Mobi') !== false + ) { + return true; + } + + return false; +} \ No newline at end of file diff --git a/App/Functions/Utilities.php b/App/Includes/Utilities.php similarity index 100% rename from App/Functions/Utilities.php rename to App/Includes/Utilities.php diff --git a/App/loader.php b/App/loader.php deleted file mode 100644 index 33d4121..0000000 --- a/App/loader.php +++ /dev/null @@ -1,16 +0,0 @@ -= 5.6", + "php": ">= 7", "apatis/array-storage": "^1", "apatis/exceptions": "^1", "apatis/transporter": "dev-master", "aura/session": "^2.1", "doctrine/dbal": "^2.5", "guzzlehttp/guzzle": "~6", + "phpfastcache/phpfastcache": "~5", "pentagonal/phpass": "^1", "pentagonal/simple_encrypt": "^1", - "slim/slim": "^2", + "slim/slim": "^3", "wa72/htmlpagedom": "^1.3" }, "require-dev": { @@ -26,5 +27,16 @@ "name": "nawa", "email": "nawa@yahoo.com" } - ] + ], + "autoload" : { + "psr-4" : { + "\\PentagonalProject\\ProjectSeventh\\": "App/Classes/" + }, + "classmap": [ + "App/Classes/" + ], + "files": [ + "App/FunctionsIncludes.php" + ] + } } diff --git a/config.php b/config.php index a75dee6..5553505 100644 --- a/config.php +++ b/config.php @@ -5,7 +5,6 @@ return [ 'directory' => [ 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', - 'app' => __DIR__ . DIRECTORY_SEPARATOR . 'App', 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', ], 'database' => [ @@ -15,6 +14,7 @@ 'name' => '', 'port' => 3306, 'charset' => 'utf-8', + 'collate' => 'utf8_unicode_ci', ], 'environment' => [ 'debug' => true, diff --git a/site_api/.htaccess b/public/.htaccess similarity index 100% rename from site_api/.htaccess rename to public/.htaccess diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..14047ed --- /dev/null +++ b/public/index.php @@ -0,0 +1,113 @@ +ja?son|javascript|xml|plain)$/', trim($accept), $match) + && !empty($match['content']) + ) { + $current = $match['content']; + } + switch ($current) { + case 'json': + case 'jason': + $accept = "application/json"; + $content = json_encode( + array( + "error" => array( + "code" => 500, + "message" => array($content) + ) + ), + JSON_PRETTY_PRINT); + break; + case 'xml': + $accept = "application/xml"; + $content = << + + + 500 + + {$content} + + + +EOF; + + break; + case 'plain': + $accept = "text/plain"; + break; + default: + $content = << + + + Internal Server Error + + + +

{$content}

+ + +EOF; + } + + header("Content-Type: {$accept}", true, 200); + $length = strlen($content); + header("Content-Length: {$length}", true, 200); + } else { + $content = "\n(Error) {$content}\n\n"; + } + + echo $content; + exit(E_CORE_ERROR); +} + +require __DIR__ . '/../vendor/autoload.php'; +$app = new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'); +print_r($app->run()); diff --git a/site_api/index.php b/site_api/index.php deleted file mode 100644 index 347a248..0000000 --- a/site_api/index.php +++ /dev/null @@ -1,11 +0,0 @@ - - Deny From All - - -# set default 403 forbidden into -# Current url - best experience -# Routes -# ------------------------------- -ErrorDocument 403 / - -# ---------------------------------------------------------------- -# ROUTES HANDLER -# ---------------------------------------------------------------- - -# Handle Index base URI '/' With -# ------------------------------- - - - RewriteEngine on - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - # use index.php as base URL - RewriteRule ^(.*)$ index.php [QSA,L] - # handle index.html & index.php to solved as / - RewriteRule ^(index\.s?html)?$ index.php [QSA,L] - diff --git a/site_web/index.php b/site_web/index.php deleted file mode 100644 index 347a248..0000000 --- a/site_web/index.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Fri, 21 Apr 2017 19:09:34 +0700 Subject: [PATCH 004/142] Sudah Mulai Menggila --- App/Includes/Constant.php | 10 +++++----- App/Includes/Environment.php | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index ac2b750..e3081a3 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -5,8 +5,8 @@ define('APACHE_SERVER', 'apache'); define('LITESPEED_SERVER', 'litespeed'); -define('NGINX_SERVER', 'nginx'); -define('IIS_SERVER', 'iis'); -define('IIS7_SERVER', 'iis7'); -define('HIAWATHA_SERVER', 'hiawatha'); -define('LIGHTTPD_SERVER', 'lighttpd'); +define('NGINX_SERVER', 'nginx'); +define('IIS_SERVER', 'iis'); +define('IIS7_SERVER', 'iis7'); +define('HIAWATHA_SERVER', 'hiawatha'); +define('LIGHTTPD_SERVER', 'lighttpd'); diff --git a/App/Includes/Environment.php b/App/Includes/Environment.php index ecdc1dd..8a63b26 100644 --- a/App/Includes/Environment.php +++ b/App/Includes/Environment.php @@ -137,13 +137,14 @@ function isIIS7() * * @return bool */ -function isMobile() { +function isMobile() +{ if (empty($_SERVER['HTTP_USER_AGENT'])) { return false; } $userAgent = $_SERVER['HTTP_USER_AGENT']; - if ( strpos($userAgent, 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.) + if (strpos($userAgent, 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.) || strpos($userAgent, 'Android') !== false || strpos($userAgent, 'Silk/') !== false || strpos($userAgent, 'Kindle') !== false @@ -155,4 +156,4 @@ function isMobile() { } return false; -} \ No newline at end of file +} From 1f4fe40b64b81604c6577f96059ad43ccd119661 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 22 Apr 2017 14:59:36 +0700 Subject: [PATCH 005/142] Hore Bro! --- App/Classes/Application.php | 6 +- App/Classes/AutoLoaderClass.php | 43 ++-- App/Classes/Config.php | 6 +- App/Classes/Database.php | 40 +-- App/Classes/Exceptions/EmptyFileException.php | 10 + .../Exceptions/InvalidFileNameException.php | 39 +++ .../Exceptions/InvalidModuleException.php | 12 + App/Classes/Interfaces/ModuleInterface.php | 37 +++ App/Classes/Module.php | 119 +++++++++ App/Classes/ModuleCollection.php | 71 ++++++ App/Classes/ModuleReader.php | 241 ++++++++++++++++++ 11 files changed, 578 insertions(+), 46 deletions(-) create mode 100644 App/Classes/Exceptions/EmptyFileException.php create mode 100644 App/Classes/Exceptions/InvalidFileNameException.php create mode 100644 App/Classes/Exceptions/InvalidModuleException.php create mode 100644 App/Classes/Interfaces/ModuleInterface.php create mode 100644 App/Classes/Module.php create mode 100644 App/Classes/ModuleCollection.php create mode 100644 App/Classes/ModuleReader.php diff --git a/App/Classes/Application.php b/App/Classes/Application.php index 0e4485a..71665ea 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -43,7 +43,7 @@ public function __construct(array $config) /** * @return string */ - public function getRootDirectory() + public function getRootDirectory() : string { return $this->rootDirectory; } @@ -51,7 +51,7 @@ public function getRootDirectory() /** * @return string */ - public function getAppDirectory() + public function getAppDirectory() : string { return $this->appDirectory; } @@ -61,7 +61,7 @@ public function getAppDirectory() * * @param $config */ - protected function init($config) + protected function init(array $config) { $config['directory'] = isset($config['directory']) ? $config['directory'] : []; if (!is_array($config['directory'])) { diff --git a/App/Classes/AutoLoaderClass.php b/App/Classes/AutoLoaderClass.php index a0e78b3..1c5ec59 100644 --- a/App/Classes/AutoLoaderClass.php +++ b/App/Classes/AutoLoaderClass.php @@ -41,7 +41,7 @@ final class AutoLoaderClass * @param string $nameSpace * @param string|array $directory */ - public function __construct($nameSpace, $directory) + public function __construct(string $nameSpace, string $directory) { $this->nameSpace = $this->resolveNameSpace($nameSpace); $this->baseDirectory = (array) $directory; @@ -50,7 +50,7 @@ public function __construct($nameSpace, $directory) /** * @return array */ - public static function getReferences() + public static function getReferences() : array { return self::$references; } @@ -58,7 +58,7 @@ public static function getReferences() /** * @return string[] class map with lower case key */ - public function getClassMap() + public function getClassMap() : array { return $this->classMap; } @@ -69,7 +69,7 @@ public function getClassMap() * @param string $string * @return string */ - protected function resolveNameSpace($string) + protected function resolveNameSpace(string $string) : string { return preg_replace( '`(\\\)+`', @@ -84,7 +84,7 @@ protected function resolveNameSpace($string) * @param string $string * @return string */ - protected function resolveNameSpaceLower($string) + protected function resolveNameSpaceLower($string) : string { return $this->toLower($this->resolveNameSpace($string)); } @@ -95,7 +95,7 @@ protected function resolveNameSpaceLower($string) * @param string $string * @return string */ - protected function toLower($string) + protected function toLower($string) : string { // sanity case insensitive class return strtolower($string); @@ -109,7 +109,7 @@ protected function toLower($string) * @param string $file the absolute file * @return bool|string */ - private function pushReference($group, $class, $file) + private function pushReference(string $group, string $class, string $file) { if ($file = stream_resolve_include_path($file)) { // references name space @@ -127,16 +127,18 @@ private function pushReference($group, $class, $file) } /** + * Load Class + * * @param string $class * @return bool */ - public function load($class) + public function load(string $class) : bool { if (!is_string($class)) { return false; } if ($file = $this->findFileFor($class)) { - // prevent multiple call instanphpfastcachece of class + // prevent multiple call of class if (class_exists($class)) { return true; } @@ -153,9 +155,9 @@ public function load($class) * * @param string $nameSpace * @param string|array $directory - * @return static + * @return AutoLoaderClass */ - public static function create($nameSpace, $directory) + public static function create(string $nameSpace, string $directory) : AutoLoaderClass { return new static($nameSpace, $directory); } @@ -167,7 +169,7 @@ public static function create($nameSpace, $directory) * @param string|array $directory directory to scan * @return bool */ - public static function createRegister($nameSpace, $directory) + public static function createRegister(string $nameSpace, string $directory) : bool { return (new static($nameSpace, $directory))->register(); } @@ -188,7 +190,7 @@ public static function createRegisterArray(array $nameSpaceAndDirectory) * @param bool $prepend * @return bool */ - public function register($prepend = false) + public function register(bool $prepend = false) : bool { return spl_autoload_register($this, true, $prepend); } @@ -207,7 +209,7 @@ public function unRegister() * @param string $Class * @return bool|string */ - protected function findFileFor($Class) + protected function findFileFor(string $Class) { $Class = $this->resolveNameSpace($Class); $class = $this->toLower($Class); @@ -224,6 +226,7 @@ protected function findFileFor($Class) return $file; } + $file = false; $namespace= $this->resolveNameSpaceLower($this->nameSpace); foreach ($this->baseDirectory as $directory) { if (!is_string($directory) || ! ($directory = realpath($directory))) { @@ -254,7 +257,7 @@ protected function findFileFor($Class) * @param string $class * @return array */ - protected function splitClassNameSpace($class) + protected function splitClassNameSpace(string $class) : array { $class = $this->resolveNameSpace($class); $nameSpaceArray = explode('\\', $class); @@ -275,7 +278,7 @@ protected function splitClassNameSpace($class) * @param string $class * @return bool|array */ - protected function getClassReference($class) + protected function getClassReference(string $class) { // check if not as a class if (!$class || substr($class, -1) == '\\') { @@ -296,7 +299,7 @@ protected function getClassReference($class) * @param string $group * @return bool|mixed */ - protected function getGroupReference($group) + protected function getGroupReference(string $group) { if ($this->hasGroupReference($group)) { return AutoLoaderClass::$references[$this->resolveNameSpace($group)]; @@ -311,7 +314,7 @@ protected function getGroupReference($group) * @param string $group * @return bool */ - protected function hasGroupReference($group) + protected function hasGroupReference(string $group) : bool { $group = $this->resolveNameSpaceLower($group); return isset(self::$references[$group]); @@ -320,7 +323,7 @@ protected function hasGroupReference($group) /** * @param $class */ - public function __invoke($class) + public function __invoke(string $class) { call_user_func_array([$this, 'load'], func_get_args()); } @@ -329,7 +332,7 @@ public function __invoke($class) /** * @param string $file */ -function IncludeFileOnce($file) +function IncludeFileOnce(string $file) { /** @noinspection PhpIncludeInspection */ include_once $file; diff --git a/App/Classes/Config.php b/App/Classes/Config.php index 103485b..76e5610 100644 --- a/App/Classes/Config.php +++ b/App/Classes/Config.php @@ -62,7 +62,7 @@ public function resetToDefault() /** * @return CollectionFetch */ - public function getCurrentCollection() + public function getCurrentCollection() : CollectionFetch { return $this->collection; } @@ -70,7 +70,7 @@ public function getCurrentCollection() /** * @return CollectionFetch */ - public function getDefaultCollection() + public function getDefaultCollection() : CollectionFetch { return $this->originalCollection; } @@ -78,7 +78,7 @@ public function getDefaultCollection() /** * @return CollectionFetch */ - public function getLastCollection() + public function getLastCollection() : CollectionFetch { return $this->lastCollection ?: $this->collection; } diff --git a/App/Classes/Database.php b/App/Classes/Database.php index 4ae120a..9875ba9 100644 --- a/App/Classes/Database.php +++ b/App/Classes/Database.php @@ -252,7 +252,7 @@ public function __construct(array $configs) * * @return Connection */ - public function getConnection() + public function getConnection() : Connection { return $this->currentConnection; } @@ -262,7 +262,7 @@ public function getConnection() * * @return string */ - public function getTablePrefix() + public function getTablePrefix() : string { return $this->currentTablePrefix; } @@ -272,7 +272,7 @@ public function getTablePrefix() * * @return string */ - public function getQuoteIdentifier() + public function getQuoteIdentifier() : string { return $this->currentQuoteIdentifier; } @@ -282,7 +282,7 @@ public function getQuoteIdentifier() * * @return array */ - public function getUserParams() + public function getUserParams() : array { return $this->currentUserParams; } @@ -292,7 +292,7 @@ public function getUserParams() * * @return array */ - public function getConnectionParams() + public function getConnectionParams() : array { return $this->getParams(); } @@ -305,7 +305,7 @@ public function getConnectionParams() * @final * @return bool|string return lowercase an fix database driver for Connection */ - final public function sanitizeSelectedAvailableDriver($driverName) + final public function sanitizeSelectedAvailableDriver(string $driverName) { if (is_string($driverName) && trim($driverName)) { $driverName = trim(strtolower($driverName)); @@ -451,7 +451,7 @@ public function quotes($quoteStr, $type = \PDO::PARAM_STR) * @param string $table the table * @return string */ - private function prefixTableCallback($table) + private function prefixTableCallback(string $table) : string { $prefix = $this->getTablePrefix(); if (!empty($prefix) && is_string($prefix) && trim($prefix)) { @@ -470,7 +470,7 @@ private function prefixTableCallback($table) * @param bool $use_identifier * @return array|null|string */ - public function prefixTables($table, $use_identifier = false) + public function prefixTables($table, bool $use_identifier = false) { if ($table instanceof \Closure || is_resource($table)) { throw new \InvalidArgumentException( @@ -530,7 +530,7 @@ public function prefixTables($table, $use_identifier = false) * @param bool $use_identifier * @return mixed */ - public function prefix($tables, $use_identifier = false) + public function prefix($tables, bool $use_identifier = false) { return $this->prefixTables($tables, $use_identifier); } @@ -543,7 +543,7 @@ public function prefix($tables, $use_identifier = false) * @param array $binds array of bind data * @return mixed */ - public function compileBindsQuestionMark($sql, $binds = null) + public function compileBindsQuestionMark(string $sql, $binds = null) { if (empty($binds) || strpos($sql, '?') === false) { return $sql; @@ -599,7 +599,7 @@ public function compileBindsQuestionMark($sql, $binds = null) * @return Statement * @throws DBALException */ - public function queryBind($sql, $statement = null) + public function queryBind(string $sql, $statement = null) { $sql = $this->compileBindsQuestionMark($sql, $statement); if ($sql === false) { @@ -633,7 +633,7 @@ public function queryBind($sql, $statement = null) * @return string * @throws \InvalidArgumentException */ - protected function tableMaybeInvalid($tableName) + protected function tableMaybeInvalid($tableName) : string { if (!is_string($tableName)) { throw new \InvalidArgumentException( @@ -658,7 +658,7 @@ protected function tableMaybeInvalid($tableName) * * @return array */ - public function listDatabases() + public function listDatabases() : array { return $this->getSchemaManager()->listDatabases(); } @@ -668,7 +668,7 @@ public function listDatabases() * * @return array */ - public function listNamespaceNames() + public function listNamespaceNames() : array { return $this->getSchemaManager()->listDatabases(); } @@ -678,7 +678,7 @@ public function listNamespaceNames() * * @return Sequence[] */ - public function listSequences() + public function listSequences() : array { return $this->getSchemaManager()->listSequences(); } @@ -689,7 +689,7 @@ public function listSequences() * @param string $tableName * @return Column[] */ - public function listTableColumns($tableName) + public function listTableColumns(string $tableName) : array { $tableName = $this->tableMaybeInvalid($tableName); return $this @@ -706,7 +706,7 @@ public function listTableColumns($tableName) * * @return Index[] */ - public function listTableIndexes($tableName) + public function listTableIndexes(string $tableName) : array { $tableName = $this->tableMaybeInvalid($tableName); return $this @@ -768,7 +768,7 @@ public function listTables() * * @return Table */ - public function listTableDetails($tableName) + public function listTableDetails(string $tableName) { $tableName = $this->tableMaybeInvalid($tableName); return $this->getSchemaManager()->listTableDetails($tableName); @@ -791,7 +791,7 @@ public function listViews() * * @return ForeignKeyConstraint[] */ - public function listTableForeignKeys($tableName) + public function listTableForeignKeys(string $tableName) { $tableName = $this->tableMaybeInvalid($tableName); return $this->getSchemaManager()->listTableForeignKeys($tableName); @@ -809,7 +809,7 @@ public function listTableForeignKeys($tableName) * @return mixed * @throws DBALException */ - public function __call($method, array $arguments) + public function __call(string $method, array $arguments) { /** * check if method exists on connection @see Connection ! diff --git a/App/Classes/Exceptions/EmptyFileException.php b/App/Classes/Exceptions/EmptyFileException.php new file mode 100644 index 0000000..a6900f6 --- /dev/null +++ b/App/Classes/Exceptions/EmptyFileException.php @@ -0,0 +1,10 @@ +file = $file; + if (func_num_args() > 1) { + $this->message = $message; + } else { + $this->message = "Invalid file of {$this->file}"; + } + } + + /** + * @return string + */ + public function getFileSet() : string + { + return $this->file; + } +} diff --git a/App/Classes/Exceptions/InvalidModuleException.php b/App/Classes/Exceptions/InvalidModuleException.php new file mode 100644 index 0000000..dd10fc8 --- /dev/null +++ b/App/Classes/Exceptions/InvalidModuleException.php @@ -0,0 +1,12 @@ +module_name) + || trim($this->module_name) == '' + ) { + $this->module_name = get_class($this); + } + + return (string) $this->module_name; + } + + /** + * {@inheritdoc} + */ + public function getModuleAuthor() : string + { + return (string) $this->module_author; + } + + /** + * {@inheritdoc} + */ + public function getModuleVersion() : string + { + return (string) $this->module_version; + } + + /** + * Get Module URL + * + * @return string + */ + public function getModuleUri(): string + { + return (string) $this->module_uri; + } + + /** + * Get Module Author + * + * @return string + */ + public function getModuleAuthorUri(): string + { + return (string) $this->module_author_uri; + } + + /** + * @return string + */ + public function getModuleDescription(): string + { + return (string) $this->module_description; + } +} diff --git a/App/Classes/ModuleCollection.php b/App/Classes/ModuleCollection.php new file mode 100644 index 0000000..5c99506 --- /dev/null +++ b/App/Classes/ModuleCollection.php @@ -0,0 +1,71 @@ +module_directory = realpath($moduleDirectory)?: $moduleDirectory; + clearstatcache($this->module_directory); + } + + /** + * Get Path Module Directory + * + * @return string + */ + public function getModuleDirectory(): string + { + return $this->module_directory; + } + + /** + * @return Module[] + */ + public function getAllModules() + { + return $this->modules; + } + + public function scan() + { + + } +} \ No newline at end of file diff --git a/App/Classes/ModuleReader.php b/App/Classes/ModuleReader.php new file mode 100644 index 0000000..92531aa --- /dev/null +++ b/App/Classes/ModuleReader.php @@ -0,0 +1,241 @@ +file = stream_resolve_include_path($file)); + if ($this->file) { + clearstatcache($this->file); + if (pathinfo($this->file, PATHINFO_EXTENSION) !== 'php') { + $this->file = false; + throw new InvalidArgumentException( + "Module file has invalid extension. Extension must be as `php`", + E_WARNING + ); + } + + return; + } + + throw new InvalidArgumentException( + "Invalid file Module to read", + E_WARNING + ); + } + + /** + * Get File Path + * + * @return bool|string + */ + public function getFilePath() + { + return $this->file; + } + + /** + * @return bool + */ + public function isValid(): bool + { + return $this->valid; + } + + /** + * @return Module|null + */ + public function getInstance() + { + return $this->instance; + } + + /** + * @return ModuleReader + * @throws InvalidFileNameException + * @throws Exception + */ + public function process() : ModuleReader + { + if (!$this->getFilePath()) { + $this->valid = false; + } + + // stop + if (isset($this->valid)) { + return $this; + } + + if (preg_match('/[^a-z0-9\_]/i', basename($this->file))) { + throw new InvalidFileNameException( + $this->file, + sprintf( + "Invalid base file name for %s, file name must be contain alpha numeric and underscore only", + basename($this->file) + ) + ); + } + + return $this->validate(); + } + + /** + * Validate + * + * @return ModuleReader + * @throws EmptyFileException + * @throws InvalidModuleException + */ + private function validate() : ModuleReader + { + /** + * strip white space is remove all new line and double spaces + * and remove all comments + * @see php_strip_whitespace() + * just het 204b byte to get content + */ + $content = substr(php_strip_whitespace($this->getFilePath()), 0, 2048); + if (!$content) { + throw new EmptyFileException( + $this->getFilePath() + ); + } + if (strtolower(substr($content, 0, 4)) !== '[^;]+)/ms', $content, $namespaces) + && !empty($namespaces['namespace']) + ) { + if (strtolower(trim($namespaces['namespace'])) == strtolower(__NAMESPACE__)) { + throw new InvalidModuleException( + "File Module contain name space of core.", + E_ERROR + ); + } + $namespace .= $namespaces['namespace']; + } + + if ($namespace !== '\\' && preg_match('`[^\\_a-z0-9]`', $namespace)) { + throw new InvalidModuleException( + "File Module contain invalid name space.", + E_ERROR + ); + } + + $moduleClass = Module::class; + preg_match( + '/use\s+ + (?:\\\{1})?'.preg_quote($moduleClass, '/').' + (?:\s+as\s+(?P[a-z0-9_]+))?;+ + /smx', + $content, + $asAlias + ); + + $alias = isset($asAlias['alias']) ? $asAlias['alias'] : null; + // replace for unused text + $content = preg_replace( + [ + '`^\<\?php\s+(?:namespace\s+[^;]+;\s*)?`smi', + '`(?:use[^;]+;\s*)*\s*(class)`smi' + ], + '$1', + $content + ); + + $regexNameSpace = $alias + ? '(?P('.preg_quote("\\{$moduleClass}", '/').'))\s*' + : '(?P('.preg_quote("\\{$moduleClass}", '/') . '|' . preg_quote($alias, '/').'))\s*'; + preg_match( + '`class\s+ + (?P[a-z_][a-z0-9\_]+) + \s+extends\s+ + '.$regexNameSpace.' + `msix', + $content, + $class + ); + + if (empty($class['class']) || empty($class['extends'])) { + throw new InvalidModuleException( + "File Module does not contain valid class or not extends to `{$moduleClass}`.", + E_ERROR + ); + } + + if (strtolower(pathinfo(basename($this->file), PATHINFO_FILENAME)) !== strtolower($class['class'])) { + throw new InvalidModuleException( + "File Module does not match between file name & class.", + E_ERROR + ); + } + + if (! preg_match('/(public\s+)?function\s+init\([^\)]*\)\s*\{/smi', $content, $match)) { + throw new InvalidModuleException( + "File Module does not contain method `init`.", + E_ERROR + ); + } + + $namespace = rtrim($namespace, '\\'); + $class = "{$namespace}\\{$class}"; + // start buffer + ob_start(); + // include once + IncludeFileOnce($this->file); + if ($error = error_get_last() && !empty($error) && $error['file'] == $this->file) { + if ($error['type'] === E_ERROR) { + @ob_end_clean(); + throw new InvalidModuleException( + "File Module contains fatal error.", + E_ERROR + ); + } + } + @ob_end_clean(); + if (!class_exists($class)) { + throw new InvalidModuleException( + "File Module does not contain class {$class}.", + E_ERROR + ); + } + + $this->instance = new $class; + return $this; + } +} From d0c18458aeba5544dfbc4a23cc958e0b9706ce14 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 22 Apr 2017 20:48:46 +0700 Subject: [PATCH 006/142] Gathel --- App/Classes/Application.php | 10 +- App/Classes/Exceptions/EmptyFileException.php | 2 +- ...Exception.php => InvalidPathException.php} | 18 +- .../Exceptions/ModuleNotFoundException.php | 10 + App/Classes/Module.php | 72 +++- App/Classes/ModuleCollection.php | 326 +++++++++++++++++- App/Classes/ModuleReader.php | 115 ++++-- App/Includes/Utilities.php | 9 + public/index.php | 4 +- 9 files changed, 514 insertions(+), 52 deletions(-) rename App/Classes/Exceptions/{InvalidFileNameException.php => InvalidPathException.php} (54%) create mode 100644 App/Classes/Exceptions/ModuleNotFoundException.php diff --git a/App/Classes/Application.php b/App/Classes/Application.php index 71665ea..befcd20 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -84,9 +84,17 @@ public function run() { $this->slim = new App( [ + 'module' => function($c) { + return (new ModuleCollection($c['settings']['directory']['module']))->scan(); + }, + 'config' => function($c) { + $this->config = new Config($c['settings']); + return $this->config; + }, 'settings' => $this->config->get() ] ); - return $this->slim; + + return $this->slim->run(); } } diff --git a/App/Classes/Exceptions/EmptyFileException.php b/App/Classes/Exceptions/EmptyFileException.php index a6900f6..2eff487 100644 --- a/App/Classes/Exceptions/EmptyFileException.php +++ b/App/Classes/Exceptions/EmptyFileException.php @@ -5,6 +5,6 @@ * Class EmptyFileException * @package PentagonalProject\ProjectSeventh\Exceptions */ -class EmptyFileException extends InvalidFileNameException +class EmptyFileException extends InvalidPathException { } diff --git a/App/Classes/Exceptions/InvalidFileNameException.php b/App/Classes/Exceptions/InvalidPathException.php similarity index 54% rename from App/Classes/Exceptions/InvalidFileNameException.php rename to App/Classes/Exceptions/InvalidPathException.php index 7c8f4fa..dc3675c 100644 --- a/App/Classes/Exceptions/InvalidFileNameException.php +++ b/App/Classes/Exceptions/InvalidPathException.php @@ -7,33 +7,33 @@ * Class InvalidFileName * @package PentagonalProject\ProjectSeventh\Exceptions */ -class InvalidFileNameException extends Exception +class InvalidPathException extends Exception { /** * @var string */ - protected $file; + protected $path; /** - * InvalidFileNameException constructor. - * @param string $file + * InvalidPathException constructor. + * @param string $path * @param string $message */ - public function __construct(string $file, string $message = '') + public function __construct(string $path, string $message = '') { - $this->file = $file; + $this->path = $path; if (func_num_args() > 1) { $this->message = $message; } else { - $this->message = "Invalid file of {$this->file}"; + $this->message = "Invalid path of {$this->file}"; } } /** * @return string */ - public function getFileSet() : string + public function getPath() : string { - return $this->file; + return $this->path; } } diff --git a/App/Classes/Exceptions/ModuleNotFoundException.php b/App/Classes/Exceptions/ModuleNotFoundException.php new file mode 100644 index 0000000..1af4652 --- /dev/null +++ b/App/Classes/Exceptions/ModuleNotFoundException.php @@ -0,0 +1,10 @@ +getModuleName(); + } + + /** + * Get Module Info + * + * @return array + */ + public function getModuleInfo() : array + { + return [ + Module::MODULE_NAME => $this->getModuleName(), + Module::MODULE_VERSION => $this->getModuleVersion(), + Module::MODULE_URI => $this->getModuleUri(), + Module::MODULE_AUTHOR => $this->getModuleAuthor(), + Module::MODULE_AUTHOR_URI => $this->getModuleAuthorUri(), + Module::MODULE_DESCRIPTION => $this->getModuleDescription() + ]; + } + + /** + * @return \ReflectionClass + */ + final protected function getReflection() : \ReflectionClass + { + static $reflection; + if (!$reflection || ! $reflection instanceof \ReflectionClass) { + $reflection = new \ReflectionClass($this); + } + + return $reflection; + } + + /** + * Get Path + * + * @return string + */ + final public function getModuleRealPath() : string + { + return $this->getReflection()->getFileName(); + } + + /** + * Get Name Space + * + * @return string + */ + final public function getModuleNameSpace() : string + { + return $this->getReflection()->getNamespaceName(); + } + + /** + * Get ShortName of Class + * + * @return string + */ + final public function getModuleShortName() : string + { + return $this->getReflection()->getShortName(); } /** @@ -67,7 +135,7 @@ public function getModuleName() : string if (!is_string($this->module_name) || trim($this->module_name) == '' ) { - $this->module_name = get_class($this); + $this->module_name = $this->getReflection()->getName(); } return (string) $this->module_name; @@ -110,6 +178,8 @@ public function getModuleAuthorUri(): string } /** + * Get Description of Module + * * @return string */ public function getModuleDescription(): string diff --git a/App/Classes/ModuleCollection.php b/App/Classes/ModuleCollection.php index 5c99506..eab65e8 100644 --- a/App/Classes/ModuleCollection.php +++ b/App/Classes/ModuleCollection.php @@ -1,49 +1,93 @@ module_directory = realpath($moduleDirectory)?: $moduleDirectory; - clearstatcache($this->module_directory); + $this->splFileInfo = new \SplFileInfo($moduleDirectory); + if ($this->splFileInfo->isLink()) { + throw new RuntimeException( + "Invalid Module Directory. Module directory could not as a symlink!", + E_COMPILE_ERROR + ); + } + + $this->moduleDirectory = $this->splFileInfo->getRealPath(); } /** @@ -53,19 +97,271 @@ public function __construct(string $moduleDirectory) */ public function getModuleDirectory(): string { - return $this->module_directory; + return $this->moduleDirectory; + } + + /** + * @return Module[] + */ + public function getAllModules() : array + { + return $this->validModules; + } + + /** + * Scan Module Directory + * + * @return ModuleCollection + */ + public function scan() : ModuleCollection + { + if ($this->hasScanned) { + return $this; + } + + /** + * @var SplFileInfo $path + */ + foreach (new RecursiveDirectoryIterator($this->getModuleDirectory()) as $path) { + $baseName = $path->getBaseName(); + // skip dotted + if ($baseName == '.' || $baseName == '..') { + continue; + } + + $directory = $this->getModuleDirectory() . DIRECTORY_SEPARATOR . $baseName; + // don't allow symlink to be execute & skip if contains file + if ($path->isLink() || ! $path->isDir()) { + $this->unwantedPath[$baseName] = $path->getType(); + continue; + } + + $file = $directory . DIRECTORY_SEPARATOR . $baseName .'.php'; + if (! file_exists($file)) { + $this->invalidModules[$baseName] = new ModuleNotFoundException( + $file, + sprintf("Module file for %s has not found", $baseName) + ); + + continue; + } + + try { + $this->validModules[$this->sanitizeModuleName($baseName)] = function () use ($file) { + $module = (new ModuleReader($file))->process(); + return $module->getInstance(); + }; + + } catch (\Exception $e) { + $this->invalidModules[$this->sanitizeModuleName($baseName)] = $e; + } + } + + return $this; + } + + /** + * Get Invalid Modules + * + * @return \Exception[] + */ + public function getInvalidModules(): array + { + return $this->invalidModules; + } + + /** + * Get Unwanted Path + * contain [file|dir|link] + * + * @see ModuleCollection::TYPE_SYMLINK + * @see ModuleCollection::TYPE_DIR + * @see ModuleCollection::TYPE_FILE + * + * @return string[] + */ + public function getUnwantedPath(): array + { + return $this->unwantedPath; + } + + /** + * @see getUnwantedPath() + * + * @return string[] + */ + public function getUnwantedPaths(): array + { + return $this->unwantedPath; + } + + /** + * Get Loaded Modules List base on Name + * + * @return string[] + */ + public function getLoadedModulesName(): array + { + return $this->loadedModules; } /** * @return Module[] */ - public function getAllModules() + public function getLoadedModules(): array + { + $module = []; + foreach ($this->getLoadedModulesName() as $value) { + if (isset($this->validModules[$value])) { + $module[$value] = $this->validModules[$value]; + } + } + + return $module; + } + + /** + * Sanitize Module Name + * + * @param string $name + * @return string + */ + protected function sanitizeModuleName(string $name) : string + { + return trim(strtolower($name)); + } + + /** + * Get Module Given By Name + * + * @access internal + * @param string $name + * @return Module + * @throws InvalidModuleException + */ + protected function &internalGetModule(string $name) : Module + { + $moduleName = $this->sanitizeModuleName($name); + if (!$moduleName) { + throw new InvalidArgumentException( + "Please insert not an empty arguments", + E_USER_ERROR + ); + } + if (!$this->exist($moduleName)) { + throw new InvalidModuleException( + sprintf("Module %s has not found", $name) + ); + } + if ($this->validModules[$moduleName] instanceof \Closure) { + $this->validModules[$moduleName] = $this->validModules[$moduleName](); + } + + return $this->validModules[$moduleName]; + } + + /** + * Get Module Info + * + * @param string $moduleName + * @return Collection + */ + public function getModuleInfo(string $moduleName) + { + return new Collection($this->internalGetModule($moduleName)->getModuleInfo()); + } + + /** + * Load Module + * + * @param string $name + * @return Module + * @throws InvalidModuleException + * @throws ModuleNotFoundException + */ + public function &load(string $name) : Module + { + $module =& $this->internalGetModule($name); + if (!$this->hasLoaded($name)) { + $module->init(); + $this->loadedModules[$this->sanitizeModuleName($name)] = true; + } + + return $module; + } + + /** + * Check if Module Exists + * + * @param string $name + * @return bool + */ + public function exist(string $name) + { + return isset($this->validModules[$this->sanitizeModuleName($name)]); + } + + /** + * Check If Module Has Loaded + * + * @param string $name + * @return bool + */ + public function hasLoaded(string $name) { - return $this->modules; + $moduleName = $this->sanitizeModuleName($name); + return $moduleName && !empty($this->loadedModules[$moduleName]); } - public function scan() + /** + * {@inheritdoc} + */ + public function count() { + return count($this->validModules); + } + /** + * @param string $offset + * @return Module + */ + public function offsetGet($offset) + { + return $this->load($offset); + } + + /** + * @param string $offset + * @return bool + */ + public function offsetExists($offset) + { + return $this->exist($offset); + } + + /** + * {@inheritdoc} + * no affected here + */ + public function offsetSet($offset, $value) + { + return; + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + return; + } + + /** + * @param string $name + * @return Module + */ + public function __get($name) + { + return $this->load($name); } -} \ No newline at end of file +} diff --git a/App/Classes/ModuleReader.php b/App/Classes/ModuleReader.php index 92531aa..e05f6c9 100644 --- a/App/Classes/ModuleReader.php +++ b/App/Classes/ModuleReader.php @@ -3,8 +3,9 @@ use Apatis\Exceptions\Exception; use Apatis\Exceptions\InvalidArgumentException; +use Apatis\Exceptions\RuntimeException; use PentagonalProject\ProjectSeventh\Exceptions\EmptyFileException; -use PentagonalProject\ProjectSeventh\Exceptions\InvalidFileNameException; +use PentagonalProject\ProjectSeventh\Exceptions\InvalidPathException; use PentagonalProject\ProjectSeventh\Exceptions\InvalidModuleException; /** @@ -28,23 +29,42 @@ class ModuleReader */ protected $instance; + /** + * @var string + */ + protected $moduleClass; + /** * ModuleReader constructor. * @param string $file */ public function __construct(string $file) { - file_exists($file) && ($this->file = stream_resolve_include_path($file)); - if ($this->file) { - clearstatcache($this->file); - if (pathinfo($this->file, PATHINFO_EXTENSION) !== 'php') { - $this->file = false; + $this->moduleClass = Module::class; + if (file_exists($file)) { + $spl = new \SplFileInfo($file); + if ($spl->isLink()) { + throw new InvalidArgumentException( + "Argument could not as a symlink.", + E_WARNING + ); + } + if (!$spl->isFile()) { + throw new InvalidArgumentException( + "Argument is not a file.", + E_WARNING + ); + } + + if (strtolower($spl->getExtension()) !== 'php') { throw new InvalidArgumentException( "Module file has invalid extension. Extension must be as `php`", E_WARNING ); } + $this->file = $spl->getRealPath(); + unset($spl); return; } @@ -59,11 +79,21 @@ public function __construct(string $file) * * @return bool|string */ - public function getFilePath() + public function getFile() { return $this->file; } + /** + * Get Directory + * + * @return string + */ + public function getDirectory() + { + return dirname($this->file); + } + /** * @return bool */ @@ -82,12 +112,12 @@ public function getInstance() /** * @return ModuleReader - * @throws InvalidFileNameException + * @throws InvalidPathException * @throws Exception */ public function process() : ModuleReader { - if (!$this->getFilePath()) { + if (!$this->getFile()) { $this->valid = false; } @@ -96,8 +126,8 @@ public function process() : ModuleReader return $this; } - if (preg_match('/[^a-z0-9\_]/i', basename($this->file))) { - throw new InvalidFileNameException( + if (preg_match('/[^a-z0-9\_]/i', pathinfo($this->file, PATHINFO_FILENAME))) { + throw new InvalidPathException( $this->file, sprintf( "Invalid base file name for %s, file name must be contain alpha numeric and underscore only", @@ -118,19 +148,39 @@ public function process() : ModuleReader */ private function validate() : ModuleReader { + if (!is_string($this->moduleClass)) { + throw new RuntimeException( + "Invalid Parent Module Class. Module extends must be as class name and string." + ); + } + + $this->moduleClass = rtrim($this->moduleClass, '\\'); + if (!class_exists($this->moduleClass) + || strtolower($this->moduleClass) != strtolower(Module::class) + && ! is_subclass_of($this->moduleClass, Module::class) + ) { + throw new RuntimeException( + sprintf( + "Parent Module class Does not extends into %s", + Module::class + ) + ); + } + /** * strip white space is remove all new line and double spaces * and remove all comments * @see php_strip_whitespace() * just het 204b byte to get content */ - $content = substr(php_strip_whitespace($this->getFilePath()), 0, 2048); + $content = substr(php_strip_whitespace($this->getFile()), 0, 2048); if (!$content) { throw new EmptyFileException( - $this->getFilePath() + $this->getFile() ); } - if (strtolower(substr($content, 0, 4)) !== '[^;]+)/ms', $content, $namespaces) + if (preg_match('/\<\?php\s+namespace\s+(?P[^;\{]+)/ms', $content, $namespaces) && !empty($namespaces['namespace']) ) { if (strtolower(trim($namespaces['namespace'])) == strtolower(__NAMESPACE__)) { @@ -157,29 +207,36 @@ private function validate() : ModuleReader ); } - $moduleClass = Module::class; + $moduleClass = $this->moduleClass; preg_match( '/use\s+ - (?:\\\{1})?'.preg_quote($moduleClass, '/').' + (?:\\\{1})?(?P'.preg_quote($moduleClass, '/').') (?:\s+as\s+(?P[a-z0-9_]+))?;+ /smx', $content, $asAlias ); - $alias = isset($asAlias['alias']) ? $asAlias['alias'] : null; + $alias = isset($asAlias['alias']) + ? $asAlias['alias'] + : null; + if (!$alias && isset($asAlias['extended'])) { + $asAlias['extended'] = explode('\\', $asAlias['extended']); + $alias = end($asAlias['extended']); + } + // replace for unused text $content = preg_replace( [ - '`^\<\?php\s+(?:namespace\s+[^;]+;\s*)?`smi', - '`(?:use[^;]+;\s*)*\s*(class)`smi' + '`^\<\?php\s+(?:namespace\s+([^;\{])*[;\{]\s*)?`smi', + '`(use[^;]+;\s*)*\s*(class)`smi' ], - '$1', + '$2', $content ); $regexNameSpace = $alias - ? '(?P('.preg_quote("\\{$moduleClass}", '/').'))\s*' + ? '(?P('.preg_quote("{$alias}", '/').'))\s*' : '(?P('.preg_quote("\\{$moduleClass}", '/') . '|' . preg_quote($alias, '/').'))\s*'; preg_match( '`class\s+ @@ -198,7 +255,7 @@ private function validate() : ModuleReader ); } - if (strtolower(pathinfo(basename($this->file), PATHINFO_FILENAME)) !== strtolower($class['class'])) { + if (strtolower(pathinfo($this->file, PATHINFO_FILENAME)) !== strtolower($class['class'])) { throw new InvalidModuleException( "File Module does not match between file name & class.", E_ERROR @@ -212,10 +269,21 @@ private function validate() : ModuleReader ); } + $class = $class['class']; $namespace = rtrim($namespace, '\\'); $class = "{$namespace}\\{$class}"; + + // prevent multiple include file if class has been loaded + if (class_exists($class)) { + throw new InvalidModuleException( + "Object class {$class} for module has been loaded.", + E_ERROR + ); + } + // start buffer ob_start(); + // include once IncludeFileOnce($this->file); if ($error = error_get_last() && !empty($error) && $error['file'] == $this->file) { @@ -235,6 +303,7 @@ private function validate() : ModuleReader ); } + $this->valid = true; $this->instance = new $class; return $this; } diff --git a/App/Includes/Utilities.php b/App/Includes/Utilities.php index 800a729..c7b1b4e 100644 --- a/App/Includes/Utilities.php +++ b/App/Includes/Utilities.php @@ -2,3 +2,12 @@ /* ------------------------------------------------------ *\ | UTILITIES | \* ------------------------------------------------------ */ + +/** + * @param string $file + */ +function IncludeFileOnce(string $file) +{ + /** @noinspection PhpIncludeInspection */ + include_once $file; +} diff --git a/public/index.php b/public/index.php index 14047ed..f8b2d58 100644 --- a/public/index.php +++ b/public/index.php @@ -109,5 +109,5 @@ } require __DIR__ . '/../vendor/autoload.php'; -$app = new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'); -print_r($app->run()); + +return (new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'))->run(); From 9d911e083f040ef43b0c9037c6e465e86765b593 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Tue, 25 Apr 2017 18:06:24 +0700 Subject: [PATCH 007/142] I'am Tired Beibeeh - Uuulaaalaaa --- .docs/Configurations/README.md | 1 + .docs/Extensions/README.md | 1 + .docs/Modules/README.md | 1 + .../Modules/ExampleModule/ExampleModule.php | 62 +++ .gitignore | 3 +- App/Classes/Abstracts/EmbeddedSystem.php | 195 +++++++++ App/Classes/Application.php | 111 ++++- App/Classes/AutoLoaderClass.php | 2 + ...tion.php => EmbeddedNotFoundException.php} | 2 +- ...ption.php => InvalidEmbeddedException.php} | 6 +- App/Classes/Extension.php | 13 + App/Classes/Interfaces/EmbeddedInterface.php | 37 ++ App/Classes/Interfaces/ModuleInterface.php | 37 -- App/Classes/Module.php | 182 +------- App/Classes/ModuleCollection.php | 367 ---------------- App/Classes/Overrides/README.md | 3 + App/Classes/Utilities/EmbeddedCollection.php | 405 ++++++++++++++++++ .../EmbeddedReader.php} | 173 +++++--- App/Classes/Utilities/ExtensionReader.php | 25 ++ App/Classes/Utilities/ModuleReader.php | 25 ++ App/Containers/Database.php | 25 ++ App/Containers/Environment.php | 39 ++ App/Containers/Extension.php | 28 ++ App/Containers/Module.php | 28 ++ App/Containers/README.md | 30 ++ App/Containers/Settings.php | 16 + App/FunctionsIncludes.php | 2 +- App/Includes/{Environment.php => Helper.php} | 15 +- Storage/logs/.gitkeep | 0 config.php | 1 + public/extensions/.gitkeep | 0 public/index.php | 4 +- 32 files changed, 1182 insertions(+), 657 deletions(-) create mode 100644 .docs/Configurations/README.md create mode 100644 .docs/Extensions/README.md create mode 100644 .docs/Modules/README.md create mode 100644 .example/Modules/ExampleModule/ExampleModule.php create mode 100644 App/Classes/Abstracts/EmbeddedSystem.php rename App/Classes/Exceptions/{ModuleNotFoundException.php => EmbeddedNotFoundException.php} (72%) rename App/Classes/Exceptions/{InvalidModuleException.php => InvalidEmbeddedException.php} (65%) create mode 100644 App/Classes/Extension.php create mode 100644 App/Classes/Interfaces/EmbeddedInterface.php delete mode 100644 App/Classes/Interfaces/ModuleInterface.php delete mode 100644 App/Classes/ModuleCollection.php create mode 100644 App/Classes/Overrides/README.md create mode 100644 App/Classes/Utilities/EmbeddedCollection.php rename App/Classes/{ModuleReader.php => Utilities/EmbeddedReader.php} (58%) create mode 100644 App/Classes/Utilities/ExtensionReader.php create mode 100644 App/Classes/Utilities/ModuleReader.php create mode 100644 App/Containers/Database.php create mode 100644 App/Containers/Environment.php create mode 100644 App/Containers/Extension.php create mode 100644 App/Containers/Module.php create mode 100644 App/Containers/README.md create mode 100644 App/Containers/Settings.php rename App/Includes/{Environment.php => Helper.php} (91%) create mode 100644 Storage/logs/.gitkeep create mode 100644 public/extensions/.gitkeep diff --git a/.docs/Configurations/README.md b/.docs/Configurations/README.md new file mode 100644 index 0000000..8de982a --- /dev/null +++ b/.docs/Configurations/README.md @@ -0,0 +1 @@ +## CONFIGURATIONS diff --git a/.docs/Extensions/README.md b/.docs/Extensions/README.md new file mode 100644 index 0000000..a5d43f5 --- /dev/null +++ b/.docs/Extensions/README.md @@ -0,0 +1 @@ +## EXTENSIONS diff --git a/.docs/Modules/README.md b/.docs/Modules/README.md new file mode 100644 index 0000000..56175c9 --- /dev/null +++ b/.docs/Modules/README.md @@ -0,0 +1 @@ +## MODULES diff --git a/.example/Modules/ExampleModule/ExampleModule.php b/.example/Modules/ExampleModule/ExampleModule.php new file mode 100644 index 0000000..9417a4a --- /dev/null +++ b/.example/Modules/ExampleModule/ExampleModule.php @@ -0,0 +1,62 @@ +getEmbeddedName(); + } + + /** + * Get EmbeddedSystem Info + * + * @return array + */ + public function getEmbeddedInfo() : array + { + return [ + EmbeddedSystem::NAME => $this->getEmbeddedName(), + EmbeddedSystem::VERSION => $this->getEmbeddedVersion(), + EmbeddedSystem::URI => $this->getEmbeddedUri(), + EmbeddedSystem::AUTHOR => $this->getEmbeddedAuthor(), + EmbeddedSystem::AUTHOR_URI => $this->getEmbeddedAuthorUri(), + EmbeddedSystem::DESCRIPTION => $this->getEmbeddedDescription(), + EmbeddedSystem::CLASS_NAME => get_class($this), + EmbeddedSystem::FILE_PATH => $this->getEmbeddedRealPath(), + ]; + } + + /** + * Get Reflection + * + * @return \ReflectionClass + */ + final protected function getEmbeddedReflection() : \ReflectionClass + { + static $reflection; + if (!$reflection || ! $reflection instanceof \ReflectionClass) { + $reflection = new \ReflectionClass($this); + } + + return $reflection; + } + + /** + * Get Path + * + * @return string + */ + final public function getEmbeddedRealPath() : string + { + return $this->getEmbeddedReflection()->getFileName(); + } + + /** + * Get Name Space + * + * @return string + */ + final public function getEmbeddedNameSpace() : string + { + return $this->getEmbeddedReflection()->getNamespaceName(); + } + + /** + * Get ShortName of Class + * + * @return string + */ + final public function getEmbeddedShortName() : string + { + return $this->getEmbeddedReflection()->getShortName(); + } + + /** + * {@inheritdoc} + */ + public function getEmbeddedName() : string + { + if (!is_string($this->embedded_name) + || trim($this->embedded_name) == '' + ) { + $this->embedded_name = $this->getEmbeddedReflection()->getName(); + } + + return (string) $this->embedded_name; + } + + /** + * {@inheritdoc} + */ + public function getEmbeddedAuthor() : string + { + return (string) $this->embedded_author; + } + + /** + * {@inheritdoc} + */ + public function getEmbeddedVersion() : string + { + return (string) $this->embedded_version; + } + + /** + * Get EmbeddedSystem URL + * + * @return string + */ + public function getEmbeddedUri(): string + { + return (string) $this->embedded_uri; + } + + /** + * Get EmbeddedSystem Author + * + * @return string + */ + public function getEmbeddedAuthorUri(): string + { + return (string) $this->embedded_author_uri; + } + + /** + * Get Description of EmbeddedSystem + * + * @return string + */ + public function getEmbeddedDescription(): string + { + return (string) $this->embedded_description; + } +} diff --git a/App/Classes/Application.php b/App/Classes/Application.php index befcd20..3e7097e 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -1,7 +1,11 @@ $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Modules', - 'storage' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Storage' + 'extension' => WEB_ROOT . DIRECTORY_SEPARATOR . 'extensions', + 'module' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Modules', + 'storage' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Storage', ], $config['directory']); $config['httpVersion'] = isset($_SERVER['SERVER_PROTOCOL']) @@ -80,21 +94,96 @@ protected function init(array $config) $this->config = new Config($config); } - public function run() + /** + * Run The application + * + * @return Application + */ + public function process() { + if ($this->hasRun) { + throw new LogicException( + 'Application has been run! Please does not re run the application procedure.', + E_ERROR + ); + } + + $c =& $this; $this->slim = new App( [ - 'module' => function($c) { - return (new ModuleCollection($c['settings']['directory']['module']))->scan(); + /** + * Application Instance + * + * Use on closure prevent being binding to + * @return Application + */ + 'application' => function () use (&$c) : Application { + return $c; }, - 'config' => function($c) { - $this->config = new Config($c['settings']); - return $this->config; + /** + * Configuration Container + * + * Use on closure prevent being binding to + * @return Config + */ + 'config' => function () use (&$c) : Config { + return $c->config; }, - 'settings' => $this->config->get() + /** + * Closure + * + * @return Database + */ + 'database' => require_once dirname(__DIR__) . '/Containers/Database.php', + /** + * Closure + * + * @return Environment + */ + 'environment' => require dirname(__DIR__) . '/Containers/Environment.php', + /** + * Module Container + * + * Closure + * + * @return EmbeddedCollection + */ + 'module' => require_once dirname(__DIR__) . '/Containers/Module.php', + /** + * Extension Container + * + * Closure + * + * @return EmbeddedCollection + */ + 'extension' => require_once dirname(__DIR__) . '/Containers/Extension.php', + /** + * @return array + */ + 'settings' => require dirname(__DIR__) . '/Containers/Settings.php', + /** + * Slim Inheritance + * + * @return App + */ + 'slim' => function () use (&$c) : App { + return $c->slim; + } ] ); - return $this->slim->run(); + $this->hasRun = true; + $this->slim->any('/[{param: .+}]', function($request, $response) { + /** @var EmbeddedCollection $module */ + $module = $this['module']; + $ret = print_r($module, true); + $body = $response->getBody(); + $body->write($ret); + $response->withBody($body); + return $response; + }); + $this->slim->run(); + + return $this; } } diff --git a/App/Classes/AutoLoaderClass.php b/App/Classes/AutoLoaderClass.php index 1c5ec59..efe12b1 100644 --- a/App/Classes/AutoLoaderClass.php +++ b/App/Classes/AutoLoaderClass.php @@ -4,6 +4,8 @@ /** * Class AutoLoaderClass * @package PentagonalProject\ProjectSeventh + * + * PSR-4 Auto Loader */ final class AutoLoaderClass { diff --git a/App/Classes/Exceptions/ModuleNotFoundException.php b/App/Classes/Exceptions/EmbeddedNotFoundException.php similarity index 72% rename from App/Classes/Exceptions/ModuleNotFoundException.php rename to App/Classes/Exceptions/EmbeddedNotFoundException.php index 1af4652..a4b0b37 100644 --- a/App/Classes/Exceptions/ModuleNotFoundException.php +++ b/App/Classes/Exceptions/EmbeddedNotFoundException.php @@ -5,6 +5,6 @@ * Class ModuleNotFoundException * @package PentagonalProject\ProjectSeventh\Exceptions */ -class ModuleNotFoundException extends InvalidPathException +class EmbeddedNotFoundException extends InvalidPathException { } diff --git a/App/Classes/Exceptions/InvalidModuleException.php b/App/Classes/Exceptions/InvalidEmbeddedException.php similarity index 65% rename from App/Classes/Exceptions/InvalidModuleException.php rename to App/Classes/Exceptions/InvalidEmbeddedException.php index dd10fc8..2875b13 100644 --- a/App/Classes/Exceptions/InvalidModuleException.php +++ b/App/Classes/Exceptions/InvalidEmbeddedException.php @@ -4,9 +4,9 @@ use Apatis\Exceptions\Exception; /** - * Class InvalidModuleException + * Class InvalidEmbeddedException * @package PentagonalProject\ProjectSeventh\Exceptions */ -class InvalidModuleException extends Exception +class InvalidEmbeddedException extends Exception { -} \ No newline at end of file +} diff --git a/App/Classes/Extension.php b/App/Classes/Extension.php new file mode 100644 index 0000000..80fcbc3 --- /dev/null +++ b/App/Classes/Extension.php @@ -0,0 +1,13 @@ +getModuleName(); - } - - /** - * Get Module Info - * - * @return array - */ - public function getModuleInfo() : array - { - return [ - Module::MODULE_NAME => $this->getModuleName(), - Module::MODULE_VERSION => $this->getModuleVersion(), - Module::MODULE_URI => $this->getModuleUri(), - Module::MODULE_AUTHOR => $this->getModuleAuthor(), - Module::MODULE_AUTHOR_URI => $this->getModuleAuthorUri(), - Module::MODULE_DESCRIPTION => $this->getModuleDescription() - ]; - } - - /** - * @return \ReflectionClass - */ - final protected function getReflection() : \ReflectionClass - { - static $reflection; - if (!$reflection || ! $reflection instanceof \ReflectionClass) { - $reflection = new \ReflectionClass($this); - } - - return $reflection; - } - - /** - * Get Path - * - * @return string - */ - final public function getModuleRealPath() : string - { - return $this->getReflection()->getFileName(); - } - - /** - * Get Name Space - * - * @return string - */ - final public function getModuleNameSpace() : string - { - return $this->getReflection()->getNamespaceName(); - } - - /** - * Get ShortName of Class - * - * @return string - */ - final public function getModuleShortName() : string - { - return $this->getReflection()->getShortName(); - } - - /** - * {@inheritdoc} - */ - public function getModuleName() : string - { - if (!is_string($this->module_name) - || trim($this->module_name) == '' - ) { - $this->module_name = $this->getReflection()->getName(); - } - - return (string) $this->module_name; - } - - /** - * {@inheritdoc} - */ - public function getModuleAuthor() : string - { - return (string) $this->module_author; - } - - /** - * {@inheritdoc} - */ - public function getModuleVersion() : string - { - return (string) $this->module_version; - } - - /** - * Get Module URL - * - * @return string - */ - public function getModuleUri(): string - { - return (string) $this->module_uri; - } - - /** - * Get Module Author - * - * @return string - */ - public function getModuleAuthorUri(): string - { - return (string) $this->module_author_uri; - } - - /** - * Get Description of Module - * - * @return string - */ - public function getModuleDescription(): string - { - return (string) $this->module_description; - } } diff --git a/App/Classes/ModuleCollection.php b/App/Classes/ModuleCollection.php deleted file mode 100644 index eab65e8..0000000 --- a/App/Classes/ModuleCollection.php +++ /dev/null @@ -1,367 +0,0 @@ -splFileInfo = new \SplFileInfo($moduleDirectory); - if ($this->splFileInfo->isLink()) { - throw new RuntimeException( - "Invalid Module Directory. Module directory could not as a symlink!", - E_COMPILE_ERROR - ); - } - - $this->moduleDirectory = $this->splFileInfo->getRealPath(); - } - - /** - * Get Path Module Directory - * - * @return string - */ - public function getModuleDirectory(): string - { - return $this->moduleDirectory; - } - - /** - * @return Module[] - */ - public function getAllModules() : array - { - return $this->validModules; - } - - /** - * Scan Module Directory - * - * @return ModuleCollection - */ - public function scan() : ModuleCollection - { - if ($this->hasScanned) { - return $this; - } - - /** - * @var SplFileInfo $path - */ - foreach (new RecursiveDirectoryIterator($this->getModuleDirectory()) as $path) { - $baseName = $path->getBaseName(); - // skip dotted - if ($baseName == '.' || $baseName == '..') { - continue; - } - - $directory = $this->getModuleDirectory() . DIRECTORY_SEPARATOR . $baseName; - // don't allow symlink to be execute & skip if contains file - if ($path->isLink() || ! $path->isDir()) { - $this->unwantedPath[$baseName] = $path->getType(); - continue; - } - - $file = $directory . DIRECTORY_SEPARATOR . $baseName .'.php'; - if (! file_exists($file)) { - $this->invalidModules[$baseName] = new ModuleNotFoundException( - $file, - sprintf("Module file for %s has not found", $baseName) - ); - - continue; - } - - try { - $this->validModules[$this->sanitizeModuleName($baseName)] = function () use ($file) { - $module = (new ModuleReader($file))->process(); - return $module->getInstance(); - }; - - } catch (\Exception $e) { - $this->invalidModules[$this->sanitizeModuleName($baseName)] = $e; - } - } - - return $this; - } - - /** - * Get Invalid Modules - * - * @return \Exception[] - */ - public function getInvalidModules(): array - { - return $this->invalidModules; - } - - /** - * Get Unwanted Path - * contain [file|dir|link] - * - * @see ModuleCollection::TYPE_SYMLINK - * @see ModuleCollection::TYPE_DIR - * @see ModuleCollection::TYPE_FILE - * - * @return string[] - */ - public function getUnwantedPath(): array - { - return $this->unwantedPath; - } - - /** - * @see getUnwantedPath() - * - * @return string[] - */ - public function getUnwantedPaths(): array - { - return $this->unwantedPath; - } - - /** - * Get Loaded Modules List base on Name - * - * @return string[] - */ - public function getLoadedModulesName(): array - { - return $this->loadedModules; - } - - /** - * @return Module[] - */ - public function getLoadedModules(): array - { - $module = []; - foreach ($this->getLoadedModulesName() as $value) { - if (isset($this->validModules[$value])) { - $module[$value] = $this->validModules[$value]; - } - } - - return $module; - } - - /** - * Sanitize Module Name - * - * @param string $name - * @return string - */ - protected function sanitizeModuleName(string $name) : string - { - return trim(strtolower($name)); - } - - /** - * Get Module Given By Name - * - * @access internal - * @param string $name - * @return Module - * @throws InvalidModuleException - */ - protected function &internalGetModule(string $name) : Module - { - $moduleName = $this->sanitizeModuleName($name); - if (!$moduleName) { - throw new InvalidArgumentException( - "Please insert not an empty arguments", - E_USER_ERROR - ); - } - if (!$this->exist($moduleName)) { - throw new InvalidModuleException( - sprintf("Module %s has not found", $name) - ); - } - if ($this->validModules[$moduleName] instanceof \Closure) { - $this->validModules[$moduleName] = $this->validModules[$moduleName](); - } - - return $this->validModules[$moduleName]; - } - - /** - * Get Module Info - * - * @param string $moduleName - * @return Collection - */ - public function getModuleInfo(string $moduleName) - { - return new Collection($this->internalGetModule($moduleName)->getModuleInfo()); - } - - /** - * Load Module - * - * @param string $name - * @return Module - * @throws InvalidModuleException - * @throws ModuleNotFoundException - */ - public function &load(string $name) : Module - { - $module =& $this->internalGetModule($name); - if (!$this->hasLoaded($name)) { - $module->init(); - $this->loadedModules[$this->sanitizeModuleName($name)] = true; - } - - return $module; - } - - /** - * Check if Module Exists - * - * @param string $name - * @return bool - */ - public function exist(string $name) - { - return isset($this->validModules[$this->sanitizeModuleName($name)]); - } - - /** - * Check If Module Has Loaded - * - * @param string $name - * @return bool - */ - public function hasLoaded(string $name) - { - $moduleName = $this->sanitizeModuleName($name); - return $moduleName && !empty($this->loadedModules[$moduleName]); - } - - /** - * {@inheritdoc} - */ - public function count() - { - return count($this->validModules); - } - - /** - * @param string $offset - * @return Module - */ - public function offsetGet($offset) - { - return $this->load($offset); - } - - /** - * @param string $offset - * @return bool - */ - public function offsetExists($offset) - { - return $this->exist($offset); - } - - /** - * {@inheritdoc} - * no affected here - */ - public function offsetSet($offset, $value) - { - return; - } - - /** - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - return; - } - - /** - * @param string $name - * @return Module - */ - public function __get($name) - { - return $this->load($name); - } -} diff --git a/App/Classes/Overrides/README.md b/App/Classes/Overrides/README.md new file mode 100644 index 0000000..16fd045 --- /dev/null +++ b/App/Classes/Overrides/README.md @@ -0,0 +1,3 @@ +## SLIM OVERRIDE + +Contains file that override slim 3 functionality diff --git a/App/Classes/Utilities/EmbeddedCollection.php b/App/Classes/Utilities/EmbeddedCollection.php new file mode 100644 index 0000000..0d6d89d --- /dev/null +++ b/App/Classes/Utilities/EmbeddedCollection.php @@ -0,0 +1,405 @@ +embeddedReader = $embeddedReader; + if (!is_dir($embeddedDirectory) || ! is_readable($embeddedDirectory)) { + throw new RuntimeException( + sprintf( + 'Invalid %s Directory. %s directory not exists or has not readable by system!', + $this->embeddedReader->getName() + ), + E_COMPILE_ERROR + ); + } + + $this->splFileInfo = new \SplFileInfo($embeddedDirectory); + if ($this->splFileInfo->isLink()) { + throw new RuntimeException( + sprintf( + 'Invalid %s Directory. %s directory could not as a symlink!', + $this->embeddedReader->getName() + ), + E_COMPILE_ERROR + ); + } + + $this->embeddedDirectory = $this->splFileInfo->getRealPath(); + } + + /** + * Get Path Embed Directory + * + * @return string + */ + public function getEmbeddedDirectory(): string + { + return $this->embeddedDirectory; + } + + /** + * @return EmbeddedSystem[] + */ + public function getAllEmbedded() : array + { + return $this->validEmbedded; + } + + /** + * Scan EmbeddedSystem Directory + * + * @return EmbeddedCollection + */ + public function scan() : EmbeddedCollection + { + if ($this->hasScanned) { + return $this; + } + + /** + * @var SplFileInfo $path + */ + foreach (new RecursiveDirectoryIterator($this->getEmbeddedDirectory()) as $path) { + $baseName = $path->getBaseName(); + // skip dotted + if ($baseName == '.' || $baseName == '..') { + continue; + } + + $directory = $this->getEmbeddedDirectory() . DIRECTORY_SEPARATOR . $baseName; + // don't allow symlink to be execute & skip if contains file + if ($path->isLink() || ! $path->isDir()) { + $this->unwantedPath[$baseName] = $path->getType(); + continue; + } + + $file = $directory . DIRECTORY_SEPARATOR . $baseName .'.php'; + if (! file_exists($file)) { + $this->invalidEmbedded[$baseName] = new EmbeddedNotFoundException( + $file, + sprintf( + '%1$s file for %2$s has not found', + $this->embeddedReader->getName(), + $baseName + ) + ); + + continue; + } + + try { + $this->validEmbedded[$this->sanitizeEmbeddedName($baseName)] = function () use ($file) { + $embedded = $this->embeddedReader->create($file)->process(); + return $embedded->getInstance(); + }; + } catch (\Exception $e) { + $this->invalidEmbedded[$this->sanitizeEmbeddedName($baseName)] = $e; + } + } + + return $this; + } + + /** + * Get Invalid Embedded + * + * @return \Exception[] + */ + public function getInvalidEmbedded(): array + { + return $this->invalidEmbedded; + } + + /** + * Get Unwanted Path + * contain [file|dir|link] + * + * @see EmbeddedCollection::TYPE_SYMLINK + * @see EmbeddedCollection::TYPE_DIR + * @see EmbeddedCollection::TYPE_FILE + * + * @return string[] + */ + public function getUnwantedPath(): array + { + return $this->unwantedPath; + } + + /** + * @see getUnwantedPath() + * + * @return string[] + */ + public function getUnwantedPaths(): array + { + return $this->unwantedPath; + } + + /** + * Get Loaded Embedded List base on Name + * + * @return string[] + */ + public function getLoadedEmbeddedName(): array + { + return $this->loadedEmbedded; + } + + /** + * @return EmbeddedSystem[] + */ + public function getLoadedEmbedded(): array + { + $embeds = []; + foreach ($this->getLoadedEmbeddedName() as $value) { + if (isset($this->validEmbedded[$value])) { + $embeds[$value] = $this->validEmbedded[$value]; + } + } + + return $embeds; + } + + /** + * Sanitize Embedded Name + * + * @param string $name + * @return string + */ + protected function sanitizeEmbeddedName(string $name) : string + { + return trim(strtolower($name)); + } + + /** + * Get Embedded Given By Name + * + * @access internal + * @param string $name + * @return EmbeddedSystem + * @throws InvalidEmbeddedException + */ + protected function &internalGetEmbedded(string $name) : EmbeddedSystem + { + $embeddedName = $this->sanitizeEmbeddedName($name); + if (!$embeddedName) { + throw new InvalidArgumentException( + "Please insert not an empty arguments", + E_USER_ERROR + ); + } + if (!$this->exist($embeddedName)) { + throw new InvalidEmbeddedException( + sprintf( + '%1$s %2$s has not found', + $this->embeddedReader->getName(), + $name + ) + ); + } + if ($this->validEmbedded[$embeddedName] instanceof \Closure) { + $this->validEmbedded[$embeddedName] = $this->validEmbedded[$embeddedName](); + } + + return $this->validEmbedded[$embeddedName]; + } + + /** + * Get EmbeddedSystem's Info + * + * @param string $embeddedName + * @return Collection + */ + public function getEmbedInfo(string $embeddedName) + { + return new Collection($this->internalGetEmbedded($embeddedName)->getEmbeddedInfo()); + } + + /** + * Get All EmbeddedSystem Info + * + * @return Collection|Collection[] + */ + public function getAllEmbeddedInfo() + { + $embed_info = new Collection(); + foreach ($this->getAllEmbedded() as $embedName => $embed) { + $embed_info[$embedName] = $this->getEmbedInfo($embedName); + } + + return $embed_info; + } + + /** + * Load Embed + * + * @param string $name + * @return EmbeddedSystem + * @throws InvalidEmbeddedException + * @throws EmbeddedNotFoundException + */ + public function &load(string $name) : EmbeddedSystem + { + $embedded =& $this->internalGetEmbedded($name); + if (!$this->hasLoaded($name)) { + $embedded->init(); + $this->loadedEmbedded[$this->sanitizeEmbeddedName($name)] = true; + } + + return $embedded; + } + + /** + * Check if Embed Exists + * + * @param string $name + * @return bool + */ + public function exist(string $name) + { + return isset($this->validEmbedded[$this->sanitizeEmbeddedName($name)]); + } + + /** + * Check If Embed Has Loaded + * + * @param string $name + * @return bool + */ + public function hasLoaded(string $name) + { + $embedName = $this->sanitizeEmbeddedName($name); + return $embedName && !empty($this->loadedEmbedded[$embedName]); + } + + /** + * {@inheritdoc} + */ + public function count() + { + return count($this->validEmbedded); + } + + /** + * @param string $offset + * @return EmbeddedSystem + */ + public function offsetGet($offset) + { + return $this->load($offset); + } + + /** + * @param string $offset + * @return bool + */ + public function offsetExists($offset) + { + return $this->exist($offset); + } + + /** + * {@inheritdoc} + * no affected here + */ + public function offsetSet($offset, $value) + { + return; + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + return; + } + + /** + * @param string $name + * @return EmbeddedSystem + */ + public function __get($name) + { + return $this->load($name); + } +} diff --git a/App/Classes/ModuleReader.php b/App/Classes/Utilities/EmbeddedReader.php similarity index 58% rename from App/Classes/ModuleReader.php rename to App/Classes/Utilities/EmbeddedReader.php index e05f6c9..6fbc692 100644 --- a/App/Classes/ModuleReader.php +++ b/App/Classes/Utilities/EmbeddedReader.php @@ -1,18 +1,19 @@ name; + } + + /** + * Set File + * * @param string $file + * @return EmbeddedReader */ - public function __construct(string $file) + protected function setFileToLoad(string $file) : EmbeddedReader { - $this->moduleClass = Module::class; if (file_exists($file)) { $spl = new \SplFileInfo($file); if ($spl->isLink()) { @@ -58,22 +82,40 @@ public function __construct(string $file) if (strtolower($spl->getExtension()) !== 'php') { throw new InvalidArgumentException( - "Module file has invalid extension. Extension must be as `php`", + sprintf( + "%s file has invalid extension. Extension must be as `php`", + $this->getName() + ), E_WARNING ); } $this->file = $spl->getRealPath(); unset($spl); - return; + return $this; } throw new InvalidArgumentException( - "Invalid file Module to read", + sprintf( + "Invalid file %s to read.", + $this->getName() + ), E_WARNING ); } + /** + * Create Instance EmbeddedReader + * + * @param string $file + * @return static + */ + public static function create(string $file) + { + $static = new static(); + return $static->setFileToLoad($file); + } + /** * Get File Path * @@ -103,7 +145,7 @@ public function isValid(): bool } /** - * @return Module|null + * @return EmbeddedSystem|null */ public function getInstance() { @@ -111,11 +153,11 @@ public function getInstance() } /** - * @return ModuleReader + * @return EmbeddedReader * @throws InvalidPathException * @throws Exception */ - public function process() : ModuleReader + public function process() : EmbeddedReader { if (!$this->getFile()) { $this->valid = false; @@ -142,27 +184,32 @@ public function process() : ModuleReader /** * Validate * - * @return ModuleReader + * @return EmbeddedReader * @throws EmptyFileException - * @throws InvalidModuleException + * @throws InvalidEmbeddedException */ - private function validate() : ModuleReader + private function validate() : EmbeddedReader { - if (!is_string($this->moduleClass)) { + if (!is_string($this->embeddedClass)) { throw new RuntimeException( - "Invalid Parent Module Class. Module extends must be as class name and string." + sprintf( + 'Invalid Parent %s Class. %s extends must be as class name and string.', + $this->getName() + ), + E_COMPILE_ERROR ); } - $this->moduleClass = rtrim($this->moduleClass, '\\'); - if (!class_exists($this->moduleClass) - || strtolower($this->moduleClass) != strtolower(Module::class) - && ! is_subclass_of($this->moduleClass, Module::class) + $this->embeddedClass = rtrim($this->embeddedClass, '\\'); + if (!class_exists($this->embeddedClass) + || strtolower($this->embeddedClass) != strtolower(EmbeddedSystem::class) + && ! is_subclass_of($this->embeddedClass, EmbeddedSystem::class) ) { throw new RuntimeException( sprintf( - "Parent Module class Does not extends into %s", - Module::class + 'Parent %1$s class does not extends into %2$s', + $this->getName(), + EmbeddedSystem::class ) ); } @@ -181,8 +228,11 @@ private function validate() : ModuleReader } if (strtolower(substr($content, 0, 5)) !== 'getName() + ), E_ERROR ); } @@ -192,8 +242,11 @@ private function validate() : ModuleReader && !empty($namespaces['namespace']) ) { if (strtolower(trim($namespaces['namespace'])) == strtolower(__NAMESPACE__)) { - throw new InvalidModuleException( - "File Module contain name space of core.", + throw new InvalidEmbeddedException( + sprintf( + 'File %s contain name space of core.', + $this->getName() + ), E_ERROR ); } @@ -201,16 +254,19 @@ private function validate() : ModuleReader } if ($namespace !== '\\' && preg_match('`[^\\_a-z0-9]`', $namespace)) { - throw new InvalidModuleException( - "File Module contain invalid name space.", + throw new InvalidEmbeddedException( + sprintf( + 'File %s contain invalid name space.', + $this->getName() + ), E_ERROR ); } - $moduleClass = $this->moduleClass; + $embeddedClass = $this->embeddedClass; preg_match( '/use\s+ - (?:\\\{1})?(?P'.preg_quote($moduleClass, '/').') + (?:\\\{1})?(?P'.preg_quote($embeddedClass, '/').') (?:\s+as\s+(?P[a-z0-9_]+))?;+ /smx', $content, @@ -237,7 +293,7 @@ private function validate() : ModuleReader $regexNameSpace = $alias ? '(?P('.preg_quote("{$alias}", '/').'))\s*' - : '(?P('.preg_quote("\\{$moduleClass}", '/') . '|' . preg_quote($alias, '/').'))\s*'; + : '(?P('.preg_quote("\\{$embeddedClass}", '/') . '|' . preg_quote($alias, '/').'))\s*'; preg_match( '`class\s+ (?P[a-z_][a-z0-9\_]+) @@ -249,22 +305,32 @@ private function validate() : ModuleReader ); if (empty($class['class']) || empty($class['extends'])) { - throw new InvalidModuleException( - "File Module does not contain valid class or not extends to `{$moduleClass}`.", + throw new InvalidEmbeddedException( + sprintf( + 'File %1$s does not contain valid class or not extends to `%2$s`.', + $this->getName(), + $embeddedClass + ), E_ERROR ); } if (strtolower(pathinfo($this->file, PATHINFO_FILENAME)) !== strtolower($class['class'])) { - throw new InvalidModuleException( - "File Module does not match between file name & class.", + throw new InvalidEmbeddedException( + sprintf( + 'File %s does not match between file name & class.', + $this->getName() + ), E_ERROR ); } if (! preg_match('/(public\s+)?function\s+init\([^\)]*\)\s*\{/smi', $content, $match)) { - throw new InvalidModuleException( - "File Module does not contain method `init`.", + throw new InvalidEmbeddedException( + sprintf( + 'File %s does not contain method `init`.', + $this->getName() + ), E_ERROR ); } @@ -275,8 +341,12 @@ private function validate() : ModuleReader // prevent multiple include file if class has been loaded if (class_exists($class)) { - throw new InvalidModuleException( - "Object class {$class} for module has been loaded.", + throw new InvalidEmbeddedException( + sprintf( + 'Object class %1$s for %2$s has been loaded.', + $class, + $this->getName() + ), E_ERROR ); } @@ -289,16 +359,23 @@ private function validate() : ModuleReader if ($error = error_get_last() && !empty($error) && $error['file'] == $this->file) { if ($error['type'] === E_ERROR) { @ob_end_clean(); - throw new InvalidModuleException( - "File Module contains fatal error.", + throw new InvalidEmbeddedException( + sprintf( + 'File %s contains fatal error.', + $this->getName() + ), E_ERROR ); } } @ob_end_clean(); if (!class_exists($class)) { - throw new InvalidModuleException( - "File Module does not contain class {$class}.", + throw new InvalidEmbeddedException( + sprintf( + 'File %1$s does not contain class %2$s.', + $this->getName(), + $class + ), E_ERROR ); } diff --git a/App/Classes/Utilities/ExtensionReader.php b/App/Classes/Utilities/ExtensionReader.php new file mode 100644 index 0000000..0905195 --- /dev/null +++ b/App/Classes/Utilities/ExtensionReader.php @@ -0,0 +1,25 @@ +get('database', [])); + }; +} diff --git a/App/Containers/Environment.php b/App/Containers/Environment.php new file mode 100644 index 0000000..52c909e --- /dev/null +++ b/App/Containers/Environment.php @@ -0,0 +1,39 @@ +get('directory[extension]'), + new ExtensionReader() + ); + $extensionCollection->scan(); + return $extensionCollection; + }; +} diff --git a/App/Containers/Module.php b/App/Containers/Module.php new file mode 100644 index 0000000..ac82848 --- /dev/null +++ b/App/Containers/Module.php @@ -0,0 +1,28 @@ +get('directory[module]'), + new ModuleReader() + ); + $moduleCollection->scan(); + return $moduleCollection; + }; +} diff --git a/App/Containers/README.md b/App/Containers/README.md new file mode 100644 index 0000000..75e18e4 --- /dev/null +++ b/App/Containers/README.md @@ -0,0 +1,30 @@ +## DO NOT CHANGE ANYTHING HERE!! + +Creating Container file guide + +1. Follow PHP7 coding guide : + **PSR-2 Coding Standards** + +2. Must be Contain namespace { //... code } + +```php + true + ]; +} diff --git a/App/FunctionsIncludes.php b/App/FunctionsIncludes.php index 9a2c71c..f149201 100644 --- a/App/FunctionsIncludes.php +++ b/App/FunctionsIncludes.php @@ -3,5 +3,5 @@ | FILES INCLUDES LIST | \* ------------------------------------------------------ */ -require_once __DIR__ . '/Includes/Environment.php'; +require_once __DIR__ . '/Includes/Helper.php'; require_once __DIR__ . '/Includes/Utilities.php'; diff --git a/App/Includes/Environment.php b/App/Includes/Helper.php similarity index 91% rename from App/Includes/Environment.php rename to App/Includes/Helper.php index 8a63b26..884effc 100644 --- a/App/Includes/Environment.php +++ b/App/Includes/Helper.php @@ -49,14 +49,15 @@ function getWebServerSoftWare() $type = IIS7_SERVER; } } + if (function_exists('apache_get_modules')) { + if (in_array('mod_security', apache_get_modules())) { + $type = APACHE_SERVER; + } - if (! $type - && ( - function_exists('apache_get_modules') - || function_exists('apache_get_version') - ) - ) { - $type = APACHE_SERVER; + if (!$type && function_exists('apache_get_version') + ) { + $type = APACHE_SERVER; + } } return $type; diff --git a/Storage/logs/.gitkeep b/Storage/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config.php b/config.php index 5553505..0ec2b18 100644 --- a/config.php +++ b/config.php @@ -6,6 +6,7 @@ 'directory' => [ 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'extensions', ], 'database' => [ 'host' => 'localhost', diff --git a/public/extensions/.gitkeep b/public/extensions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/public/index.php b/public/index.php index f8b2d58..121447b 100644 --- a/public/index.php +++ b/public/index.php @@ -108,6 +108,6 @@ exit(E_CORE_ERROR); } +// Require Composer Autoload require __DIR__ . '/../vendor/autoload.php'; - -return (new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'))->run(); +return (new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'))->process(); From 1e385cb800cc9a6c0ff4bf07b589d29b4e6763f0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Tue, 25 Apr 2017 18:12:26 +0700 Subject: [PATCH 008/142] I'am Tired Beibeeh - Uuulaaalaaa --- .docs/README.md | 1 + README.md | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .docs/README.md diff --git a/.docs/README.md b/.docs/README.md new file mode 100644 index 0000000..0e6e0ca --- /dev/null +++ b/.docs/README.md @@ -0,0 +1 @@ +## DOCUMENTATION diff --git a/README.md b/README.md index f33f209..d785808 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,18 @@ # PENTAGONAL PROJECT -`pentagonal project api` +--- -# LICENSE + +### `J U S T _ F O R _ F U N !?` + + +--- + +## DOCUMENTATION + +See [Documentation](.docs) + + +## LICENSE [BSD 3-Clause License](LICENSE) From c2428f81fb3acbf26f0f27952c743d20f8cba46b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Tue, 25 Apr 2017 18:15:03 +0700 Subject: [PATCH 009/142] I'am Tired Beibeeh - Uuulaaalaaa --- .docs/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.docs/README.md b/.docs/README.md index 0e6e0ca..3ecc0da 100644 --- a/.docs/README.md +++ b/.docs/README.md @@ -1 +1,12 @@ ## DOCUMENTATION + +```json +{} +``` + +--- + + +- [Configurations](Configurations) +- [Extensions](Extensions) +- [Modules](Modules) From 013079ecede32dc4ba8bfb5735ce3e6f25b1d4eb Mon Sep 17 00:00:00 2001 From: pentagonal Date: Wed, 26 Apr 2017 17:30:27 +0700 Subject: [PATCH 010/142] Hola Halo TVRI `sharp` Aummmmm --- .travis.yml | 16 + App/Classes/Application.php | 327 ++++++++---- App/Classes/Arguments.php | 113 ++++ App/Classes/Database.php | 37 ++ .../Exceptions/FileNotFoundException.php | 20 + .../Exceptions/InvalidPathException.php | 4 +- App/Classes/Hook.php | 483 ++++++++++++++++++ App/Classes/README.md | 3 + App/Classes/Session.php | 280 ++++++++++ App/Classes/Utilities/EmbeddedReader.php | 5 + App/Components/ApplicationMiddleware.php | 35 ++ App/Components/ApplicationRoutes.php | 26 + App/Components/ApplicationSlimObject.php | 107 ++++ App/Components/README.md | 7 + App/Containers/Config.php | 46 ++ App/Containers/Database.php | 101 +++- App/Containers/Environment.php | 4 + App/Containers/Extension.php | 6 +- App/Containers/Hook.php | 20 + App/Containers/Module.php | 6 +- App/Containers/README.md | 20 +- App/Containers/Session.php | 49 ++ App/Containers/Settings.php | 4 + App/FunctionsIncludes.php | 1 + App/Includes/README.md | 7 + App/README.md | 3 + README.md | 14 +- VERSION | 1 + {.docs => _docs}/Configurations/README.md | 0 {.docs => _docs}/Extensions/README.md | 0 {.docs => _docs}/Modules/README.md | 0 {.docs => _docs}/README.md | 0 .../ExampleExtension/ExampleExtension.php | 62 +++ .../Modules/ExampleModule/ExampleModule.php | 2 +- _example/README.md | 1 + composer.json | 2 +- config.php | 25 +- phpcs.xml | 1 + public/index.php | 30 +- 39 files changed, 1729 insertions(+), 139 deletions(-) create mode 100644 .travis.yml create mode 100644 App/Classes/Arguments.php create mode 100644 App/Classes/Exceptions/FileNotFoundException.php create mode 100644 App/Classes/Hook.php create mode 100644 App/Classes/README.md create mode 100644 App/Classes/Session.php create mode 100644 App/Components/ApplicationMiddleware.php create mode 100644 App/Components/ApplicationRoutes.php create mode 100644 App/Components/ApplicationSlimObject.php create mode 100644 App/Components/README.md create mode 100644 App/Containers/Config.php create mode 100644 App/Containers/Hook.php create mode 100644 App/Containers/Session.php create mode 100644 App/Includes/README.md create mode 100644 App/README.md create mode 100644 VERSION rename {.docs => _docs}/Configurations/README.md (100%) rename {.docs => _docs}/Extensions/README.md (100%) rename {.docs => _docs}/Modules/README.md (100%) rename {.docs => _docs}/README.md (100%) create mode 100644 _example/Extensions/ExampleExtension/ExampleExtension.php rename {.example => _example}/Modules/ExampleModule/ExampleModule.php (94%) create mode 100644 _example/README.md diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f2501e6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +sudo: false + +language: php + +php: + - 7.0 + - 7.1 + - hhvm + +before_script: + - composer install -o + +script: ./vendor/bin/phpcs + +matrix: + fast_finish: true diff --git a/App/Classes/Application.php b/App/Classes/Application.php index 3e7097e..f4b6b21 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -1,11 +1,10 @@ appDirectory = dirname(__DIR__); + $this->componentDirectory = $this->getAppDirectory('Components'); + $this->containerDirectory = $this->getAppDirectory('Containers'); $this->rootDirectory = dirname($this->appDirectory); - $this->init($config); + if (!defined('WEB_ROOT')) { + define('WEB_ROOT', dirname($_SERVER['SCRIPT_FILENAME'])); + } + $this->webRootDirectory = $this->getFixPath(WEB_ROOT, false); + } + + /** + * Returning Directory Separator + * + * @return string + */ + public function getDS() + { + return $this->ds; + } + + /** + * Fix Path Separator + * + * @param string $path + * @param bool $useCleanPrefix + * @return string + */ + public function getFixPath(string $path = '', $useCleanPrefix = false) : string + { + /** + * Trimming path string + */ + if (($path = trim($path)) == '') { + return $path; + } + + $path = preg_replace('`(\/|\\\)+`', $this->getDS(), $path); + if ($useCleanPrefix) { + $path = $this->getDS() . ltrim($path, $this->getDS()); + } + + return $path; } /** * Get Root Directory * + * @param string $path + * @return string + */ + public function getRootDirectory(string $path = '') : string + { + return $this->rootDirectory . $this->getFixPath($path, true); + } + + /** + * Get Web Root Directory + * + * @param string $path * @return string */ - public function getRootDirectory() : string + public function getWebRootDirectory(string $path = '') : string { - return $this->rootDirectory; + return $this->webRootDirectory . $this->getFixPath($path, true); } /** * Get Application Directory * + * @param string $path * @return string */ - public function getAppDirectory() : string + public function getAppDirectory(string $path = '') : string { - return $this->appDirectory; + return $this->appDirectory . $this->getFixPath($path, true); } /** - * Initialize + * Get Application Directory + * + * @param string $path + * @return string + */ + public function getContainerDirectory(string $path = '') : string + { + return $this->containerDirectory . $this->getFixPath($path, true); + } + + /** + * Get Application Component Directory + * @param string $path + * @return string + */ + public function getComponentDirectory(string $path = '') : string + { + return $this->componentDirectory . $this->getFixPath($path, true); + } + + /** + * Include Scope * - * @param $config + * @param-read string $file + * @return mixed + * @throws FileNotFoundException */ - protected function init(array &$config) + public function includeScope() { - $config['directory'] = isset($config['directory']) ? $config['directory'] : []; - if (!is_array($config['directory'])) { - $config['directory'] = []; + if (func_num_args() < 1) { + throw new InvalidArgumentException( + 'Argument 1 could not be empty.', + E_USER_ERROR + ); + } + + if (!is_string(func_get_arg(0))) { + throw new InvalidArgumentException( + sprintf( + 'Argument 1 must be as a string %s given.', + gettype(func_get_arg(0)) + ), + E_USER_ERROR + ); } - $config['directory'] = array_merge([ - 'extension' => WEB_ROOT . DIRECTORY_SEPARATOR . 'extensions', - 'module' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Modules', - 'storage' => $this->getRootDirectory() .DIRECTORY_SEPARATOR . ' Storage', - ], $config['directory']); - - $config['httpVersion'] = isset($_SERVER['SERVER_PROTOCOL']) - && strpos($_SERVER['SERVER_PROTOCOL'], '/') !== false - ? explode('/', $_SERVER['SERVER_PROTOCOL'])[1] - : '1.1'; - - $this->config = new Config($config); + + if (!($path = stream_resolve_include_path(func_get_arg(0)))) { + throw new FileNotFoundException( + func_get_arg(0) + ); + } + + /** + * closure include of scope to prevent access @uses Application + * bind to @uses Arguments + * if inside of include call $this it wil be access as @uses Arguments object + * @uses Application::APP_KEY to access application instance + * eg : + * $this->get(Application::APP_KEY) + */ + $args = func_get_args(); + $args[self::APP_KEY] =& $this; + $fn = (function () { + /** @var Arguments $this */ + /** @noinspection PhpIncludeInspection */ + return include $this[0]; + })->bindTo(new Arguments($args)); + + return $fn(); + } + + /** + * Include Scope + * + * @param-read string $file + * @return mixed + * @throws FileNotFoundException + */ + public function includeScopeOnce() + { + if (func_num_args() < 1) { + throw new InvalidArgumentException( + 'Argument 1 could not be empty.', + E_USER_ERROR + ); + } + + if (!is_string(func_get_arg(0))) { + throw new InvalidArgumentException( + sprintf( + 'Argument 1 must be as a string %s given.', + gettype(func_get_arg(0)) + ), + E_USER_ERROR + ); + } + + if (!($path = stream_resolve_include_path(func_get_arg(0)))) { + throw new FileNotFoundException( + func_get_arg(0) + ); + } + + /** + * closure include of scope to prevent access @uses Application + * bind to @uses Arguments + * if inside of include call $this it wil be access as @uses Arguments object + * @uses Application::APP_KEY to access application instance + * eg : + * $this->get(Application::APP_KEY) + */ + $args = func_get_args(); + $args[self::APP_KEY] =& $this; + $fn = (function () { + /** @var Arguments $this */ + /** @noinspection PhpIncludeInspection */ + return include_once $this[0]; + })->bindTo(new Arguments($args)); + + return $fn(); + } + + /** + * @return App + */ + public function &getSlim() + { + return $this->slim; } /** * Run The application * + * @param array $config * @return Application */ - public function process() + public function process(array $config) { if ($this->hasRun) { throw new LogicException( @@ -108,82 +289,16 @@ public function process() ); } - $c =& $this; - $this->slim = new App( - [ - /** - * Application Instance - * - * Use on closure prevent being binding to - * @return Application - */ - 'application' => function () use (&$c) : Application { - return $c; - }, - /** - * Configuration Container - * - * Use on closure prevent being binding to - * @return Config - */ - 'config' => function () use (&$c) : Config { - return $c->config; - }, - /** - * Closure - * - * @return Database - */ - 'database' => require_once dirname(__DIR__) . '/Containers/Database.php', - /** - * Closure - * - * @return Environment - */ - 'environment' => require dirname(__DIR__) . '/Containers/Environment.php', - /** - * Module Container - * - * Closure - * - * @return EmbeddedCollection - */ - 'module' => require_once dirname(__DIR__) . '/Containers/Module.php', - /** - * Extension Container - * - * Closure - * - * @return EmbeddedCollection - */ - 'extension' => require_once dirname(__DIR__) . '/Containers/Extension.php', - /** - * @return array - */ - 'settings' => require dirname(__DIR__) . '/Containers/Settings.php', - /** - * Slim Inheritance - * - * @return App - */ - 'slim' => function () use (&$c) : App { - return $c->slim; - } - ] + // must be call it first + $this->slim = $this->includeScope( + $this->getComponentDirectory('ApplicationSlimObject.php'), + $config ); - - $this->hasRun = true; - $this->slim->any('/[{param: .+}]', function($request, $response) { - /** @var EmbeddedCollection $module */ - $module = $this['module']; - $ret = print_r($module, true); - $body = $response->getBody(); - $body->write($ret); - $response->withBody($body); - return $response; - }); + // call middleware + $this->includeScope($this->getComponentDirectory('ApplicationMiddleware.php')); + // determine & call routes + $this->includeScope($this->getComponentDirectory('ApplicationRoutes.php')); $this->slim->run(); - return $this; } } diff --git a/App/Classes/Arguments.php b/App/Classes/Arguments.php new file mode 100644 index 0000000..9d325fd --- /dev/null +++ b/App/Classes/Arguments.php @@ -0,0 +1,113 @@ +arguments =& $arguments; + } + + /** + * Get Arguments + * + * @param int|string|float $offset + * @param null $default + * @return mixed|null + */ + public function &get($offset, $default = null) + { + if ($this->has($offset)) { + return $this->arguments[$offset]; + } + + return $default; + } + + /** + * Check if has Arguments + * + * @param int|mixed|float $offset + * @return bool + */ + public function has($offset) + { + return (array_key_exists($offset, $this->arguments)); + } + + /** + * Set Arguments + * + * @param int|string|float $offset + * @param mixed $value + */ + public function set($offset, $value) + { + $this->arguments[$offset] = $value; + } + + /** + * Remove/Unset Arguments + * + * @param int|string|float $offset + */ + public function remove($offset) + { + unset($this->arguments[$offset]); + } + + /** + * Count Arguments + * + * @return int + */ + public function count() : int + { + return count($this->arguments); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) + { + return $this->has($offset); + } +} diff --git a/App/Classes/Database.php b/App/Classes/Database.php index 9875ba9..f0adb84 100644 --- a/App/Classes/Database.php +++ b/App/Classes/Database.php @@ -179,6 +179,13 @@ public function __construct(array $configs) * Merge User Param */ $this->currentUserParams = array_merge($this->currentUserParams, $configs); + if (empty($this->currentUserParams['driver']) + && isset($this->currentUserParams['port']) + && $this->currentUserParams['port'] == 3306 + ) { + $this->currentUserParams['driver'] = 'mysql'; + } + if (!isset($this->currentUserParams['driver'])) { throw new DBALException('Driver must be declare.', E_USER_ERROR); } @@ -225,9 +232,39 @@ public function __construct(array $configs) } $this->currentUserParams['path'] = $this->currentUserParams['name']; } + $this->currentUserParams['dbname'] = $this->currentUserParams['name']; unset($this->currentUserParams['name']); + if (is_string($this->currentUserParams['charset']) + && strpos($this->currentUserParams['charset'], '-') + ) { + $this->currentUserParams['charset'] = str_replace( + '-', + '', + trim(strtolower($this->currentUserParams['charset'])) + ); + } + + if (!is_string($this->currentUserParams['charset']) + || trim($this->currentUserParams['charset']) == '' + ) { + $charset = 'utf8'; + if (isset($this->currentUserParams['collate'])) { + $collate = $this->currentUserParams['collate']; + if (!is_string($collate)) { + $collate = 'utf8_unicode_ci'; + } + $collate = preg_replace('`(\-|\_)+`', '_', $collate); + $collate = trim(strtolower($collate)); + $this->currentUserParams['collate'] = $collate; + $collateArray = explode('_', $collate); + $charset = reset($collateArray); + } + + $this->currentUserParams['charset'] = $charset; + } + /** * create new parameters */ diff --git a/App/Classes/Exceptions/FileNotFoundException.php b/App/Classes/Exceptions/FileNotFoundException.php new file mode 100644 index 0000000..8e0be69 --- /dev/null +++ b/App/Classes/Exceptions/FileNotFoundException.php @@ -0,0 +1,20 @@ +path = $path; + $this->path = $path; if (func_num_args() > 1) { $this->message = $message; } else { - $this->message = "Invalid path of {$this->file}"; + $this->message = "Invalid path of {$path}"; } } diff --git a/App/Classes/Hook.php b/App/Classes/Hook.php new file mode 100644 index 0000000..2911d67 --- /dev/null +++ b/App/Classes/Hook.php @@ -0,0 +1,483 @@ +filters = new Collection(); + $this->merged = new Collection(); + $this->current = new Collection(); + } + + /** + * Create Unique ID if function is not string + * + * @param callable $function function to call + * + * @access private + * @return string|bool + */ + final private function uniqueId($function) + { + if (is_string($function)) { + return $function; + } + + if (is_object($function)) { + // Closures are currently implemented as objects + $function = [ $function, '' ]; + } elseif (!is_array($function)) { + $function = [ $function ]; + } + + $function = array_values($function); + if (is_object($function[0])) { + return \spl_object_hash($function[0]) . $function[1]; + } elseif (count($function) > 1 || is_string($function[0])) { + // call as static + return $function[0] . '::' . $function[1]; + } + + // unexpected result + return null; + } + + /** + * Sanitize Key + * + * @param string $keyName + * @return bool|string + */ + protected function sanitizeKeyName($keyName) + { + return is_string($keyName) && trim($keyName) != '' + ? trim($keyName) + : false; + } + + /** + * Add Hooks Function it just like a WordPress add_action() / add_filter() hooks + * + * @param string $hookName Hook Name + * @param Callable $callable Callable + * @param integer $priority priority + * @param integer $acceptedArguments num count of accepted args / parameter + * + * @return boolean + * @throws \InvalidArgumentException + * @throws \RuntimeException + */ + public function add( + $hookName, + callable $callable, + $priority = 10, + $acceptedArguments = 1 + ) { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName) { + throw new \InvalidArgumentException( + 'Invalid Hook Name Specified', + E_USER_ERROR + ); + } + + $id = $this->uniqueId($callable); + if ($id === null) { + throw new \RuntimeException( + sprintf( + 'Invalid callable specified on hook name %s', + $hookName + ), + E_USER_ERROR + ); + } + $priority = !is_numeric($priority) + ? 10 + : abs(intval($priority)); + + if (!$this->filters->has($hookName)) { + $this->filters[$hookName] = new Collection(); + } + if (!$this->filters[$hookName]->has($priority)) { + $this->filters[$hookName]->set($priority, new Collection()); + } + + $this + ->filters + ->get($hookName) + ->get($priority) + ->set( + $id, + [ + self::KEY_FUNCTION => $callable, + self::KEY_ACCEPTED_ARGS => $acceptedArguments + ] + ); + + // remove merged hook + $this->merged->remove($hookName); + return true; + } + + /** + * Check if hook name exists + * + * @param string $hookName Hook name + * @param string|mixed $functionToCheck Specially Functions on Hook + * + * @return boolean|int + */ + public function exists($hookName, $functionToCheck = false) + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName || ! $this->filters->has($hookName)) { + return false; + } + + // Don't reset the internal array pointer + $has = $this->filters[$hookName]->isEmpty(); + // Make sure at least one priority has a filter callback + if ($has) { + $exists = false; + foreach ($this->filters[$hookName] as $callbacks) { + if (! empty($callbacks)) { + $exists = true; + break; + } + } + + if (! $exists) { + $has = false; + } + } + + // recheck + if ($functionToCheck === false || $has === false) { + return $has; + } + + if (! $id = $this->uniqueId($functionToCheck)) { + return false; + } + + foreach ($this->filters[$hookName] as $priority) { + if ($priority->has($id)) { + return $priority; + } + } + + return false; + } + + /** + * Applying Hooks for replaceable and returning as $value param + * + * @param string $hookName Hook Name replaceable + * @param mixed $value returning value + * + * @return mixed + */ + public function apply($hookName, $value) + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName) { + throw new \InvalidArgumentException( + 'Invalid Hook Name Specified', + E_USER_ERROR + ); + } + if ($this->filters->has($hookName)) { + return $value; + } + + // add increment data + $this->current->increment($hookName); + + /** + * Sorting + */ + if ($this->merged->has($hookName)) { + $this->filters[$hookName]->kSort(); + $this->merged->set($hookName, true); + } + + // reset sorting position + $this->filters[$hookName]->reset(); + $args = func_get_args(); + do { + foreach ($this->filters[$hookName]->current() as $collection) { + if (!is_null($collection[self::KEY_FUNCTION])) { + $args[1] = $value; + $value = call_user_func_array( + $collection[self::KEY_FUNCTION], + array_slice( + $args, + 1, + (int) $collection[self::KEY_ACCEPTED_ARGS] + ) + ); + } + } + } while ($this->filters[$hookName]->next() !== false); + + $this->current->pop(); + + return $value; + } + /** + * Call hook from existing declared hook record + * + * @param string $hookName Hook Name + * @param string $arg the arguments for next parameter + * + * @return boolean + */ + public function call($hookName, $arg = '') + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName) { + return false; + } + + if (! isset($this->actions[$hookName])) { + $this->actions[$hookName] = 1; + } else { + $this->actions[$hookName]++; + } + + if (! $this->filters->has($hookName)) { + return null; + } + + $this->current->increment($hookName); + + $args = []; + if (is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0])) { + $args[] =& $arg[0]; + } else { + $args[] = $arg; + } + + for ($a = 2, $num = func_num_args(); $a < $num; $a++) { + $args[] = func_get_arg($a); + } + + // Sort + if (! $this->merged->has($hookName)) { + $this->filters[$hookName]->kSort(); + $this->merged->set($hookName, true); + } + $this->filters[$hookName]->reset(); + do { + foreach ($this->filters[$hookName]->current() as $collection) { + if (!is_null($collection[self::KEY_FUNCTION])) { + call_user_func_array( + $collection[self::KEY_FUNCTION], + array_slice( + $args, + 0, + (int) $collection[self::KEY_ACCEPTED_ARGS] + ) + ); + } + } + } while ($this->filters[$hookName]->next() !== false); + + $this->current->pop(); + return true; + } + + /** + * Replace Hooks Function, this will replace all existing hooks + * + * @param string $hookName Hook Name + * @param string $functionToReplace Function to replace + * @param Callable $callable Callable + * @param integer $priority priority + * @param integer $acceptedArguments num count of accepted args / parameter + * @param boolean $create true if want to create new if not exists + * + * @return boolean + * @throws \InvalidArgumentException + * @throws \RuntimeException + */ + public function replace( + $hookName, + $functionToReplace, + $callable, + $priority = 10, + $acceptedArguments = 1, + $create = true + ) { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName) { + throw new \InvalidArgumentException( + "Invalid Hook Name Specified", + E_USER_ERROR + ); + } + + if (!is_callable($callable)) { + throw new \RuntimeException( + "Invalid Hook Callable Specified", + E_USER_ERROR + ); + } + + if (($has = $this->exists($hookName, $functionToReplace)) || $create) { + $has && $this->remove($hookName, $functionToReplace); + // add hooks first + return $this->add($hookName, $callable, $priority, $acceptedArguments); + } + + return false; + } + + /** + * Removing Hook (remove single hook) + * + * @param string $hookName Hook Name + * @param string $functionToRemove functions that to remove from determine $hookName + * @param integer $priority priority + * + * @return boolean + */ + public function remove($hookName, $functionToRemove, $priority = 10) + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName) { + return false; + } + + $functionToRemove = $this->uniqueId($functionToRemove); + $r = $this->filters[$hookName]->get($priority); + $r = $r ? $r->has($functionToRemove) : false; + if ($r === true) { + $this->filters[$hookName][$priority]->remove($functionToRemove); + if ($this->filters[$hookName][$priority]->isEmpty()) { + $this->filters[$hookName]->remove($priority); + } + if ($this->filters[$hookName]->isEmpty()) { + $this->filters[$hookName]->clear(); + } + $this->merged->remove($hookName); + } + + return $r; + } + + /** + * Remove all of the hooks from a filter. + * + * @param string $hookName The filter to remove hooks from. + * @param int|bool $priority Optional. The priority number to remove. Default false. + * + * @return boolean + */ + public function removeAll($hookName, $priority = false) + { + if (isset($this->filters[$hookName])) { + if (false === $priority || $priority === null) { + $this->filters[$hookName]->clear(); + } elseif ($this->filters[$hookName]->has($priority)) { + $this->filters[$hookName][$priority]->clear(); + } + } + + $this->merged->remove($hookName); + return true; + } + + /** + * Current position + * + * @return string functions + */ + public function current() + { + return $this->current->end(); + } + + /** + * Count all existences Hook + * + * @param string $hookName Hook name + * + * @return integer Hooks Count + */ + public function count($hookName) + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName || ! $this->filters->has($hookName)) { + return false; + } + return $this->filters[$hookName]->count(); + } + + /** + * Check if hook has doing + * + * @param string $hookName Hook name + * + * @return boolean true if has doing + */ + public function hasDoing($hookName = null) + { + if (null === $hookName) { + return ! empty($this->current); + } + + $hookName = $this->sanitizeKeyName($hookName); + return $hookName && $this->current->has($hookName); + } + + /** + * Check if action hook as execute + * + * @param string $hookName Hook Name + * + * @return integer Count of hook action if has did action + */ + public function hasCalled($hookName) + { + $hookName = $this->sanitizeKeyName($hookName); + if (!$hookName || ! isset($this->actions[$hookName])) { + return 0; + } + + return $this->actions[$hookName]; + } +} diff --git a/App/Classes/README.md b/App/Classes/README.md new file mode 100644 index 0000000..078a02d --- /dev/null +++ b/App/Classes/README.md @@ -0,0 +1,3 @@ +## CLASSES + +Collection class files to be work as engine of application diff --git a/App/Classes/Session.php b/App/Classes/Session.php new file mode 100644 index 0000000..da836ef --- /dev/null +++ b/App/Classes/Session.php @@ -0,0 +1,280 @@ +newInstance($_COOKIE); + } + + $this->session =& $session; + $this->setSegmentName(__CLASS__); + } + + /** + * This Method also change Segments + * + * @param string $name + */ + public function setSegmentName($name) + { + if (!is_string($name)) { + throw new \InvalidArgumentException( + sprintf( + 'Session Segment Name must be as a string %s given.', + gettype($name) + ), + E_USER_ERROR + ); + } + + $this->segmentName = $name; + } + + /** + * Create Instance Session + * + * @param string|null $name + * @param AuraSession|null $session + * @return Session + * @throws \InvalidArgumentException + */ + public static function &createWithName($name = null, AuraSession $session = null) + { + $session = ! is_null($session) ? new static : new static($session); + if (is_null($name)) { + return $session; + } + + $session->setSegmentName($name); + return $session; + } + + /** + * Get object Session + * + * @return AuraSession + */ + public function &getSession() + { + return $this->session; + } + + /** + * Start Or Resume Session + * + * @return bool + */ + public function startOrResume() + { + if (!$this->session->isStarted()) { + return $this->session->start(); + } + + return $this->session->resume(); + } + + /** + * Get the Session segment + * + * @return Segment + */ + public function getSegment() + { + $segment = $this->getSession()->getSegment($this->getSegmentName()); + return $segment; + } + + /** + * Get session stored Name Value + * + * @return string + */ + public function getSegmentName() + { + return $this->segmentName; + } + + /** + * Get C.S.R.F from Aura session + * + * @return CSRFToken + */ + public function getCSRFToken() + { + return $this->getSession()->getCsrfToken(); + } + + /** + * Getting C.S.R.F token values + * + * @return string + */ + public function getCSRFTokenValue() + { + return $this->getCSRFToken()->getValue(); + } + + /** + * validate token set + * + * @param string $value + * @return bool + */ + public function validateToken($value) + { + if (!is_string($value)) { + return false; + } + + return $this->getCSRFToken()->isValid($value); + } + + /** + * @param string $keyName + * @param mixed $value + */ + public function flash($keyName, $value) + { + $this->setFlash($keyName, $value); + } + + /** + * @param string $keyName + * @param mixed $value + */ + public function flashNow($keyName, $value) + { + $this->setFlashNow($keyName, $value); + } + + /** + * Check whether Session is exists or not on segment + * + * @param string $keyName + * @return bool + */ + public function exist($keyName) + { + # double check + return + $this->get($keyName, true) !== true + && $this->get($keyName, false) !== false; + } + + /** + * Remove Session from segment + * + * @param string $keyName + */ + public function remove($keyName) + { + if ($this->exist($keyName)) { + unset($_SESSION[$this->getSegmentName()][$keyName]); + } + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) + { + return $this->exist($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } + + /** + * Magic Method Call for BackWards Compatibility + * + * @uses Segment + * @param string $name + * @param array $arguments + * @return mixed + */ + public function __call($name, array $arguments) + { + $return = call_user_func_array( + [$this->getSegment(), $name], + $arguments + ); + return $return; + } +} diff --git a/App/Classes/Utilities/EmbeddedReader.php b/App/Classes/Utilities/EmbeddedReader.php index 6fbc692..32d0bb3 100644 --- a/App/Classes/Utilities/EmbeddedReader.php +++ b/App/Classes/Utilities/EmbeddedReader.php @@ -281,6 +281,11 @@ private function validate() : EmbeddedReader $alias = end($asAlias['extended']); } + // remove declarations + if (stripos($content, 'declare') !== false) { + $content = preg_replace('`declare\s*\([^\)]+\)\s*\;\s*`smi', '', $content); + } + // replace for unused text $content = preg_replace( [ diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php new file mode 100644 index 0000000..6936da6 --- /dev/null +++ b/App/Components/ApplicationMiddleware.php @@ -0,0 +1,35 @@ +getSlim(); + // middle ware + $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, App $next) { + /** + * @var $this Container + */ + return $next($request, $response); + }); +} diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php new file mode 100644 index 0000000..1e8076d --- /dev/null +++ b/App/Components/ApplicationRoutes.php @@ -0,0 +1,26 @@ +getSlim(); +} diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php new file mode 100644 index 0000000..64bfb97 --- /dev/null +++ b/App/Components/ApplicationSlimObject.php @@ -0,0 +1,107 @@ + function () use (&$c) : Application { + return $c; + }, + /** + * Configuration Container + * + * Use on closure prevent being binding to + * @return Config + */ + 'config' => $c->includeScope($c->getContainerDirectory('Config.php'), $this[1]), + /** + * Closure + * + * @return Database + */ + 'database' => $c->includeScope($c->getContainerDirectory('Database.php')), + /** + * Closure + * + * @return Environment + */ + 'environment' => $c->includeScope($c->getContainerDirectory('Environment.php')), + /** + * Closure + * + * @return Hook + */ + 'hook' => $c->includeScope($c->getContainerDirectory('Hook.php')), + /** + * Module Container + * + * Closure + * + * @return EmbeddedCollection + */ + 'module' => $c->includeScope($c->getContainerDirectory('Module.php')), + /** + * Extension Container + * + * Closure + * + * @return EmbeddedCollection + */ + 'extension' => $c->includeScope($c->getContainerDirectory('Extension.php')), + /** + * @return array + */ + 'settings' => $c->includeScope($c->getContainerDirectory('Settings.php')), + /** + * Session Container + * + * Closure + * + * @return Session + */ + 'session' => $c->includeScope($c->getContainerDirectory('Session.php')), + /** + * Slim Inheritance + * + * @return App + */ + 'slim' => function (Container $container) : App { + /** + * @var Application $application + */ + $application =& $container['application']; + return $application->getSlim(); + } + ] + ); +} diff --git a/App/Components/README.md b/App/Components/README.md new file mode 100644 index 0000000..086ca3c --- /dev/null +++ b/App/Components/README.md @@ -0,0 +1,7 @@ +## COMPONENT + +Contains Component for file includes on: + +Application file on : [Application.php](../Classes/Application.php#L232) + +on method `process(array $config)` diff --git a/App/Containers/Config.php b/App/Containers/Config.php new file mode 100644 index 0000000..2d6cbae --- /dev/null +++ b/App/Containers/Config.php @@ -0,0 +1,46 @@ + $application->getWebRootDirectory('extensions'), + 'module' => $application->getRootDirectory('Modules'), + 'storage' => $application->getRootDirectory(' Storage'), + ], $config['directory']); + + return new Config($config); + }; +} diff --git a/App/Containers/Database.php b/App/Containers/Database.php index 1937b8e..d1f62bd 100644 --- a/App/Containers/Database.php +++ b/App/Containers/Database.php @@ -1,4 +1,8 @@ get('database', [])); + $config =& $c['config']; + $databaseConfig = (array) $config->get('database', []); + + /* --------------------------------------------------- + * DATABASE CONFIG VALIDATION + * --------------------------------------------------- + */ + $isEmptyDriver = empty($databaseConfig['driver']); + $isSQLite = (!$isEmptyDriver + && ( + trim(strtolower($databaseConfig['driver'])) == 'sqlite' + || trim(strtolower($databaseConfig['driver'])) == 'pdo_sqlite' + ) + ); + if (empty($databaseConfig['host']) && ! $isSQLite) { + $databaseConfig['host'] = 'localhost'; + } + + if ($isEmptyDriver) { + $port = !empty($databaseConfig['port']) + ? $databaseConfig['port'] + : 3306; + if (abs($port) === 3306) { + $databaseConfig['driver'] = 'mysql'; + } + } + + if (!$isSQLite) { + if (empty($databaseConfig['user'])) { + throw new InvalidArgumentException( + 'Database User could not be empty', + E_USER_ERROR + ); + } + + if (!is_string($databaseConfig['user'])) { + throw new InvalidArgumentException( + sprintf( + 'Database User must be as a string, %s given.', + gettype($databaseConfig['user']) + ), + E_USER_ERROR + ); + } + + if (empty($databaseConfig['name'])) { + throw new InvalidArgumentException( + 'Database Name could not be empty', + E_USER_ERROR + ); + } + + if (!is_string($databaseConfig['name'])) { + throw new InvalidArgumentException( + sprintf( + 'Database Name must be as a string, %s given.', + gettype($databaseConfig['name']) + ), + E_USER_ERROR + ); + } + } else { + // if doing mysql + if (empty($databaseConfig['name']) && empty($databaseConfig['path'])) { + throw new InvalidArgumentException( + 'Database Path could not be empty.', + E_USER_ERROR + ); + } + $path = ! empty($databaseConfig['path']) && is_string($databaseConfig['path']) + ? $databaseConfig['path'] + : $databaseConfig['name']; + if (!is_string($path)) { + throw new InvalidArgumentException( + sprintf( + 'Database Path must be as a string, %s given.', + gettype($path) + ), + E_USER_ERROR + ); + } + } + + /* --------------------------------------------------- + * END DATABASE CONFIG VALIDATION + * --------------------------------------------------- + */ + + // set new Config + $config->set('database', $databaseConfig); + $database = new Database($databaseConfig); + return $database; }; } diff --git a/App/Containers/Environment.php b/App/Containers/Environment.php index 52c909e..d261618 100644 --- a/App/Containers/Environment.php +++ b/App/Containers/Environment.php @@ -1,4 +1,8 @@ get(\PentagonalProject\ProjectSeventh\Application::APP_KEY)` diff --git a/App/Containers/Session.php b/App/Containers/Session.php new file mode 100644 index 0000000..fccbc9d --- /dev/null +++ b/App/Containers/Session.php @@ -0,0 +1,49 @@ +get('session', []); + if (!empty($configSession)) { + if (isset($configSession['save_path']) && $configSession['save_path']) { + $session->getSession()->setSavePath($configSession['save_path']); + } + if (isset($configSession['name']) && $configSession['name']) { + $session->getSession()->setName($configSession['name']); + } + if (isset($configSession['cache_limiter']) && $configSession['cache_limiter']) { + $session->getSession()->setCacheLimiter($configSession['cache_limiter']); + } + if (isset($configSession['segment_name']) && $configSession['segment_name']) { + $session->setSegmentName($configSession['segment_name']); + } + $cookieParamsKey = ['lifetime', 'path', 'domain', 'secure', 'httponly']; + $cookieParams = []; + foreach ($configSession as $key => $value) { + in_array($key, $cookieParamsKey) && $cookieParams[$key] = $value; + } + + $session->getSession()->setCookieParams($cookieParams); + } + + return $session; + }; +} diff --git a/App/Containers/Settings.php b/App/Containers/Settings.php index 64c2a0f..5c73211 100644 --- a/App/Containers/Settings.php +++ b/App/Containers/Settings.php @@ -1,4 +1,8 @@ = 7", "apatis/array-storage": "^1", diff --git a/config.php b/config.php index 0ec2b18..7a6c75f 100644 --- a/config.php +++ b/config.php @@ -2,11 +2,17 @@ /* ------------------------------------------------------ *\ | CONFIG | \* ------------------------------------------------------ */ +/** + * Use @const WEB_ROOT to get Public / Web Directory + */ return [ 'directory' => [ - 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', - 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'extensions', + 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', + 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => WEB_ROOT . DIRECTORY_SEPARATOR . 'extensions', + // load from example + // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', + // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', ], 'database' => [ 'host' => 'localhost', @@ -14,7 +20,8 @@ 'password' => '', 'name' => '', 'port' => 3306, - 'charset' => 'utf-8', + 'driver' => 'mysql', + 'charset' => 'utf8', 'collate' => 'utf8_unicode_ci', ], 'environment' => [ @@ -23,9 +30,13 @@ 'log' => true, ], 'session' => [ - 'path' => '/', + 'name' => null, 'save_path' => null, - 'expire' => null, - 'domain' => '*', + // values of cookie params + 'path' => '/', + 'lifetime' => 0, + 'domain' => null, + 'httponly' => null, + 'secure' => null, ], ]; diff --git a/phpcs.xml b/phpcs.xml index 2d6df1c..f799c05 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -16,4 +16,5 @@ App Modules + public diff --git a/public/index.php b/public/index.php index 121447b..144a9f1 100644 --- a/public/index.php +++ b/public/index.php @@ -4,22 +4,17 @@ \* ------------------------------------------------------ */ /** - * define web root constant - */ -define('WEB_ROOT', __DIR__); - -/** - * Minimum Php Version is 7.0 + * Minimum PHP Version is 7.0 */ if (version_compare(phpversion(), "7.0", "<")) { preg_match('`^\d+(\.\d+)*`', PHP_VERSION, $match); $content = sprintf("Minimum Requirement php version is 7.0 and %s given", $match[0]); if (php_sapi_name() !== 'cli') { $accept = isset($_SERVER['CONTENT_TYPE']) - ? array($_SERVER['CONTENT_TYPE']) + ? [$_SERVER['CONTENT_TYPE']] : ( isset($_SERVER['HTTP_ACCEPT']) ? explode(',', $_SERVER['HTTP_ACCEPT']) - : array("text/html") + : ["text/html"] ); $accept = strtolower($accept[0]); $current = null; @@ -33,13 +28,14 @@ case 'jason': $accept = "application/json"; $content = json_encode( - array( - "error" => array( + [ + "error" => [ "code" => 500, - "message" => array($content) - ) - ), - JSON_PRETTY_PRINT); + "message" => [$content] + ] + ], + JSON_PRETTY_PRINT + ); break; case 'xml': $accept = "application/xml"; @@ -110,4 +106,8 @@ // Require Composer Autoload require __DIR__ . '/../vendor/autoload.php'; -return (new PentagonalProject\ProjectSeventh\Application((array) require __DIR__. '/../config.php'))->process(); +// if the composer that must not ../App/FunctionIncludes.php +// try to includes once +require_once __DIR__ .'/../App/FunctionsIncludes.php'; +return (new PentagonalProject\ProjectSeventh\Application()) + ->process((array) require __DIR__. '/../config.php'); From 2938e6c060ac5b57881d13323955b6fb1eeaa216 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Wed, 26 Apr 2017 17:57:34 +0700 Subject: [PATCH 011/142] Hayoo --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c1daa41..181f2bb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # PENTAGONAL PROJECT +[![Build Status](https://travis-ci.org/PentagonalProject/ProjectSeventh.svg?branch=development)](https://travis-ci.org/PentagonalProject/ProjectSeventh) + --- From 01b913951f529a9fac74ad3f44f5bac566204a64 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Wed, 26 Apr 2017 18:05:58 +0700 Subject: [PATCH 012/142] diilangi sek --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f2501e6..5a587f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ language: php php: - 7.0 - 7.1 - - hhvm before_script: - composer install -o From c1906a3a9cf14a685aaf814564b753e0464b9d74 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Wed, 26 Apr 2017 18:11:28 +0700 Subject: [PATCH 013/142] Bijim --- App/Components/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Components/README.md b/App/Components/README.md index 086ca3c..85bb6fb 100644 --- a/App/Components/README.md +++ b/App/Components/README.md @@ -2,6 +2,6 @@ Contains Component for file includes on: -Application file on : [Application.php](../Classes/Application.php#L232) +Application file on : [Application.php](../Classes/Application.php#L283) on method `process(array $config)` From f02702682d352fdd183923287029fdc97077583d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 27 Apr 2017 19:10:14 +0700 Subject: [PATCH 014/142] Lupaaa ... Lupa Lupa Lupa... --- App/Classes/Utilities/Generate.php | 14 + App/Classes/Utilities/SimplePasswordCheck.php | 260 ++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 App/Classes/Utilities/Generate.php create mode 100644 App/Classes/Utilities/SimplePasswordCheck.php diff --git a/App/Classes/Utilities/Generate.php b/App/Classes/Utilities/Generate.php new file mode 100644 index 0000000..2cf6e45 --- /dev/null +++ b/App/Classes/Utilities/Generate.php @@ -0,0 +1,14 @@ +,./?"'; +} diff --git a/App/Classes/Utilities/SimplePasswordCheck.php b/App/Classes/Utilities/SimplePasswordCheck.php new file mode 100644 index 0000000..f0dddd6 --- /dev/null +++ b/App/Classes/Utilities/SimplePasswordCheck.php @@ -0,0 +1,260 @@ +\`\;\:\s]) + ( + (\S|\s|\d){:min_length:,} + ) + | (?=.*[0-9]) + (?=.*[a-z]) + (?=.*[A-Z]) + (?=.*[\~\\\.\+\*\?\^\$\[\]\(\)\|\{\}\\\'\#\_\-\&\%\@\=\"\!\<\>\`\;\:]) + ( + (\w|\s|\S|\d){:min_length:,} + ) + )$ + /mx'; + + /** + * Regex for Good Password + */ + const REGEX_GOOD_PASS_TEST = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])((.+){7,})$/im'; + + /** + * Regex For Moderate Password + */ + const REGEX_MODERATE_PASS_TEST = '/^(?=.*[a-z])(?=.*[0-9])((\S|\s){6,})$/im'; + + /** + * Regex for Weak Password + */ + const REGEX_WEAK_PASS_TEST = '/^(?=.*([a-z]|[0-9]))((\S|\s){1,})$/im'; + + /** + * Minimum Password Length + * + * @var int + */ + protected $minimumLength = 8; + + /** + * @var string + */ + protected $storedPassword; + + /** + * Result Status + * + * @var int + */ + protected $status; + + /** + * @var bool[] + */ + protected $statusProcess = []; + + /** + * PasswordCheck constructor. + * @param string $password + */ + public function __construct(string $password) + { + $this->storedPassword = $password; + } + + /** + * Get Password Regex + * + * @return string + */ + public function getPasswordRegex() : string + { + return str_replace( + ':min_length:', + $this->minimumLength, + self::REGEX_STRONG_PASS_TEST + ); + } + + + /** + * Check if Password is Strong + * + * @param string $pass + * @return bool + */ + protected function testForStrongPass(string $pass) : bool + { + if (! isset($this->statusProcess[self::PASSWORD_STRONG])) { + $this->statusProcess[self::PASSWORD_STRONG] = (bool) ( + $this->testForGoodness($pass) + && preg_match($this->getPasswordRegex(), $pass) + ); + } + + return $this->statusProcess[self::PASSWORD_STRONG]; + } + + /** + * Check if Password Is Weak + * + * @param string $pass + * @return bool + */ + protected function testForWeakness(string $pass) : bool + { + if (! isset($this->statusProcess[self::PASSWORD_WEAK])) { + $this->statusProcess[self::PASSWORD_WEAK] = (bool) ( + preg_match(self::REGEX_WEAK_PASS_TEST, $pass) + ); + } + + return $this->statusProcess[self::PASSWORD_WEAK]; + } + + /** + * check if Password is Good + * + * @param string $pass + * @return bool + */ + protected function testForGoodness(string $pass) : bool + { + if (! isset($this->statusProcess[self::PASSWORD_GOOD])) { + $this->statusProcess[self::PASSWORD_GOOD] = (bool)( + $this->testForModerate($pass) && preg_match(self::REGEX_GOOD_PASS_TEST, $pass) + ); + } + + return $this->statusProcess[self::PASSWORD_GOOD]; + } + + /** + * check if Password pass Moderate + * + * @param string $pass + * @return bool + */ + protected function testForModerate(string $pass) : bool + { + if (! isset($this->statusProcess[self::PASSWORD_MODERATE])) { + $this->statusProcess[self::PASSWORD_MODERATE] = (bool) ( + $this->testForWeakness($pass) + && preg_match(self::REGEX_GOOD_PASS_TEST, $pass) + ); + } + + return $this->statusProcess[self::PASSWORD_MODERATE]; + } + + /** + * check if Password is empty + * + * @return bool + */ + public function isEmpty() : bool + { + return $this->getScore() < self::PASSWORD_WEAK; + } + + /** + * check if Password is weak + * + * @return bool + */ + public function isWeak() : bool + { + return $this->getScore() === self::PASSWORD_WEAK; + } + + /** + * check if Password is moderate + * + * @return bool + */ + public function isModerate() : bool + { + return $this->getScore() === self::PASSWORD_MODERATE; + } + + /** + * check if Password is good + * + * @return bool + */ + public function isGood() : bool + { + return $this->getScore() === self::PASSWORD_GOOD; + } + + /** + * check if Password is good + * + * @return bool + */ + public function isStrong() : bool + { + return $this->getScore() > self::PASSWORD_GOOD; + } + + /** + * Returning Score By Password with return value Constant + * + * @return int + */ + public function getScore() : int + { + if (isset($this->status)) { + return $this->status; + } + + $storedPassword = trim($this->storedPassword); + if ($storedPassword == '') { + return $this->status = self::PASSWORD_EMPTY; + } + + // always minimum length is 8 + $this->minimumLength < 8 && $this->minimumLength = 8; + + if ($this->testForStrongPass($storedPassword)) { + return $this->status = self::PASSWORD_STRONG; + } + + if ($this->testForGoodness($storedPassword)) { + return $this->status = self::PASSWORD_GOOD; + } + + if ($this->testForModerate($storedPassword)) { + return $this->status = self::PASSWORD_MODERATE; + } + + if ($this->testForModerate($storedPassword)) { + return $this->status = self::PASSWORD_MODERATE; + } + + return $this->status = self::PASSWORD_WEAK; + } +} From 75b8bf7fc1fd194d100a9cf02ae2109007015d7b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 11 May 2017 11:41:54 +0700 Subject: [PATCH 015/142] Ulu ulu ulu --- puja kerang ajaib --- .../Abstracts/ResponseGeneratorAbstract.php | 440 ++++++++++++++++++ App/Includes/Constant.php | 1 + App/Includes/Helper.php | 24 +- 3 files changed, 453 insertions(+), 12 deletions(-) create mode 100644 App/Classes/Abstracts/ResponseGeneratorAbstract.php diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php new file mode 100644 index 0000000..5dc22dc --- /dev/null +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -0,0 +1,440 @@ +setRequest($request); + $this->setResponse($response); + } + + /** + * Set Data + * + * @param mixed $data + * @return static + */ + public function setData($data) + { + $this->data = $data; + return $this; + } + + /** + * Get data + * + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * Set Character Set + * + * @param string $data + * @return static + */ + public function setCharset($data) + { + if (is_string($data)) { + $data = strtolower(trim($data)); + if ($data == '') { + $data = null; + } elseif (preg_match('/([^0-9]*)[\-]([0-9]+)?$/', $data, $match)) { + // sanitize to default utf8 + $data = $match[0] . '-' . (!empty($match[1]) ? $match[1] : '8'); + } + } + + $this->charset = $data; + return $this; + } + + /** + * Get character set + * + * @return string + */ + public function getCharset() + { + return $this->charset; + } + + /** + * Maps a file extensions to a mimeType. + * + * @param $extension string The file extension. + * + * @return string|null + * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types + */ + public static function getMimeTypeFromExtension(string $extension) + { + static $mimeTypes = [ + '7z' => 'application/x-7z-compressed', + 'aac' => 'audio/x-aac', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'atom' => 'application/atom+xml', + 'avi' => 'video/x-msvideo', + 'bmp' => 'image/bmp', + 'bz2' => 'application/x-bzip2', + 'cer' => 'application/pkix-cert', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'css' => 'text/css', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'deb' => 'application/x-debian-package', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dvi' => 'application/x-dvi', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'etx' => 'text/x-setext', + 'flac' => 'audio/flac', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gz' => 'application/gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ini' => 'text/plain', + 'iso' => 'application/x-iso9660-image', + 'jar' => 'application/java-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'latex' => 'application/x-latex', + 'log' => 'text/plain', + 'm4a' => 'audio/mp4', + 'm4v' => 'video/mp4', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4v' => 'video/mp4', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'pbm' => 'image/x-portable-bitmap', + 'pdf' => 'application/pdf', + 'pgm' => 'image/x-portable-graymap', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'ppm' => 'image/x-portable-pixmap', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'svg' => 'image/svg+xml', + 'swf' => 'application/x-shockwave-flash', + 'tar' => 'application/x-tar', + 'tiff' => 'image/tiff', + 'torrent' => 'application/x-bittorrent', + 'ttf' => 'application/x-font-ttf', + 'txt' => 'text/plain', + 'wav' => 'audio/x-wav', + 'webm' => 'video/webm', + 'wma' => 'audio/x-ms-wma', + 'wmv' => 'video/x-ms-wmv', + 'woff' => 'application/x-font-woff', + 'wsdl' => 'application/wsdl+xml', + 'xbm' => 'image/x-xbitmap', + 'xls' => 'application/vnd.ms-excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml' => 'application/xml', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'yaml' => 'text/yaml', + 'yml' => 'text/yaml', + 'zip' => 'application/zip', + ]; + + $extension = strtolower($extension); + + return isset($mimeTypes[$extension]) + ? $mimeTypes[$extension] + : null; + } + + /** + * Generate content type + * + * @uses $this->getMimeTypeFromExtension() + * @return string + */ + protected function generateTheContentType() + { + $charset = $this->getCharset(); + $this->mimeType = !is_string($this->mimeType) || trim($this->mimeType) == '' + ? 'text/html' + : strtolower(trim($this->mimeType)); + + if ($this->recheckMimeType || strpos($this->mimeType, '/') === false) { + if (preg_match( + '/(?:(?:[^/]*)(?:\\\+|\/+))?(html?|javascript|calendar|css|plain)/', + $this->mimeType, + $match + ) && !empty($match[1]) + ) { + $this->mimeType = $this->mimeType == 'htm' + ? 'html' + : $this->mimeType; + $this->mimeType = "text/{$match[1]}"; + } elseif (strpos($this->mimeType, 'ico') !== false || strpos($this->mimeType, 'icns') !== false) { + $this->mimeType = 'image/x-icon'; + $charset = null; + } elseif (strpos($this->mimeType, 'sgm') !== false) { + $this->mimeType = 'text/sgml'; + } elseif (preg_match( + '/(?:(?:[^/]*)(?:\\\+|\/+))?(ja?son|xml|ogg|pdf|postscript|zip|ttf2?)/', + $this->mimeType, + $match + ) && !empty($match[1]) + ) { + if ($match[1] == 'jason') { + $match[1] = 'json'; + } elseif ($match[1] == 'ttf2' || $match[1] == 'ttf') { + $match[1] = 'x-font-ttf'; + } + $this->mimeType = 'application/' . $match[1]; + } elseif (preg_match( + '/(?:(?:[^/]*)(?:\\\+|\/+))?(jpe?g?|png|w?bmp|gif|pbm|tif(?:f+)?|png|ppm|ras|xbm|xpm|xwd)/', + $this->mimeType, + $match + ) + && !empty($match[1]) + ) { + if ($match[1] == 'wbmp') { + $match[1] = 'bmp'; + } elseif (strpos($match[1], 'tif') !== false) { + $match[1] = 'tiff'; + } + $this->mimeType = $this->getMimeTypeFromExtension($match[1]); + } else { + $mimeType = null; + $this->mimeType = preg_replace('/(\\\|\/)+/', '/', trim($this->mimeType)); + if (preg_match('/([^\]*)(?:\/(.+(\+.+)?)/?', $this->mimeType, $match) && !empty($match)) { + if (!empty($match[3])) { + $mimeType = $this->getMimeTypeFromExtension($match[3]); + } + if (!$mimeType && !empty($match[2])) { + $mimeType = $this->getMimeTypeFromExtension($match[2]); + } + if (!$mimeType) { + $mimeType = $this->getMimeTypeFromExtension($match[1]); + } + } + if (!$mimeType) { + if (preg_match('/te?xt|plain|ini/', $this->mimeType)) { + $mimeType = 'txt'; + } + $mimeType = $this->getMimeTypeFromExtension($mimeType); + // fallback to default `text/html` + if (!$mimeType) { + $mimeType = 'text/html'; + } + $this->mimeType = $mimeType; + } + } + } + + return $this->mimeType . ($charset ? ';charset=' . $charset : ''); + } + + /** + * Get Mime Type + * + * @return string + */ + public function getMimeType() + { + $this->generateTheContentType(); + return $this->mimeType; + } + + /** + * Set Mime Type + * + * @param string $mimeType + * @return static + */ + public function setMimeType(string $mimeType) + { + $this->mimeType = $mimeType; + return $this; + } + + /** + * @param $encoding + * @return static + */ + public function setEncoding($encoding) + { + $this->encoding = $encoding; + return $this; + } + + /** + * Set Response Status + * + * @param int $status + * @return static + */ + public function setStatusCode($status) + { + if ($this->response->withStatus($status)->getReasonPhrase() == '') { + throw new \InvalidArgumentException( + 'Invalid response code given.', + E_USER_ERROR + ); + } + + $this->statusCode = abs($status); + return $this; + } + + /** + * Get Status Code + * + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Generate + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return static + */ + public static function generate(RequestInterface $request, ResponseInterface $response) + { + return new static($request, $response); + } + + /** + * Serve The response + * + * @return ResponseInterface + */ + abstract public function serve() : ResponseInterface; + + /** + * @return RequestInterface + */ + public function getRequest(): RequestInterface + { + return $this->request; + } + + /** + * Set Override Request + * + * @param RequestInterface $request + * @return static + */ + public function setRequest(RequestInterface $request) + { + $this->request = $request; + return $this; + } + + /** + * @return ResponseInterface + */ + public function getResponse(): ResponseInterface + { + return $this->response; + } + + /** + * Set Override Response + * + * @param ResponseInterface $response + * @return static + */ + public function setResponse(ResponseInterface $response) + { + $this->response = $response; + return $this; + } +} \ No newline at end of file diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index e3081a3..e8fe2c1 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -10,3 +10,4 @@ define('IIS7_SERVER', 'iis7'); define('HIAWATHA_SERVER', 'hiawatha'); define('LIGHTTPD_SERVER', 'lighttpd'); +define('UNKNOWN_SERVER', ''); diff --git a/App/Includes/Helper.php b/App/Includes/Helper.php index 884effc..719c78d 100644 --- a/App/Includes/Helper.php +++ b/App/Includes/Helper.php @@ -6,9 +6,9 @@ /** * Get Web Server Type * - * @return bool|string + * @return string */ -function getWebServerSoftWare() +function getWebServerSoftWare() : string { static $type; @@ -20,7 +20,7 @@ function getWebServerSoftWare() ? $_SERVER['SERVER_SOFTWARE'] : null; - $type = false; + $type = UNKNOWN_SERVER; if (stripos($software, 'lighttpd') !== false) { $type = LIGHTTPD_SERVER; @@ -54,7 +54,7 @@ function getWebServerSoftWare() $type = APACHE_SERVER; } - if (!$type && function_exists('apache_get_version') + if ($type == UNKNOWN_SERVER && function_exists('apache_get_version') ) { $type = APACHE_SERVER; } @@ -68,7 +68,7 @@ function getWebServerSoftWare() * * @return bool */ -function isApache() +function isApache() : bool { return in_array(getWebServerSoftWare(), [APACHE_SERVER, LITESPEED_SERVER]); } @@ -78,7 +78,7 @@ function isApache() * * @return bool */ -function isLitespeed() +function isLiteSpeed(): bool { return getWebServerSoftWare() === LIGHTTPD_SERVER; } @@ -88,7 +88,7 @@ function isLitespeed() * * @return bool */ -function isNginx() +function isNginx(): bool { return getWebServerSoftWare() === NGINX_SERVER; } @@ -98,7 +98,7 @@ function isNginx() * * @return bool */ -function isHiawatha() +function isHiawatha(): bool { return getWebServerSoftWare() === HIAWATHA_SERVER; } @@ -108,7 +108,7 @@ function isHiawatha() * * @return bool */ -function isLighttpd() +function isLighttpd() : bool { return getWebServerSoftWare() === LIGHTTPD_SERVER; } @@ -118,7 +118,7 @@ function isLighttpd() * * @return bool */ -function isIIS() +function isIIS() : bool { return in_array(getWebServerSoftWare(), [IIS_SERVER, IIS7_SERVER]); } @@ -128,7 +128,7 @@ function isIIS() * * @return bool */ -function isIIS7() +function isIIS7() : bool { return getWebServerSoftWare() === IIS7_SERVER; } @@ -138,7 +138,7 @@ function isIIS7() * * @return bool */ -function isMobile() +function isMobile() : bool { if (empty($_SERVER['HTTP_USER_AGENT'])) { return false; From 0a7ea27d99d4d92c486fa9ee53a9462570a2f5fa Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 11 May 2017 14:23:40 +0700 Subject: [PATCH 016/142] Sungguh Keterlaluan --- .../Abstracts/ResponseGeneratorAbstract.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php index 5dc22dc..d9bfddf 100644 --- a/App/Classes/Abstracts/ResponseGeneratorAbstract.php +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -247,10 +247,10 @@ protected function generateTheContentType() if ($this->recheckMimeType || strpos($this->mimeType, '/') === false) { if (preg_match( - '/(?:(?:[^/]*)(?:\\\+|\/+))?(html?|javascript|calendar|css|plain)/', - $this->mimeType, - $match - ) && !empty($match[1]) + '/(?:(?:[^/]*)(?:\\\+|\/+))?(html?|javascript|calendar|css|plain)/', + $this->mimeType, + $match + ) && !empty($match[1]) ) { $this->mimeType = $this->mimeType == 'htm' ? 'html' @@ -262,10 +262,10 @@ protected function generateTheContentType() } elseif (strpos($this->mimeType, 'sgm') !== false) { $this->mimeType = 'text/sgml'; } elseif (preg_match( - '/(?:(?:[^/]*)(?:\\\+|\/+))?(ja?son|xml|ogg|pdf|postscript|zip|ttf2?)/', - $this->mimeType, - $match - ) && !empty($match[1]) + '/(?:(?:[^/]*)(?:\\\+|\/+))?(ja?son|xml|ogg|pdf|postscript|zip|ttf2?)/', + $this->mimeType, + $match + ) && !empty($match[1]) ) { if ($match[1] == 'jason') { $match[1] = 'json'; @@ -274,10 +274,10 @@ protected function generateTheContentType() } $this->mimeType = 'application/' . $match[1]; } elseif (preg_match( - '/(?:(?:[^/]*)(?:\\\+|\/+))?(jpe?g?|png|w?bmp|gif|pbm|tif(?:f+)?|png|ppm|ras|xbm|xpm|xwd)/', - $this->mimeType, - $match - ) + '/(?:(?:[^/]*)(?:\\\+|\/+))?(jpe?g?|png|w?bmp|gif|pbm|tif(?:f+)?|png|ppm|ras|xbm|xpm|xwd)/', + $this->mimeType, + $match + ) && !empty($match[1]) ) { if ($match[1] == 'wbmp') { @@ -437,4 +437,4 @@ public function setResponse(ResponseInterface $response) $this->response = $response; return $this; } -} \ No newline at end of file +} From 567abcfcca6ff4e3a1612f0626f9ec25f7162fbc Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 11 May 2017 14:32:30 +0700 Subject: [PATCH 017/142] Yo Wis Ben --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b915b97..a3f29b4 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "pentagonalproject/project-seventh", "description": "Project API Handler", "type": "project", - "version": "0.1.0-a", + "version": "0.1.0-alphaDev", "require": { "php": ">= 7", "apatis/array-storage": "^1", From f9c4933cea251dde7f3d66aa37a34aba13bb4839 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 11 May 2017 14:32:46 +0700 Subject: [PATCH 018/142] Duwe Bojo Seng Galak --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e57f642..f2a9c30 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -version 0.1.0-a \ No newline at end of file +version 0.1.0-alphaDev \ No newline at end of file From 07e9d5b7166ddf0d3d9d0607c31618dcbff732b0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 15:53:16 +0700 Subject: [PATCH 019/142] Ndang Mulio Sri ... Foldermu Kari --- App/Classes/Application.php | 2 ++ App/Containers/Config.php | 4 ++-- {public/extensions => Extensions}/.gitkeep | 0 config.php | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) rename {public/extensions => Extensions}/.gitkeep (100%) diff --git a/App/Classes/Application.php b/App/Classes/Application.php index f4b6b21..135ef16 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -267,6 +267,8 @@ public function includeScopeOnce() } /** + * Get Run Slim Instance + * * @return App */ public function &getSlim() diff --git a/App/Containers/Config.php b/App/Containers/Config.php index 2d6cbae..3975e36 100644 --- a/App/Containers/Config.php +++ b/App/Containers/Config.php @@ -36,9 +36,9 @@ /** @var Application $application */ $application = $container['application']; $config['directory'] = array_merge([ - 'extension' => $application->getWebRootDirectory('extensions'), + 'extension' => $application->getRootDirectory('Extensions'), 'module' => $application->getRootDirectory('Modules'), - 'storage' => $application->getRootDirectory(' Storage'), + 'storage' => $application->getRootDirectory('Storage'), ], $config['directory']); return new Config($config); diff --git a/public/extensions/.gitkeep b/Extensions/.gitkeep similarity index 100% rename from public/extensions/.gitkeep rename to Extensions/.gitkeep diff --git a/config.php b/config.php index 7a6c75f..872632b 100644 --- a/config.php +++ b/config.php @@ -9,7 +9,7 @@ 'directory' => [ 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => WEB_ROOT . DIRECTORY_SEPARATOR . 'extensions', + 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', // load from example // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', From 03905e595322ae8a11f8aa85b265e00cef33b63e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 15:53:32 +0700 Subject: [PATCH 020/142] Sek sek bijim --- Extensions/.htaccess | 1 + 1 file changed, 1 insertion(+) create mode 100644 Extensions/.htaccess diff --git a/Extensions/.htaccess b/Extensions/.htaccess new file mode 100644 index 0000000..31f17f9 --- /dev/null +++ b/Extensions/.htaccess @@ -0,0 +1 @@ +Deny From All From 5da567d347de7b176046cf4912a9319cf90ba8e3 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 15:54:59 +0700 Subject: [PATCH 021/142] Masalah Gawe Umak?! --- Extensions/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Extensions/.gitkeep diff --git a/Extensions/.gitkeep b/Extensions/.gitkeep deleted file mode 100644 index e69de29..0000000 From d963883891b2766c381be122faab306d5450908d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 15:55:08 +0700 Subject: [PATCH 022/142] Masalah Gawe Umak?! --- Extensions/index.php | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Extensions/index.php diff --git a/Extensions/index.php b/Extensions/index.php new file mode 100644 index 0000000..f5e988e --- /dev/null +++ b/Extensions/index.php @@ -0,0 +1,2 @@ + Date: Fri, 12 May 2017 16:09:36 +0700 Subject: [PATCH 023/142] Nambahi Kimcil Ben Mesra --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/README.md b/README.md index 181f2bb..5ea1b51 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,15 @@ --- +### IMPORTANT + +```txt +This Repository is gawe dolanan and then gak usah kakean protes!! +When kowe still protes tak uppercut opo need tak cipok mubeng? +Lek need kowe yo must contribute nang this repository! + +OK nyet? Monyet? +``` ## DOCUMENTATION @@ -30,3 +39,47 @@ See [VERSION](VERSION) ## LICENSE [BSD 3-Clause License](LICENSE) + +```txt +^ LICENSE NDUWUR IKU GAK USAH DIREKEN.. + +IKU NGONO MEK GAWE ONO - ONOAN AE BEN KETOK KEREN +RUMANGSAMU AKU NGERTI MAKSUDE? +ORAA!!!! BABAR BLASSSS!!! + +RUMANGSAMU AKU PENGEN TENAR NGONOA? +TENAR KOYO ARTIS NGONOA?! + +LOH IYO MES TAH TIII TIII!!! ARTIS KOK!!!?! +TERKENAAAALLL BAYARANE BER-DIGIT DIGIT KOYO KALKULATOR CASIO SENG : + +6/2(2+1) = 1 + +LAH LEK SEMARPON ITUNGANE NGENE!!! + +6/2(2+1) = 9 + +AKU NGONO GAK MIKIRI NGONO'an TIMBANG GENDENG NGANGGUR!!! + +ARTIS NGONO BAYARANE GEDE!! +LAH SOPO SENG GAK GELEM GEDE!? +AKU NGONO GELEM BAYARAN DUWIT DUDU MEK GEDE?! + +GEDE ISO AE : + +1. DIBAYAR SAMBAT'e GEDE!!! +2. DIBAYAR ALASAN'e GEDE!!! +3. DIBAYAR KIMCIL SENG GEDE!!! (anu'e GEDE!!) +4. DIBAYAR NYICIL GEDE WEKTUNE!!! + +RUMANGSAMU AKU KONGKON MANGAN SAMBATAN TA? + + +MANGKANE WES TALAH!!! +GAK USAH KAKEAN PECETOT !!!?! +CLONE'en AE REPONE .. BENAKNO ..!!! +WES NGONO AE YO WONG !!! + +(UWONG TA KEONG KOWE IKU MEDIT TEMEN?!) + +``` \ No newline at end of file From b4038d5e96435663786f379e9ac4e05e5df1e2e5 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 16:20:12 +0700 Subject: [PATCH 024/142] Nambahi Kimcil Maneh Ben Mesra --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ea1b51..a748c8e 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ RUMANGSAMU AKU KONGKON MANGAN SAMBATAN TA? MANGKANE WES TALAH!!! GAK USAH KAKEAN PECETOT !!!?! -CLONE'en AE REPONE .. BENAKNO ..!!! +CLONE'en OPO FORK'en AE REPONE .. BENAKNO ..!!! WES NGONO AE YO WONG !!! (UWONG TA KEONG KOWE IKU MEDIT TEMEN?!) From a6adf2753ea6dfceabb5aeee11fb52c7e9a10f2d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 19:19:21 +0700 Subject: [PATCH 025/142] HP Iphone Keat!!! --- .../Abstracts/ResponseGeneratorAbstract.php | 47 +++-- App/Classes/ReponseGenerator/Json.php | 37 ++++ App/Classes/ReponseGenerator/Xml.php | 166 ++++++++++++++++++ 3 files changed, 234 insertions(+), 16 deletions(-) create mode 100644 App/Classes/ReponseGenerator/Json.php create mode 100644 App/Classes/ReponseGenerator/Xml.php diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php index d9bfddf..3e7ce2b 100644 --- a/App/Classes/Abstracts/ResponseGeneratorAbstract.php +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -43,7 +43,7 @@ abstract class ResponseGeneratorAbstract /** * @var int */ - protected $statusCode = 200; + protected $statusCode; /** * @var int @@ -83,6 +83,24 @@ public function getData() return $this->data; } + /** + * @return int + */ + public function getEncoding(): int + { + return $this->encoding; + } + + /** + * @param int $encoding + * @return static + */ + public function setEncoding(int $encoding) + { + $this->encoding = $encoding; + return $this; + } + /** * Set Character Set * @@ -238,9 +256,8 @@ public static function getMimeTypeFromExtension(string $extension) * @uses $this->getMimeTypeFromExtension() * @return string */ - protected function generateTheContentType() + protected function fixMimeType() { - $charset = $this->getCharset(); $this->mimeType = !is_string($this->mimeType) || trim($this->mimeType) == '' ? 'text/html' : strtolower(trim($this->mimeType)); @@ -314,7 +331,16 @@ protected function generateTheContentType() } } - return $this->mimeType . ($charset ? ';charset=' . $charset : ''); + return $this->mimeType; + } + + /** + * @return string + */ + public function getContentType() : string + { + $charset = $this->getCharset(); + return $this->getMimeType() . ($charset ? ';charset=' . $charset : ''); } /** @@ -324,8 +350,7 @@ protected function generateTheContentType() */ public function getMimeType() { - $this->generateTheContentType(); - return $this->mimeType; + return $this->fixMimeType(); } /** @@ -340,16 +365,6 @@ public function setMimeType(string $mimeType) return $this; } - /** - * @param $encoding - * @return static - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - return $this; - } - /** * Set Response Status * diff --git a/App/Classes/ReponseGenerator/Json.php b/App/Classes/ReponseGenerator/Json.php new file mode 100644 index 0000000..9549b8e --- /dev/null +++ b/App/Classes/ReponseGenerator/Json.php @@ -0,0 +1,37 @@ +setMimeType('application/json'); + } + + /** + * {@inheritdoc} + */ + public function serve(): ResponseInterface + { + /** @var Response $response */ + $response = $this->getResponse(); + return $response->withJson( + $this->getData(), + $this->getStatusCode(), + $this->getEncoding() + ); + } +} diff --git a/App/Classes/ReponseGenerator/Xml.php b/App/Classes/ReponseGenerator/Xml.php new file mode 100644 index 0000000..f5e9352 --- /dev/null +++ b/App/Classes/ReponseGenerator/Xml.php @@ -0,0 +1,166 @@ + + * +// SET DATA +[ + 'Array1' => [ # array + 'ArrayNested2' => [ # array + 'Array With Invalid Tag Nested 2' => [ # array + 'No Array Key', # string + 'WithArrayKey' => [ # array + 'Value 1', # string + 1, # integer + true, # boolean + false, # boolean + null # null + ] + ] + ] + ] +] + +// XML RESPONSE + + + + + + No Array Key + + Value 1 + 1 + 1 + 0 + + + + + + + */ +/** + * Class Xml + * @package PentagonalProject\ProjectSeventh\ResponseGenerator + */ +class Xml extends ResponseGeneratorAbstract +{ + /** + * {@inheritdoc} + */ + public function __construct(RequestInterface $request, ResponseInterface $response) + { + parent::__construct($request, $response); + $this->setMimeType('application/xml'); + } + + /** + * {@inheritdoc} + */ + public function serve(): ResponseInterface + { + $body = $this->getResponse()->getBody(); + $body->write($this->generateXML()); + $response = $this + ->getResponse() + ->withBody($body) + ->withHeader('Content-Type', $this->getContentType()); + if ($this->getStatusCode()) { + $response = $response->withStatus($this->getStatusCode()); + } + + return $response; + } + + /** + * @param string $type + * @return string + */ + protected function getKeyFor(string $type) : string + { + $return = $type; + switch ($type) { + case 'int': + return 'integer'; + case 'bool': + return 'boolean'; + case 'NULL': + case 'null': + return 'null'; + } + + return $return; + } + + /** + * Generate Pair XML + * + * @param mixed $content + * @param int $counted + * @return string + */ + protected function generatePairXML($content, int $counted = 0) + { + $retVal = ""; + if (is_array($content)) { + $counted_array = count($content); + $c = 1; + foreach ($content as $key => $value) { + $count = $counted + 1; + $tab = str_repeat(" ", $count); + $type = gettype($key); + $valueType = $this->getKeyFor(gettype($value)); + if (! is_string($key) || is_numeric($key)) { + $type = is_numeric($key) ? 'integer' : $type; + $retVal .= "\n{$tab}<{$this->getKeyFor($type)} key=\"{$key}\" type=\"{$valueType}\">"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = "getKeyFor($type)}>"; + } elseif (preg_match('/[^a-z]/', $key[0]) !== false) { + // escape attribute + $key = str_replace('"', '\"', $key); + $retVal .= "\n{$tab}"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = ""; + } else { + $retVal .= "\n{$tab}<{$key} type=\"{$valueType}\">"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = ""; + } + if ($c === $counted_array) { + $endVal .= "\n"; + } + $retVal .= (is_array($value) ? $tab : '') .$endVal; + $c++; + } + } else { + if (is_bool($content)) { + return $content ? 1 : 0; + } + return $content; + } + + return $retVal; + } + + /** + * Generate XML data + * + * @return string + */ + protected function generateXML() : string + { + return "getCharset()}\"?>" + . "\n" + . $this->generatePairXML((array) $this->getData()) + . ""; + } +} From 619a6218b53e4459e95c9e5fee3144e461fdeca6 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 19:23:38 +0700 Subject: [PATCH 026/142] Cusss ahhh --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a748c8e..f55a91d 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,20 @@ WES NGONO AE YO WONG !!! (UWONG TA KEONG KOWE IKU MEDIT TEMEN?!) -``` \ No newline at end of file +``` + + +### PENTING JUGA + +```txt +Ihhh .... tolong yaaa ... +jelek - jelek gini ini script juga coding standard make +PSR2 loh .... +akika aja ampe bikin `phpcs.xml` ... pusiiiiing deh kepala eikee... +emangnye itu file buat apaan? +ih jijay deh kalo yey yey tara make `phpcbf` mending yey sanaaa !!! +Pulang ke kandang kambing .. ihhhh + +Kalo tara coding standard, emangyaa eike cowok apakaahhh ... + +``` From 9ccd95cd68f3bad3c2331114484bba4d5805f85b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 19:31:41 +0700 Subject: [PATCH 027/142] Cocol dikit ahh --- site_apache.conf.example | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 site_apache.conf.example diff --git a/site_apache.conf.example b/site_apache.conf.example new file mode 100644 index 0000000..cc6c664 --- /dev/null +++ b/site_apache.conf.example @@ -0,0 +1,21 @@ +# Change 127.0.0.1 to IP + + # Domain Name / Server + ServerName domain.cug + + # Server Aliasing + ServerAlias domain.cug www.domain.cug + + # Document Index Root Public + DocumentRoot /path/to/public + + # Email For Server Admin + ServerAdmin admin@domain.cug + + # Grant Of Directory + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + From bd198a7bd0ae647e787d9e5994f0ba16e6bc009b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 19:31:57 +0700 Subject: [PATCH 028/142] Tusuk ihhh --- site_nginx.conf.example | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 site_nginx.conf.example diff --git a/site_nginx.conf.example b/site_nginx.conf.example new file mode 100644 index 0000000..23a960f --- /dev/null +++ b/site_nginx.conf.example @@ -0,0 +1,37 @@ +server { + + # port + listen 80; + + # host + server_name domain.cug; + + # indexing + index index.php; + + # root path for public + root /path/to/public; + + # Disable Logging for error + access_log /dev/null; + error_log /dev/null; + + # Query File Indexing + location / { + try_files $uri /index.php$is_args$args; + } + + # NGinX Worker + location ~ \.php { + try_files $uri = 404; + # Fast CGI + fastcgi_split_path_info ^(.+\.php)(/.+)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_index index.php; + + # listen for cgi param port + fastcgi_pass 127.0.0.1:9000; + } +} From 98899d9beaa67605dc323458c2c97ad86fb96ee9 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 12 May 2017 19:33:01 +0700 Subject: [PATCH 029/142] eike type ses --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f55a91d..2cff5fd 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,6 @@ emangnye itu file buat apaan? ih jijay deh kalo yey yey tara make `phpcbf` mending yey sanaaa !!! Pulang ke kandang kambing .. ihhhh -Kalo tara coding standard, emangyaa eike cowok apakaahhh ... +Kalo tara coding standard, emangnyaa eike cowok apakaahhh ... ``` From 9b4977622b69c7f9ea677de9aec1e494f1e5c389 Mon Sep 17 00:00:00 2001 From: Ammar Faizi Date: Fri, 12 May 2017 23:16:40 +0700 Subject: [PATCH 030/142] =?UTF-8?q?Newbie=20numpang=20contrib=20?= =?UTF-8?q?=F0=9F=98=85=F0=9F=98=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2cff5fd..92a5617 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,6 @@ Pulang ke kandang kambing .. ihhhh Kalo tara coding standard, emangnyaa eike cowok apakaahhh ... ``` + + +Salam Es Teh \ No newline at end of file From 874d82b4d3bcf7403aaaa60e09cb29aac4456bde Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 11:53:28 +0700 Subject: [PATCH 031/142] Update Anggota Baru --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 92a5617..76795da 100644 --- a/README.md +++ b/README.md @@ -101,4 +101,6 @@ Kalo tara coding standard, emangnyaa eike cowok apakaahhh ... ``` -Salam Es Teh \ No newline at end of file +Salam Es Teh + +`^ salam es teh diatas gak usah dianggep yang nulis rada sakit` From 892067c7545bac23ee3157c6a60a0b27d44a66d4 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:28:10 +0700 Subject: [PATCH 032/142] Surya 12 - Selera Pemberani --- App/Classes/Hook.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/App/Classes/Hook.php b/App/Classes/Hook.php index 2911d67..895629b 100644 --- a/App/Classes/Hook.php +++ b/App/Classes/Hook.php @@ -5,7 +5,11 @@ /** * Class Hook - * @package Pentagonal\SlimHelper + * @package PentagonalProject\ProjectSeventh + * + * This source code base on WordPress hooks functionality + * code of WordPress convert to Current Object Hook + * But not all of features implemented here */ class Hook { @@ -219,7 +223,8 @@ public function apply($hookName, $value) E_USER_ERROR ); } - if ($this->filters->has($hookName)) { + + if (!$this->filters->has($hookName)) { return $value; } From 8a844eed1e17164f87d5532b98ef62acad07bf35 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:29:28 +0700 Subject: [PATCH 033/142] Jomblo dilarang lihat!! --- App/Components/ApplicationMiddleware.php | 232 ++++++++++++++++++++++- App/Components/ApplicationRoutes.php | 2 +- App/Components/ApplicationSlimObject.php | 24 +-- 3 files changed, 241 insertions(+), 17 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index 6936da6..927d044 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -7,29 +7,253 @@ namespace { + use Apatis\Exceptions\RuntimeException; use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; + use PentagonalProject\ProjectSeventh\Hook; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; - use Slim\App; + use Slim\CallableResolver; use Slim\Container; + use Slim\Handlers\AbstractError; + use Slim\Handlers\AbstractHandler; + use Slim\Handlers\NotAllowed; + use Slim\Handlers\NotFound; + use Slim\Handlers\Error; + use Slim\Handlers\PhpError; + use Slim\Handlers\Strategies\RequestResponse; + use Slim\Http\Uri; + use Slim\Interfaces\CallableResolverInterface; + use Slim\Interfaces\InvocationStrategyInterface; if (!isset($this) || ! $this instanceof Arguments) { return; } /** @var Application $c */ - $c =& $this['application']; + $c =& $this[CONTAINER_APPLICATION]; if (!$c instanceof Application) { return; } $slim =& $c->getSlim(); - // middle ware - $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, App $next) { + + /** + * MiddleWare FIX Uri + * That means Duplicate URI Indexing + * /index.php/(REQUEST_URI) ==== /(REQUEST_URI) + */ + $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { /** + * @var Uri $uri + */ + $uri = $request->getUri(); + $serverParams = $request->getServerParams(); + if (isset($serverParams['SCRIPT_NAME']) + && $uri->getBasePath() === $serverParams['SCRIPT_NAME'] + ) { + $request = $request->withUri($uri->withBasePath(dirname($uri->getBasePath()))); + } + return $next($request, $response); + }); + + /** + * Middle Ware With Handler + */ + $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { + if (!isset($this[CONTAINER_CALLABLE_RESOLVER])) { + /** + * Callable Resolver + * + * @var $this Container + * @return AbstractHandler + */ + $this[CONTAINER_CALLABLE_RESOLVER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $callableResolver = $hook->apply( + HOOK_HANDLER_CALLABLE_RESOLVER, + function (Container $container) { + return new CallableResolver($container); + }, + $this + ); + $callableResolver = $callableResolver($this); + if (!$callableResolver instanceof CallableResolverInterface) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Callable Resolver. Callable Resolver must be instance of %s", + CallableResolverInterface::class + ), + E_ERROR + ); + } + + return $callableResolver; + }; + } + + if (!isset($this[CONTAINER_FOUND_HANDLER])) { + /** + * Found Handler + * + * @var $this Container + * @return AbstractHandler + */ + $this[CONTAINER_FOUND_HANDLER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $callableResolver = $hook->apply( + HOOK_HANDLER_FOUND_RESPONSE, + function () { + return new RequestResponse; + }, + $this + ); + $callableResolver = $callableResolver($this); + if (!$callableResolver instanceof InvocationStrategyInterface) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Found Handler. Found Handler must be instance of %s", + InvocationStrategyInterface::class + ), + E_ERROR + ); + } + + return $callableResolver; + }; + } + + if (!isset($this[CONTAINER_NOT_FOUND_HANDLER])) { + /** + * Not Found Handler + * + * @var $this Container + * @return AbstractHandler + */ + $this[CONTAINER_NOT_FOUND_HANDLER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $notFoundHandler = $hook->apply(HOOK_HANDLER_ERROR_404, function () { + return new NotFound(); + }, $this); + $notFoundHandler = $notFoundHandler($this); + if (!$notFoundHandler instanceof AbstractHandler) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Not Found Handler. Not Found Handler must be instance of %s", + AbstractHandler::class + ), + E_ERROR + ); + } + + return $notFoundHandler; + }; + } + + /** + * Not Allowed Handler + * * @var $this Container + * @return AbstractHandler */ + $this[CONTAINER_NOT_ALLOWED_HANDLER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $notAllowedHandler = $hook->apply(HOOK_HANDLER_ERROR_403, function () { + return new NotAllowed(); + }, $this); + $notAllowedHandler = $notAllowedHandler($this); + if (!$notAllowedHandler instanceof AbstractHandler) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Not Allowed Handler. Not Allowed Handler must be instance of %s", + AbstractHandler::class + ), + E_ERROR + ); + } + + return $notAllowedHandler; + }; + if (!isset($this[CONTAINER_ERROR_HANDLER])) { + /** + * Error Handler + * + * @var $this Container + * @return AbstractHandler + */ + $this[CONTAINER_ERROR_HANDLER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $errorHandler = $hook->apply( + HOOK_HANDLER_ERROR_500, + function (Container $container) { + return new Error($container->get('settings')['displayErrorDetails']); + }, + $this + ); + $errorHandler = $errorHandler($this); + if (!$errorHandler instanceof AbstractError) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Error Handler. Error Handler must be instance of %s", + AbstractError::class + ), + E_ERROR + ); + } + + return $errorHandler; + }; + } + + if (!isset($this[CONTAINER_PHP_ERROR_HANDLER])) { + /** + * Php Error Handler + * + * @var $this Container + * @return AbstractHandler + */ + $this[CONTAINER_PHP_ERROR_HANDLER] = function () { + /** + * @var Hook $hook + */ + $hook = $this[CONTAINER_HOOK]; + $errorPhpHandler = $hook->apply( + HOOK_HANDLER_ERROR_PHP, + function (Container $container) { + return new PhpError($container->get('settings')['displayErrorDetails']); + }, + $this + ); + $errorPhpHandler = $errorPhpHandler($this); + if (!$errorPhpHandler instanceof AbstractError) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Php Error Handler. Php Error Handler must be instance of %s", + AbstractError::class + ), + E_ERROR + ); + } + + return $errorPhpHandler; + }; + } + return $next($request, $response); }); } diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index 1e8076d..bb27d83 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -14,7 +14,7 @@ } /** @var Application $c */ - $c =& $this['application']; + $c =& $this[CONTAINER_APPLICATION]; if (!$c instanceof Application) { return; } diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index 64bfb97..17a6c71 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -21,7 +21,7 @@ } /** @var Application $c */ - $c =& $this['application']; + $c =& $this[CONTAINER_APPLICATION]; if (!$c instanceof Application) { return; } @@ -34,7 +34,7 @@ * Use on closure prevent being binding to * @return Application */ - 'application' => function () use (&$c) : Application { + CONTAINER_APPLICATION => function () use (&$c) : Application { return $c; }, /** @@ -43,25 +43,25 @@ * Use on closure prevent being binding to * @return Config */ - 'config' => $c->includeScope($c->getContainerDirectory('Config.php'), $this[1]), + CONTAINER_CONFIG => $c->includeScope($c->getContainerDirectory('Config.php'), $this[1]), /** * Closure * * @return Database */ - 'database' => $c->includeScope($c->getContainerDirectory('Database.php')), + CONTAINER_DATABASE => $c->includeScope($c->getContainerDirectory('Database.php')), /** * Closure * * @return Environment */ - 'environment' => $c->includeScope($c->getContainerDirectory('Environment.php')), + CONTAINER_ENVIRONMENT => $c->includeScope($c->getContainerDirectory('Environment.php')), /** * Closure * * @return Hook */ - 'hook' => $c->includeScope($c->getContainerDirectory('Hook.php')), + CONTAINER_HOOK => $c->includeScope($c->getContainerDirectory('Hook.php')), /** * Module Container * @@ -69,7 +69,7 @@ * * @return EmbeddedCollection */ - 'module' => $c->includeScope($c->getContainerDirectory('Module.php')), + CONTAINER_MODULE => $c->includeScope($c->getContainerDirectory('Module.php')), /** * Extension Container * @@ -77,11 +77,11 @@ * * @return EmbeddedCollection */ - 'extension' => $c->includeScope($c->getContainerDirectory('Extension.php')), + CONTAINER_EXTENSION => $c->includeScope($c->getContainerDirectory('Extension.php')), /** * @return array */ - 'settings' => $c->includeScope($c->getContainerDirectory('Settings.php')), + CONTAINER_SETTINGS => $c->includeScope($c->getContainerDirectory('Settings.php')), /** * Session Container * @@ -89,17 +89,17 @@ * * @return Session */ - 'session' => $c->includeScope($c->getContainerDirectory('Session.php')), + CONTAINER_SESSION => $c->includeScope($c->getContainerDirectory('Session.php')), /** * Slim Inheritance * * @return App */ - 'slim' => function (Container $container) : App { + CONTAINER_SLIM => function (Container $container) : App { /** * @var Application $application */ - $application =& $container['application']; + $application =& $container[CONTAINER_APPLICATION]; return $application->getSlim(); } ] From 144adc3fd07315a0d637c13b96bd189dfacae865 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:30:41 +0700 Subject: [PATCH 034/142] Tak Sengaja, Lewat Depan Rumahmu... Ku Melihat, Ada Tenda Biru. Dihiasi, Indahnya Janur Kuning... Aku Bertanya, Pernikahan Siapa..?! --- App/Includes/Constant.php | 79 +++++++++++++++++++++++++++++++++++---- App/Includes/Helper.php | 38 +++++++++---------- 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index e8fe2c1..22632ac 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -3,11 +3,74 @@ | CONSTANT | \* ------------------------------------------------------ */ -define('APACHE_SERVER', 'apache'); -define('LITESPEED_SERVER', 'litespeed'); -define('NGINX_SERVER', 'nginx'); -define('IIS_SERVER', 'iis'); -define('IIS7_SERVER', 'iis7'); -define('HIAWATHA_SERVER', 'hiawatha'); -define('LIGHTTPD_SERVER', 'lighttpd'); -define('UNKNOWN_SERVER', ''); +/* SERVER TYPE CONSTANT + * ----------------------------- */ +define('SERVER_TYPE_APACHE', 'apache'); +define('SERVER_TYPE_LITESPEED', 'litespeed'); +define('SERVER_TYPE_NGINX', 'nginx'); +define('SERVER_TYPE_IIS', 'iis'); +define('SERVER_TYPE_IIS7', 'iis7'); +define('SERVER_TYPE_HIAWATHA', 'hiawatha'); +define('SERVER_TYPE_LIGHTTPD', 'lighttpd'); +define('SERVER_TYPE_UNKNOWN', ''); + +/* GLOBAL CONTAINER NAME CONSTANT + * ----------------------------- */ +define('CONTAINER_APPLICATION', \PentagonalProject\ProjectSeventh\Application::APP_KEY); +define('CONTAINER_APP', CONTAINER_APPLICATION); + +define('CONTAINER_CONFIG', 'config'); +define('CONTAINER_CONFIGS', CONTAINER_CONFIG); + +define('CONTAINER_DATABASE', 'database'); +define('CONTAINER_DATABASES', CONTAINER_DATABASE); + +define('CONTAINER_ENVIRONMENT', 'environment'); +define('CONTAINER_ENVIRONMENTS', CONTAINER_ENVIRONMENT); + +define('CONTAINER_HOOK', 'hook'); +define('CONTAINER_HOOKS', CONTAINER_HOOK); + +define('CONTAINER_MODULE', 'module'); +define('CONTAINER_MODULES', CONTAINER_MODULE); + +define('CONTAINER_EXTENSION', 'extension'); +define('CONTAINER_EXTENSIONS', CONTAINER_EXTENSION); + +define('CONTAINER_SETTING', 'settings'); +define('CONTAINER_SETTINGS', CONTAINER_SETTING); + +define('CONTAINER_SESSION', 'session'); +define('CONTAINER_SESSIONS', CONTAINER_SESSION); + +define('CONTAINER_SLIM', 'slim'); +define('CONTAINER_REQUEST', 'request'); +define('CONTAINER_RESPONSE', 'response'); +define('CONTAINER_ROUTER', 'router'); +define('CONTAINER_NOT_ALLOWED_HANDLER', 'notAllowedHandler'); +define('CONTAINER_ERROR_HANDLER', 'errorHandler'); +define('CONTAINER_NOT_FOUND_HANDLER', 'notFoundHandler'); +define('CONTAINER_FOUND_HANDLER', 'foundHandler'); +define('CONTAINER_PHP_ERROR_HANDLER', 'phpErrorHandler'); +define('CONTAINER_CALLABLE_RESOLVER', 'callableResolver'); + +// add empty for helper Auto Complete IDE +define('CONTAINER_', ''); + + +/* GLOBAL HOOK CONSTANT + * ----------------------------- */ +define('HOOK_HANDLER_ERROR', 'Handler:Error'); + +define('HOOK_HANDLER_ERROR_404', HOOK_HANDLER_ERROR . ':404'); +define('HOOK_HANDLER_ERROR_NOT_FOUND', HOOK_HANDLER_ERROR_404); + +define('HOOK_HANDLER_ERROR_500', HOOK_HANDLER_ERROR . ':500'); +define('HOOK_HANDLER_ERROR_EXCEPTION', HOOK_HANDLER_ERROR_500); + +define('HOOK_HANDLER_ERROR_403', HOOK_HANDLER_ERROR . ':403'); +define('HOOK_HANDLER_ERROR_NOT_ALLOWED', HOOK_HANDLER_ERROR_403); + +define('HOOK_HANDLER_ERROR_PHP', HOOK_HANDLER_ERROR . ':Php'); +define('HOOK_HANDLER_CALLABLE_RESOLVER', 'Handler:Callable:Resolver'); +define('HOOK_HANDLER_FOUND_RESPONSE', 'Handler:Found:Response'); diff --git a/App/Includes/Helper.php b/App/Includes/Helper.php index 719c78d..942d0b3 100644 --- a/App/Includes/Helper.php +++ b/App/Includes/Helper.php @@ -20,43 +20,43 @@ function getWebServerSoftWare() : string ? $_SERVER['SERVER_SOFTWARE'] : null; - $type = UNKNOWN_SERVER; + $type = SERVER_TYPE_UNKNOWN; if (stripos($software, 'lighttpd') !== false) { - $type = LIGHTTPD_SERVER; + $type = SERVER_TYPE_LIGHTTPD; } if (strpos($software, 'Hiawatha') !== false) { - $type = HIAWATHA_SERVER; + $type = SERVER_TYPE_HIAWATHA; } if (strpos($software, 'Apache') !== false) { - $type = APACHE_SERVER; + $type = SERVER_TYPE_APACHE; } elseif (strpos($software, 'Litespeed') !== false) { - $type = LITESPEED_SERVER; + $type = SERVER_TYPE_LITESPEED; } if (strpos($software, 'nginx') !== false) { - $type = NGINX_SERVER; + $type = SERVER_TYPE_NGINX; } - if ($type !== APACHE_SERVER && $type !== LITESPEED_SERVER + if ($type !== SERVER_TYPE_APACHE && $type !== SERVER_TYPE_LITESPEED && strpos($software, 'Microsoft-IIS') !== false && strpos($software, 'ExpressionDevServer') !== false ) { - $type = IIS_SERVER; + $type = SERVER_TYPE_IIS; if (intval(substr($software, strpos($software, 'Microsoft-IIS/')+14)) >= 7) { - $type = IIS7_SERVER; + $type = SERVER_TYPE_IIS7; } } if (function_exists('apache_get_modules')) { if (in_array('mod_security', apache_get_modules())) { - $type = APACHE_SERVER; + $type = SERVER_TYPE_APACHE; } - if ($type == UNKNOWN_SERVER && function_exists('apache_get_version') + if ($type == SERVER_TYPE_UNKNOWN && function_exists('apache_get_version') ) { - $type = APACHE_SERVER; + $type = SERVER_TYPE_APACHE; } } @@ -70,7 +70,7 @@ function getWebServerSoftWare() : string */ function isApache() : bool { - return in_array(getWebServerSoftWare(), [APACHE_SERVER, LITESPEED_SERVER]); + return in_array(getWebServerSoftWare(), [SERVER_TYPE_APACHE, SERVER_TYPE_LITESPEED]); } /** @@ -80,7 +80,7 @@ function isApache() : bool */ function isLiteSpeed(): bool { - return getWebServerSoftWare() === LIGHTTPD_SERVER; + return getWebServerSoftWare() === SERVER_TYPE_LIGHTTPD; } /** @@ -90,7 +90,7 @@ function isLiteSpeed(): bool */ function isNginx(): bool { - return getWebServerSoftWare() === NGINX_SERVER; + return getWebServerSoftWare() === SERVER_TYPE_NGINX; } /** @@ -100,7 +100,7 @@ function isNginx(): bool */ function isHiawatha(): bool { - return getWebServerSoftWare() === HIAWATHA_SERVER; + return getWebServerSoftWare() === SERVER_TYPE_HIAWATHA; } /** @@ -110,7 +110,7 @@ function isHiawatha(): bool */ function isLighttpd() : bool { - return getWebServerSoftWare() === LIGHTTPD_SERVER; + return getWebServerSoftWare() === SERVER_TYPE_LIGHTTPD; } /** @@ -120,7 +120,7 @@ function isLighttpd() : bool */ function isIIS() : bool { - return in_array(getWebServerSoftWare(), [IIS_SERVER, IIS7_SERVER]); + return in_array(getWebServerSoftWare(), [SERVER_TYPE_IIS, SERVER_TYPE_IIS7]); } /** @@ -130,7 +130,7 @@ function isIIS() : bool */ function isIIS7() : bool { - return getWebServerSoftWare() === IIS7_SERVER; + return getWebServerSoftWare() === SERVER_TYPE_IIS7; } /** From edfba36de80c4e9837864ab0a707b037d247489e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:31:29 +0700 Subject: [PATCH 035/142] Cewek seksi lewat :* ihhh ihh ihhh --- App/Containers/Config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/App/Containers/Config.php b/App/Containers/Config.php index 3975e36..9cc7d03 100644 --- a/App/Containers/Config.php +++ b/App/Containers/Config.php @@ -14,7 +14,7 @@ use PentagonalProject\ProjectSeventh\Config; use Slim\Container; - if (!isset($this) || ! $this instanceof Arguments) { + if (!isset($this) || ! $this instanceof Arguments) { return; } @@ -34,7 +34,7 @@ return function (Container $container) use (&$config) : Config { /** @var Application $application */ - $application = $container['application']; + $application = $container[CONTAINER_APPLICATION]; $config['directory'] = array_merge([ 'extension' => $application->getRootDirectory('Extensions'), 'module' => $application->getRootDirectory('Modules'), From 0c0d3f32ee7474d3ad2d3e7e3032e857d03b8d03 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:32:47 +0700 Subject: [PATCH 036/142] Perawan Semok <3 .. NTAP!!! --- App/Containers/Database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Containers/Database.php b/App/Containers/Database.php index d1f62bd..355319b 100644 --- a/App/Containers/Database.php +++ b/App/Containers/Database.php @@ -24,7 +24,7 @@ /** * @var Config $config */ - $config =& $c['config']; + $config =& $c[CONTAINER_CONFIG]; $databaseConfig = (array) $config->get('database', []); /* --------------------------------------------------- From 5bdd04d8c36ad1990f7c3919b20568022c8bf50d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:33:25 +0700 Subject: [PATCH 037/142] Iman sih kuat, si otong yang kagak nahannn!!!! --- App/Containers/Extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Containers/Extension.php b/App/Containers/Extension.php index 31e6d9b..3bdffd5 100644 --- a/App/Containers/Extension.php +++ b/App/Containers/Extension.php @@ -21,7 +21,7 @@ */ return function (Container $c) : EmbeddedCollection { /** @var Config $config */ - $config = $c['config']; + $config = $c[CONTAINER_CONFIG]; $extensionCollection = new EmbeddedCollection( $config->get('directory[extension]'), new ExtensionReader() From 8f9ea8ef210d6207668409379bc659586364f14f Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:33:52 +0700 Subject: [PATCH 038/142] Hentai dulu lah --- App/Containers/Module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Containers/Module.php b/App/Containers/Module.php index 5b8fe92..1a150f3 100644 --- a/App/Containers/Module.php +++ b/App/Containers/Module.php @@ -21,7 +21,7 @@ */ return function (Container $c) : EmbeddedCollection { /** @var Config $config */ - $config = $c['config']; + $config = $c[CONTAINER_CONFIG]; $moduleCollection = new EmbeddedCollection( $config->get('directory[module]'), new ModuleReader() From dede3434c36109ea815da0226222209ebe6ef6e9 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:34:30 +0700 Subject: [PATCH 039/142] Lagi 5s - Suka Sama Semoknya Si Semlohe <3 --- App/Containers/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Containers/Session.php b/App/Containers/Session.php index fccbc9d..c64a470 100644 --- a/App/Containers/Session.php +++ b/App/Containers/Session.php @@ -20,7 +20,7 @@ return function (Container $container) : Session { $session = new Session(); /** @var Config $config */ - $config = $container['config']; + $config = $container[CONTAINER_CONFIG]; $configSession = (array) $config->get('session', []); if (!empty($configSession)) { if (isset($configSession['save_path']) && $configSession['save_path']) { From 1f9ad07ab0ec46455af519be5cd67d80f4984b65 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:36:18 +0700 Subject: [PATCH 040/142] =?UTF-8?q?Kapak=20Naga=20Geni=F0=9F=90=89=20212?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/.htaccess | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Extensions/.htaccess diff --git a/Extensions/.htaccess b/Extensions/.htaccess deleted file mode 100644 index 31f17f9..0000000 --- a/Extensions/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny From All From 31552bcbafdb7040555e079bbf8b0967c27e40f1 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 13 May 2017 16:38:31 +0700 Subject: [PATCH 041/142] NIKITA WILLY Bikin gemessssssssssssssss!!!!!!!! Muah --- phpcs.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/phpcs.xml b/phpcs.xml index f799c05..b778130 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -16,5 +16,6 @@ App Modules + Extensions public From 1941ae6f8e971f6877426861c031e3cdcbb02fcd Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:09:08 +0700 Subject: [PATCH 042/142] Untuku ngilu --- App/Containers/Config.php | 36 ++++++++++++++++++++++++++++++++++++ App/Containers/Settings.php | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/App/Containers/Config.php b/App/Containers/Config.php index 9cc7d03..6139d28 100644 --- a/App/Containers/Config.php +++ b/App/Containers/Config.php @@ -12,6 +12,8 @@ use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\Config; + use PentagonalProject\ProjectSeventh\Hook; + use phpFastCache\CacheManager; use Slim\Container; if (!isset($this) || ! $this instanceof Arguments) { @@ -40,7 +42,41 @@ 'module' => $application->getRootDirectory('Modules'), 'storage' => $application->getRootDirectory('Storage'), ], $config['directory']); + if (!isset($config['cache']) || !is_array($config['cache'])) { + $config['cache'] = [ + 'driver' => 'Auto', + 'config' => CacheManager::getDefaultConfig() + ]; + } + if (!is_string($config['cache']['driver']) || trim($config['cache']['driver']) == '') { + $config['cache']['driver'] = 'Auto'; + } + $config['cache']['driver'] = CacheManager::standardizeDriverName($config['cache']['driver']); + if (!in_array($config['cache']['driver'], CacheManager::getStaticAllDrivers())) { + $config['cache']['driver'] = 'Auto'; + } + if (!is_array($config['cache']['config'])) { + $config['cache']['config'] = CacheManager::getDefaultConfig(); + } + /** + * @var Hook $hook + */ + $hook = $container[CONTAINER_HOOK]; + $cacheDriver = $hook->apply(HOOK_HANDLER_CACHE_DRIVER, $config['cache']['driver']); + $cacheConfig = $hook->apply(HOOK_HANDLER_CACHE_CONFIG, $config['cache']['config']); + $cacheDriver = !is_string($cacheDriver) + ? 'Auto' + : CacheManager::standardizeDriverName($cacheDriver); + $cacheConfig = !is_array($cacheConfig) + ? CacheManager::getDefaultConfig() + : $cacheConfig; + + if (!$cacheDriver || !in_array($cacheDriver, CacheManager::getStaticAllDrivers())) { + $cacheDriver = 'Auto'; + } + $config['cache']['driver'] = $cacheDriver; + $config['cache']['config'] = $cacheConfig; return new Config($config); }; } diff --git a/App/Containers/Settings.php b/App/Containers/Settings.php index 5c73211..445b116 100644 --- a/App/Containers/Settings.php +++ b/App/Containers/Settings.php @@ -15,6 +15,6 @@ */ return [ // input config - 'displayErrorDetails' => true + 'displayErrorDetails' => false, ]; } From 05d67f10324c814d3788306d6e1bef6cfef725d4 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:09:53 +0700 Subject: [PATCH 043/142] Nambah Bojo Enak kayae --- App/Components/ApplicationSlimObject.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index 17a6c71..e63a2bc 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -37,6 +37,13 @@ CONTAINER_APPLICATION => function () use (&$c) : Application { return $c; }, + /** + * Configuration Container + * + * Use on closure prevent being binding to + * @return Config + */ + CONTAINER_CACHE => $c->includeScope($c->getContainerDirectory('Cache.php')), /** * Configuration Container * From 38ec33b0f34b4d8b799b77cdd45bb9ec8e3888f0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:10:39 +0700 Subject: [PATCH 044/142] Nambah Saitik ae bengi iki ... yaa yaaa.. --- App/Classes/Config.php | 123 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/App/Classes/Config.php b/App/Classes/Config.php index 76e5610..ad5ed4a 100644 --- a/App/Classes/Config.php +++ b/App/Classes/Config.php @@ -8,7 +8,7 @@ * Class Config * @package PentagonalProject\ProjectSeventh */ -class Config +class Config implements \ArrayAccess { /** * @var CollectionFetch @@ -24,6 +24,7 @@ class Config * @var CollectionFetch */ protected $lastCollection; + /** * Config constructor. * @param array $setting @@ -50,6 +51,18 @@ public function get($key = null, $default = null) return $this->collection->fetch($key, $default); } + /** + * Offset Exists + * + * @param string $key + * @return bool + */ + public function exist($key) : bool + { + return $this->get($key, false) !== false + && $this->get($key, true) !== true; + } + /** * Reset Collection to default */ @@ -99,6 +112,7 @@ public function set($key, $values = null) 'Invalid key name given! Key config must be as a string!' ); } + if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $key, $matches)) > 1) { // Does the index contain array notation $the_key = null; @@ -134,4 +148,111 @@ public function set($key, $values = null) $this->collection->set($key, $values); } + + /** + * Remove Key from nested selector + * + * @param string $key + */ + public function remove($key) + { + if (!is_string($key) && !is_numeric($key)) { + throw new InvalidArgumentException( + 'Invalid key name given! Key config to remove must be as a string!' + ); + } + + if (!$this->exist($key)) { + return; + } + + if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $key, $matches)) > 1) { + $firstKey = reset($matches[0]); + $keyName = $firstKey; + $tmp = $this->collection[$keyName]; + if (!is_array($tmp)) { + return; + } + array_shift($matches[0]); + $unsetPosition = 0; + foreach ($matches[0] as $keyNum => $keyName) { + $keyName = trim($keyName, '[]'); + if ($unsetPosition <> $keyNum && + (!is_array($tmp) || ! array_key_exists($keyName, $tmp)) + ) { + return; + } + + $unsetPosition++; + $tmp = $tmp[$keyName]; + } + + $tmp = $this->collection[$firstKey]; + $currentUnsetPosition = 0; + // binding anonymous function to handle array reference + $recursiveUnset = function ( + &$array, + $unwanted_key + ) use ( + $unsetPosition, + &$currentUnsetPosition, + &$recursiveUnset +) { + $currentUnsetPosition++; + if ($unsetPosition !== $currentUnsetPosition) { + if (array_key_exists($unwanted_key, $array)) { + unset($array[$unwanted_key]); + } + // stop + return; + } + foreach ($array as &$value) { + if (is_array($value)) { + $recursiveUnset($value, $unwanted_key); + } + } + }; + + // call closure to binding reference + $recursiveUnset($tmp, $keyName); + $this->collection[$firstKey] = $tmp; + unset($tmp); + return; // stop + } + + unset($this->collection[$key]); + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) : bool + { + return $this->exist($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) + { + return $this->set($offset, $value); + } + + /** + * @param int|string $offset + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } } From 2936d59a61858f222857f51573467a2ad5836ed2 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:11:05 +0700 Subject: [PATCH 045/142] Mak cluruttt --- App/Components/ApplicationMiddleware.php | 53 +++++++++++++----------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index 927d044..f56c63a 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -10,6 +10,7 @@ use Apatis\Exceptions\RuntimeException; use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; + use PentagonalProject\ProjectSeventh\Config; use PentagonalProject\ProjectSeventh\Hook; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -39,11 +40,23 @@ $slim =& $c->getSlim(); /** - * MiddleWare FIX Uri + * MiddleWare Fix Uri + * * That means Duplicate URI Indexing * /index.php/(REQUEST_URI) ==== /(REQUEST_URI) + * & Remark of ErrorDetails Setting */ $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { + /** + * Remark Display Error Details + * + * @var Config $config + */ + $config = $this[CONTAINER_CONFIG]; + $this[CONTAINER_SETTING]['displayErrorDetails'] = (bool) ( + $config->get('environment[debug]', false) || $config->get('environment[error]', false) + ); + /** * @var Uri $uri */ @@ -75,12 +88,9 @@ $hook = $this[CONTAINER_HOOK]; $callableResolver = $hook->apply( HOOK_HANDLER_CALLABLE_RESOLVER, - function (Container $container) { - return new CallableResolver($container); - }, + new CallableResolver($this), $this ); - $callableResolver = $callableResolver($this); if (!$callableResolver instanceof CallableResolverInterface) { throw new RuntimeException( sprintf( @@ -109,12 +119,9 @@ function (Container $container) { $hook = $this[CONTAINER_HOOK]; $callableResolver = $hook->apply( HOOK_HANDLER_FOUND_RESPONSE, - function () { - return new RequestResponse; - }, + new RequestResponse, $this ); - $callableResolver = $callableResolver($this); if (!$callableResolver instanceof InvocationStrategyInterface) { throw new RuntimeException( sprintf( @@ -141,10 +148,11 @@ function () { * @var Hook $hook */ $hook = $this[CONTAINER_HOOK]; - $notFoundHandler = $hook->apply(HOOK_HANDLER_ERROR_404, function () { - return new NotFound(); - }, $this); - $notFoundHandler = $notFoundHandler($this); + $notFoundHandler = $hook->apply( + HOOK_HANDLER_ERROR_404, + new NotFound, + $this + ); if (!$notFoundHandler instanceof AbstractHandler) { throw new RuntimeException( sprintf( @@ -170,10 +178,11 @@ function () { * @var Hook $hook */ $hook = $this[CONTAINER_HOOK]; - $notAllowedHandler = $hook->apply(HOOK_HANDLER_ERROR_403, function () { - return new NotAllowed(); - }, $this); - $notAllowedHandler = $notAllowedHandler($this); + $notAllowedHandler = $hook->apply( + HOOK_HANDLER_ERROR_403, + new NotAllowed, + $this + ); if (!$notAllowedHandler instanceof AbstractHandler) { throw new RuntimeException( sprintf( @@ -200,12 +209,9 @@ function () { $hook = $this[CONTAINER_HOOK]; $errorHandler = $hook->apply( HOOK_HANDLER_ERROR_500, - function (Container $container) { - return new Error($container->get('settings')['displayErrorDetails']); - }, + new Error($this->get('settings')['displayErrorDetails']), $this ); - $errorHandler = $errorHandler($this); if (!$errorHandler instanceof AbstractError) { throw new RuntimeException( sprintf( @@ -234,12 +240,9 @@ function (Container $container) { $hook = $this[CONTAINER_HOOK]; $errorPhpHandler = $hook->apply( HOOK_HANDLER_ERROR_PHP, - function (Container $container) { - return new PhpError($container->get('settings')['displayErrorDetails']); - }, + new PhpError($this->get('settings')['displayErrorDetails']), $this ); - $errorPhpHandler = $errorPhpHandler($this); if (!$errorPhpHandler instanceof AbstractError) { throw new RuntimeException( sprintf( From cc9603fef1ab6a7ff10da4753c6a3e501bc68caf Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:11:32 +0700 Subject: [PATCH 046/142] Rumangsane iki maeng untuku loroh se? --- App/Includes/Constant.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index 22632ac..1a41fb3 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -42,6 +42,8 @@ define('CONTAINER_SESSION', 'session'); define('CONTAINER_SESSIONS', CONTAINER_SESSION); +// cache +define('CONTAINER_CACHE', 'cache'); define('CONTAINER_SLIM', 'slim'); define('CONTAINER_REQUEST', 'request'); @@ -74,3 +76,5 @@ define('HOOK_HANDLER_ERROR_PHP', HOOK_HANDLER_ERROR . ':Php'); define('HOOK_HANDLER_CALLABLE_RESOLVER', 'Handler:Callable:Resolver'); define('HOOK_HANDLER_FOUND_RESPONSE', 'Handler:Found:Response'); +define('HOOK_HANDLER_CACHE_DRIVER', 'Handler:Cache:Driver'); +define('HOOK_HANDLER_CACHE_CONFIG', 'Handler:Cache:Config'); From 506d095962e12a7bec7c41501d1d3c1c861420ad Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:13:52 +0700 Subject: [PATCH 047/142] Loroh untu sek kober mikiri rondo --- config.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/config.php b/config.php index 872632b..35e4247 100644 --- a/config.php +++ b/config.php @@ -29,6 +29,24 @@ 'error' => true, 'log' => true, ], + 'cache' => [ + // driver name + 'driver' => 'auto', + /** + * @see \phpFastCache\CacheManager::getDefaultConfig() + */ + 'config' => [ + 'securityKey' => 'auto', + 'ignoreSymfonyNotice' => false, + 'defaultTtl' => 900, + 'htaccess' => true, + 'default_chmod' => 0777, + 'path' => '', + 'fallback' => false, + 'limited_memory_each_object' => 4096, + 'compress_data' => false, + ] + ], 'session' => [ 'name' => null, 'save_path' => null, From d89ed40f498ec5c015b06b0e7e1c5139f17c4514 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 14 May 2017 21:14:17 +0700 Subject: [PATCH 048/142] Iki kenek gawe nyimpen rondo asli ta aku gak goroh --- App/Containers/Cache.php | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 App/Containers/Cache.php diff --git a/App/Containers/Cache.php b/App/Containers/Cache.php new file mode 100644 index 0000000..ba62f7c --- /dev/null +++ b/App/Containers/Cache.php @@ -0,0 +1,42 @@ + Date: Sun, 21 May 2017 13:44:12 +0700 Subject: [PATCH 049/142] Jangkrek!!! PICEK!! --- App/.htaccess | 2 ++ Modules/.htaccess | 3 +++ 2 files changed, 5 insertions(+) diff --git a/App/.htaccess b/App/.htaccess index 31f17f9..7ea9a3c 100644 --- a/App/.htaccess +++ b/App/.htaccess @@ -1 +1,3 @@ +# Deny access from all + Deny From All diff --git a/Modules/.htaccess b/Modules/.htaccess index 31f17f9..f3c72eb 100644 --- a/Modules/.htaccess +++ b/Modules/.htaccess @@ -1 +1,4 @@ +# Deny access from all +# Modules never put any public access assets + Deny From All From 1c03fec44c2497896c09cb7c9ff8a8efd387321a Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 13:44:26 +0700 Subject: [PATCH 050/142] Nambah setitik --- config.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/config.php b/config.php index 35e4247..26071a2 100644 --- a/config.php +++ b/config.php @@ -57,4 +57,20 @@ 'httponly' => null, 'secure' => null, ], + // auto loading on separate loaded init + 'autoload' => [ + // load on inside middleware before another autoload middle ware loaded + 'modules' => [ + ], + // load on inside middleware before another autoload middle ware loaded + // after modules + 'extensions' => [ + ], + // load middle ware end of middle ware init + 'middleware' => [ + ], + // load on routes + 'routes' => [ + ], + ], ]; From c76c35764115ab6db3590bddfcfc3426e9586375 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 13:46:14 +0700 Subject: [PATCH 051/142] Nambah Konfig'an iki lo cug!! --- App/Components/ApplicationMiddleware.php | 61 +++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index f56c63a..d7e48ba 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -1,6 +1,4 @@ getSlim(); + $slim =& $app->getSlim(); /** * MiddleWare Fix Uri @@ -259,4 +258,54 @@ return $next($request, $response); }); + + /** + * Modules & Extension Loader Autoload from config + */ + $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { + /** + * @var Config $config + */ + $config = $this[CONTAINER_CONFIG]; + if (($modules = $config['autoload']['modules']) && is_array($modules)) { + /** + * @var EmbeddedCollection $moduleLoader + */ + $moduleLoader = $this[CONTAINER_MODULE]; + foreach ($modules as $module) { + if (is_string($module) & $moduleLoader->exist($module)) { + $moduleLoader->load($module); + } + } + } + if (($extensions = $config['autoload']['extensions']) && is_array($extensions)) { + /** + * @var EmbeddedCollection $extensionLoader + */ + $extensionLoader = $this[CONTAINER_MODULE]; + foreach ($extensions as $extension) { + if (is_string($extension) & $extensionLoader->exist($extension)) { + $extensionLoader->load($extension); + } + } + } + + return $next($request, $response); + }); + + /** + * Includes Middleware auto load from config + */ + + /** + * @var Config $config + */ + $config = $slim->getContainer()[CONTAINER_CONFIG]; + if (($middleWares = $config['autoload']['middleware']) && is_array($middleWares)) { + foreach ($middleWares as $middleWare) { + if (is_string($middleWare) && file_exists($middleWare)) { + $app->includeScope($middleWare); + } + } + } } From 77e546fd686ee307de3d3ca50d976492e7148189 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 13:46:38 +0700 Subject: [PATCH 052/142] Tak Tambahi Ben Matamu Gak Picek! --- App/Components/ApplicationRoutes.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index bb27d83..55df05e 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -13,14 +13,22 @@ return; } - /** @var Application $c */ - $c =& $this[CONTAINER_APPLICATION]; - if (!$c instanceof Application) { + /** @var Application $app */ + $app =& $this[CONTAINER_APPLICATION]; + if (!$app instanceof Application) { return; } /** * @var App $slim */ - // $slim =& $c->getSlim(); + $slim =& $app->getSlim(); + $config = $slim->getContainer()[CONTAINER_CONFIG]; + if (($routes = $config['autoload']['routes'])&& is_array($routes)) { + foreach ($routes as $route) { + if (is_string($route) && file_exists($route)) { + $app->includeScope($route); + } + } + } } From 26c2a09f5f0979ef734c38caa0779e72155db864 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 13:47:00 +0700 Subject: [PATCH 053/142] Ngubah Jeneng tok! Gak usah jenang abang barang! --- App/Components/ApplicationSlimObject.php | 32 +++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index e63a2bc..8ef3580 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -20,12 +20,14 @@ return; } - /** @var Application $c */ - $c =& $this[CONTAINER_APPLICATION]; - if (!$c instanceof Application) { + /** @var Application $app */ + $app =& $this[CONTAINER_APPLICATION]; + if (!$app instanceof Application) { return; } - + /** + * @return \Slim\App + */ return new App( [ /** @@ -34,8 +36,8 @@ * Use on closure prevent being binding to * @return Application */ - CONTAINER_APPLICATION => function () use (&$c) : Application { - return $c; + CONTAINER_APPLICATION => function () use (&$app) : Application { + return $app; }, /** * Configuration Container @@ -43,32 +45,32 @@ * Use on closure prevent being binding to * @return Config */ - CONTAINER_CACHE => $c->includeScope($c->getContainerDirectory('Cache.php')), + CONTAINER_CACHE => $app->includeScope($app->getContainerDirectory('Cache.php')), /** * Configuration Container * * Use on closure prevent being binding to * @return Config */ - CONTAINER_CONFIG => $c->includeScope($c->getContainerDirectory('Config.php'), $this[1]), + CONTAINER_CONFIG => $app->includeScope($app->getContainerDirectory('Config.php'), $this[1]), /** * Closure * * @return Database */ - CONTAINER_DATABASE => $c->includeScope($c->getContainerDirectory('Database.php')), + CONTAINER_DATABASE => $app->includeScope($app->getContainerDirectory('Database.php')), /** * Closure * * @return Environment */ - CONTAINER_ENVIRONMENT => $c->includeScope($c->getContainerDirectory('Environment.php')), + CONTAINER_ENVIRONMENT => $app->includeScope($app->getContainerDirectory('Environment.php')), /** * Closure * * @return Hook */ - CONTAINER_HOOK => $c->includeScope($c->getContainerDirectory('Hook.php')), + CONTAINER_HOOK => $app->includeScope($app->getContainerDirectory('Hook.php')), /** * Module Container * @@ -76,7 +78,7 @@ * * @return EmbeddedCollection */ - CONTAINER_MODULE => $c->includeScope($c->getContainerDirectory('Module.php')), + CONTAINER_MODULE => $app->includeScope($app->getContainerDirectory('Module.php')), /** * Extension Container * @@ -84,11 +86,11 @@ * * @return EmbeddedCollection */ - CONTAINER_EXTENSION => $c->includeScope($c->getContainerDirectory('Extension.php')), + CONTAINER_EXTENSION => $app->includeScope($app->getContainerDirectory('Extension.php')), /** * @return array */ - CONTAINER_SETTINGS => $c->includeScope($c->getContainerDirectory('Settings.php')), + CONTAINER_SETTINGS => $app->includeScope($app->getContainerDirectory('Settings.php')), /** * Session Container * @@ -96,7 +98,7 @@ * * @return Session */ - CONTAINER_SESSION => $c->includeScope($c->getContainerDirectory('Session.php')), + CONTAINER_SESSION => $app->includeScope($app->getContainerDirectory('Session.php')), /** * Slim Inheritance * From 48ba6f5f575f39ffaba7a067ba805add182f4997 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 13:51:27 +0700 Subject: [PATCH 054/142] Jangkrek! Mek PSR2 tok !!GATHEL!! --- App/Components/ApplicationRoutes.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index 55df05e..cddb88d 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -24,11 +24,11 @@ */ $slim =& $app->getSlim(); $config = $slim->getContainer()[CONTAINER_CONFIG]; - if (($routes = $config['autoload']['routes'])&& is_array($routes)) { - foreach ($routes as $route) { - if (is_string($route) && file_exists($route)) { - $app->includeScope($route); - } - } - } + if (($routes = $config['autoload']['routes'])&& is_array($routes)) { + foreach ($routes as $route) { + if (is_string($route) && file_exists($route)) { + $app->includeScope($route); + } + } + } } From ab9b034d33db49c9f2299df8172382b63eef3e15 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 14:17:12 +0700 Subject: [PATCH 055/142] Nambah Komen COK! --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 76795da..3ac77ce 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ Contains Example modules, extensions script etc. See [Example](_example) +## HOW TO DEVELOP & USE + +Installation and doing development, Please refer below + +See [INSTALL.md](INSTALL.md) + ## VERSION See [VERSION](VERSION) From 7adcfe04b8847d6ec4700f53ee0223a9e09a39bf Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 14:17:27 +0700 Subject: [PATCH 056/142] Nambah Tulisan Ae COK! --- composer.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/composer.json b/composer.json index a3f29b4..c213127 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,8 @@ "version": "0.1.0-alphaDev", "require": { "php": ">= 7", + "ext-PDO": ">= 7", + "ext-pcre": ">= 7", "apatis/array-storage": "^1", "apatis/exceptions": "^1", "apatis/transporter": "dev-master", @@ -21,6 +23,13 @@ "squizlabs/php_codesniffer": "2.*", "phpunit/phpunit": "^5" }, + "suggest": { + "ext-curl": "To allow using Guzzle HTTP.", + "ext-openssl": "For better Encryption process on pentagonal/simple_encrypt", + "ext-mbstring": "For compatibility any package.", + "ext-mcrypt": "For compatibility any package.", + "ext-iconv": "For better sanitation characters & text output." + }, "license": "BSD", "authors": [ { From e1adfa81f57516f9ebe30664d827572b2687c915 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 14:17:51 +0700 Subject: [PATCH 057/142] Sepurane aku khilaf --- public/.htaccess | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/.htaccess b/public/.htaccess index c04d6cc..f39c426 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -3,7 +3,10 @@ # --------------------------------------------------------------- # Don't Allow directory indexing -Options Indexes FollowSymLinks Multiviews +Options -Indexes + +# Follow The Symlinks +Options FollowSymLinks Multiviews # ---------------------------------------------------------------- # SECURITY ENGAGEMENT From 8d4f9bdd4ad7087aed3237d4f4777b84afc944b5 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 14:18:17 +0700 Subject: [PATCH 058/142] Ben lego Dapuramu --- INSTALL.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..6e423de --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,52 @@ +# INSTALLATION + +Please refer [config.php](config.php) that contains configuration. + +### Requirements + +- Php 7 or later +- Php PDO extension (for database) +- Php PCRE extension + +Suggests + +- Php cURL Extension (for guzzle) +- Php openssl Extension (for encryption) +- Php mbString extension (for back compatibility) +- Php mbCrypt extension (for back compatibility) +- Php iconv extension (for better sanitation characters conversion) + + +### NOTE + +Public index content is on : + +[public/index.php](public/index.php) + +That mean your document root must be follow on `public/` directory. + +If you want to change structure of `index.php` to your another place / current script directory, +just move the `index.php` & `.htaccess` file. +And open `index.php` and then change. + +``` +return (new PentagonalProject\ProjectSeventh\Application()) + ->process((array) require __DIR__. '/../config.php'); +``` + +with + +``` +return (new PentagonalProject\ProjectSeventh\Application()) + ->process((array) require '/path/to/your/config.php'); +``` + +Just change require file of `config.php`, and `config.php` must be as contains array return. + +### Library Install + +Use composer to install, go to script directory and run: + +```bash +composer install --no-dev --optimize-autoloader +``` From db017142171313c7edfaf591617eac1ac394c142 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 14:20:55 +0700 Subject: [PATCH 059/142] Kurang titik uhhhh ahhh --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 6e423de..0f32ca1 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -8,7 +8,7 @@ Please refer [config.php](config.php) that contains configuration. - Php PDO extension (for database) - Php PCRE extension -Suggests +### Suggests - Php cURL Extension (for guzzle) - Php openssl Extension (for encryption) From da10e315096f2d84c5d729e03c344bd1def3692f Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:24:35 +0700 Subject: [PATCH 060/142] Nambah ArrayAccess iki lo --- App/Classes/Application.php | 84 ++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/App/Classes/Application.php b/App/Classes/Application.php index 135ef16..ea544c1 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -1,6 +1,7 @@ slim->run(); return $this; } + + /** + * Get Application + * + * @param string $name + * @return mixed + * @throws Error + */ + public function getContainer($name) + { + if (!$this->hasContainer($name)) { + settype($name, 'string'); + throw new Error( + sprintf( + "Application container %s is not exists!", + $name + ) + ); + } + + return $this->getSlim()->getContainer()->get($name); + } + + /** + * if application exists + * + * @param string $name + * @return bool + */ + public function hasContainer($name) + { + if (!is_string($name)) { + return false; + } + + $slim = $this->getSlim(); + if ($slim instanceof App) { + $container = $slim->getContainer(); + return $container->has($name); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) + { + return $this->hasContainer($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($offset) + { + return $this->getContainer($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) + { + if ($this->getSlim() && $this->getSlim() instanceof App) { + $container = $this->getSlim()->getContainer(); + $container[$offset] = $value; + } + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + if ($this->getSlim() && $this->getSlim() instanceof App) { + $container = $this->getSlim()->getContainer(); + unset($container[$offset]); + } + } } From 00d964b1fc36e4fbcc4a3a86872fa5aa560c1532 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:24:53 +0700 Subject: [PATCH 061/142] Mboh Karepmu --- App/Components/ApplicationMiddleware.php | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index d7e48ba..f7e421e 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -10,6 +10,8 @@ use PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\Config; use PentagonalProject\ProjectSeventh\Hook; + use PentagonalProject\ProjectSeventh\HttpHandler\PhpError; + use PentagonalProject\ProjectSeventh\HttpHandler\Error; use PentagonalProject\ProjectSeventh\Utilities\EmbeddedCollection; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -19,8 +21,6 @@ use Slim\Handlers\AbstractHandler; use Slim\Handlers\NotAllowed; use Slim\Handlers\NotFound; - use Slim\Handlers\Error; - use Slim\Handlers\PhpError; use Slim\Handlers\Strategies\RequestResponse; use Slim\Http\Uri; use Slim\Interfaces\CallableResolverInterface; @@ -208,7 +208,10 @@ $hook = $this[CONTAINER_HOOK]; $errorHandler = $hook->apply( HOOK_HANDLER_ERROR_500, - new Error($this->get('settings')['displayErrorDetails']), + new Error( + $this->get('settings')['displayErrorDetails'], + $this[CONTAINER_APPLICATION] + ), $this ); if (!$errorHandler instanceof AbstractError) { @@ -239,7 +242,10 @@ $hook = $this[CONTAINER_HOOK]; $errorPhpHandler = $hook->apply( HOOK_HANDLER_ERROR_PHP, - new PhpError($this->get('settings')['displayErrorDetails']), + new PhpError( + $this->get('settings')['displayErrorDetails'], + $this[CONTAINER_APPLICATION] + ), $this ); if (!$errorPhpHandler instanceof AbstractError) { @@ -267,7 +273,7 @@ * @var Config $config */ $config = $this[CONTAINER_CONFIG]; - if (($modules = $config['autoload']['modules']) && is_array($modules)) { + if (($modules = $config['autoload[modules]']) && is_array($modules)) { /** * @var EmbeddedCollection $moduleLoader */ @@ -300,12 +306,19 @@ /** * @var Config $config */ - $config = $slim->getContainer()[CONTAINER_CONFIG]; - if (($middleWares = $config['autoload']['middleware']) && is_array($middleWares)) { + $config = $app[CONTAINER_CONFIG]; + if (($middleWares = $config['autoload[middleware]']) && is_array($middleWares)) { + $c = 0; foreach ($middleWares as $middleWare) { if (is_string($middleWare) && file_exists($middleWare)) { $app->includeScope($middleWare); + $c++; } } + + ($c > 0) && + $app[CONTAINER_LOG]->debug('Additional Middleware initiated', [ + 'Count' => $c + ]); } } From 95cc697360fd9b49168ae8b8b2f54a20a4a31655 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:25:06 +0700 Subject: [PATCH 062/142] Sogok sitik --- App/Components/ApplicationSlimObject.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index 8ef3580..2368ad1 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -66,27 +66,28 @@ */ CONTAINER_ENVIRONMENT => $app->includeScope($app->getContainerDirectory('Environment.php')), /** + * Extension Container + * * Closure * - * @return Hook + * @return EmbeddedCollection */ - CONTAINER_HOOK => $app->includeScope($app->getContainerDirectory('Hook.php')), + CONTAINER_EXTENSION => $app->includeScope($app->getContainerDirectory('Extension.php')), /** - * Module Container - * * Closure * - * @return EmbeddedCollection + * @return Hook */ - CONTAINER_MODULE => $app->includeScope($app->getContainerDirectory('Module.php')), + CONTAINER_HOOK => $app->includeScope($app->getContainerDirectory('Hook.php')), + CONTAINER_LOG => $app->includeScope($app->getContainerDirectory('Log.php')), /** - * Extension Container + * Module Container * * Closure * * @return EmbeddedCollection */ - CONTAINER_EXTENSION => $app->includeScope($app->getContainerDirectory('Extension.php')), + CONTAINER_MODULE => $app->includeScope($app->getContainerDirectory('Module.php')), /** * @return array */ From 3215590956aa07789960f947cc344bb92e0fed76 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:25:17 +0700 Subject: [PATCH 063/142] Tesek Wengkeng --- App/Components/ApplicationRoutes.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index cddb88d..70110b8 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -7,6 +7,7 @@ use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; + use PentagonalProject\ProjectSeventh\Config; use Slim\App; if (!isset($this) || ! $this instanceof Arguments) { @@ -20,15 +21,20 @@ } /** - * @var App $slim + * @var Config $config */ - $slim =& $app->getSlim(); - $config = $slim->getContainer()[CONTAINER_CONFIG]; - if (($routes = $config['autoload']['routes'])&& is_array($routes)) { + $config = $app[CONTAINER_CONFIG]; + if (($routes = $config['autoload[routes]'])&& is_array($routes)) { + $c = 0; foreach ($routes as $route) { if (is_string($route) && file_exists($route)) { $app->includeScope($route); + $c++; } } + ($c > 0) && + $app[CONTAINER_LOG]->debug('Additional Routes initiated', [ + 'Count' => $c + ]); } } From c340a2fa7bd575697d1371cb6d4c31d2e142b2c1 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:25:48 +0700 Subject: [PATCH 064/142] Commit Bertubi - tubi --- App/Containers/Cache.php | 10 +++++++++- App/Containers/Database.php | 13 ++++++++++--- App/Containers/Extension.php | 12 +++++++++--- App/Containers/Module.php | 12 +++++++++--- App/Containers/Session.php | 1 + 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/App/Containers/Cache.php b/App/Containers/Cache.php index ba62f7c..8436a6e 100644 --- a/App/Containers/Cache.php +++ b/App/Containers/Cache.php @@ -34,9 +34,17 @@ } } - return CacheManager::getInstance( + $cache = CacheManager::getInstance( $config['cache[driver]'], $config['cache[config]'] ); + + $container[CONTAINER_LOG]->debug( + 'Cache initiated', + [ + 'Driver' => $config['cache[driver]'] + ] + ); + return $cache; }; } diff --git a/App/Containers/Database.php b/App/Containers/Database.php index 355319b..67456f0 100644 --- a/App/Containers/Database.php +++ b/App/Containers/Database.php @@ -17,14 +17,14 @@ /** * Database Container * - * @param Container $c + * @param Container $container * @return Database */ - return function (Container $c): Database { + return function (Container $container): Database { /** * @var Config $config */ - $config =& $c[CONTAINER_CONFIG]; + $config =& $container[CONTAINER_CONFIG]; $databaseConfig = (array) $config->get('database', []); /* --------------------------------------------------- @@ -115,6 +115,13 @@ // set new Config $config->set('database', $databaseConfig); $database = new Database($databaseConfig); + $container[CONTAINER_LOG]->debug( + 'Database initiated', + [ + 'Driver' => $databaseConfig['driver'] + ] + ); + return $database; }; } diff --git a/App/Containers/Extension.php b/App/Containers/Extension.php index 3bdffd5..3267386 100644 --- a/App/Containers/Extension.php +++ b/App/Containers/Extension.php @@ -16,17 +16,23 @@ /** * Module Container * - * @var Container $c + * @var Container $container * @return EmbeddedCollection */ - return function (Container $c) : EmbeddedCollection { + return function (Container $container) : EmbeddedCollection { /** @var Config $config */ - $config = $c[CONTAINER_CONFIG]; + $config = $container[CONTAINER_CONFIG]; $extensionCollection = new EmbeddedCollection( $config->get('directory[extension]'), new ExtensionReader() ); $extensionCollection->scan(); + $container[CONTAINER_LOG]->debug( + 'Extensions initiated & scan', + [ + 'Count' => $extensionCollection->count() + ] + ); return $extensionCollection; }; } diff --git a/App/Containers/Module.php b/App/Containers/Module.php index 1a150f3..67cf0ed 100644 --- a/App/Containers/Module.php +++ b/App/Containers/Module.php @@ -16,17 +16,23 @@ /** * Module Container * - * @var Container $c + * @var Container $container * @return EmbeddedCollection */ - return function (Container $c) : EmbeddedCollection { + return function (Container $container) : EmbeddedCollection { /** @var Config $config */ - $config = $c[CONTAINER_CONFIG]; + $config = $container[CONTAINER_CONFIG]; $moduleCollection = new EmbeddedCollection( $config->get('directory[module]'), new ModuleReader() ); $moduleCollection->scan(); + $container[CONTAINER_LOG]->debug( + 'Extensions initiated & scan', + [ + 'Count' => $moduleCollection->count() + ] + ); return $moduleCollection; }; } diff --git a/App/Containers/Session.php b/App/Containers/Session.php index c64a470..101352c 100644 --- a/App/Containers/Session.php +++ b/App/Containers/Session.php @@ -44,6 +44,7 @@ $session->getSession()->setCookieParams($cookieParams); } + $container[CONTAINER_LOG]->debug('Session initiated'); return $session; }; } From 663177a42d6743bdcf94962e5857b38cfc1c5029 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:26:19 +0700 Subject: [PATCH 065/142] Nambahi Gawe Ndelok Ndasmu! --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index c213127..531890f 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "aura/session": "^2.1", "doctrine/dbal": "^2.5", "guzzlehttp/guzzle": "~6", + "monolog/monolog": "~1", "phpfastcache/phpfastcache": "~5", "pentagonal/phpass": "^1", "pentagonal/simple_encrypt": "^1", From d72768540416d3858a68ec9873c2becd0c8b3445 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:26:37 +0700 Subject: [PATCH 066/142] Ben kowe seneng --- config.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.php b/config.php index 26071a2..29208c5 100644 --- a/config.php +++ b/config.php @@ -28,6 +28,8 @@ 'debug' => true, 'error' => true, 'log' => true, + // logs.log if there / or \ will be convert to underscore + 'log_name' => DEFAULT_LOG_NAME, ], 'cache' => [ // driver name From d917cad59186db4c6c4b2d5d8eb12ba027c3befe Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:26:55 +0700 Subject: [PATCH 067/142] Tambah Belonjo --- App/Includes/Constant.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index 1a41fb3..1f6cdc1 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -31,6 +31,9 @@ define('CONTAINER_HOOK', 'hook'); define('CONTAINER_HOOKS', CONTAINER_HOOK); +define('CONTAINER_LOG', 'log'); +define('CONTAINER_LOGS', CONTAINER_LOG); + define('CONTAINER_MODULE', 'module'); define('CONTAINER_MODULES', CONTAINER_MODULE); @@ -78,3 +81,8 @@ define('HOOK_HANDLER_FOUND_RESPONSE', 'Handler:Found:Response'); define('HOOK_HANDLER_CACHE_DRIVER', 'Handler:Cache:Driver'); define('HOOK_HANDLER_CACHE_CONFIG', 'Handler:Cache:Config'); + +/* GLOBAL CONSTANT + * ----------------------------- */ + +define('DEFAULT_LOG_NAME', 'logs.log'); \ No newline at end of file From df21826ba6cd49ce9bbc661f3299bf7e8b4c00c9 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:27:25 +0700 Subject: [PATCH 068/142] Yo iki ngkok gawe ngrekan ndasmu! --- App/Containers/Log.php | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 App/Containers/Log.php diff --git a/App/Containers/Log.php b/App/Containers/Log.php new file mode 100644 index 0000000..e0bf043 --- /dev/null +++ b/App/Containers/Log.php @@ -0,0 +1,62 @@ +getFixPath( + $config['directory[storage]'] + . '/logs/' + . $logName + ); + + $logger->pushHandler(new StreamHandler( + $logName, + $type + )); + } + return $logger; + }; +} From 84062a9cc496362fbf2919470319d08e63d328d0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:27:54 +0700 Subject: [PATCH 069/142] Rasane uhhhh ahhhh NTAPH! --- App/Classes/HttpHandler/Error.php | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 App/Classes/HttpHandler/Error.php diff --git a/App/Classes/HttpHandler/Error.php b/App/Classes/HttpHandler/Error.php new file mode 100644 index 0000000..ef11715 --- /dev/null +++ b/App/Classes/HttpHandler/Error.php @@ -0,0 +1,53 @@ +app = $app; + parent::__construct($displayErrorDetails); + } + + /** + * {@inheritdoc} + */ + public function __invoke( + ServerRequestInterface $request, + ResponseInterface $response, + \Exception $exception + ) { + /** @var Logger $log */ + $log = $this->app[CONTAINER_LOG]; + $log->error( + $exception->getMessage(), + [ + 'file' => $exception->getFile(), + 'code' => $exception->getCode(), + 'line' => $exception->getLine() + ] + ); + + return parent::__invoke($request, $response, $exception); + } +} From f68d558e8bd16a140d52d6bdda10b8f356f7fb2f Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:28:09 +0700 Subject: [PATCH 070/142] Rasane jan uhhhh ahhhh usluk usluk ahhhh --- App/Classes/HttpHandler/PhpError.php | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 App/Classes/HttpHandler/PhpError.php diff --git a/App/Classes/HttpHandler/PhpError.php b/App/Classes/HttpHandler/PhpError.php new file mode 100644 index 0000000..8053151 --- /dev/null +++ b/App/Classes/HttpHandler/PhpError.php @@ -0,0 +1,52 @@ +app = $app; + parent::__construct($displayErrorDetails); + } + + /** + * {@inheritdoc} + */ + public function __invoke( + ServerRequestInterface $request, + ResponseInterface $response, + \Throwable $error + ) { + /** @var Logger $log */ + $log = $this->app[CONTAINER_LOG]; + $log->error( + $error->getMessage(), + [ + 'file' => $error->getFile(), + 'code' => $error->getCode(), + 'line' => $error->getLine() + ] + ); + + return parent::__invoke($request, $response, $error); + } +} \ No newline at end of file From cdfb0a0af8f44193d2c601af4be3998795a6974c Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:29:42 +0700 Subject: [PATCH 071/142] Rasane uhhhh ahhhh NTAPH! --- App/Classes/HttpHandler/Error.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/App/Classes/HttpHandler/Error.php b/App/Classes/HttpHandler/Error.php index ef11715..1ff6b80 100644 --- a/App/Classes/HttpHandler/Error.php +++ b/App/Classes/HttpHandler/Error.php @@ -23,7 +23,7 @@ class Error extends \Slim\Handlers\Error * @param bool $displayErrorDetails Set to true to display full details * @param Application $app */ - public function __construct($displayErrorDetails = false, Application $app) + public function __construct($displayErrorDetails = false, Application $app = null) { $this->app = $app; parent::__construct($displayErrorDetails); @@ -37,16 +37,18 @@ public function __invoke( ResponseInterface $response, \Exception $exception ) { - /** @var Logger $log */ - $log = $this->app[CONTAINER_LOG]; - $log->error( - $exception->getMessage(), - [ - 'file' => $exception->getFile(), - 'code' => $exception->getCode(), - 'line' => $exception->getLine() - ] - ); + if ($this->app instanceof Application) { + /** @var Logger $log */ + $log = $this->app[CONTAINER_LOG]; + $log->error( + $exception->getMessage(), + [ + 'file' => $exception->getFile(), + 'code' => $exception->getCode(), + 'line' => $exception->getLine() + ] + ); + } return parent::__invoke($request, $response, $exception); } From 2868418227c3e6c1441dbc488b40b3ffd8d54534 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:29:45 +0700 Subject: [PATCH 072/142] Rasane jan uhhhh ahhhh usluk usluk ahhhh --- App/Classes/HttpHandler/PhpError.php | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/App/Classes/HttpHandler/PhpError.php b/App/Classes/HttpHandler/PhpError.php index 8053151..99251cc 100644 --- a/App/Classes/HttpHandler/PhpError.php +++ b/App/Classes/HttpHandler/PhpError.php @@ -1,5 +1,6 @@ app = $app; parent::__construct($displayErrorDetails); @@ -36,17 +37,19 @@ public function __invoke( ResponseInterface $response, \Throwable $error ) { - /** @var Logger $log */ - $log = $this->app[CONTAINER_LOG]; - $log->error( - $error->getMessage(), - [ - 'file' => $error->getFile(), - 'code' => $error->getCode(), - 'line' => $error->getLine() - ] - ); + if ($this->app instanceof Application) { + /** @var Logger $log */ + $log = $this->app[CONTAINER_LOG]; + $log->error( + $error->getMessage(), + [ + 'file' => $error->getFile(), + 'code' => $error->getCode(), + 'line' => $error->getLine() + ] + ); + } return parent::__invoke($request, $response, $error); } -} \ No newline at end of file +} From bbed04f7cd2f685466941ab72f632777004f871b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:29:54 +0700 Subject: [PATCH 073/142] Tambah Belonjo --- App/Includes/Constant.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index 1f6cdc1..405e2e3 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -85,4 +85,4 @@ /* GLOBAL CONSTANT * ----------------------------- */ -define('DEFAULT_LOG_NAME', 'logs.log'); \ No newline at end of file +define('DEFAULT_LOG_NAME', 'logs.log'); From 9a8a587cfb0a0b9723eb8955e0c3a808d8342c0c Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:34:24 +0700 Subject: [PATCH 074/142] Butuh kehangatan uhhhh --- _example/Extensions/ExampleExtension/ExampleExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_example/Extensions/ExampleExtension/ExampleExtension.php b/_example/Extensions/ExampleExtension/ExampleExtension.php index 45228fb..04a7abf 100644 --- a/_example/Extensions/ExampleExtension/ExampleExtension.php +++ b/_example/Extensions/ExampleExtension/ExampleExtension.php @@ -59,4 +59,4 @@ public function init() // TODO: Implement init() method. } } -} \ No newline at end of file +} From eb2ad7c0fc66e7bd25b5bff35bbafccba3bf84f0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:38:44 +0700 Subject: [PATCH 075/142] Rai Sange --- _docs/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_docs/README.md b/_docs/README.md index 3ecc0da..47a75d7 100644 --- a/_docs/README.md +++ b/_docs/README.md @@ -7,6 +7,7 @@ --- -- [Configurations](Configurations) -- [Extensions](Extensions) -- [Modules](Modules) +- [Applications](Applications) `Manage applications & lists` +- [Configurations](Configurations) `Manage Configurations` +- [Extensions](Extensions) `Extensions Management` +- [Modules](Modules) `Modules Management` From 45e974b0c225bbfffad1139e14b1202b5b3ea937 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:39:14 +0700 Subject: [PATCH 076/142] Ngombe Ciu Sak Tutup Botole --- _docs/Applications/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 _docs/Applications/README.md diff --git a/_docs/Applications/README.md b/_docs/Applications/README.md new file mode 100644 index 0000000..9aaf2e1 --- /dev/null +++ b/_docs/Applications/README.md @@ -0,0 +1 @@ +## Applications From c12f03ff1f043733b5144450cdaf97334dffc878 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:40:24 +0700 Subject: [PATCH 077/142] Anuku aceng beibh --- Storage/.htaccess | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Storage/.htaccess b/Storage/.htaccess index 31f17f9..77e14fa 100644 --- a/Storage/.htaccess +++ b/Storage/.htaccess @@ -1 +1,4 @@ +# Deny access from all +# That means log file never allow to be shown + Deny From All From b8b80761d063821cf646b01568dc7b5e26a27072 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:42:46 +0700 Subject: [PATCH 078/142] Aceng terus ae, usluke kapan? --- .../ExampleExtension/ExampleExtension.php | 62 ------------------- .../Modules/ExampleModule/ExampleModule.php | 62 ------------------- _example/README.md | 1 - 3 files changed, 125 deletions(-) delete mode 100644 _example/Extensions/ExampleExtension/ExampleExtension.php delete mode 100644 _example/Modules/ExampleModule/ExampleModule.php delete mode 100644 _example/README.md diff --git a/_example/Extensions/ExampleExtension/ExampleExtension.php b/_example/Extensions/ExampleExtension/ExampleExtension.php deleted file mode 100644 index 04a7abf..0000000 --- a/_example/Extensions/ExampleExtension/ExampleExtension.php +++ /dev/null @@ -1,62 +0,0 @@ - Date: Sun, 21 May 2017 15:43:42 +0700 Subject: [PATCH 079/142] Sek tak budal golek Kimcil --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ac77ce..acc16b7 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ See [Documentation](_docs) Contains Example modules, extensions script etc. -See [Example](_example) +See [Example](_docs/Example) ## HOW TO DEVELOP & USE From b4d5ef37ea4797f210c5f530d62f638379b2ae5e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 21 May 2017 15:44:13 +0700 Subject: [PATCH 080/142] Kandani Kok aku tak budal sek golek Kimcil !! COK - i --- .../ExampleExtension/ExampleExtension.php | 62 +++++++++++++++++++ .../Modules/ExampleModule/ExampleModule.php | 62 +++++++++++++++++++ _docs/Example/README.md | 1 + 3 files changed, 125 insertions(+) create mode 100644 _docs/Example/Extensions/ExampleExtension/ExampleExtension.php create mode 100644 _docs/Example/Modules/ExampleModule/ExampleModule.php create mode 100644 _docs/Example/README.md diff --git a/_docs/Example/Extensions/ExampleExtension/ExampleExtension.php b/_docs/Example/Extensions/ExampleExtension/ExampleExtension.php new file mode 100644 index 0000000..04a7abf --- /dev/null +++ b/_docs/Example/Extensions/ExampleExtension/ExampleExtension.php @@ -0,0 +1,62 @@ + Date: Mon, 22 May 2017 15:34:28 +0700 Subject: [PATCH 081/142] Tambahan cocolan --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 17c0368..5681524 100644 --- a/.gitignore +++ b/.gitignore @@ -173,5 +173,8 @@ vendor # Ignore Visual Studio code .vscode +# ON LOCAL DEV /Modules/*/ -/Storage/logs/*.* +/Extensions/*/ +/Config/Config.php + From 76ec6f4dcac9a895e70ea52d2f5ed83f2a6c9c2d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:35:28 +0700 Subject: [PATCH 082/142] Tambah sitik lah --- Config/Config.php | 73 +++++++++++++++++++++++++++++++ Config/Example.Config.php | 73 +++++++++++++++++++++++++++++++ Config/Example.Routes.php | 92 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 Config/Config.php create mode 100644 Config/Example.Config.php create mode 100644 Config/Example.Routes.php diff --git a/Config/Config.php b/Config/Config.php new file mode 100644 index 0000000..71dd3cb --- /dev/null +++ b/Config/Config.php @@ -0,0 +1,73 @@ + [ + 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', + 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', + // load from example + // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', + // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', + ], + 'database' => [ + 'host' => 'localhost', + 'user' => '', + 'password' => '', + 'name' => '', + 'port' => 3306, + 'driver' => 'mysql', + 'charset' => 'utf8', + 'collate' => 'utf8_unicode_ci', + ], + 'environment' => [ + 'debug' => true, + 'error' => true, + 'log' => true, + // logs.log if there / or \ will be convert to underscore + 'log_name' => DEFAULT_LOG_NAME, + ], + 'cache' => [ + // driver name + 'driver' => 'auto', + /** + * @see \phpFastCache\CacheManager::getDefaultConfig() + */ + 'config' => [ + 'securityKey' => 'auto', + 'ignoreSymfonyNotice' => false, + 'defaultTtl' => 900, + 'htaccess' => true, + 'default_chmod' => 0777, + 'path' => '', + 'fallback' => false, + 'limited_memory_each_object' => 4096, + 'compress_data' => false, + ] + ], + 'session' => [ + 'name' => null, + 'save_path' => null, + // values of cookie params + 'path' => '/', + 'lifetime' => 0, + 'domain' => null, + 'httponly' => null, + 'secure' => null, + ], + // auto loading on separate loaded init + 'autoload' => [ + // load middle ware end of middle ware init + 'middleware' => [ + ], + // load on routes + 'routes' => [ + // example Route + __DIR__ . '/Example.Routes.php' + ], + ], +]; diff --git a/Config/Example.Config.php b/Config/Example.Config.php new file mode 100644 index 0000000..71dd3cb --- /dev/null +++ b/Config/Example.Config.php @@ -0,0 +1,73 @@ + [ + 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', + 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', + // load from example + // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', + // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', + ], + 'database' => [ + 'host' => 'localhost', + 'user' => '', + 'password' => '', + 'name' => '', + 'port' => 3306, + 'driver' => 'mysql', + 'charset' => 'utf8', + 'collate' => 'utf8_unicode_ci', + ], + 'environment' => [ + 'debug' => true, + 'error' => true, + 'log' => true, + // logs.log if there / or \ will be convert to underscore + 'log_name' => DEFAULT_LOG_NAME, + ], + 'cache' => [ + // driver name + 'driver' => 'auto', + /** + * @see \phpFastCache\CacheManager::getDefaultConfig() + */ + 'config' => [ + 'securityKey' => 'auto', + 'ignoreSymfonyNotice' => false, + 'defaultTtl' => 900, + 'htaccess' => true, + 'default_chmod' => 0777, + 'path' => '', + 'fallback' => false, + 'limited_memory_each_object' => 4096, + 'compress_data' => false, + ] + ], + 'session' => [ + 'name' => null, + 'save_path' => null, + // values of cookie params + 'path' => '/', + 'lifetime' => 0, + 'domain' => null, + 'httponly' => null, + 'secure' => null, + ], + // auto loading on separate loaded init + 'autoload' => [ + // load middle ware end of middle ware init + 'middleware' => [ + ], + // load on routes + 'routes' => [ + // example Route + __DIR__ . '/Example.Routes.php' + ], + ], +]; diff --git a/Config/Example.Routes.php b/Config/Example.Routes.php new file mode 100644 index 0000000..9b889fa --- /dev/null +++ b/Config/Example.Routes.php @@ -0,0 +1,92 @@ +getSlim(); + $slim->any( + '/helo[/[{name: [A-Za-z0-9\S]+}[/]]]', + function ( + ServerRequestInterface $request, + ResponseInterface $response, + $args + ) { + /** + * @var Response $response + * @var Body $body + */ + $body = $response->getBody(); + $body->write( + sprintf( + '"Helo %1$s, You are in (%2$s)', + isset($args['name']) ? $args['name'] : 'you!', + $request->getUri() + ) + ); + return $response->withBody($body); + } + ); + + $slim->any( + '/xml[/]', + function ( + ServerRequestInterface $request, + ResponseInterface $response + ) { + return Xml::generate($request, $response) + ->setData([ + 'KeyData' => [ + 'TestDataArray' => 'Value', + 'TestDataArray2' => 'Value', + 'TestDataArrayValue' => [ + 'Value' + ], + ] + ]) + ->setStatusCode(404) + ->serve(); + } + ); + + $slim->any( + '/json[/]', + function ( + ServerRequestInterface $request, + ResponseInterface $response + ) { + return Json::generate($request, $response) + ->setData([ + 'KeyData' => [ + 'TestDataArray' => 'Value', + 'TestDataArray2' => 'Value', + 'TestDataArrayValue' => [ + 'Value' + ], + ] + ]) + // add encoding option + ->setEncoding(JSON_PRETTY_PRINT | JSON_FORCE_OBJECT) + ->setStatusCode(404) + ->serve(); + } + ); +} From c8ec1ae6863266a1dbbeb1630700e78a22a1e77d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:35:53 +0700 Subject: [PATCH 083/142] Di ubah sitik biar greng --- App/Classes/Abstracts/ResponseGeneratorAbstract.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php index 3e7ce2b..392160a 100644 --- a/App/Classes/Abstracts/ResponseGeneratorAbstract.php +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -263,6 +263,10 @@ protected function fixMimeType() : strtolower(trim($this->mimeType)); if ($this->recheckMimeType || strpos($this->mimeType, '/') === false) { + $selectedContentTypes = array_filter(explode(',', $this->mimeType)); + if (count($selectedContentTypes)) { + $this->mimeType = current($selectedContentTypes); + } if (preg_match( '/(?:(?:[^/]*)(?:\\\+|\/+))?(html?|javascript|calendar|css|plain)/', $this->mimeType, From 35314c7695f33c470321a7e4173f710d8c758298 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:36:25 +0700 Subject: [PATCH 084/142] Uhuk uhuk ahh --- App/Classes/ReponseGenerator/Xml.php | 134 ++------------------------- 1 file changed, 7 insertions(+), 127 deletions(-) diff --git a/App/Classes/ReponseGenerator/Xml.php b/App/Classes/ReponseGenerator/Xml.php index f5e9352..283d902 100644 --- a/App/Classes/ReponseGenerator/Xml.php +++ b/App/Classes/ReponseGenerator/Xml.php @@ -2,58 +2,21 @@ namespace PentagonalProject\ProjectSeventh\ResponseGenerator; use PentagonalProject\ProjectSeventh\Abstracts\ResponseGeneratorAbstract; +use PentagonalProject\ProjectSeventh\Utilities\XmlBuilderTrait; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -/* - * XML EXAMPLE FOR RETURNING GET REAL DATA VALUE - * This for Tricky XML Return Data - * if got invalid attribute will be use tag as - * - * -// SET DATA -[ - 'Array1' => [ # array - 'ArrayNested2' => [ # array - 'Array With Invalid Tag Nested 2' => [ # array - 'No Array Key', # string - 'WithArrayKey' => [ # array - 'Value 1', # string - 1, # integer - true, # boolean - false, # boolean - null # null - ] - ] - ] - ] -] - -// XML RESPONSE - - - - - - No Array Key - - Value 1 - 1 - 1 - 0 - - - - - - - */ /** * Class Xml * @package PentagonalProject\ProjectSeventh\ResponseGenerator */ class Xml extends ResponseGeneratorAbstract { + /** + * @uses XmlBuilderTrait + */ + use XmlBuilderTrait; + /** * {@inheritdoc} */ @@ -69,7 +32,7 @@ public function __construct(RequestInterface $request, ResponseInterface $respon public function serve(): ResponseInterface { $body = $this->getResponse()->getBody(); - $body->write($this->generateXML()); + $body->write($this->generateXML($this->getCharset(), (array) $this->getData())); $response = $this ->getResponse() ->withBody($body) @@ -80,87 +43,4 @@ public function serve(): ResponseInterface return $response; } - - /** - * @param string $type - * @return string - */ - protected function getKeyFor(string $type) : string - { - $return = $type; - switch ($type) { - case 'int': - return 'integer'; - case 'bool': - return 'boolean'; - case 'NULL': - case 'null': - return 'null'; - } - - return $return; - } - - /** - * Generate Pair XML - * - * @param mixed $content - * @param int $counted - * @return string - */ - protected function generatePairXML($content, int $counted = 0) - { - $retVal = ""; - if (is_array($content)) { - $counted_array = count($content); - $c = 1; - foreach ($content as $key => $value) { - $count = $counted + 1; - $tab = str_repeat(" ", $count); - $type = gettype($key); - $valueType = $this->getKeyFor(gettype($value)); - if (! is_string($key) || is_numeric($key)) { - $type = is_numeric($key) ? 'integer' : $type; - $retVal .= "\n{$tab}<{$this->getKeyFor($type)} key=\"{$key}\" type=\"{$valueType}\">"; - $retVal .= $this->generatePairXML($value, $count); - $endVal = "getKeyFor($type)}>"; - } elseif (preg_match('/[^a-z]/', $key[0]) !== false) { - // escape attribute - $key = str_replace('"', '\"', $key); - $retVal .= "\n{$tab}"; - $retVal .= $this->generatePairXML($value, $count); - $endVal = ""; - } else { - $retVal .= "\n{$tab}<{$key} type=\"{$valueType}\">"; - $retVal .= $this->generatePairXML($value, $count); - $endVal = ""; - } - if ($c === $counted_array) { - $endVal .= "\n"; - } - $retVal .= (is_array($value) ? $tab : '') .$endVal; - $c++; - } - } else { - if (is_bool($content)) { - return $content ? 1 : 0; - } - return $content; - } - - return $retVal; - } - - /** - * Generate XML data - * - * @return string - */ - protected function generateXML() : string - { - return "getCharset()}\"?>" - . "\n" - . $this->generatePairXML((array) $this->getData()) - . ""; - } } From 6923a992083c9379ecff872e1edfca363c5e281e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:36:50 +0700 Subject: [PATCH 085/142] Biar Tambah Ganteng --- App/Classes/Utilities/XmlBuilderTrait.php | 138 ++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 App/Classes/Utilities/XmlBuilderTrait.php diff --git a/App/Classes/Utilities/XmlBuilderTrait.php b/App/Classes/Utilities/XmlBuilderTrait.php new file mode 100644 index 0000000..83911b4 --- /dev/null +++ b/App/Classes/Utilities/XmlBuilderTrait.php @@ -0,0 +1,138 @@ + + * +// SET DATA +[ + 'Array1' => [ # array + 'ArrayNested2' => [ # array + 'Array With Invalid Tag Nested 2' => [ # array + 'No Array Key', # string + 'WithArrayKey' => [ # array + 'Value 1', # string + 1, # integer + true, # boolean + false, # boolean + null # null + ] + ] + ] + ] +] + +// XML RESPONSE + + + + + + No Array Key + + Value 1 + 1 + 1 + 0 + + + + + + + */ + +/** + * Trait XmlBuilderTrait + * @package PentagonalProject\ProjectSeventh\Utilities + */ +trait XmlBuilderTrait +{ + /** + * @param string $type + * @return string + */ + protected function getXMLKeyFor(string $type) : string + { + $return = $type; + switch ($type) { + case 'int': + return 'integer'; + case 'bool': + return 'boolean'; + case 'NULL': + case 'null': + return 'null'; + } + + return $return; + } + + /** + * Generate Pair XML + * + * @param mixed $content + * @param int $counted + * @return string + */ + protected function generatePairXML($content, int $counted = 0) + { + $retVal = ""; + if (is_array($content)) { + $counted_array = count($content); + $c = 1; + foreach ($content as $key => $value) { + $count = $counted + 1; + $tab = str_repeat(" ", $count); + $type = gettype($key); + $valueType = $this->getXMLKeyFor(gettype($value)); + if (! is_string($key) || is_numeric($key)) { + $type = is_numeric($key) ? 'integer' : $type; + $retVal .= "\n{$tab}<{$this->getXMLKeyFor($type)} key=\"{$key}\" type=\"{$valueType}\">"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = "getXMLKeyFor($type)}>"; + } elseif (preg_match('/^[^a-z]|[^a-z0-9]/i', $key) !== 0) { + // escape attribute + $key = str_replace('"', '\"', $key); + $retVal .= "\n{$tab}"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = ""; + } else { + $retVal .= "\n{$tab}<{$key} type=\"{$valueType}\">"; + $retVal .= $this->generatePairXML($value, $count); + $endVal = ""; + } + if ($c === $counted_array) { + $endVal .= "\n"; + } + $retVal .= (is_array($value) ? $tab : '') .$endVal; + $c++; + } + } else { + if (is_bool($content)) { + return $content ? 1 : 0; + } + return $content; + } + + return $retVal; + } + + /** + * Generate XML Data + * + * @param string $charset + * @param array $data + * @return string + */ + protected function generateXML(string $charset, array $data) : string + { + return "" + . "\n" + . $this->generatePairXML($data) + . ""; + } +} From de60959c502af608c0d91d25b3ca7db42648eaf7 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:37:06 +0700 Subject: [PATCH 086/142] Guluku cengeng --- App/Components/ApplicationMiddleware.php | 35 ------------------------ 1 file changed, 35 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index f7e421e..f807d54 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -12,7 +12,6 @@ use PentagonalProject\ProjectSeventh\Hook; use PentagonalProject\ProjectSeventh\HttpHandler\PhpError; use PentagonalProject\ProjectSeventh\HttpHandler\Error; - use PentagonalProject\ProjectSeventh\Utilities\EmbeddedCollection; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Slim\CallableResolver; @@ -265,40 +264,6 @@ return $next($request, $response); }); - /** - * Modules & Extension Loader Autoload from config - */ - $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { - /** - * @var Config $config - */ - $config = $this[CONTAINER_CONFIG]; - if (($modules = $config['autoload[modules]']) && is_array($modules)) { - /** - * @var EmbeddedCollection $moduleLoader - */ - $moduleLoader = $this[CONTAINER_MODULE]; - foreach ($modules as $module) { - if (is_string($module) & $moduleLoader->exist($module)) { - $moduleLoader->load($module); - } - } - } - if (($extensions = $config['autoload']['extensions']) && is_array($extensions)) { - /** - * @var EmbeddedCollection $extensionLoader - */ - $extensionLoader = $this[CONTAINER_MODULE]; - foreach ($extensions as $extension) { - if (is_string($extension) & $extensionLoader->exist($extension)) { - $extensionLoader->load($extension); - } - } - } - - return $next($request, $response); - }); - /** * Includes Middleware auto load from config */ From 629d35726c76fbe816bb5cd1fc6e7a24d3573bf3 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:37:18 +0700 Subject: [PATCH 087/142] Anuku Aceng --- App/Components/ApplicationRoutes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index 70110b8..72c72d5 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -8,7 +8,6 @@ use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\Config; - use Slim\App; if (!isset($this) || ! $this instanceof Arguments) { return; From e8188e338e3c8d2720e6221207cfa7b8ef1f506d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:37:31 +0700 Subject: [PATCH 088/142] Biar Gueh Keliatan Ganteng --- INSTALL.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 0f32ca1..ece424a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,6 @@ # INSTALLATION -Please refer [config.php](config.php) that contains configuration. +Please refer [Config/Example.Config.php](Config/Example.Config.php) that contains configuration. ### Requirements @@ -31,17 +31,17 @@ And open `index.php` and then change. ``` return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require __DIR__. '/../config.php'); + ->process((array) require __DIR__. '/../Config/Config.php'); ``` with ``` return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require '/path/to/your/config.php'); + ->process((array) require '/path/to/your/Config.php'); ``` -Just change require file of `config.php`, and `config.php` must be as contains array return. +Just change require Configuration file of `Example.Config.php`, and `Configuration File` must be as contains array return. ### Library Install @@ -50,3 +50,9 @@ Use composer to install, go to script directory and run: ```bash composer install --no-dev --optimize-autoloader ``` + +If there was additional file on core directory, please update composer autoload + +```bash +composer dump-autoload --optimize-autoloader +``` From b70e284206b13931d085f01fb00e2428a372a1ad Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:37:50 +0700 Subject: [PATCH 089/142] Tambah Bang - Cocol Tusuk Ih --- phpcs.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/phpcs.xml b/phpcs.xml index b778130..9a29b0a 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -15,6 +15,7 @@ App + Config Modules Extensions public From 155a01e2b458a9d70e84b3b24c5b3c25fdc9db73 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:38:02 +0700 Subject: [PATCH 090/142] Ra Kanggo --- config.php | 78 ------------------------------------------------------ 1 file changed, 78 deletions(-) delete mode 100644 config.php diff --git a/config.php b/config.php deleted file mode 100644 index 29208c5..0000000 --- a/config.php +++ /dev/null @@ -1,78 +0,0 @@ - [ - 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', - 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', - // load from example - // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', - // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', - ], - 'database' => [ - 'host' => 'localhost', - 'user' => '', - 'password' => '', - 'name' => '', - 'port' => 3306, - 'driver' => 'mysql', - 'charset' => 'utf8', - 'collate' => 'utf8_unicode_ci', - ], - 'environment' => [ - 'debug' => true, - 'error' => true, - 'log' => true, - // logs.log if there / or \ will be convert to underscore - 'log_name' => DEFAULT_LOG_NAME, - ], - 'cache' => [ - // driver name - 'driver' => 'auto', - /** - * @see \phpFastCache\CacheManager::getDefaultConfig() - */ - 'config' => [ - 'securityKey' => 'auto', - 'ignoreSymfonyNotice' => false, - 'defaultTtl' => 900, - 'htaccess' => true, - 'default_chmod' => 0777, - 'path' => '', - 'fallback' => false, - 'limited_memory_each_object' => 4096, - 'compress_data' => false, - ] - ], - 'session' => [ - 'name' => null, - 'save_path' => null, - // values of cookie params - 'path' => '/', - 'lifetime' => 0, - 'domain' => null, - 'httponly' => null, - 'secure' => null, - ], - // auto loading on separate loaded init - 'autoload' => [ - // load on inside middleware before another autoload middle ware loaded - 'modules' => [ - ], - // load on inside middleware before another autoload middle ware loaded - // after modules - 'extensions' => [ - ], - // load middle ware end of middle ware init - 'middleware' => [ - ], - // load on routes - 'routes' => [ - ], - ], -]; From 65fdbb8b1ca9ef6021623a647432390363de75b7 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Mon, 22 May 2017 15:38:17 +0700 Subject: [PATCH 091/142] Ihhhhh ahhhh uhhh --- public/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.php b/public/index.php index 144a9f1..a9c884e 100644 --- a/public/index.php +++ b/public/index.php @@ -110,4 +110,4 @@ // try to includes once require_once __DIR__ .'/../App/FunctionsIncludes.php'; return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require __DIR__. '/../config.php'); + ->process((array) require __DIR__ . '/../Config/Config.php'); From a451c6bdab4ac2c89445bc7bbf41d9d3f880ad3f Mon Sep 17 00:00:00 2001 From: pentagonal Date: Tue, 23 May 2017 17:28:03 +0700 Subject: [PATCH 092/142] Mbenakno cug --- App/Containers/Environment.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/App/Containers/Environment.php b/App/Containers/Environment.php index d261618..d2aeb1c 100644 --- a/App/Containers/Environment.php +++ b/App/Containers/Environment.php @@ -19,17 +19,17 @@ */ return function () : Environment { $server = $_SERVER; - if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' + if (!empty($server['HTTPS']) && strtolower($server['HTTPS']) !== 'off' // hide behind proxy / maybe cloud flare cdn - || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) - && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' - || !empty($_SERVER['HTTP_FRONT_END_HTTPS']) - && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off' + || isset($server['HTTP_X_FORWARDED_PROTO']) + && $server['HTTP_X_FORWARDED_PROTO'] === 'https' + || !empty($server['HTTP_FRONT_END_HTTPS']) + && strtolower($server['HTTP_FRONT_END_HTTPS']) !== 'off' ) { // detect if non standard protocol - if ($_SERVER['SERVER_PORT'] == 80 - && (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) - || isset($_SERVER['HTTP_FRONT_END_HTTPS']) + if ($server['SERVER_PORT'] == 80 + && (isset($server['HTTP_X_FORWARDED_PROTO']) + || isset($server['HTTP_FRONT_END_HTTPS']) ) ) { $server['SERVER_PORT'] = 443; From 8584912457fbc001b44a8411fad683c47ddce756 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 13:32:20 +0700 Subject: [PATCH 093/142] Tambah Silit #eh sitik --- App/Classes/Abstracts/ResponseGeneratorAbstract.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php index 392160a..ca3cceb 100644 --- a/App/Classes/Abstracts/ResponseGeneratorAbstract.php +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -43,7 +43,7 @@ abstract class ResponseGeneratorAbstract /** * @var int */ - protected $statusCode; + protected $statusCode = 200; /** * @var int From b216e61fcc96e5b643fcebe78a62d62a1014955f Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 13:32:32 +0700 Subject: [PATCH 094/142] Nah iki tambahane --- App/Classes/ReponseGenerator/Text.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 App/Classes/ReponseGenerator/Text.php diff --git a/App/Classes/ReponseGenerator/Text.php b/App/Classes/ReponseGenerator/Text.php new file mode 100644 index 0000000..0b00e54 --- /dev/null +++ b/App/Classes/ReponseGenerator/Text.php @@ -0,0 +1,21 @@ +setMimeType('text/plain'); + } +} From 4f4a8cb822bfc7a7f12dcc787bfad1290eb6d5be Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 13:32:47 +0700 Subject: [PATCH 095/142] Iki yo Tambahane pisan --- App/Classes/ReponseGenerator/Html.php | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 App/Classes/ReponseGenerator/Html.php diff --git a/App/Classes/ReponseGenerator/Html.php b/App/Classes/ReponseGenerator/Html.php new file mode 100644 index 0000000..cd52035 --- /dev/null +++ b/App/Classes/ReponseGenerator/Html.php @@ -0,0 +1,39 @@ +setMimeType('text/html'); + } + + /** + * {@inheritdoc} + */ + public function serve(): ResponseInterface + { + $body = $this->getResponse()->getBody(); + $data = $this->getData(); + settype($data, 'string'); + $body->write($data); + + return $this + ->getResponse() + ->withBody($body) + ->withStatus($this->getStatusCode()) + ->withHeader('Content-Type', $this->getContentType()); + } +} From 0336fdd21055dc2927875a151fc8c066a8acc294 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 13:36:35 +0700 Subject: [PATCH 096/142] Jangkreeeeeeeeeeeeeeeeeek --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index acc16b7..2961402 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PENTAGONAL PROJECT -[![Build Status](https://travis-ci.org/PentagonalProject/ProjectSeventh.svg?branch=development)](https://travis-ci.org/PentagonalProject/ProjectSeventh) +[![Build Status](https://api.travis-ci.org/PentagonalProject/ProjectSeventh.svg?branch=development)](https://travis-ci.org/PentagonalProject/ProjectSeventh) --- From 1c48c3bba6f9ee055757e230166af41f508b1714 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 14:09:45 +0700 Subject: [PATCH 097/142] Biar Varokah --- site_apache.conf.example | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/site_apache.conf.example b/site_apache.conf.example index cc6c664..8dc4b8a 100644 --- a/site_apache.conf.example +++ b/site_apache.conf.example @@ -19,3 +19,43 @@ Require all granted + +# SSL Config +# Check If SSL Module Loaded (optional) + + # 443 is common https port + + # Domain Name / Server + ServerName domain.cug + + # Server Aliasing + ServerAlias domain.cug www.domain.cug + + # Document Index Root Public / Symlink to path + DocumentRoot /path/to/public + + # Email For Server Admin + ServerAdmin admin@domain.cug + + # enable SSL Engine + SSLEngine on + + # disable verify client + SSLVerifyClient none + + # ca / root chain certificate if not use self signed + SSLCACertificateFile /path/to/ca.crt + SSLCertificateFile /path/to/certificate.crt + SSLCertificateKeyFile /path/to/certificate.key + + # requires strong ciphers + SSLCipherSuite HIGH:!aNULL:!MD5 + + # Grant Of Directory + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + + \ No newline at end of file From 1a33283c4e4102e52a2591213716863478cfb41d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 14:10:00 +0700 Subject: [PATCH 098/142] Biar Kimcil Datang --- site_nginx.conf.example | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/site_nginx.conf.example b/site_nginx.conf.example index 23a960f..0d05091 100644 --- a/site_nginx.conf.example +++ b/site_nginx.conf.example @@ -3,18 +3,28 @@ server { # port listen 80; + # If use SSL & Want To use Multi Port Listen + + # listen 443 ssl; + # ssl on; + # certificate must be contain bundle to allow browser validate + # ssl_certificate /path/to/certificate.crt + # ssl_certificate_key /path/to/certificate.key + # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + # ssl_ciphers HIGH:!aNULL:!MD5; + # host - server_name domain.cug; + server_name domain.cug www.domain.cug; - # indexing - index index.php; + # indexing - order index.php first and then index.html & index.htm + index index.php index.html index.htm; # root path for public root /path/to/public; # Disable Logging for error - access_log /dev/null; - error_log /dev/null; + # access_log /dev/null; + # error_log /dev/null; # Query File Indexing location / { @@ -24,6 +34,10 @@ server { # NGinX Worker location ~ \.php { try_files $uri = 404; + + # try below to handle all 404 not found with script + # try_files $uri /index.php$is_args$args; + # Fast CGI fastcgi_split_path_info ^(.+\.php)(/.+)$; include fastcgi_params; @@ -32,6 +46,7 @@ server { fastcgi_index index.php; # listen for cgi param port + # port for cgi params has followed of fast cgi config fastcgi_pass 127.0.0.1:9000; } } From 8105203d04b3f0081d26f954d4a7ba17336c84b6 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 16:25:27 +0700 Subject: [PATCH 099/142] Komit saja semuaaaaaaaaaaaaaa!!!!!!!!!!!!!! Jancok --- App/Containers/Log.php | 10 ++++-- App/Includes/Constant.php | 18 +++++++++-- App/Includes/Helper.php | 67 +++++++++++++++++++++++++++++++++++++++ Config/Config.php | 9 ++++-- Config/Example.Config.php | 9 ++++-- public/index.php | 2 +- 6 files changed, 105 insertions(+), 10 deletions(-) diff --git a/App/Containers/Log.php b/App/Containers/Log.php index e0bf043..444c338 100644 --- a/App/Containers/Log.php +++ b/App/Containers/Log.php @@ -26,13 +26,15 @@ $type = is_int($config['environment[log]']) ? $config['environment[log]'] : ($config['environment[debug]'] - ? Logger::DEBUG + ? LOG_MODE_DEFAULT : Logger::WARNING ); + $logName = $config['environment[log_name]']; - if (!is_string($logName)) { - $logName = 'log.log'; + if (!$logName || !is_string($logName) || trim($logName) == '') { + $logName = getDefaultLogNameByCode($type, 'logs.log'); } + $logName = str_replace( [ '/', @@ -41,7 +43,9 @@ '_', $logName ); + $config['environment[log_name]'] = $logName; + /** * @var Application $app */ diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index 405e2e3..4dcdb1b 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -82,7 +82,21 @@ define('HOOK_HANDLER_CACHE_DRIVER', 'Handler:Cache:Driver'); define('HOOK_HANDLER_CACHE_CONFIG', 'Handler:Cache:Config'); -/* GLOBAL CONSTANT +/* GLOBAL CONSTANT LOG MODE * ----------------------------- */ -define('DEFAULT_LOG_NAME', 'logs.log'); +/** + * @see \Monolog\Logger + */ +define('LOG_MODE_ALERT', \Monolog\Logger::ALERT); // int 550 +define('LOG_MODE_CRITICAL', \Monolog\Logger::CRITICAL); // int 500 +define('LOG_MODE_DEBUG', \Monolog\Logger::DEBUG); // int 100 +define('LOG_MODE_EMERGENCY', \Monolog\Logger::EMERGENCY); // int 600 +define('LOG_MODE_ERROR', \Monolog\Logger::ERROR); // int 400 +define('LOG_MODE_INFO', \Monolog\Logger::INFO); // int 200 +define('LOG_MODE_NOTICE', \Monolog\Logger::NOTICE); // int 250 +define('LOG_MODE_WARNING', \Monolog\Logger::WARNING); // int 300 +define('LOG_MODE_DEFAULT', \Monolog\Logger::NOTICE); // int 250 + +/* GLOBAL CONSTANT + * ----------------------------- */ diff --git a/App/Includes/Helper.php b/App/Includes/Helper.php index 942d0b3..9550f2d 100644 --- a/App/Includes/Helper.php +++ b/App/Includes/Helper.php @@ -158,3 +158,70 @@ function isMobile() : bool return false; } + +/** + * Get Alias Log Level + * + * @param int $code + * @return int if no match between code will be return int 0 + */ +function getAliasLogLevel(int $code) : int +{ + switch ($code) { + case E_NOTICE: + case E_USER_NOTICE: + case E_DEPRECATED: + case E_USER_DEPRECATED: + return \Monolog\Logger::NOTICE; + case E_ERROR: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + return \Monolog\Logger::ERROR; + case E_WARNING: + case E_USER_WARNING: + case E_COMPILE_WARNING: + return \Monolog\Logger::WARNING; + case E_ALL: + return \Monolog\Logger::DEBUG; + } + + return 0; +} + +/** + * Get Default Log Name By Code + * + * @param int $code + * @param string $default + * @return string + */ +function getDefaultLogNameByCode($code, string $default = 'logs.log') : string +{ + $code = is_numeric($code) && !is_float($code) + ? abs($code) + : $code; + if (!is_int($code)) { + return $default; + } + + switch (getAliasLogLevel($code)) { + case \Monolog\Logger::NOTICE: + return 'notice.log'; + case \Monolog\Logger::ERROR: + return 'error.log'; + case \Monolog\Logger::WARNING: + return 'warning.log'; + case \Monolog\Logger::INFO: + return 'info.log'; + case \Monolog\Logger::DEBUG: + return 'debug.log'; + case \Monolog\Logger::EMERGENCY: + return 'emergency.log'; + case \Monolog\Logger::CRITICAL: + return 'critical.log'; + case \Monolog\Logger::ALERT; + return 'alert.log'; + } + + return $default; +} diff --git a/Config/Config.php b/Config/Config.php index 71dd3cb..6aae84a 100644 --- a/Config/Config.php +++ b/Config/Config.php @@ -25,11 +25,16 @@ 'collate' => 'utf8_unicode_ci', ], 'environment' => [ + // beware debug log will be make your disk full, use this for dev only 'debug' => true, + // set Notice for log + 'log' => LOG_MODE_NOTICE, + // show error verbose 'error' => true, - 'log' => true, // logs.log if there / or \ will be convert to underscore - 'log_name' => DEFAULT_LOG_NAME, + // log placed under directory[storage]/logs (Default 'Storage/logs') + // and set null or empty value to make log automatically set by log level + 'log_name' => null, ], 'cache' => [ // driver name diff --git a/Config/Example.Config.php b/Config/Example.Config.php index 71dd3cb..6aae84a 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -25,11 +25,16 @@ 'collate' => 'utf8_unicode_ci', ], 'environment' => [ + // beware debug log will be make your disk full, use this for dev only 'debug' => true, + // set Notice for log + 'log' => LOG_MODE_NOTICE, + // show error verbose 'error' => true, - 'log' => true, // logs.log if there / or \ will be convert to underscore - 'log_name' => DEFAULT_LOG_NAME, + // log placed under directory[storage]/logs (Default 'Storage/logs') + // and set null or empty value to make log automatically set by log level + 'log_name' => null, ], 'cache' => [ // driver name diff --git a/public/index.php b/public/index.php index a9c884e..ca13e80 100644 --- a/public/index.php +++ b/public/index.php @@ -107,7 +107,7 @@ // Require Composer Autoload require __DIR__ . '/../vendor/autoload.php'; // if the composer that must not ../App/FunctionIncludes.php -// try to includes once +// try to includes once (beware FunctionsIncludes.php must be load after vendor loaded) require_once __DIR__ .'/../App/FunctionsIncludes.php'; return (new PentagonalProject\ProjectSeventh\Application()) ->process((array) require __DIR__ . '/../Config/Config.php'); From 4456cb8e5fb8edef831247e93b120adff610cbb8 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 25 May 2017 18:04:20 +0700 Subject: [PATCH 100/142] Jaran dobol --- App/Includes/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Includes/Helper.php b/App/Includes/Helper.php index 9550f2d..7d6f281 100644 --- a/App/Includes/Helper.php +++ b/App/Includes/Helper.php @@ -219,7 +219,7 @@ function getDefaultLogNameByCode($code, string $default = 'logs.log') : string return 'emergency.log'; case \Monolog\Logger::CRITICAL: return 'critical.log'; - case \Monolog\Logger::ALERT; + case \Monolog\Logger::ALERT: return 'alert.log'; } From 3ae8cf7104be2318e4f1ca39ae3ec76ca2fa792d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 26 May 2017 16:09:01 +0700 Subject: [PATCH 101/142] Jemboooot --- INSTALL.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index ece424a..430d523 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -34,6 +34,8 @@ return (new PentagonalProject\ProjectSeventh\Application()) ->process((array) require __DIR__. '/../Config/Config.php'); ``` +## + with ``` @@ -43,6 +45,71 @@ return (new PentagonalProject\ProjectSeventh\Application()) Just change require Configuration file of `Example.Config.php`, and `Configuration File` must be as contains array return. + +## + +Or you can fill config inside index.php on process + +``` +return (new PentagonalProject\ProjectSeventh\Application()) + ->process([ + 'directory' => [ + ], + 'database' => [ + 'host' => 'db_host', + 'user' => 'db_user', + 'password' => 'db_pass', + 'name' => 'db_name', + 'port' => 3306, + 'driver' => 'mysql', + 'charset' => 'utf8', + 'collate' => 'utf8_unicode_ci', + ], + 'environment' => [ + 'debug' => false, + 'log' => LOG_MODE_NOTICE, + 'error' => true, + 'log_name' => null, + ], + 'cache' => [ + 'driver' => 'driverName', + /** + * @see \phpFastCache\CacheManager::getDefaultConfig() + */ + 'config' => [ + 'securityKey' => 'auto', + 'ignoreSymfonyNotice' => false, + 'defaultTtl' => 900, + 'htaccess' => true, + 'default_chmod' => 0777, + 'path' => '', + 'fallback' => false, + 'limited_memory_each_object' => 4096, + 'compress_data' => false, + ] + ], + 'session' => [ + 'name' => null, + 'save_path' => null, + // values of cookie params + 'path' => '/', + 'lifetime' => 0, + 'domain' => null, + 'httponly' => null, + 'secure' => null, + ], + // auto loading on separate loaded init + 'autoload' => [ + 'middleware' => [], + 'routes' => [ + // example Route + '/Path/To/RouteFile.php' + ], + ] + ]); +``` + + ### Library Install Use composer to install, go to script directory and run: From bd8477cfb49f20e842f5bdffcfbb660db3e7bee7 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 26 May 2017 16:09:11 +0700 Subject: [PATCH 102/142] Kontoooll --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2961402..e673cfc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PENTAGONAL PROJECT +## KIM CHILL - KEY POLAND - KART CHEER AND [![Build Status](https://api.travis-ci.org/PentagonalProject/ProjectSeventh.svg?branch=development)](https://travis-ci.org/PentagonalProject/ProjectSeventh) From 61db8e7997229ec1113df290f6101b2d63f77038 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 26 May 2017 16:19:39 +0700 Subject: [PATCH 103/142] Bedebah --- INSTALL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index 430d523..909c064 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -64,6 +64,8 @@ return (new PentagonalProject\ProjectSeventh\Application()) 'driver' => 'mysql', 'charset' => 'utf8', 'collate' => 'utf8_unicode_ci', + // database prefix + 'prefix' => 'db_', ], 'environment' => [ 'debug' => false, From 067fe101dcf043860f39951f0d6e41d2d32fde42 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 26 May 2017 16:19:55 +0700 Subject: [PATCH 104/142] Alaaaaaaaaaaaaaa jembuuut --- Config/Config.php | 2 ++ Config/Example.Config.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Config/Config.php b/Config/Config.php index 6aae84a..ea2b82b 100644 --- a/Config/Config.php +++ b/Config/Config.php @@ -23,6 +23,8 @@ 'driver' => 'mysql', 'charset' => 'utf8', 'collate' => 'utf8_unicode_ci', + // database prefix + 'prefix' => 'db_', ], 'environment' => [ // beware debug log will be make your disk full, use this for dev only diff --git a/Config/Example.Config.php b/Config/Example.Config.php index 6aae84a..ea2b82b 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -23,6 +23,8 @@ 'driver' => 'mysql', 'charset' => 'utf8', 'collate' => 'utf8_unicode_ci', + // database prefix + 'prefix' => 'db_', ], 'environment' => [ // beware debug log will be make your disk full, use this for dev only From fadecdfd202dc9cda6885f4cecf94bb902a4ddc9 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sun, 28 May 2017 13:46:37 +0700 Subject: [PATCH 105/142] Masalah Buat elohhh elohhh elohh!!!?! --- App/Containers/Config.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/App/Containers/Config.php b/App/Containers/Config.php index 6139d28..3db11fe 100644 --- a/App/Containers/Config.php +++ b/App/Containers/Config.php @@ -15,6 +15,7 @@ use PentagonalProject\ProjectSeventh\Hook; use phpFastCache\CacheManager; use Slim\Container; + use Slim\Http\Response; if (!isset($this) || ! $this instanceof Arguments) { return; @@ -35,6 +36,20 @@ : '1.1'; return function (Container $container) use (&$config) : Config { + // override Server Protocol + $container['settings']['httpVersion'] = $config['httpVersion']; + /** @var Response $response */ + $response = clone $container[CONTAINER_RESPONSE]; + if ($response->getProtocolVersion() != $config['httpVersion']) { + unset($container[CONTAINER_RESPONSE]); + try { + $newResponse = $response->withProtocolVersion($config['httpVersion']); + $container[CONTAINER_RESPONSE] = $newResponse; + } catch (\Exception $exception) { + $container[CONTAINER_RESPONSE] = $response; + } + } + /** @var Application $application */ $application = $container[CONTAINER_APPLICATION]; $config['directory'] = array_merge([ From 2f4bc617e784b292885e2bfc8a818563dea0e982 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:09:51 +0700 Subject: [PATCH 106/142] mmmm mm mmmmmm --- Config/Config.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Config/Config.php b/Config/Config.php index ea2b82b..cd62a49 100644 --- a/Config/Config.php +++ b/Config/Config.php @@ -7,9 +7,9 @@ */ return [ 'directory' => [ - 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', - 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', + 'storage' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage', + 'module' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Extensions', // load from example // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', From f34f56e2169aec87c2ff499edaff88824ccab916 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:10:04 +0700 Subject: [PATCH 107/142] silitku gatel --- Config/Example.Config.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Config/Example.Config.php b/Config/Example.Config.php index ea2b82b..cd62a49 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -7,9 +7,9 @@ */ return [ 'directory' => [ - 'storage' => __DIR__ . DIRECTORY_SEPARATOR . 'Storage', - 'module' => __DIR__ . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => __DIR__ . DIRECTORY_SEPARATOR . 'Extensions', + 'storage' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage', + 'module' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Modules', + 'extension' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Extensions', // load from example // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', From 9e1b99ec2177805cd65c1d29396e744e2a8473a0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:15:18 +0700 Subject: [PATCH 108/142] Anuku gatel --- Config/Example.Config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/Example.Config.php b/Config/Example.Config.php index cd62a49..60b14d3 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -40,7 +40,7 @@ ], 'cache' => [ // driver name - 'driver' => 'auto', + 'driver' => 'redis', /** * @see \phpFastCache\CacheManager::getDefaultConfig() */ @@ -50,7 +50,7 @@ 'defaultTtl' => 900, 'htaccess' => true, 'default_chmod' => 0777, - 'path' => '', + 'path' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR . 'Cache', 'fallback' => false, 'limited_memory_each_object' => 4096, 'compress_data' => false, From 15ce34eb2377690ec39a20323940a61e15eaf857 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:15:28 +0700 Subject: [PATCH 109/142] Gatle apane? --- Storage/Cache/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Storage/Cache/.gitkeep diff --git a/Storage/Cache/.gitkeep b/Storage/Cache/.gitkeep new file mode 100644 index 0000000..e69de29 From 81ab506e3ffe2bac1a9c343985c36ef7b5efd829 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:15:41 +0700 Subject: [PATCH 110/142] ulu ulu ulu --- Config/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/Config.php b/Config/Config.php index cd62a49..f41224a 100644 --- a/Config/Config.php +++ b/Config/Config.php @@ -50,7 +50,7 @@ 'defaultTtl' => 900, 'htaccess' => true, 'default_chmod' => 0777, - 'path' => '', + 'path' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR . 'Cache', 'fallback' => false, 'limited_memory_each_object' => 4096, 'compress_data' => false, From 28d13239594b17a59f18e618e1c69d3b14cfabd2 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:16:56 +0700 Subject: [PATCH 111/142] ulu ulu ulu --- Config/Config.php | 2 +- Config/Example.Config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/Config.php b/Config/Config.php index f41224a..60b14d3 100644 --- a/Config/Config.php +++ b/Config/Config.php @@ -40,7 +40,7 @@ ], 'cache' => [ // driver name - 'driver' => 'auto', + 'driver' => 'redis', /** * @see \phpFastCache\CacheManager::getDefaultConfig() */ diff --git a/Config/Example.Config.php b/Config/Example.Config.php index 60b14d3..f41224a 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -40,7 +40,7 @@ ], 'cache' => [ // driver name - 'driver' => 'redis', + 'driver' => 'auto', /** * @see \phpFastCache\CacheManager::getDefaultConfig() */ From 71bbb591a069799ea31a7cc537db0f7e07f93b90 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:19:37 +0700 Subject: [PATCH 112/142] Nambah Cug --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5681524..57fbed4 100644 --- a/.gitignore +++ b/.gitignore @@ -177,4 +177,5 @@ vendor /Modules/*/ /Extensions/*/ /Config/Config.php +/Config/Routes From 60623d8f3ed4c84212001842de4cd8c52f5976c8 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 16:24:09 +0700 Subject: [PATCH 113/142] Remove ignored files --- Config/Config.php | 80 ----------------------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 Config/Config.php diff --git a/Config/Config.php b/Config/Config.php deleted file mode 100644 index 60b14d3..0000000 --- a/Config/Config.php +++ /dev/null @@ -1,80 +0,0 @@ - [ - 'storage' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage', - 'module' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Modules', - 'extension' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Extensions', - // load from example - // 'extension' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Extensions', - // 'module' => __DIR__ . DIRECTORY_SEPARATOR . '_example/Modules', - ], - 'database' => [ - 'host' => 'localhost', - 'user' => '', - 'password' => '', - 'name' => '', - 'port' => 3306, - 'driver' => 'mysql', - 'charset' => 'utf8', - 'collate' => 'utf8_unicode_ci', - // database prefix - 'prefix' => 'db_', - ], - 'environment' => [ - // beware debug log will be make your disk full, use this for dev only - 'debug' => true, - // set Notice for log - 'log' => LOG_MODE_NOTICE, - // show error verbose - 'error' => true, - // logs.log if there / or \ will be convert to underscore - // log placed under directory[storage]/logs (Default 'Storage/logs') - // and set null or empty value to make log automatically set by log level - 'log_name' => null, - ], - 'cache' => [ - // driver name - 'driver' => 'redis', - /** - * @see \phpFastCache\CacheManager::getDefaultConfig() - */ - 'config' => [ - 'securityKey' => 'auto', - 'ignoreSymfonyNotice' => false, - 'defaultTtl' => 900, - 'htaccess' => true, - 'default_chmod' => 0777, - 'path' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR . 'Cache', - 'fallback' => false, - 'limited_memory_each_object' => 4096, - 'compress_data' => false, - ] - ], - 'session' => [ - 'name' => null, - 'save_path' => null, - // values of cookie params - 'path' => '/', - 'lifetime' => 0, - 'domain' => null, - 'httponly' => null, - 'secure' => null, - ], - // auto loading on separate loaded init - 'autoload' => [ - // load middle ware end of middle ware init - 'middleware' => [ - ], - // load on routes - 'routes' => [ - // example Route - __DIR__ . '/Example.Routes.php' - ], - ], -]; From ee86feda65917ca4631db24a7ef13d928933c106 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 18:13:31 +0700 Subject: [PATCH 114/142] Yes Buko!! --- App/Classes/AutoLoaderClass.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/App/Classes/AutoLoaderClass.php b/App/Classes/AutoLoaderClass.php index efe12b1..c7465a9 100644 --- a/App/Classes/AutoLoaderClass.php +++ b/App/Classes/AutoLoaderClass.php @@ -38,6 +38,11 @@ final class AutoLoaderClass */ protected $baseDirectory = []; + /** + * @var array + */ + protected $missedClass = []; + /** * AutoLoaderClass constructor. * @param string $nameSpace @@ -139,6 +144,7 @@ public function load(string $class) : bool if (!is_string($class)) { return false; } + if ($file = $this->findFileFor($class)) { // prevent multiple call of class if (class_exists($class)) { @@ -149,6 +155,12 @@ public function load(string $class) : bool return true; } + $class = ltrim($class, '\\'); + // counting missed + $this->missedClass[$class] = isset($this->missedClass[$class]) + ? $this->missedClass[$class]++ + : 1; + return false; } From f809fb97582b9d79929a51cbf27725cc8ffe46a5 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 18:14:04 +0700 Subject: [PATCH 115/142] Biar berkaaahhh, Sesuatu ya?! --- App/Classes/Abstracts/BaseRouteGroup.php | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 App/Classes/Abstracts/BaseRouteGroup.php diff --git a/App/Classes/Abstracts/BaseRouteGroup.php b/App/Classes/Abstracts/BaseRouteGroup.php new file mode 100644 index 0000000..3b7dd3f --- /dev/null +++ b/App/Classes/Abstracts/BaseRouteGroup.php @@ -0,0 +1,33 @@ +container = $container; + } + + /** + * Invoker For Route Group + * + * @return mixed + */ + abstract public function __invoke(); +} From d8d96a7b39b796cf78bfadbbefa68dbb991ed4ad Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 18:14:28 +0700 Subject: [PATCH 116/142] Aku cowok Ganteng!!! Mau Gak sama aku? --- App/Classes/Abstracts/BaseRouteSegment.php | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 App/Classes/Abstracts/BaseRouteSegment.php diff --git a/App/Classes/Abstracts/BaseRouteSegment.php b/App/Classes/Abstracts/BaseRouteSegment.php new file mode 100644 index 0000000..2077edd --- /dev/null +++ b/App/Classes/Abstracts/BaseRouteSegment.php @@ -0,0 +1,42 @@ +container = $container; + } + + /** + * Base Invoker + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @param array $params slim routes parameters + * @return ResponseInterface + */ + abstract public function __invoke( + RequestInterface $request, + ResponseInterface $response, + array $params = [] + ) : ResponseInterface; +} From 605d161f597719ca6b8c323ea0ee1ce1893fcb0d Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 18:14:38 +0700 Subject: [PATCH 117/142] Hmmm sudah kuduga --- App/Classes/ComposerLoaderPSR4.php | 118 +++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 App/Classes/ComposerLoaderPSR4.php diff --git a/App/Classes/ComposerLoaderPSR4.php b/App/Classes/ComposerLoaderPSR4.php new file mode 100644 index 0000000..b38946b --- /dev/null +++ b/App/Classes/ComposerLoaderPSR4.php @@ -0,0 +1,118 @@ +classLoader = $classLoader ?: new ClassLoader(); + } + + /** + * Add PSR4 + * + * @param array $nameSpacePath key as NameSpace & value as paths + * @return ComposerLoaderPSR4 + * @throws InvalidArgumentException + */ + public function addArray(array $nameSpacePath) : ComposerLoaderPSR4 + { + foreach ($nameSpacePath as $nameSpace => $paths) { + // if there was has a slash fix to backslash + if (strpos($nameSpace, '/') !== false) { + $nameSpace = preg_replace('(\\\|\/)', '\\', $nameSpace); + } + // Trim & add su-fix back slash that make Name Space Valid + $nameSpace = trim($nameSpace, '\\') . '\\'; + if (!is_string($paths) && ! is_array($paths)) { + throw new InvalidArgumentException( + sprintf( + "Invalid paths for Name Space %s. Paths must be as a string or array.", + $nameSpace + ), + E_USER_ERROR + ); + } elseif (is_array($paths)) { + foreach ($paths as $keyPath => $path) { + if (!is_string($path)) { + throw new InvalidArgumentException( + sprintf( + "Invalid path value for Name Space %s in key %s. Path must be as a string.", + $nameSpace, + $keyPath + ), + E_USER_ERROR + ); + } + } + } + + $this->classLoader->addPsr4( + $nameSpace, + (array) $paths + ); + } + + return $this; + } + + /** + * Add Path + * + * @param string $prefix + * @param string|array $paths + * @return ComposerLoaderPSR4 + */ + public function add(string $prefix, $paths) : ComposerLoaderPSR4 + { + return $this->addArray([$prefix => $paths]); + } + + /** + * Register Auto loader + * + * @param bool $prepend + */ + public function register($prepend = false) + { + $this->classLoader->register($prepend); + } + + /** + * UnRegister The Loader + */ + public function unRegister() + { + $this->classLoader->unregister(); + } + + /** + * @param array $path + * @param ClassLoader|null $classLoader + * @return ComposerLoaderPSR4 + */ + public static function create(array $path, ClassLoader $classLoader = null) : ComposerLoaderPSR4 + { + $object = new static($classLoader ?: new ClassLoader()); + $object->addArray($path); + return $object; + } +} From 5b8cc9e2ecb03cdf41ab541eeb1fa12797092838 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Thu, 1 Jun 2017 18:14:54 +0700 Subject: [PATCH 118/142] hmmm jembutnya itu lohhhh ....!!!?! --- App/Classes/Interfaces/BaseRouteInterface.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 App/Classes/Interfaces/BaseRouteInterface.php diff --git a/App/Classes/Interfaces/BaseRouteInterface.php b/App/Classes/Interfaces/BaseRouteInterface.php new file mode 100644 index 0000000..b4886d0 --- /dev/null +++ b/App/Classes/Interfaces/BaseRouteInterface.php @@ -0,0 +1,13 @@ + Date: Fri, 2 Jun 2017 03:44:23 +0700 Subject: [PATCH 119/142] Nambah Bojo Lak Penak a --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 57fbed4..e1bb4c3 100644 --- a/.gitignore +++ b/.gitignore @@ -178,4 +178,4 @@ vendor /Extensions/*/ /Config/Config.php /Config/Routes - +/Private From 6866fe714c8a115ea22649d2becec600c0cf80c1 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:44:51 +0700 Subject: [PATCH 120/142] Mbenakno COK! --- App/Classes/ReponseGenerator/Html.php | 14 ++++++++++++-- App/Classes/ReponseGenerator/Json.php | 11 ++++++++++- App/Classes/ReponseGenerator/Xml.php | 15 +++++++++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/App/Classes/ReponseGenerator/Html.php b/App/Classes/ReponseGenerator/Html.php index cd52035..3ca985a 100644 --- a/App/Classes/ReponseGenerator/Html.php +++ b/App/Classes/ReponseGenerator/Html.php @@ -4,6 +4,7 @@ use PentagonalProject\ProjectSeventh\Abstracts\ResponseGeneratorAbstract; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Slim\Http\Body; /** * Class Html @@ -25,15 +26,24 @@ public function __construct(RequestInterface $request, ResponseInterface $respon */ public function serve(): ResponseInterface { - $body = $this->getResponse()->getBody(); + $body = new Body(fopen('php://temp', 'r+')); $data = $this->getData(); settype($data, 'string'); $body->write($data); - return $this + $response = $this ->getResponse() ->withBody($body) ->withStatus($this->getStatusCode()) ->withHeader('Content-Type', $this->getContentType()); + + if ($response->hasHeader('Content-Length')) { + $response = $response->withHeader( + 'Content-Length', + $response->getBody()->getSize() + ); + } + + return $response; } } diff --git a/App/Classes/ReponseGenerator/Json.php b/App/Classes/ReponseGenerator/Json.php index 9549b8e..336badd 100644 --- a/App/Classes/ReponseGenerator/Json.php +++ b/App/Classes/ReponseGenerator/Json.php @@ -28,10 +28,19 @@ public function serve(): ResponseInterface { /** @var Response $response */ $response = $this->getResponse(); - return $response->withJson( + $response = $response->withJson( $this->getData(), $this->getStatusCode(), $this->getEncoding() ); + + if ($response->hasHeader('Content-Length')) { + $response = $response->withHeader( + 'Content-Length', + $response->getBody()->getSize() + ); + } + + return $response; } } diff --git a/App/Classes/ReponseGenerator/Xml.php b/App/Classes/ReponseGenerator/Xml.php index 283d902..cc64eef 100644 --- a/App/Classes/ReponseGenerator/Xml.php +++ b/App/Classes/ReponseGenerator/Xml.php @@ -5,6 +5,8 @@ use PentagonalProject\ProjectSeventh\Utilities\XmlBuilderTrait; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Slim\Http\Body; +use Slim\Http\Response; /** * Class Xml @@ -31,8 +33,10 @@ public function __construct(RequestInterface $request, ResponseInterface $respon */ public function serve(): ResponseInterface { - $body = $this->getResponse()->getBody(); - $body->write($this->generateXML($this->getCharset(), (array) $this->getData())); + $body = new Body(fopen('php://temp', 'r+')); + $body->write( + $this->generateXML($this->getCharset(), (array) $this->getData()) + ); $response = $this ->getResponse() ->withBody($body) @@ -40,6 +44,13 @@ public function serve(): ResponseInterface if ($this->getStatusCode()) { $response = $response->withStatus($this->getStatusCode()); } + /** @var Response $response */ + if ($response->hasHeader('Content-Length')) { + $response = $response->withHeader( + 'Content-Length', + $response->getBody()->getSize() + ); + } return $response; } From e28107c8f7a1380b219230021c203398c40d7567 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:45:20 +0700 Subject: [PATCH 121/142] Icik icik ehem --- App/Classes/Abstracts/ResponseGeneratorAbstract.php | 1 + App/Classes/Application.php | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/App/Classes/Abstracts/ResponseGeneratorAbstract.php b/App/Classes/Abstracts/ResponseGeneratorAbstract.php index ca3cceb..093e00a 100644 --- a/App/Classes/Abstracts/ResponseGeneratorAbstract.php +++ b/App/Classes/Abstracts/ResponseGeneratorAbstract.php @@ -59,6 +59,7 @@ public function __construct(RequestInterface $request, ResponseInterface $respon { $this->setRequest($request); $this->setResponse($response); + $this->setStatusCode($response->getStatusCode()); } /** diff --git a/App/Classes/Application.php b/App/Classes/Application.php index ea544c1..ecefc6d 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -5,6 +5,7 @@ use Apatis\Exceptions\InvalidArgumentException; use Apatis\Exceptions\LogicException; use PentagonalProject\ProjectSeventh\Exceptions\FileNotFoundException; +use Psr\Http\Message\ResponseInterface; use Slim\App; /** @@ -281,9 +282,9 @@ public function &getSlim() * Run The application * * @param array $config - * @return Application + * @return ResponseInterface */ - public function process(array $config) + public function process(array $config) : ResponseInterface { if ($this->hasRun) { throw new LogicException( @@ -301,8 +302,8 @@ public function process(array $config) $this->includeScope($this->getComponentDirectory('ApplicationMiddleware.php')); // determine & call routes $this->includeScope($this->getComponentDirectory('ApplicationRoutes.php')); - $this->slim->run(); - return $this; + + return $this->slim->run(true); } /** From 66adba33c9e11f0bc5a66052dd8b6bff56d3dad8 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:45:38 +0700 Subject: [PATCH 122/142] Biar Ganteng Maksimal --- INSTALL.md | 153 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 64 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 909c064..73d71c9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -29,18 +29,35 @@ If you want to change structure of `index.php` to your another place / current s just move the `index.php` & `.htaccess` file. And open `index.php` and then change. -``` -return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require __DIR__. '/../Config/Config.php'); +```php +process((array) require __DIR__. '/../Config/Config.php'); +$app->getSlim()->respond($response); ``` ## with -``` -return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require '/path/to/your/Config.php'); +```php +process((array) require '/path/to/your/Config.php'); +$app->getSlim()->respond($response); ``` Just change require Configuration file of `Example.Config.php`, and `Configuration File` must be as contains array return. @@ -50,65 +67,73 @@ Just change require Configuration file of `Example.Config.php`, and `Configurati Or you can fill config inside index.php on process -``` -return (new PentagonalProject\ProjectSeventh\Application()) - ->process([ - 'directory' => [ - ], - 'database' => [ - 'host' => 'db_host', - 'user' => 'db_user', - 'password' => 'db_pass', - 'name' => 'db_name', - 'port' => 3306, - 'driver' => 'mysql', - 'charset' => 'utf8', - 'collate' => 'utf8_unicode_ci', - // database prefix - 'prefix' => 'db_', - ], - 'environment' => [ - 'debug' => false, - 'log' => LOG_MODE_NOTICE, - 'error' => true, - 'log_name' => null, - ], - 'cache' => [ - 'driver' => 'driverName', - /** - * @see \phpFastCache\CacheManager::getDefaultConfig() - */ - 'config' => [ - 'securityKey' => 'auto', - 'ignoreSymfonyNotice' => false, - 'defaultTtl' => 900, - 'htaccess' => true, - 'default_chmod' => 0777, - 'path' => '', - 'fallback' => false, - 'limited_memory_each_object' => 4096, - 'compress_data' => false, - ] - ], - 'session' => [ - 'name' => null, - 'save_path' => null, - // values of cookie params - 'path' => '/', - 'lifetime' => 0, - 'domain' => null, - 'httponly' => null, - 'secure' => null, - ], - // auto loading on separate loaded init - 'autoload' => [ - 'middleware' => [], - 'routes' => [ - // example Route - '/Path/To/RouteFile.php' - ], +```php +process([ + 'directory' => [ + ], + 'database' => [ + 'host' => 'db_host', + 'user' => 'db_user', + 'password' => 'db_pass', + 'name' => 'db_name', + 'port' => 3306, + 'driver' => 'mysql', + 'charset' => 'utf8', + 'collate' => 'utf8_unicode_ci', + // database prefix + 'prefix' => 'db_', + ], + 'environment' => [ + 'debug' => false, + 'log' => LOG_MODE_NOTICE, + 'error' => true, + 'log_name' => null, + ], + 'cache' => [ + 'driver' => 'driverName', + /** + * @see \phpFastCache\CacheManager::getDefaultConfig() + */ + 'config' => [ + 'securityKey' => 'auto', + 'ignoreSymfonyNotice' => false, + 'defaultTtl' => 900, + 'htaccess' => true, + 'default_chmod' => 0777, + 'path' => '', + 'fallback' => false, + 'limited_memory_each_object' => 4096, + 'compress_data' => false, ] - ]); + ], + 'session' => [ + 'name' => null, + 'save_path' => null, + // values of cookie params + 'path' => '/', + 'lifetime' => 0, + 'domain' => null, + 'httponly' => null, + 'secure' => null, + ], + // auto loading on separate loaded init + 'autoload' => [ + 'middleware' => [], + 'routes' => [ + // example Route + '/Path/To/RouteFile.php' + ], + ] +]); +$app->getSlim()->respond($response); ``` From fd21df659261b613628819d2a73245827d35af6e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:46:43 +0700 Subject: [PATCH 123/142] Kamu kamu kepo banget ih Mmuah --- public/index.php | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/public/index.php b/public/index.php index ca13e80..eb5422d 100644 --- a/public/index.php +++ b/public/index.php @@ -93,9 +93,9 @@ EOF; } - header("Content-Type: {$accept}", true, 200); $length = strlen($content); - header("Content-Length: {$length}", true, 200); + header("Content-Type: {$accept}", true, 500); + header("Content-Length: {$length}", true, 500); } else { $content = "\n(Error) {$content}\n\n"; } @@ -109,5 +109,26 @@ // if the composer that must not ../App/FunctionIncludes.php // try to includes once (beware FunctionsIncludes.php must be load after vendor loaded) require_once __DIR__ .'/../App/FunctionsIncludes.php'; -return (new PentagonalProject\ProjectSeventh\Application()) - ->process((array) require __DIR__ . '/../Config/Config.php'); +/** + * @var \PentagonalProject\ProjectSeventh\Application $app + */ +$app = new PentagonalProject\ProjectSeventh\Application(); +register_shutdown_function(function () { + print_r(error_get_last()); + exit; +}); + +/** + * @var \PentagonalProject\ProjectSeventh\Hook $hook + * @var \Psr\Http\Message\ResponseInterface $response + */ +$response = $app->process((array) require __DIR__ . '/../Config/Config.php'); +$hook = $app[CONTAINER_HOOK]; +$app + ->getSlim() + ->respond( + $hook->apply( + HOOK_HANDLER_RESPONSE, + $response + ) + ); From 68082de300347b7b318c651fb8e38153eab99edb Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:47:19 +0700 Subject: [PATCH 124/142] Bokong e arek iku sekseehh , suka suka suka deh --- App/Containers/Config.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/App/Containers/Config.php b/App/Containers/Config.php index 3db11fe..514611d 100644 --- a/App/Containers/Config.php +++ b/App/Containers/Config.php @@ -30,17 +30,24 @@ if (!is_array($config['directory'])) { $config['directory'] = []; } - $config['httpVersion'] = isset($_SERVER['SERVER_PROTOCOL']) + + // override Environment as Array + if (!isset($config['environment']) || !is_array($config['environment'])) { + $config['environment'] = []; + } + + // auto httpVersion + $config['environment']['httpVersion'] = isset($_SERVER['SERVER_PROTOCOL']) && strpos($_SERVER['SERVER_PROTOCOL'], '/') !== false ? explode('/', $_SERVER['SERVER_PROTOCOL'])[1] : '1.1'; return function (Container $container) use (&$config) : Config { // override Server Protocol - $container['settings']['httpVersion'] = $config['httpVersion']; + $container['settings']['httpVersion'] = $config['environment']['httpVersion']; /** @var Response $response */ $response = clone $container[CONTAINER_RESPONSE]; - if ($response->getProtocolVersion() != $config['httpVersion']) { + if ($response->getProtocolVersion() != $config['environment']['httpVersion']) { unset($container[CONTAINER_RESPONSE]); try { $newResponse = $response->withProtocolVersion($config['httpVersion']); @@ -49,7 +56,6 @@ $container[CONTAINER_RESPONSE] = $response; } } - /** @var Application $application */ $application = $container[CONTAINER_APPLICATION]; $config['directory'] = array_merge([ @@ -63,6 +69,7 @@ 'config' => CacheManager::getDefaultConfig() ]; } + if (!is_string($config['cache']['driver']) || trim($config['cache']['driver']) == '') { $config['cache']['driver'] = 'Auto'; } @@ -92,6 +99,14 @@ } $config['cache']['driver'] = $cacheDriver; $config['cache']['config'] = $cacheConfig; - return new Config($config); + $config = new Config($config); + /** + * Config Override + */ + $container['settings']['displayErrorDetails'] = (bool) $config['environment[error]']; + $container['settings']['addContentLengthHeader'] = ! isset($config['environment[addContentLengthHeader]']) + ? true + : (bool) $config['environment[addContentLengthHeader]']; + return $config; }; } From a98f8e6f327404115220ae8ab4c4b62fed611c70 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:47:33 +0700 Subject: [PATCH 125/142] ikue gedeee --- App/Components/ApplicationMiddleware.php | 209 ----------------------- App/Components/ApplicationSlimObject.php | 43 ++++- 2 files changed, 42 insertions(+), 210 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index f807d54..035f245 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -5,25 +5,12 @@ namespace { - use Apatis\Exceptions\RuntimeException; use PentagonalProject\ProjectSeventh\Application; use PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\Config; - use PentagonalProject\ProjectSeventh\Hook; - use PentagonalProject\ProjectSeventh\HttpHandler\PhpError; - use PentagonalProject\ProjectSeventh\HttpHandler\Error; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; - use Slim\CallableResolver; - use Slim\Container; - use Slim\Handlers\AbstractError; - use Slim\Handlers\AbstractHandler; - use Slim\Handlers\NotAllowed; - use Slim\Handlers\NotFound; - use Slim\Handlers\Strategies\RequestResponse; use Slim\Http\Uri; - use Slim\Interfaces\CallableResolverInterface; - use Slim\Interfaces\InvocationStrategyInterface; if (!isset($this) || ! $this instanceof Arguments) { return; @@ -65,201 +52,6 @@ ) { $request = $request->withUri($uri->withBasePath(dirname($uri->getBasePath()))); } - return $next($request, $response); - }); - - /** - * Middle Ware With Handler - */ - $slim->add(function (ServerRequestInterface $request, ResponseInterface $response, $next) { - if (!isset($this[CONTAINER_CALLABLE_RESOLVER])) { - /** - * Callable Resolver - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_CALLABLE_RESOLVER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $callableResolver = $hook->apply( - HOOK_HANDLER_CALLABLE_RESOLVER, - new CallableResolver($this), - $this - ); - if (!$callableResolver instanceof CallableResolverInterface) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Callable Resolver. Callable Resolver must be instance of %s", - CallableResolverInterface::class - ), - E_ERROR - ); - } - - return $callableResolver; - }; - } - - if (!isset($this[CONTAINER_FOUND_HANDLER])) { - /** - * Found Handler - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_FOUND_HANDLER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $callableResolver = $hook->apply( - HOOK_HANDLER_FOUND_RESPONSE, - new RequestResponse, - $this - ); - if (!$callableResolver instanceof InvocationStrategyInterface) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Found Handler. Found Handler must be instance of %s", - InvocationStrategyInterface::class - ), - E_ERROR - ); - } - - return $callableResolver; - }; - } - - if (!isset($this[CONTAINER_NOT_FOUND_HANDLER])) { - /** - * Not Found Handler - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_NOT_FOUND_HANDLER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $notFoundHandler = $hook->apply( - HOOK_HANDLER_ERROR_404, - new NotFound, - $this - ); - if (!$notFoundHandler instanceof AbstractHandler) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Not Found Handler. Not Found Handler must be instance of %s", - AbstractHandler::class - ), - E_ERROR - ); - } - - return $notFoundHandler; - }; - } - - /** - * Not Allowed Handler - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_NOT_ALLOWED_HANDLER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $notAllowedHandler = $hook->apply( - HOOK_HANDLER_ERROR_403, - new NotAllowed, - $this - ); - if (!$notAllowedHandler instanceof AbstractHandler) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Not Allowed Handler. Not Allowed Handler must be instance of %s", - AbstractHandler::class - ), - E_ERROR - ); - } - - return $notAllowedHandler; - }; - if (!isset($this[CONTAINER_ERROR_HANDLER])) { - /** - * Error Handler - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_ERROR_HANDLER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $errorHandler = $hook->apply( - HOOK_HANDLER_ERROR_500, - new Error( - $this->get('settings')['displayErrorDetails'], - $this[CONTAINER_APPLICATION] - ), - $this - ); - if (!$errorHandler instanceof AbstractError) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Error Handler. Error Handler must be instance of %s", - AbstractError::class - ), - E_ERROR - ); - } - - return $errorHandler; - }; - } - - if (!isset($this[CONTAINER_PHP_ERROR_HANDLER])) { - /** - * Php Error Handler - * - * @var $this Container - * @return AbstractHandler - */ - $this[CONTAINER_PHP_ERROR_HANDLER] = function () { - /** - * @var Hook $hook - */ - $hook = $this[CONTAINER_HOOK]; - $errorPhpHandler = $hook->apply( - HOOK_HANDLER_ERROR_PHP, - new PhpError( - $this->get('settings')['displayErrorDetails'], - $this[CONTAINER_APPLICATION] - ), - $this - ); - if (!$errorPhpHandler instanceof AbstractError) { - throw new RuntimeException( - sprintf( - "Invalid Hook for Php Error Handler. Php Error Handler must be instance of %s", - AbstractError::class - ), - E_ERROR - ); - } - - return $errorPhpHandler; - }; - } return $next($request, $response); }); @@ -267,7 +59,6 @@ /** * Includes Middleware auto load from config */ - /** * @var Config $config */ diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index 2368ad1..7bee722 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -14,7 +14,11 @@ use PentagonalProject\ProjectSeventh\Utilities\EmbeddedCollection; use Slim\App; use Slim\Container; + use Slim\Handlers\AbstractError; + use Slim\Handlers\AbstractHandler; use Slim\Http\Environment; + use Slim\Interfaces\CallableResolverInterface; + use Slim\Interfaces\InvocationStrategyInterface; if (!isset($this) || ! $this instanceof Arguments) { return; @@ -25,6 +29,7 @@ if (!$app instanceof Application) { return; } + /** * @return \Slim\App */ @@ -111,7 +116,43 @@ */ $application =& $container[CONTAINER_APPLICATION]; return $application->getSlim(); - } + }, + /** + * Callable Resolver + * + * @return CallableResolverInterface + */ + CONTAINER_CALLABLE_RESOLVER => $app->includeScope($app->getContainerDirectory('CallableResolver.php')), + /** + * Found Handler + * + * @return InvocationStrategyInterface + */ + CONTAINER_FOUND_HANDLER => $app->includeScope($app->getContainerDirectory('FoundHandler.php')), + /** + * Not Found Handler + * + * @return AbstractHandler + */ + CONTAINER_NOT_FOUND_HANDLER => $app->includeScope($app->getContainerDirectory('NotFoundHandler.php')), + /** + * Not Allowed Handler + * + * @return AbstractHandler + */ + CONTAINER_NOT_ALLOWED_HANDLER => $app->includeScope($app->getContainerDirectory('NotAllowedHandler.php')), + /** + * Error Handler + * + * @return AbstractError + */ + CONTAINER_ERROR_HANDLER => $app->includeScope($app->getContainerDirectory('ErrorHandler.php')), + /** + * Php Error Handler + * + * @return AbstractError + */ + CONTAINER_PHP_ERROR_HANDLER => $app->includeScope($app->getContainerDirectory('PhpErrorHandler.php')), ] ); } From d610db137f0b3a299f3f2ff26d971205d56d5769 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:48:01 +0700 Subject: [PATCH 126/142] Biar Tegang --- App/Includes/Constant.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index 4dcdb1b..ba3ecac 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -82,6 +82,8 @@ define('HOOK_HANDLER_CACHE_DRIVER', 'Handler:Cache:Driver'); define('HOOK_HANDLER_CACHE_CONFIG', 'Handler:Cache:Config'); +define('HOOK_HANDLER_RESPONSE', 'Handler:Response'); + /* GLOBAL CONSTANT LOG MODE * ----------------------------- */ From 2647e91e7ad2c42f8f77623abede9edba1c2886b Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 03:48:26 +0700 Subject: [PATCH 127/142] hmmmm senyumnya menggoda iman dan anunya menggoda imron --- App/Containers/CallableResolver.php | 46 ++++++++++++++++++++++++++ App/Containers/ErrorHandler.php | 49 ++++++++++++++++++++++++++++ App/Containers/FoundHandler.php | 45 +++++++++++++++++++++++++ App/Containers/NotAllowedHandler.php | 46 ++++++++++++++++++++++++++ App/Containers/NotFoundHandler.php | 46 ++++++++++++++++++++++++++ App/Containers/PhpErrorHandler.php | 49 ++++++++++++++++++++++++++++ 6 files changed, 281 insertions(+) create mode 100644 App/Containers/CallableResolver.php create mode 100644 App/Containers/ErrorHandler.php create mode 100644 App/Containers/FoundHandler.php create mode 100644 App/Containers/NotAllowedHandler.php create mode 100644 App/Containers/NotFoundHandler.php create mode 100644 App/Containers/PhpErrorHandler.php diff --git a/App/Containers/CallableResolver.php b/App/Containers/CallableResolver.php new file mode 100644 index 0000000..48e9f45 --- /dev/null +++ b/App/Containers/CallableResolver.php @@ -0,0 +1,46 @@ +apply( + HOOK_HANDLER_CALLABLE_RESOLVER, + new CallableResolver($container), + $container + ); + + if (! $callableResolver instanceof CallableResolverInterface) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Callable Resolver. Callable Resolver must be instance of %s", + CallableResolverInterface::class + ), + E_ERROR + ); + } + + return $callableResolver; + }; +} diff --git a/App/Containers/ErrorHandler.php b/App/Containers/ErrorHandler.php new file mode 100644 index 0000000..4908e8e --- /dev/null +++ b/App/Containers/ErrorHandler.php @@ -0,0 +1,49 @@ +apply( + HOOK_HANDLER_ERROR_500, + new Error( + $container->get('settings')['displayErrorDetails'], + $container[CONTAINER_APPLICATION] + ), + $container + ); + + if (! $errorHandler instanceof AbstractError) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Error Handler. Error Handler must be instance of %s", + AbstractError::class + ), + E_ERROR + ); + } + + return $errorHandler; + }; +} diff --git a/App/Containers/FoundHandler.php b/App/Containers/FoundHandler.php new file mode 100644 index 0000000..bba9d1c --- /dev/null +++ b/App/Containers/FoundHandler.php @@ -0,0 +1,45 @@ +apply( + HOOK_HANDLER_FOUND_RESPONSE, + new RequestResponse(), + $container + ); + if (! $callableResolver instanceof InvocationStrategyInterface) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Found Handler. Found Handler must be instance of %s", + InvocationStrategyInterface::class + ), + E_ERROR + ); + } + + return $callableResolver; + }; +} diff --git a/App/Containers/NotAllowedHandler.php b/App/Containers/NotAllowedHandler.php new file mode 100644 index 0000000..a69f636 --- /dev/null +++ b/App/Containers/NotAllowedHandler.php @@ -0,0 +1,46 @@ +apply( + HOOK_HANDLER_ERROR_403, + new NotAllowed(), + $container + ); + + if (! $notAllowedHandler instanceof AbstractHandler) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Not Allowed Handler. Not Allowed Handler must be instance of %s", + AbstractHandler::class + ), + E_ERROR + ); + } + + return $notAllowedHandler; + }; +} diff --git a/App/Containers/NotFoundHandler.php b/App/Containers/NotFoundHandler.php new file mode 100644 index 0000000..db95052 --- /dev/null +++ b/App/Containers/NotFoundHandler.php @@ -0,0 +1,46 @@ +apply( + HOOK_HANDLER_ERROR_404, + new NotFound(), + $container + ); + + if (! $notFoundHandler instanceof AbstractHandler) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Not Found Handler. Not Found Handler must be instance of %s", + AbstractHandler::class + ), + E_ERROR + ); + } + + return $notFoundHandler; + }; +} diff --git a/App/Containers/PhpErrorHandler.php b/App/Containers/PhpErrorHandler.php new file mode 100644 index 0000000..5746738 --- /dev/null +++ b/App/Containers/PhpErrorHandler.php @@ -0,0 +1,49 @@ +apply( + HOOK_HANDLER_ERROR_PHP, + new PhpError( + $container->get('settings')['displayErrorDetails'], + $container[CONTAINER_APPLICATION] + ), + $container + ); + + if (! $errorPhpHandler instanceof AbstractError) { + throw new RuntimeException( + sprintf( + "Invalid Hook for Php Error Handler. Php Error Handler must be instance of %s", + AbstractError::class + ), + E_ERROR + ); + } + + return $errorPhpHandler; + }; +} From 7d072d4490320d17241e98b08faa5a931bc8f9d0 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Fri, 2 Jun 2017 11:59:32 +0700 Subject: [PATCH 128/142] Ahaaaayy --- public/index.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/index.php b/public/index.php index eb5422d..affbaa6 100644 --- a/public/index.php +++ b/public/index.php @@ -119,11 +119,16 @@ }); /** + * Get Response From Process + * * @var \PentagonalProject\ProjectSeventh\Hook $hook * @var \Psr\Http\Message\ResponseInterface $response */ $response = $app->process((array) require __DIR__ . '/../Config/Config.php'); $hook = $app[CONTAINER_HOOK]; +/** + * Print The Response Output + */ $app ->getSlim() ->respond( From 83a3df917e111616bfc32244fca4cac95406466e Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 3 Jun 2017 16:58:30 +0700 Subject: [PATCH 129/142] Dall --- App/Classes/Application.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/App/Classes/Application.php b/App/Classes/Application.php index ecefc6d..5f38b59 100644 --- a/App/Classes/Application.php +++ b/App/Classes/Application.php @@ -298,6 +298,9 @@ public function process(array $config) : ResponseInterface $this->getComponentDirectory('ApplicationSlimObject.php'), $config ); + + // call container + $this->includeScope($this->getComponentDirectory('ApplicationContainer.php')); // call middleware $this->includeScope($this->getComponentDirectory('ApplicationMiddleware.php')); // determine & call routes From eccf07648ae35f1d7cce563772f1a17a4a9fbba2 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 3 Jun 2017 16:58:48 +0700 Subject: [PATCH 130/142] Suweeeeeeeeeeeeeeeeeeen komat kamit kabeh --- App/Components/ApplicationMiddleware.php | 12 +++++++++--- App/Components/ApplicationRoutes.php | 10 +++++++++- App/Components/ApplicationSlimObject.php | 6 ++++++ App/Containers/Log.php | 6 +++++- App/Includes/Constant.php | 6 ++++++ App/Includes/Helper.php | 16 ++++++++++++++-- Config/Example.Config.php | 7 +++++++ Config/Example.Routes.php | 18 ++++++++---------- INSTALL.md | 12 ++++++++++-- public/index.php | 5 +---- 10 files changed, 75 insertions(+), 23 deletions(-) diff --git a/App/Components/ApplicationMiddleware.php b/App/Components/ApplicationMiddleware.php index 035f245..9521e4a 100644 --- a/App/Components/ApplicationMiddleware.php +++ b/App/Components/ApplicationMiddleware.php @@ -58,16 +58,22 @@ /** * Includes Middleware auto load from config - */ - /** + * * @var Config $config */ $config = $app[CONTAINER_CONFIG]; if (($middleWares = $config['autoload[middleware]']) && is_array($middleWares)) { $c = 0; + // anonymous function to require file as binding Slim\App + $slimInit = function ($file) { + /** @noinspection PhpIncludeInspection */ + require_once $file; + }; + // binding to Slim\App for $this + $slimInit = $slimInit->bindTo($slim); foreach ($middleWares as $middleWare) { if (is_string($middleWare) && file_exists($middleWare)) { - $app->includeScope($middleWare); + $slimInit($middleWare); $c++; } } diff --git a/App/Components/ApplicationRoutes.php b/App/Components/ApplicationRoutes.php index 72c72d5..4076d4b 100644 --- a/App/Components/ApplicationRoutes.php +++ b/App/Components/ApplicationRoutes.php @@ -25,9 +25,17 @@ $config = $app[CONTAINER_CONFIG]; if (($routes = $config['autoload[routes]'])&& is_array($routes)) { $c = 0; + // anonymous function to require file as binding Slim\App + $slimInit = function ($file) { + /** @noinspection PhpIncludeInspection */ + require_once $file; + }; + + // binding to Slim\App for $this + $slimInit = $slimInit->bindTo($app->getSlim()); foreach ($routes as $route) { if (is_string($route) && file_exists($route)) { - $app->includeScope($route); + $slimInit($route); $c++; } } diff --git a/App/Components/ApplicationSlimObject.php b/App/Components/ApplicationSlimObject.php index 7bee722..fe6c3d2 100644 --- a/App/Components/ApplicationSlimObject.php +++ b/App/Components/ApplicationSlimObject.php @@ -153,6 +153,12 @@ * @return AbstractError */ CONTAINER_PHP_ERROR_HANDLER => $app->includeScope($app->getContainerDirectory('PhpErrorHandler.php')), + /** + * ShutDown Handler + * + * @return mixed + */ + CONTAINER_SHUTDOWN => $app->includeScope($app->getContainerDirectory('ShutdownHandler.php')), ] ); } diff --git a/App/Containers/Log.php b/App/Containers/Log.php index 444c338..772dbde 100644 --- a/App/Containers/Log.php +++ b/App/Containers/Log.php @@ -29,7 +29,10 @@ ? LOG_MODE_DEFAULT : Logger::WARNING ); - + $type = getAliasLogLevel($type); + $type = $type > 0 ? $type : 0; + } + if (!empty($type)) { $logName = $config['environment[log_name]']; if (!$logName || !is_string($logName) || trim($logName) == '') { $logName = getDefaultLogNameByCode($type, 'logs.log'); @@ -61,6 +64,7 @@ $type )); } + return $logger; }; } diff --git a/App/Includes/Constant.php b/App/Includes/Constant.php index ba3ecac..0890a78 100644 --- a/App/Includes/Constant.php +++ b/App/Includes/Constant.php @@ -48,6 +48,9 @@ // cache define('CONTAINER_CACHE', 'cache'); +// shutdown Handler +define('CONTAINER_SHUTDOWN', 'shutdown'); + define('CONTAINER_SLIM', 'slim'); define('CONTAINER_REQUEST', 'request'); define('CONTAINER_RESPONSE', 'response'); @@ -82,6 +85,9 @@ define('HOOK_HANDLER_CACHE_DRIVER', 'Handler:Cache:Driver'); define('HOOK_HANDLER_CACHE_CONFIG', 'Handler:Cache:Config'); +// shutdown Hook +define('HOOK_HANDLER_SHUTDOWN', 'Handler:Shutdown'); +// response define('HOOK_HANDLER_RESPONSE', 'Handler:Response'); /* GLOBAL CONSTANT LOG MODE diff --git a/App/Includes/Helper.php b/App/Includes/Helper.php index 7d6f281..e048093 100644 --- a/App/Includes/Helper.php +++ b/App/Includes/Helper.php @@ -168,21 +168,33 @@ function isMobile() : bool function getAliasLogLevel(int $code) : int { switch ($code) { + case \Monolog\Logger::ALERT: + return \Monolog\Logger::ALERT; + case \Monolog\Logger::CRITICAL: + return \Monolog\Logger::CRITICAL; + case E_ALL: + case \Monolog\Logger::DEBUG: + return \Monolog\Logger::DEBUG; case E_NOTICE: case E_USER_NOTICE: case E_DEPRECATED: case E_USER_DEPRECATED: + case \Monolog\Logger::NOTICE: return \Monolog\Logger::NOTICE; case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: + case \Monolog\Logger::ERROR: return \Monolog\Logger::ERROR; + case \Monolog\Logger::INFO: + return \Monolog\Logger::INFO; + case \Monolog\Logger::EMERGENCY: + return \Monolog\Logger::EMERGENCY; case E_WARNING: case E_USER_WARNING: case E_COMPILE_WARNING: + case \Monolog\Logger::WARNING: return \Monolog\Logger::WARNING; - case E_ALL: - return \Monolog\Logger::DEBUG; } return 0; diff --git a/Config/Example.Config.php b/Config/Example.Config.php index f41224a..b5145ef 100644 --- a/Config/Example.Config.php +++ b/Config/Example.Config.php @@ -67,9 +67,16 @@ 'secure' => null, ], // auto loading on separate loaded init + // files that loaded has variable $this that instanceof Slim\App 'autoload' => [ + // load Container / Register Additional Container + 'container' => [ + __DIR__ . '/Example.Container.php' + ], // load middle ware end of middle ware init 'middleware' => [ + // example Route + __DIR__ . '/Example.Middleware.php' ], // load on routes 'routes' => [ diff --git a/Config/Example.Routes.php b/Config/Example.Routes.php index 9b889fa..2131b66 100644 --- a/Config/Example.Routes.php +++ b/Config/Example.Routes.php @@ -2,10 +2,12 @@ /* ------------------------------------------------------ *\ | ROUTES EXAMPLE | \* ------------------------------------------------------ */ - +/** + * @uses \Slim\App + * for instance of $this + */ namespace { - use \PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\ResponseGenerator\Json; use PentagonalProject\ProjectSeventh\ResponseGenerator\Xml; use Psr\Http\Message\ResponseInterface; @@ -14,16 +16,12 @@ use Slim\Http\Body; use Slim\Http\Response; - if (!isset($this) || ! $this instanceof Arguments) { + if (!isset($this) || ! $this instanceof App) { header('HTTP/1.1 403 Forbidden'); return; } - /** - * @var App $slim - */ - $slim = $this[CONTAINER_APPLICATION]->getSlim(); - $slim->any( + $this->any( '/helo[/[{name: [A-Za-z0-9\S]+}[/]]]', function ( ServerRequestInterface $request, @@ -46,7 +44,7 @@ function ( } ); - $slim->any( + $this->any( '/xml[/]', function ( ServerRequestInterface $request, @@ -67,7 +65,7 @@ function ( } ); - $slim->any( + $this->any( '/json[/]', function ( ServerRequestInterface $request, diff --git a/INSTALL.md b/INSTALL.md index 73d71c9..5c146ec 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -98,7 +98,7 @@ $response = $app->process([ 'log_name' => null, ], 'cache' => [ - 'driver' => 'driverName', + 'driver' => 'driverName', // change with existing driver /** * @see \phpFastCache\CacheManager::getDefaultConfig() */ @@ -112,6 +112,7 @@ $response = $app->process([ 'fallback' => false, 'limited_memory_each_object' => 4096, 'compress_data' => false, + // add additional config eg : host & port for redis ] ], 'session' => [ @@ -126,7 +127,14 @@ $response = $app->process([ ], // auto loading on separate loaded init 'autoload' => [ - 'middleware' => [], + 'container' => [ + // example Container + '/Path/To/ContainerFile.php' + ], + 'middleware' => [ + // example Middleware + '/Path/To/MiddleWareFile.php' + ], 'routes' => [ // example Route '/Path/To/RouteFile.php' diff --git a/public/index.php b/public/index.php index affbaa6..c1763f9 100644 --- a/public/index.php +++ b/public/index.php @@ -113,10 +113,6 @@ * @var \PentagonalProject\ProjectSeventh\Application $app */ $app = new PentagonalProject\ProjectSeventh\Application(); -register_shutdown_function(function () { - print_r(error_get_last()); - exit; -}); /** * Get Response From Process @@ -125,6 +121,7 @@ * @var \Psr\Http\Message\ResponseInterface $response */ $response = $app->process((array) require __DIR__ . '/../Config/Config.php'); + $hook = $app[CONTAINER_HOOK]; /** * Print The Response Output From 60c3c7f1ae32665d74b4667bf7d0776b0f944655 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 3 Jun 2017 16:59:04 +0700 Subject: [PATCH 131/142] Komit kabeh kesel aku --- App/Components/ApplicationContainer.php | 72 +++++++++++++++++++++++++ App/Containers/ShutdownHandler.php | 32 +++++++++++ Config/Example.Container.php | 33 ++++++++++++ Config/Example.Middleware.php | 26 +++++++++ 4 files changed, 163 insertions(+) create mode 100644 App/Components/ApplicationContainer.php create mode 100644 App/Containers/ShutdownHandler.php create mode 100644 Config/Example.Container.php create mode 100644 Config/Example.Middleware.php diff --git a/App/Components/ApplicationContainer.php b/App/Components/ApplicationContainer.php new file mode 100644 index 0000000..6859b39 --- /dev/null +++ b/App/Components/ApplicationContainer.php @@ -0,0 +1,72 @@ +apply( + HOOK_HANDLER_SHUTDOWN, + $app[CONTAINER_SHUTDOWN] + ); + if (is_callable($handler)) { + call_user_func($handler); + } + }); + + /** + * Includes Container auto load from config + * + * @var Config $config + */ + $config = $app[CONTAINER_CONFIG]; + if (($Containers = $config['autoload[container]']) && is_array($Containers)) { + $c = 0; + // anonymous function to require file as binding Slim\App + $slimInit = function ($file) { + /** @noinspection PhpIncludeInspection */ + require_once $file; + }; + // binding to Slim\App for $this + $slimInit = $slimInit->bindTo($app->getSlim()); + foreach ($Containers as $Container) { + if (is_string($Container) && file_exists($Container)) { + // include + $slimInit($Container); + $c++; + } + } + + ($c > 0) && + $app[CONTAINER_LOG]->debug('Additional Container initiated', [ + 'Count' => $c + ]); + } +} diff --git a/App/Containers/ShutdownHandler.php b/App/Containers/ShutdownHandler.php new file mode 100644 index 0000000..a12c0a3 --- /dev/null +++ b/App/Containers/ShutdownHandler.php @@ -0,0 +1,32 @@ +error( + $lastError['message'], + $lastError + ); + } + }; + }; +} diff --git a/Config/Example.Container.php b/Config/Example.Container.php new file mode 100644 index 0000000..f16af63 --- /dev/null +++ b/Config/Example.Container.php @@ -0,0 +1,33 @@ +getContainer(); + + /** + * Example Container + * + * create example container + * @param ContainerInterface $container + * @return stdClass + */ + $container['example'] = function (ContainerInterface $container) { + return new \stdClass(); + }; +} diff --git a/Config/Example.Middleware.php b/Config/Example.Middleware.php new file mode 100644 index 0000000..58ebee2 --- /dev/null +++ b/Config/Example.Middleware.php @@ -0,0 +1,26 @@ +add(function (ServerRequestInterface $serverRequest, ResponseInterface $response, $next) { + // do code + return $next($serverRequest, $response); + }); +} From 7552eb40bf1c6fe0f23e20b2771e106591406e81 Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 3 Jun 2017 23:02:04 +0700 Subject: [PATCH 132/142] Asuuu --- App/Classes/Utilities/EmbeddedReader.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/App/Classes/Utilities/EmbeddedReader.php b/App/Classes/Utilities/EmbeddedReader.php index 32d0bb3..0515d82 100644 --- a/App/Classes/Utilities/EmbeddedReader.php +++ b/App/Classes/Utilities/EmbeddedReader.php @@ -5,6 +5,7 @@ use Apatis\Exceptions\InvalidArgumentException; use Apatis\Exceptions\RuntimeException; use PentagonalProject\ProjectSeventh\Abstracts\EmbeddedSystem; +use PentagonalProject\ProjectSeventh\Arguments; use PentagonalProject\ProjectSeventh\Exceptions\EmptyFileException; use PentagonalProject\ProjectSeventh\Exceptions\InvalidPathException; use PentagonalProject\ProjectSeventh\Exceptions\InvalidEmbeddedException; @@ -360,7 +361,12 @@ private function validate() : EmbeddedReader ob_start(); // include once - IncludeFileOnce($this->file); + (function ($file) { + /** @noinspection PhpIncludeInspection */ + require_once $file; + }) + // binding to None of $this + ->bindTo(null)($this->file); if ($error = error_get_last() && !empty($error) && $error['file'] == $this->file) { if ($error['type'] === E_ERROR) { @ob_end_clean(); @@ -373,7 +379,9 @@ private function validate() : EmbeddedReader ); } } - @ob_end_clean(); + if (ob_get_length()) { + @ob_end_clean(); + } if (!class_exists($class)) { throw new InvalidEmbeddedException( sprintf( @@ -384,7 +392,15 @@ private function validate() : EmbeddedReader E_ERROR ); } - + if (! method_exists($class, 'init')) { + throw new InvalidEmbeddedException( + sprintf( + 'File %1$s does not contain method `init`.', + $this->getName() + ), + E_ERROR + ); + } $this->valid = true; $this->instance = new $class; return $this; From e35c4aea419baed444ce51fbbab07cf55ed8d94c Mon Sep 17 00:00:00 2001 From: pentagonal Date: Sat, 3 Jun 2017 23:02:13 +0700 Subject: [PATCH 133/142] Biar Keren --- .../DatabaseSchemeTableDefinition.php | 485 ++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 App/Classes/Utilities/DatabaseSchemeTableDefinition.php diff --git a/App/Classes/Utilities/DatabaseSchemeTableDefinition.php b/App/Classes/Utilities/DatabaseSchemeTableDefinition.php new file mode 100644 index 0000000..09238de --- /dev/null +++ b/App/Classes/Utilities/DatabaseSchemeTableDefinition.php @@ -0,0 +1,485 @@ + [ + * "id" => [ + * // Type Map + * "bigint", + * // Options @see \Doctrine\DBAL\Schema\Column + * [ + * "autoincrement" => true, + * "length" => 10, + * "index" => true, + * ] + * ], + * "username" => [ + * "string", + * [] + * ], + * ] + * ]; + */ +class DatabaseSchemeTableDefinition +{ + const NAME_TYPE = 'type'; + const NAME_OPTIONS = 'options'; + const NAME_PROPERTIES = 'properties'; + + /** + * @var array + */ + protected $originalScheme; + + /** + * @var array + */ + protected $schemes = []; + + /** + * @var array + */ + protected $invalidScheme = []; + + /** + * @var bool + */ + protected $hasBuild = false; + + /** + * @var Table[] + */ + protected $cachedTable; + + /** + * DatabaseSchemeUtilities constructor. + * @param array $schemes + */ + public function __construct(array $schemes) + { + $this->originalScheme = $schemes; + } + + /** + * Build Scheme + */ + protected function protectedBuildSchemes() + { + if ($this->hasBuild) { + return; + } + + $this->hasBuild = true; + /** + * List Available Properties + * + * @var array + */ + $availableOptions = [ + 'column' => [ + 'autoincrement' => 'boolean', + 'length' => 'integer', + 'precision' => 'integer', + 'scale' => 'integer', + 'unsigned' => 'boolean', + 'fixed' => 'boolean', + 'notnull' => 'boolean', + 'default' => 'mixed', + 'comment' => 'string', + ], + 'table_set' => [ + 'primarykey' => 'mixed', + ], + 'table_add' => [ + 'index' => 'mixed', + 'uniqueindex' => 'mixed', + 'foreignkey' => 'array', + 'foreignkeyconstraint' => 'array', + ], + ]; + foreach ($this->originalScheme as $table => $definitions) { + if (!is_array($definitions)) { + $this->invalidScheme[$table] = true; + continue; + } + + foreach ($definitions as $column => $definition) { + if (isset($this->invalidScheme[$table])) { + break; + } + + $columnType = $this->resolveTypeMap(reset($definition)); + if (!$columnType) { + $this->invalidScheme[$table] = true; + break; + } + + $options = (array) next($definition); + $properties = []; + foreach ($options as $optionKey => $value) { + unset($options[$optionKey]); + if (is_numeric($optionKey)) { + continue; + } + $optionKey = strtolower($optionKey); + if (isset($availableOptions['column'][$optionKey])) { + $type = $availableOptions['column'][$optionKey]; + if ($type !== 'mixed') { + $oldValue = $value; + if (!settype($value, $type)) { + $value = $oldValue; + } + } + + $options[$optionKey] = $value; + continue; + } + if (isset($availableOptions['table_set'][$optionKey])) { + if (!is_string($value)) { + $value = (bool) $value; + } + if ($value === false) { + continue; + } + $properties['set'][$optionKey][$column] = $value === '' ? true : $value; + } elseif (isset($availableOptions['table_add'][$optionKey])) { + $type = $availableOptions['table_add'][$optionKey]; + if ($type === 'array') { + if (gettype($value) !== 'array') { + continue; + } + if (!empty($value)) { + $properties['add'][$optionKey][$column] = $value; + } + continue; + } + if (!is_string($value)) { + $value = (bool) $value; + } + if ($value) { + $properties['add'][$optionKey][$column] = $value; + } + } + } + + if (isset($options['autoincrement']) && ! isset($properties['set']['primarykey'][$column])) { + $properties['set']['primarykey'][$column] = true; + } + + $definitions[$column] = [ + static::NAME_TYPE => $columnType, + static::NAME_OPTIONS => $options, + static::NAME_PROPERTIES => $properties + ]; + } + + if (!isset($this->invalidScheme[$table])) { + $this->schemes[$table] = $definitions; + } + } + } + + /** + * Get Build Schemes + * + * @return array + */ + public function getSchemes() + { + $this->protectedBuildSchemes(); + + return $this->schemes; + } + + /** + * Get Invalid Scheme + * + * @return array + */ + public function getInvalidSchemes() + { + $this->protectedBuildSchemes(); + return $this->invalidScheme; + } + + /** + * Convert Into Column + * + * @return array|Table[] + */ + public function getTablesFromSchemes() + { + if (!isset($this->cachedTable)) { + $this->cachedTable = []; + foreach ($this->getSchemes() as $tableName => $columns) { + $table = new Table( + $tableName + ); + foreach ($columns as $columnName => $definitions) { + $table->addColumn( + $columnName, + $definitions[static::NAME_TYPE], + $definitions[static::NAME_OPTIONS] + ); + if (isset($definitions[static::NAME_PROPERTIES]['set'])) { + foreach ($definitions[static::NAME_PROPERTIES]['set'] as $context => $value) { + foreach ($value as $newContext => $realValue) { + $args = [ [$newContext], (is_string($realValue) ? $realValue : false)]; + call_user_func_array( + [ + $table, + "set{$context}" + ], + $args + ); + } + } + } + if (($definitions[static::NAME_PROPERTIES]['add'])) { + foreach ($definitions[static::NAME_PROPERTIES]['add'] as $context => $value) { + foreach ($value as $newContext => $realValue) { + // use for Foreign Key + if (is_array($realValue)) { + $args = [$newContext, $realValue]; + $context = 'foreignkeyconstraint'; + } else { + $args = [ [$newContext], (is_string($realValue) ? $realValue : false)]; + } + call_user_func_array( + [ + $table, + "add{$context}" + ], + $args + ); + } + } + } + } + + $this->cachedTable[$tableName] = $table; + } + } + + return $this->cachedTable; + } + + /** + * As Table Use Database + * + * @param Database $database + * @return array|Table[] + */ + public function getTablesFromSchemesWith(Database $database) : array + { + $tables = $this->getTablesFromSchemes(); + foreach ($tables as $tableName => $table) { + $tables[$tableName] = new Table( + $database->prefixTables($table->getName()), + $table->getColumns(), + $table->getIndexes(), + $table->getForeignKeys(), + 0, + $table->getOptions() + ); + } + + return $tables; + } + + /** + * Get Scheme With Given Params + * + * @return Schema + */ + public function getSchemaTablesWith() : Schema + { + $database = null; + $schemaConfig = new SchemaConfig(); + $sequences = []; + $nameSpace = []; + foreach (func_get_args() as $key => $value) { + if ($value instanceof Database) { + $database = $value; + continue; + } + if ($value instanceof SchemaConfig) { + $schemaConfig = $value; + continue; + } + if (is_array($value) && count($value) > 0) { + $isSequenceValid = true; + $isNameSpaceValid = true; + foreach ($value as $seq) { + if (is_object($value) && ! $seq instanceof Sequence) { + $isSequenceValid = false; + if (!$isNameSpaceValid) { + break; + } + continue; + } + + if (!is_string($seq)) { + $isNameSpaceValid = false; + if (!$isSequenceValid) { + break; + } + } + } + + $sequences = $isSequenceValid ? $value : $sequences; + $nameSpace = $isNameSpaceValid ? $value : $nameSpace; + } + } + $tables = $database + ? $this->getTablesFromSchemesWith($database) + : $this->getTablesFromSchemes(); + return new Schema( + $tables, + $sequences, + $schemaConfig, + $nameSpace + ); + } + + /** + * Get SQL Migration Of Query as Array + * + * @param Database $database + * + * @return array|string[] + */ + public function getSQLWithDatabase(Database $database) : array + { + /** + * @var Schema $schema + */ + $schema = call_user_func_array( + [$this, 'getSchemaTablesWith'], + func_get_args() + ); + + /** + * @var Database $database + */ + return $schema->getMigrateFromSql( + $database->getSchemaManager()->createSchema(), + $database->getDatabasePlatform() + ); + } + + /** + * Get Array QUERY SQL From Create Table + * + * @param Database $database + * @return array + */ + public function getSQLCreateTableWithDatabase(Database $database) : array + { + /** + * @var Schema $schema + */ + $schema = call_user_func_array( + [$this, 'getSchemaTablesWith'], + func_get_args() + ); + + return $schema->getMigrateFromSql( + new Schema(), + $database->getDatabasePlatform() + ); + } + + /** + * Execute Query From Given Tables + * + * @param Database $database + * @return int + * @throws \Exception + */ + public function executeSQLWith(Database $database) : int + { + /** + * array + */ + $migration = call_user_func_array( + [$this, 'getSQLWithDatabase'], + func_get_args() + ); + + $count = 0; + if (!empty($migration)) { + $database->beginTransaction(); + try { + foreach ($migration as $query) { + $stmt = $database->prepare($query); + $stmt->execute(); + $stmt->closeCursor(); + $count++; + } + $database->rollBack(); + } catch (\Exception $exception) { + $database->rollBack(); + throw $exception; + } + } + + return $count; + } + + /** + * Additional Mapping Type Fix + * + * @param string $type + * @return string|null null if not match + */ + public static function resolveTypeMap($type) + { + if (!is_string($type)) { + return null; + } + + $type = strtolower($type); + preg_match( + '# + (?Pbin) + | (?Pdatetimez|timez) + | (?Pgu|id) + | (?Pdate) + | (?P