new pisilinux web sites
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Operating System Files
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
# OSX
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Config files with secrets - use .example versions as template
|
||||||
|
Projects/*/Config/Database.php
|
||||||
|
Projects/*/Config/Services.php
|
||||||
|
|
||||||
|
# Upload directories - track folders but ignore contents
|
||||||
|
upload/*
|
||||||
|
!upload/.gitkeep
|
||||||
|
uploads/*
|
||||||
|
!uploads/.gitkeep
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#----------------------------------------------------------------------
|
||||||
|
# This file automatically created and updated
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
<ifModule mod_gzip.c>
|
||||||
|
mod_gzip_on Yes
|
||||||
|
mod_gzip_dechunk Yes
|
||||||
|
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
|
||||||
|
mod_gzip_item_include handler ^cgi-script$
|
||||||
|
mod_gzip_item_include mime ^text/.*
|
||||||
|
mod_gzip_item_include mime ^application/x-javascript.*
|
||||||
|
mod_gzip_item_exclude mime ^image/.*
|
||||||
|
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
|
||||||
|
</ifModule>
|
||||||
|
|
||||||
|
<ifModule mod_expires.c>
|
||||||
|
ExpiresActive On
|
||||||
|
ExpiresDefault "access plus 1 seconds"
|
||||||
|
ExpiresByType text/html "access plus 1 seconds"
|
||||||
|
ExpiresByType image/gif "access plus 2592000 seconds"
|
||||||
|
ExpiresByType image/jpeg "access plus 2592000 seconds"
|
||||||
|
ExpiresByType image/png "access plus 2592000 seconds"
|
||||||
|
ExpiresByType text/css "access plus 604800 seconds"
|
||||||
|
ExpiresByType text/javascript "access plus 216000 seconds"
|
||||||
|
ExpiresByType application/x-javascript "access plus 216000 seconds"
|
||||||
|
</ifModule>
|
||||||
|
|
||||||
|
<ifModule mod_headers.c>
|
||||||
|
<filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
|
||||||
|
Header set Cache-Control "max-age=2592000, public"
|
||||||
|
</filesMatch>
|
||||||
|
<filesMatch "\.(css)$">
|
||||||
|
Header set Cache-Control "max-age=604800, public"
|
||||||
|
</filesMatch>
|
||||||
|
<filesMatch "\.(js)$">
|
||||||
|
Header set Cache-Control "max-age=216000, private"
|
||||||
|
</filesMatch>
|
||||||
|
<filesMatch "\.(xml|txt)$">
|
||||||
|
Header set Cache-Control "max-age=216000, public, must-revalidate"
|
||||||
|
</filesMatch>
|
||||||
|
<filesMatch "\.(html|htm|php)$">
|
||||||
|
Header set Cache-Control "max-age=1, private, must-revalidate"
|
||||||
|
</filesMatch>
|
||||||
|
</ifModule>
|
||||||
|
|
||||||
|
<ifModule mod_expires.c>
|
||||||
|
Header set Connection keep-alive
|
||||||
|
</ifModule>
|
||||||
|
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
Options -Indexes
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<FilesMatch "^(?i:docker\-compose\.yml|Dockerfile)$">
|
||||||
|
deny from all
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteBase /
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule ^(.*)$ /zeroneed.php?/$1 [QSA]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
ErrorDocument 403 /zeroneed.php
|
||||||
|
|
||||||
|
DirectoryIndex zeroneed.php
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
# Denied entry to this directory and its subdirectories
|
||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Deny from all
|
||||||
Vendored
Vendored
Vendored
Vendored
Vendored
Vendored
Vendored
Vendored
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
# Allow entry to this directory and its subdirectories
|
||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Allow from all
|
||||||
BIN
Binary file not shown.
Vendored
@@ -0,0 +1,5 @@
|
|||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
# Denied entry to this directory and its subdirectories
|
||||||
|
#----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Deny from all
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload.php @generated by Composer
|
||||||
|
|
||||||
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
|
return ComposerAutoloaderInit18a22f10e44b8b77ed023b6677d08bad::getLoader();
|
||||||
@@ -0,0 +1,445 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||||
|
*
|
||||||
|
* $loader = new \Composer\Autoload\ClassLoader();
|
||||||
|
*
|
||||||
|
* // register classes with namespaces
|
||||||
|
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||||
|
* $loader->add('Symfony', __DIR__.'/framework');
|
||||||
|
*
|
||||||
|
* // activate the autoloader
|
||||||
|
* $loader->register();
|
||||||
|
*
|
||||||
|
* // to enable searching the include path (eg. for PEAR packages)
|
||||||
|
* $loader->setUseIncludePath(true);
|
||||||
|
*
|
||||||
|
* In this example, if you try to use a class in the Symfony\Component
|
||||||
|
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||||
|
* the autoloader will first look for the class under the component/
|
||||||
|
* directory, and it will then fallback to the framework/ directory if not
|
||||||
|
* found before giving up.
|
||||||
|
*
|
||||||
|
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
* @see http://www.php-fig.org/psr/psr-0/
|
||||||
|
* @see http://www.php-fig.org/psr/psr-4/
|
||||||
|
*/
|
||||||
|
class ClassLoader
|
||||||
|
{
|
||||||
|
// PSR-4
|
||||||
|
private $prefixLengthsPsr4 = array();
|
||||||
|
private $prefixDirsPsr4 = array();
|
||||||
|
private $fallbackDirsPsr4 = array();
|
||||||
|
|
||||||
|
// PSR-0
|
||||||
|
private $prefixesPsr0 = array();
|
||||||
|
private $fallbackDirsPsr0 = array();
|
||||||
|
|
||||||
|
private $useIncludePath = false;
|
||||||
|
private $classMap = array();
|
||||||
|
private $classMapAuthoritative = false;
|
||||||
|
private $missingClasses = array();
|
||||||
|
private $apcuPrefix;
|
||||||
|
|
||||||
|
public function getPrefixes()
|
||||||
|
{
|
||||||
|
if (!empty($this->prefixesPsr0)) {
|
||||||
|
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrefixesPsr4()
|
||||||
|
{
|
||||||
|
return $this->prefixDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFallbackDirs()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFallbackDirsPsr4()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassMap()
|
||||||
|
{
|
||||||
|
return $this->classMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $classMap Class to filename map
|
||||||
|
*/
|
||||||
|
public function addClassMap(array $classMap)
|
||||||
|
{
|
||||||
|
if ($this->classMap) {
|
||||||
|
$this->classMap = array_merge($this->classMap, $classMap);
|
||||||
|
} else {
|
||||||
|
$this->classMap = $classMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix, either
|
||||||
|
* appending or prepending to the ones previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param array|string $paths The PSR-0 root directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*/
|
||||||
|
public function add($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
(array) $paths,
|
||||||
|
$this->fallbackDirsPsr0
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
$this->fallbackDirsPsr0,
|
||||||
|
(array) $paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$first = $prefix[0];
|
||||||
|
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($prepend) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
(array) $paths,
|
||||||
|
$this->prefixesPsr0[$first][$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
$this->prefixesPsr0[$first][$prefix],
|
||||||
|
(array) $paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace, either
|
||||||
|
* appending or prepending to the ones previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param array|string $paths The PSR-4 base directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function addPsr4($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
// Register directories for the root namespace.
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
(array) $paths,
|
||||||
|
$this->fallbackDirsPsr4
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
$this->fallbackDirsPsr4,
|
||||||
|
(array) $paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||||
|
// Register directories for a new namespace.
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||||
|
} elseif ($prepend) {
|
||||||
|
// Prepend directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
(array) $paths,
|
||||||
|
$this->prefixDirsPsr4[$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Append directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
$this->prefixDirsPsr4[$prefix],
|
||||||
|
(array) $paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix,
|
||||||
|
* replacing any others previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param array|string $paths The PSR-0 base directories
|
||||||
|
*/
|
||||||
|
public function set($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr0 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace,
|
||||||
|
* replacing any others previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param array|string $paths The PSR-4 base directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setPsr4($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr4 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns on searching the include path for class files.
|
||||||
|
*
|
||||||
|
* @param bool $useIncludePath
|
||||||
|
*/
|
||||||
|
public function setUseIncludePath($useIncludePath)
|
||||||
|
{
|
||||||
|
$this->useIncludePath = $useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to check if the autoloader uses the include path to check
|
||||||
|
* for classes.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getUseIncludePath()
|
||||||
|
{
|
||||||
|
return $this->useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns off searching the prefix and fallback directories for classes
|
||||||
|
* that have not been registered with the class map.
|
||||||
|
*
|
||||||
|
* @param bool $classMapAuthoritative
|
||||||
|
*/
|
||||||
|
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||||
|
{
|
||||||
|
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should class lookup fail if not found in the current class map?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isClassMapAuthoritative()
|
||||||
|
{
|
||||||
|
return $this->classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||||
|
*
|
||||||
|
* @param string|null $apcuPrefix
|
||||||
|
*/
|
||||||
|
public function setApcuPrefix($apcuPrefix)
|
||||||
|
{
|
||||||
|
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getApcuPrefix()
|
||||||
|
{
|
||||||
|
return $this->apcuPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @param bool $prepend Whether to prepend the autoloader or not
|
||||||
|
*/
|
||||||
|
public function register($prepend = false)
|
||||||
|
{
|
||||||
|
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters this instance as an autoloader.
|
||||||
|
*/
|
||||||
|
public function unregister()
|
||||||
|
{
|
||||||
|
spl_autoload_unregister(array($this, 'loadClass'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given class or interface.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
* @return bool|null True if loaded, null otherwise
|
||||||
|
*/
|
||||||
|
public function loadClass($class)
|
||||||
|
{
|
||||||
|
if ($file = $this->findFile($class)) {
|
||||||
|
includeFile($file);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the path to the file where the class is defined.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
*
|
||||||
|
* @return string|false The path if found, false otherwise
|
||||||
|
*/
|
||||||
|
public function findFile($class)
|
||||||
|
{
|
||||||
|
// class map lookup
|
||||||
|
if (isset($this->classMap[$class])) {
|
||||||
|
return $this->classMap[$class];
|
||||||
|
}
|
||||||
|
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||||
|
if ($hit) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findFileWithExtension($class, '.php');
|
||||||
|
|
||||||
|
// Search for Hack files if we are running on HHVM
|
||||||
|
if (false === $file && defined('HHVM_VERSION')) {
|
||||||
|
$file = $this->findFileWithExtension($class, '.hh');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
apcu_add($this->apcuPrefix.$class, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $file) {
|
||||||
|
// Remember that this class does not exist.
|
||||||
|
$this->missingClasses[$class] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function findFileWithExtension($class, $ext)
|
||||||
|
{
|
||||||
|
// PSR-4 lookup
|
||||||
|
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
|
||||||
|
$first = $class[0];
|
||||||
|
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||||
|
$subPath = $class;
|
||||||
|
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||||
|
$subPath = substr($subPath, 0, $lastPos);
|
||||||
|
$search = $subPath.'\\';
|
||||||
|
if (isset($this->prefixDirsPsr4[$search])) {
|
||||||
|
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||||
|
$length = $this->prefixLengthsPsr4[$first][$search];
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-4 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 lookup
|
||||||
|
if (false !== $pos = strrpos($class, '\\')) {
|
||||||
|
// namespaced class name
|
||||||
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||||
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||||
|
} else {
|
||||||
|
// PEAR-like class name
|
||||||
|
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->prefixesPsr0[$first])) {
|
||||||
|
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||||
|
if (0 === strpos($class, $prefix)) {
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 include paths.
|
||||||
|
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope isolated include.
|
||||||
|
*
|
||||||
|
* Prevents access to $this/self from included files.
|
||||||
|
*/
|
||||||
|
function includeFile($file)
|
||||||
|
{
|
||||||
|
include $file;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_classmap.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_files.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array();
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_namespaces.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
);
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'ZN\\XML\\' => array($vendorDir . '/package-xml'),
|
||||||
|
'ZN\\Validation\\' => array($vendorDir . '/package-validation'),
|
||||||
|
'ZN\\Storage\\' => array($vendorDir . '/package-storage'),
|
||||||
|
'ZN\\Shopping\\' => array($vendorDir . '/package-shopping'),
|
||||||
|
'ZN\\Services\\' => array($vendorDir . '/package-services'),
|
||||||
|
'ZN\\Security\\' => array($vendorDir . '/package-security'),
|
||||||
|
'ZN\\Response\\' => array($vendorDir . '/package-response'),
|
||||||
|
'ZN\\Request\\' => array($vendorDir . '/package-request'),
|
||||||
|
'ZN\\Remote\\' => array($vendorDir . '/package-remote'),
|
||||||
|
'ZN\\Protection\\' => array($vendorDir . '/package-protection'),
|
||||||
|
'ZN\\Prompt\\' => array($vendorDir . '/package-prompt'),
|
||||||
|
'ZN\\Payment\\' => array($vendorDir . '/package-payment'),
|
||||||
|
'ZN\\Pagination\\' => array($vendorDir . '/package-pagination'),
|
||||||
|
'ZN\\Language\\' => array($vendorDir . '/package-language'),
|
||||||
|
'ZN\\Image\\' => array($vendorDir . '/package-image'),
|
||||||
|
'ZN\\Hypertext\\' => array($vendorDir . '/package-hypertext'),
|
||||||
|
'ZN\\Helpers\\' => array($vendorDir . '/package-helpers'),
|
||||||
|
'ZN\\Generator\\' => array($vendorDir . '/package-generator'),
|
||||||
|
'ZN\\Filesystem\\' => array($vendorDir . '/package-filesystem'),
|
||||||
|
'ZN\\EventHandler\\' => array($vendorDir . '/package-event-handler'),
|
||||||
|
'ZN\\Email\\' => array($vendorDir . '/package-email'),
|
||||||
|
'ZN\\DateTime\\' => array($vendorDir . '/package-datetime'),
|
||||||
|
'ZN\\Database\\' => array($vendorDir . '/package-database'),
|
||||||
|
'ZN\\DataTypes\\' => array($vendorDir . '/package-datatypes'),
|
||||||
|
'ZN\\Cryptography\\' => array($vendorDir . '/package-cryptography'),
|
||||||
|
'ZN\\Crontab\\' => array($vendorDir . '/package-crontab'),
|
||||||
|
'ZN\\Console\\' => array($vendorDir . '/package-console'),
|
||||||
|
'ZN\\Compression\\' => array($vendorDir . '/package-compression'),
|
||||||
|
'ZN\\Comparison\\' => array($vendorDir . '/package-comparison'),
|
||||||
|
'ZN\\Captcha\\' => array($vendorDir . '/package-captcha'),
|
||||||
|
'ZN\\Cache\\' => array($vendorDir . '/package-cache'),
|
||||||
|
'ZN\\Buffering\\' => array($vendorDir . '/package-buffering'),
|
||||||
|
'ZN\\Authorization\\' => array($vendorDir . '/package-authorization'),
|
||||||
|
'ZN\\Authentication\\' => array($vendorDir . '/package-authentication'),
|
||||||
|
'ZN\\' => array($vendorDir . '/package-zerocore'),
|
||||||
|
);
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_real.php @generated by Composer
|
||||||
|
|
||||||
|
class ComposerAutoloaderInit18a22f10e44b8b77ed023b6677d08bad
|
||||||
|
{
|
||||||
|
private static $loader;
|
||||||
|
|
||||||
|
public static function loadClassLoader($class)
|
||||||
|
{
|
||||||
|
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||||
|
require __DIR__ . '/ClassLoader.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getLoader()
|
||||||
|
{
|
||||||
|
if (null !== self::$loader) {
|
||||||
|
return self::$loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
spl_autoload_register(array('ComposerAutoloaderInit18a22f10e44b8b77ed023b6677d08bad', 'loadClassLoader'), true, true);
|
||||||
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||||
|
spl_autoload_unregister(array('ComposerAutoloaderInit18a22f10e44b8b77ed023b6677d08bad', 'loadClassLoader'));
|
||||||
|
|
||||||
|
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||||
|
if ($useStaticLoader) {
|
||||||
|
require_once __DIR__ . '/autoload_static.php';
|
||||||
|
|
||||||
|
call_user_func(\Composer\Autoload\ComposerStaticInit18a22f10e44b8b77ed023b6677d08bad::getInitializer($loader));
|
||||||
|
} else {
|
||||||
|
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->set($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
|
if ($classMap) {
|
||||||
|
$loader->addClassMap($classMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader->register(true);
|
||||||
|
|
||||||
|
if ($useStaticLoader) {
|
||||||
|
$includeFiles = Composer\Autoload\ComposerStaticInit18a22f10e44b8b77ed023b6677d08bad::$files;
|
||||||
|
} else {
|
||||||
|
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||||
|
}
|
||||||
|
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||||
|
composerRequire18a22f10e44b8b77ed023b6677d08bad($fileIdentifier, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $loader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function composerRequire18a22f10e44b8b77ed023b6677d08bad($fileIdentifier, $file)
|
||||||
|
{
|
||||||
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
|
require $file;
|
||||||
|
|
||||||
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_static.php @generated by Composer
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
class ComposerStaticInit18a22f10e44b8b77ed023b6677d08bad
|
||||||
|
{
|
||||||
|
public static $files = array ();
|
||||||
|
|
||||||
|
public static $prefixLengthsPsr4 = array (
|
||||||
|
'Z' =>
|
||||||
|
array (
|
||||||
|
'ZN\\XML\\' => 7,
|
||||||
|
'ZN\\Validation\\' => 14,
|
||||||
|
'ZN\\Storage\\' => 11,
|
||||||
|
'ZN\\Shopping\\' => 12,
|
||||||
|
'ZN\\Services\\' => 12,
|
||||||
|
'ZN\\Security\\' => 12,
|
||||||
|
'ZN\\Response\\' => 12,
|
||||||
|
'ZN\\Request\\' => 11,
|
||||||
|
'ZN\\Remote\\' => 10,
|
||||||
|
'ZN\\Protection\\' => 14,
|
||||||
|
'ZN\\Prompt\\' => 10,
|
||||||
|
'ZN\\Payment\\' => 11,
|
||||||
|
'ZN\\Pagination\\' => 14,
|
||||||
|
'ZN\\Language\\' => 12,
|
||||||
|
'ZN\\Image\\' => 9,
|
||||||
|
'ZN\\Hypertext\\' => 13,
|
||||||
|
'ZN\\Helpers\\' => 11,
|
||||||
|
'ZN\\Generator\\' => 13,
|
||||||
|
'ZN\\Filesystem\\' => 14,
|
||||||
|
'ZN\\EventHandler\\' => 16,
|
||||||
|
'ZN\\Email\\' => 9,
|
||||||
|
'ZN\\DateTime\\' => 12,
|
||||||
|
'ZN\\Database\\' => 12,
|
||||||
|
'ZN\\DataTypes\\' => 13,
|
||||||
|
'ZN\\Cryptography\\' => 16,
|
||||||
|
'ZN\\Crontab\\' => 11,
|
||||||
|
'ZN\\Console\\' => 11,
|
||||||
|
'ZN\\Compression\\' => 15,
|
||||||
|
'ZN\\Comparison\\' => 14,
|
||||||
|
'ZN\\Captcha\\' => 11,
|
||||||
|
'ZN\\Cache\\' => 9,
|
||||||
|
'ZN\\Buffering\\' => 13,
|
||||||
|
'ZN\\Authorization\\' => 17,
|
||||||
|
'ZN\\Authentication\\' => 18,
|
||||||
|
'ZN\\' => 3,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $prefixDirsPsr4 = array (
|
||||||
|
'ZN\\XML\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-xml',
|
||||||
|
),
|
||||||
|
'ZN\\Validation\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-validation',
|
||||||
|
),
|
||||||
|
'ZN\\Storage\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-storage',
|
||||||
|
),
|
||||||
|
'ZN\\Shopping\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-shopping',
|
||||||
|
),
|
||||||
|
'ZN\\Services\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-services',
|
||||||
|
),
|
||||||
|
'ZN\\Security\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-security',
|
||||||
|
),
|
||||||
|
'ZN\\Response\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-response',
|
||||||
|
),
|
||||||
|
'ZN\\Request\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-request',
|
||||||
|
),
|
||||||
|
'ZN\\Remote\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-remote',
|
||||||
|
),
|
||||||
|
'ZN\\Protection\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-protection',
|
||||||
|
),
|
||||||
|
'ZN\\Prompt\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-prompt',
|
||||||
|
),
|
||||||
|
'ZN\\Payment\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-payment',
|
||||||
|
),
|
||||||
|
'ZN\\Pagination\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-pagination',
|
||||||
|
),
|
||||||
|
'ZN\\Language\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-language',
|
||||||
|
),
|
||||||
|
'ZN\\Image\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-image',
|
||||||
|
),
|
||||||
|
'ZN\\Hypertext\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-hypertext',
|
||||||
|
),
|
||||||
|
'ZN\\Helpers\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-helpers',
|
||||||
|
),
|
||||||
|
'ZN\\Generator\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-generator',
|
||||||
|
),
|
||||||
|
'ZN\\Filesystem\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-filesystem',
|
||||||
|
),
|
||||||
|
'ZN\\EventHandler\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-event-handler',
|
||||||
|
),
|
||||||
|
'ZN\\Email\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-email',
|
||||||
|
),
|
||||||
|
'ZN\\DateTime\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-datetime',
|
||||||
|
),
|
||||||
|
'ZN\\Database\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-database',
|
||||||
|
),
|
||||||
|
'ZN\\DataTypes\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-datatypes',
|
||||||
|
),
|
||||||
|
'ZN\\Cryptography\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-cryptography',
|
||||||
|
),
|
||||||
|
'ZN\\Crontab\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-crontab',
|
||||||
|
),
|
||||||
|
'ZN\\Console\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-console',
|
||||||
|
),
|
||||||
|
'ZN\\Compression\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-compression',
|
||||||
|
),
|
||||||
|
'ZN\\Comparison\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-comparison',
|
||||||
|
),
|
||||||
|
'ZN\\Captcha\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-captcha',
|
||||||
|
),
|
||||||
|
'ZN\\Cache\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-cache',
|
||||||
|
),
|
||||||
|
'ZN\\Buffering\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-buffering',
|
||||||
|
),
|
||||||
|
'ZN\\Authorization\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-authorization',
|
||||||
|
),
|
||||||
|
'ZN\\Authentication\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-authentication',
|
||||||
|
),
|
||||||
|
'ZN\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/package-zerocore',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
{
|
||||||
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->prefixLengthsPsr4 = ComposerStaticInit18a22f10e44b8b77ed023b6677d08bad::$prefixLengthsPsr4;
|
||||||
|
$loader->prefixDirsPsr4 = ComposerStaticInit18a22f10e44b8b77ed023b6677d08bad::$prefixDirsPsr4;
|
||||||
|
|
||||||
|
}, null, ClassLoader::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Agent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* IP v4
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function get() : string
|
||||||
|
{
|
||||||
|
return $_SERVER['HTTP_USER_AGENT'] ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Configuration
|
||||||
|
*
|
||||||
|
* Enabled when the configuration file can not be accessed.
|
||||||
|
*/
|
||||||
|
class AuthenticationDefaultConfiguration
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| User
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Includes configurations for the User library.
|
||||||
|
|
|
||||||
|
| encode: When the user is registered in, the algorithm to encrypt the
|
||||||
|
| password is set.
|
||||||
|
|
|
||||||
|
| matching: It specifies which tables and columns the User class will use.
|
||||||
|
|
|
||||||
|
| joining: This setting is used if the users table consists of joined
|
||||||
|
| tables.
|
||||||
|
|
|
||||||
|
| emailSenderInfo: This is to specify the sender name and email
|
||||||
|
| information of the e-mail to be sent during the activation process or
|
||||||
|
| password forgotten operations.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $encode = 'md5';
|
||||||
|
public $spectator = '';
|
||||||
|
public $matching =
|
||||||
|
[
|
||||||
|
'table' => '',
|
||||||
|
'columns' =>
|
||||||
|
[
|
||||||
|
'username' => '', # Required
|
||||||
|
'password' => '', # Required
|
||||||
|
'email' => '', # Relative
|
||||||
|
'active' => '', # Relative
|
||||||
|
'banned' => '', # Relative
|
||||||
|
'activation' => '', # Relative
|
||||||
|
'verification' => '', # Rleative
|
||||||
|
'otherLogin' => [] # Relative
|
||||||
|
]
|
||||||
|
];
|
||||||
|
public $joining =
|
||||||
|
[
|
||||||
|
'column' => '',
|
||||||
|
'tables' => []
|
||||||
|
];
|
||||||
|
public $emailSenderInfo =
|
||||||
|
[
|
||||||
|
'name' => '',
|
||||||
|
'mail' => ''
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Language
|
||||||
|
*
|
||||||
|
* Enabled when the language file can not be accessed.
|
||||||
|
*/
|
||||||
|
class AuthenticationDefaultLanguage
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| User
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The language of the User library.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $en =
|
||||||
|
[
|
||||||
|
'registerSuccess' => 'Your registration was completed successfully.',
|
||||||
|
'registerError' => 'You have already registered with the system for the transaction could not be performed!',
|
||||||
|
'registerEmailError' => 'Your process because the system could not be performed previously registered e-mail!',
|
||||||
|
'registerUsernameError' => "The data should include the user name and password!",
|
||||||
|
'loginError' => 'Login failed. The user name or password is incorrect!',
|
||||||
|
'bannedError' => 'You can not login because you have been banned from the system!',
|
||||||
|
'loginSuccess' => 'You have logged in successfully. Redirecting .. Please wait.',
|
||||||
|
'registerUnknownError' => 'Unknown error!',
|
||||||
|
'oldPasswordError' => 'You have entered the wrong password!',
|
||||||
|
'passwordNotMatchError' => 'Passwords do not match!',
|
||||||
|
'updateProcessSuccess' => 'The update process is successful.',
|
||||||
|
'forgotPasswordError' => "You are not registered on the system or your username is incorrect!",
|
||||||
|
'forgotPasswordSuccess' => "Your password has been sent to your email.",
|
||||||
|
'newYourPassword' => "Sent New Password.",
|
||||||
|
'emailError' => "Don't send your mail!",
|
||||||
|
'emailImformationError' => "E-mail information is found!",
|
||||||
|
'username' => "User Name",
|
||||||
|
'password' => "Password",
|
||||||
|
'learnNewPassword' => "Click to login with your new password.",
|
||||||
|
'activation' => "Click to complete the activation process.",
|
||||||
|
'activationProcess' => "User activation process.",
|
||||||
|
'activationError' => "You can not log in to complete the activation process.",
|
||||||
|
'activationEmail' => "For the completion of your registration, please click on the activation link sent to your e-mail address.",
|
||||||
|
'activationCompleteError' => "The activation process could not be completed!",
|
||||||
|
'activationComplete' => "The activation process is completed with success.",
|
||||||
|
'resendActivationError' => 'Activation code e-mail could not be sent if the specified e-mail address has already been activated!',
|
||||||
|
'verificationEmail' => 'Verification Email',
|
||||||
|
'verificationOrEmailError' => 'Verification code or email information is wrong!'
|
||||||
|
];
|
||||||
|
|
||||||
|
public $tr =
|
||||||
|
[
|
||||||
|
'registerSuccess' => 'Kaydınızı başarı ile tamamlandı.',
|
||||||
|
'registerError' => 'Sisteme daha önceden kayıt olduğunuz için işleminiz gerçekleştirilemedi!',
|
||||||
|
'registerEmailError' => 'Sisteme daha önceden kayıtlı e-posta olduğu için işleminiz gerçekleştirilemedi!',
|
||||||
|
'registerUsernameError' => 'Veri, kullanıcı adı ve şifre bilgisini içermelidir!',
|
||||||
|
'loginError' => 'Giriş başarısız. Kullanıcı adı veya şifre yanlış!',
|
||||||
|
'bannedError' => 'Sistemden banlamış olduğunuz için giriş yapamazsınız!',
|
||||||
|
'loginSuccess' => 'Başarı ile giriş yaptınız. Yönlendiriliyorsunuz.. Lütfen bekleyin.',
|
||||||
|
'registerUnknownError' => 'Bilinmeyen hata!',
|
||||||
|
'oldPasswordError' => 'Şifrenizi yanlış girdiniz!',
|
||||||
|
'passwordNotMatchError' => 'Şifreler uyumlu değil!',
|
||||||
|
'updateProcessSuccess' => 'Güncelleme işlemi başarılı.',
|
||||||
|
'forgotPasswordError' => 'Sistemde kayıtlı değilsiniz ya da kullanıcı adınız yanlış!',
|
||||||
|
'forgotPasswordSuccess' => 'Şifreniz e-postanıza gönderilmiştir.',
|
||||||
|
'newYourPassword' => 'Gönderilen Yeni Şifreniz.',
|
||||||
|
'emailError' => 'E-posta gönderilemedi!',
|
||||||
|
'emailImformationError' => 'E-posta bilgisi bulunmamaktadır!',
|
||||||
|
'username' => 'Kullanıcı Adınız',
|
||||||
|
'password' => 'Şifreniz',
|
||||||
|
'learnNewPassword' => 'Yeni şifrenizle giriş yapmak için lütfen tıklayınız.',
|
||||||
|
'activation' => 'Aktivasyon işlemini tamamlamak için tıklayınız.',
|
||||||
|
'activationProcess' => 'Üye aktivasyon işlemi.',
|
||||||
|
'activationError' => 'Aktivasyon işlemini tamamlamadan giriş yapamazsınız.',
|
||||||
|
'activationEmail' => 'Kaydınızın tamamlanması için lütfen e-posta adresinize gönderilen aktivasyon linkine tıklayınız.',
|
||||||
|
'activationCompleteError' => 'Aktivasyon işlemi tamamlanamadı!',
|
||||||
|
'activationComplete' => 'Aktivasyon işlemi başarı ile tamamlandı.',
|
||||||
|
'resendActivationError' => 'Belirtilen e-posta adresinin etkinleştirilmesi zaten yapılmış olduğundan aktivasyon kodu e-postası gönderilemedi!',
|
||||||
|
'verificationEmail' => 'Doğrulama E-postası',
|
||||||
|
'verificationOrEmailError' => 'Doğrulama kodu veya Eposta bilgisi yanlış!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Data extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Data
|
||||||
|
*
|
||||||
|
* @param string $tbl = NULL
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function get(?string $tbl = NULL)
|
||||||
|
{
|
||||||
|
if( $this->getUsernameSessionCookie() )
|
||||||
|
{
|
||||||
|
$r[$tbl] = $this->getUserDataRow();
|
||||||
|
|
||||||
|
if( ! empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
$joinCol = $r[$tbl]->{$this->joinColumn};
|
||||||
|
|
||||||
|
foreach( $this->joinTables as $table => $this->joinColumn )
|
||||||
|
{
|
||||||
|
$r[$table] = $this->getUserDataRowByJoinTableAndColumn($table, $joinCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
return (object) $r[$tbl];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ! empty($tbl) )
|
||||||
|
{
|
||||||
|
return (object) $r[$tbl];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (object) $r; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active Count
|
||||||
|
*
|
||||||
|
* @param string $type = 'active'
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function activeCount($type = 'active') : int
|
||||||
|
{
|
||||||
|
$column = $this->getConfig['matching']['columns'][$type];
|
||||||
|
|
||||||
|
return $this->dbClass->where($column, 1)->get($this->tableName)->totalRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Banned Count
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function bannedCount() : int
|
||||||
|
{
|
||||||
|
return $this->activeCount('banned');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count() : int
|
||||||
|
{
|
||||||
|
return $this->dbClass->get($this->tableName)->totalRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data row
|
||||||
|
*/
|
||||||
|
protected function getUserDataRow()
|
||||||
|
{
|
||||||
|
$this->_multiUsernameColumns($username = $this->getUsernameSessionCookie());
|
||||||
|
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username, 'and')
|
||||||
|
->where($this->passwordColumn, $this->getPasswordSessionCookie())
|
||||||
|
->get($this->tableName)
|
||||||
|
->row();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data row by join table and column
|
||||||
|
*/
|
||||||
|
protected function getUserDataRowByJoinTableAndColumn($table, $column)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->joinColumn, $column)->get($table)->row();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get username session and cookie
|
||||||
|
*/
|
||||||
|
protected function getUsernameSessionCookie()
|
||||||
|
{
|
||||||
|
return $this->sessionClass->select($uniqueUsernameKey = $this->getUniqueUsernameKey()) ?: $this->cookieClass->select($uniqueUsernameKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get password session cookie
|
||||||
|
*/
|
||||||
|
protected function getPasswordSessionCookie()
|
||||||
|
{
|
||||||
|
return $this->sessionClass->select($uniquePasswordKey = $this->getUniquePasswordKey()) ?: $this->cookieClass->select($uniquePasswordKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Authentication\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class ActivationColumnException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'tr' => 'Aktivasyon kolonu ayarlı değil!',
|
||||||
|
'en' => 'Activation column not set!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Authentication\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class ActivationReturnLinkNotFoundException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'tr' => 'Aktivasyon işlemi için dönüş linki belirtilmelidir!',
|
||||||
|
'en' => 'The return link must be specified for the activation process!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Authentication\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class InvalidArgumentException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'tr' => '[%] parametre geçersiz bilgi içeriyor!',
|
||||||
|
'en' => '[%] parameter contains invalid information!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Authentication\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class InvalidEmailException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'tr' => '[%] parametresi geçersiz bir e-posta adresidir!',
|
||||||
|
'en' => '[%] parameter is an invalid email address!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\IS;
|
||||||
|
use ZN\Base;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Request\URL;
|
||||||
|
use ZN\Request\URI;
|
||||||
|
use ZN\Response\Redirect;
|
||||||
|
use ZN\Cryptography\Encode;
|
||||||
|
|
||||||
|
class ForgotPassword extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Email
|
||||||
|
*
|
||||||
|
* @param string $email
|
||||||
|
*/
|
||||||
|
public function email(string $email)
|
||||||
|
{
|
||||||
|
Properties::$parameters['email'] = $email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verification
|
||||||
|
*
|
||||||
|
* @param string $verification
|
||||||
|
*
|
||||||
|
* @return ForgotPassword
|
||||||
|
*/
|
||||||
|
public function verification(string $verification)
|
||||||
|
{
|
||||||
|
Properties::$parameters['verification'] = $verification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password change process
|
||||||
|
*
|
||||||
|
* @param string $changePassword
|
||||||
|
*
|
||||||
|
* @return ForgotPassword
|
||||||
|
*/
|
||||||
|
public function passwordChangeProcess(string $changePassword = 'before')
|
||||||
|
{
|
||||||
|
Properties::$parameters['changePassword'] = $changePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forgot Password
|
||||||
|
*
|
||||||
|
* @param string $email = NULL
|
||||||
|
* @param string $returnLinkPath = NULL
|
||||||
|
* @param string $changePassword = 'before'
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function do(?string $email = NULL, ?string $returnLinkPath = NULL, string $changePassword = 'before') : bool
|
||||||
|
{
|
||||||
|
$this->controlPropertiesParameters($email, $verification, $returnLinkPath, $changePassword);
|
||||||
|
|
||||||
|
$row = $this->getUserDataRowByEmail($email);
|
||||||
|
|
||||||
|
if( isset($row->{$this->usernameColumn}) )
|
||||||
|
{
|
||||||
|
if( ! empty($this->verificationColumn) )
|
||||||
|
{
|
||||||
|
if( ! $verification || $verification !== $row->{$this->verificationColumn} )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('verificationOrEmailError');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! IS::url($returnLinkPath) )
|
||||||
|
{
|
||||||
|
$returnLinkPath = URL::site($returnLinkPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newPassword = $this->createRandomNewPassword();
|
||||||
|
$encodePassword = $this->getEncryptionPassword($newPassword);
|
||||||
|
|
||||||
|
$message = $this->getEmailTemplate
|
||||||
|
([
|
||||||
|
'user' => $username = $row->{$this->usernameColumn},
|
||||||
|
'pass' => $newPassword,
|
||||||
|
'url' => $this->encryptionReturnLink($returnLinkPath, $username, $encodePassword)
|
||||||
|
], 'ForgotPassword');
|
||||||
|
|
||||||
|
if( $this->sendForgotPasswordEmail($email, $message) )
|
||||||
|
{
|
||||||
|
if( $changePassword === 'before' )
|
||||||
|
{
|
||||||
|
if( $this->updateUserPassword($email, $encodePassword) )
|
||||||
|
{
|
||||||
|
return $this->setSuccessMessage('forgotPasswordSuccess');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setErrorMessage('updateError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setSuccessMessage('forgotPasswordSuccess');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('emailError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('forgotPasswordError');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password change complete
|
||||||
|
*/
|
||||||
|
public function passwordChangeComplete(?string $redirect = NULL)
|
||||||
|
{
|
||||||
|
$this->decryptionReturnLink($username, $password);
|
||||||
|
|
||||||
|
if( $this->updateUserPasswordByUsernameAndPassword($username, $password) )
|
||||||
|
{
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
if( $redirect !== NULL )
|
||||||
|
{
|
||||||
|
new Redirect($redirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setSuccessMessage('updateProcessSuccess');
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setErrorMessage('forgotPasswordError');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected encryption return link
|
||||||
|
*/
|
||||||
|
protected function encryptionReturnLink($returnLinkPath, $username, $newEncodePassword)
|
||||||
|
{
|
||||||
|
return Base::suffix($returnLinkPath) . base64_encode($username) . '/' . base64_encode($newEncodePassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected decryption return link
|
||||||
|
*/
|
||||||
|
protected function decryptionReturnLink(&$username, &$password)
|
||||||
|
{
|
||||||
|
$username = base64_decode(URI::segment(-2));
|
||||||
|
$password = base64_decode(URI::segment(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data row by email
|
||||||
|
*/
|
||||||
|
protected function getUserDataRowByEmail($email)
|
||||||
|
{
|
||||||
|
if( ! empty($this->emailColumn) )
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->emailColumn, $email); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->usernameColumn, $email);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->dbClass->get($this->tableName)->row();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected create random new password
|
||||||
|
*/
|
||||||
|
protected function createRandomNewPassword()
|
||||||
|
{
|
||||||
|
return Encode\RandomPassword::create(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected send forgot password email
|
||||||
|
*/
|
||||||
|
protected function sendForgotPasswordEmail($receiver, $message)
|
||||||
|
{
|
||||||
|
$return = Singleton::class('ZN\Email\Sender')
|
||||||
|
->sender($this->senderMail, $this->senderName)
|
||||||
|
->receiver($receiver, $receiver)
|
||||||
|
->subject(Properties::$setEmailTemplateSubject ?? $this->getLang['newYourPassword'])
|
||||||
|
->content($message)
|
||||||
|
->send();
|
||||||
|
|
||||||
|
Properties::$setEmailTemplateSubject = NULL;
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected update user password
|
||||||
|
*/
|
||||||
|
protected function updateUserPassword($email, $password)
|
||||||
|
{
|
||||||
|
if( ! empty($this->emailColumn) )
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->emailColumn, $email, 'and'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->usernameColumn, $email, 'and');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->dbClass->update($this->tableName, [$this->passwordColumn => $password]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected update user password with username
|
||||||
|
*/
|
||||||
|
protected function updateUserPasswordByUsernameAndPassword($username, $newPassword)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username)->update($this->tableName, [$this->passwordColumn => $newPassword]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected control properties parameters
|
||||||
|
*/
|
||||||
|
protected function controlPropertiesParameters(&$email, &$verification, &$returnLinkPath, &$changePassword)
|
||||||
|
{
|
||||||
|
$email = Properties::$parameters['email'] ?? $email;
|
||||||
|
$verification = Properties::$parameters['verification'] ?? NULL;
|
||||||
|
$returnLinkPath = Properties::$parameters['returnLink'] ?? $returnLinkPath;
|
||||||
|
$changePassword = Properties::$parameters['changePassword'] ?? $changePassword;
|
||||||
|
|
||||||
|
Properties::$parameters = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Request\Request;
|
||||||
|
|
||||||
|
class IP
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* IP v4.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function v4() : string
|
||||||
|
{
|
||||||
|
return Request::ipv4();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Information
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get errors
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function error()
|
||||||
|
{
|
||||||
|
return Properties::$error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get success
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function success()
|
||||||
|
{
|
||||||
|
return Properties::$success;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Login extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Username
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
public function username(string $username)
|
||||||
|
{
|
||||||
|
Properties::$parameters['username'] = $username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password
|
||||||
|
*
|
||||||
|
* @param string $password
|
||||||
|
*/
|
||||||
|
public function password(string $password)
|
||||||
|
{
|
||||||
|
Properties::$parameters['password'] = $password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remember
|
||||||
|
*
|
||||||
|
* @param bool $remember = true
|
||||||
|
*/
|
||||||
|
public function remember(bool $remember = true)
|
||||||
|
{
|
||||||
|
Properties::$parameters['remember'] = $remember;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do Login
|
||||||
|
*
|
||||||
|
* @param string $username = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
* @param mixed $rememberMe = false
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function do(?string $username = NULL, ?string $password = NULL, $rememberMe = false) : bool
|
||||||
|
{
|
||||||
|
$rpassword = $password;
|
||||||
|
|
||||||
|
$this->controlPropertiesParameters($username, $password, $rememberMe);
|
||||||
|
|
||||||
|
if( ! is_scalar($rememberMe) )
|
||||||
|
{
|
||||||
|
$rememberMe = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$password = $this->getEncryptionPassword($password);
|
||||||
|
|
||||||
|
$this->_multiUsernameColumns($username);
|
||||||
|
|
||||||
|
$r = $this->getUserTableByUsername($username)->row();
|
||||||
|
|
||||||
|
if( ! isset($r->{$this->passwordColumn}) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('loginError');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->bannedColumn) )
|
||||||
|
{
|
||||||
|
$bannedControl = $r->{$this->bannedColumn};
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->activationColumn) )
|
||||||
|
{
|
||||||
|
$activationControl = $r->{$this->activationColumn}; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
! empty($r->{$this->usernameColumn}) && ($r->{$this->passwordColumn} == $password || ($this->spectator !== NULL && $this->spectator == $rpassword)) )
|
||||||
|
{
|
||||||
|
if( $this->spectator !== NULL )
|
||||||
|
{
|
||||||
|
$password = $r->{$this->passwordColumn}; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->bannedColumn) && ! empty($bannedControl) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('bannedError');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->activationColumn) && empty($activationControl) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('activationError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->startUserSession($username, $password);
|
||||||
|
|
||||||
|
if( ! empty($rememberMe) )
|
||||||
|
{
|
||||||
|
$this->startPermanentUserSessionWithCookie($username, $password); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->activeColumn) )
|
||||||
|
{
|
||||||
|
$this->setUserStateActive($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setSuccessMessage('loginSuccess');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('loginError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is Login
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is() : bool
|
||||||
|
{
|
||||||
|
$getUserData = $this->getUserData();
|
||||||
|
|
||||||
|
if( ! empty($this->bannedColumn) && ! empty($getUserData->{$this->bannedColumn}) )
|
||||||
|
{
|
||||||
|
$this->logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->rememberUsernameAndPassword($cUsername, $cPassword);
|
||||||
|
|
||||||
|
if( isset($getUserData->{$this->usernameColumn}) )
|
||||||
|
{
|
||||||
|
$isLogin = true;
|
||||||
|
}
|
||||||
|
elseif( $this->userExists($cUsername, $cPassword) )
|
||||||
|
{
|
||||||
|
$isLogin = $this->startUserSession($cUsername, $cPassword); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$isLogin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $isLogin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected user exists
|
||||||
|
*/
|
||||||
|
protected function userExists($username, $password)
|
||||||
|
{
|
||||||
|
if( ! empty($username) && ! empty($password) )
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username, 'and')
|
||||||
|
->where($this->passwordColumn, $password)
|
||||||
|
->get($this->tableName)
|
||||||
|
->totalRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected remember username and password
|
||||||
|
*/
|
||||||
|
protected function rememberUsernameAndPassword(&$username, &$password)
|
||||||
|
{
|
||||||
|
$username = $this->cookieClass->select($this->getUniqueUsernameKey());
|
||||||
|
$password = $this->cookieClass->select($this->getUniquePasswordKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected set user state active
|
||||||
|
*/
|
||||||
|
protected function setUserStateActive($username)
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->usernameColumn, $username)
|
||||||
|
->update($this->tableName, [$this->activeColumn => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected start user session
|
||||||
|
*/
|
||||||
|
protected function startUserSession($username, $password)
|
||||||
|
{
|
||||||
|
$this->sessionClass->insert($this->getUniqueUsernameKey(), $username);
|
||||||
|
$this->sessionClass->insert($this->getUniquePasswordKey(), $password);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected start permanent user session with cookie
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
protected function startPermanentUserSessionWithCookie($username, $password)
|
||||||
|
{
|
||||||
|
if( $this->cookieClass->select($uniqueUsernameKey = $this->getUniqueUsernameKey()) !== $username )
|
||||||
|
{
|
||||||
|
$this->cookieClass->insert($uniqueUsernameKey, $username);
|
||||||
|
$this->cookieClass->insert($this->getUniquePasswordKey(), $password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data
|
||||||
|
*/
|
||||||
|
protected function getUserData()
|
||||||
|
{
|
||||||
|
return (new Data)->get($this->tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected logout
|
||||||
|
*/
|
||||||
|
protected function logout()
|
||||||
|
{
|
||||||
|
(new Logout)->do();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected control properties parameters
|
||||||
|
*/
|
||||||
|
protected function controlPropertiesParameters(&$username, &$password, &$rememberMe)
|
||||||
|
{
|
||||||
|
$username = Properties::$parameters['username'] ?? $username;
|
||||||
|
$password = Properties::$parameters['password'] ?? $password;
|
||||||
|
$rememberMe = Properties::$parameters['remember'] ?? $rememberMe;
|
||||||
|
|
||||||
|
Properties::$parameters = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Response\Redirect;
|
||||||
|
|
||||||
|
class Logout extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Do Logout
|
||||||
|
*
|
||||||
|
* @param string $redirectUrl = NULL
|
||||||
|
* @param int $time = 0
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function do(?string $redirectUrl = NULL, int $time = 0)
|
||||||
|
{
|
||||||
|
if( $this->isUserStateActive() !== NULL )
|
||||||
|
{
|
||||||
|
if( ! empty($this->activeColumn) )
|
||||||
|
{
|
||||||
|
$this->setUserStatePassive($this->isUserStateActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endUserProcessAndRedirect($redirectUrl, $time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected is user state active
|
||||||
|
*/
|
||||||
|
protected function isUserStateActive()
|
||||||
|
{
|
||||||
|
return (new Data)->get($this->tableName)->{$this->usernameColumn} ?? NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected set user state passive
|
||||||
|
*/
|
||||||
|
protected function setUserStatePassive($username)
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->usernameColumn, $username)
|
||||||
|
->update($this->tableName, [$this->activeColumn => 0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected end user process
|
||||||
|
*/
|
||||||
|
protected function endUserProcessAndRedirect($redirectUrl, $time)
|
||||||
|
{
|
||||||
|
$this->cookieClass ->delete($uniqueUsernameKey = $this->getUniqueUsernameKey());
|
||||||
|
$this->cookieClass ->delete($this->getUniquePasswordKey());
|
||||||
|
$this->sessionClass->delete($uniqueUsernameKey);
|
||||||
|
|
||||||
|
new Redirect((string) $redirectUrl, $time, [], Properties::$redirectExit);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Properties
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps parameters
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $parameters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps errors
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps success
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirecting
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $redirectExit = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps set email template
|
||||||
|
*
|
||||||
|
* 5.7.3[added]
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public static $setEmailTemplate = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps set email subject. [6.7.0]
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public static $setEmailTemplateSubject = NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,354 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\IS;
|
||||||
|
use ZN\Base;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Request\URL;
|
||||||
|
use ZN\Request\URI;
|
||||||
|
use ZN\Response\Redirect;
|
||||||
|
|
||||||
|
class Register extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Auto login.
|
||||||
|
*
|
||||||
|
* @param mixed $autoLogin = true
|
||||||
|
*/
|
||||||
|
public function autoLogin($autoLogin = true)
|
||||||
|
{
|
||||||
|
Properties::$parameters['autoLogin'] = $autoLogin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do register.
|
||||||
|
*
|
||||||
|
* @param string|array $data = NULL
|
||||||
|
* @param mixed $autoLogin = false
|
||||||
|
* @param string $activationReturnLink = ''
|
||||||
|
*
|
||||||
|
* @return Bool
|
||||||
|
*/
|
||||||
|
public function do($data = NULL, $autoLogin = false, string $activationReturnLink = '') : bool
|
||||||
|
{
|
||||||
|
$this->autoMatchColumns($data);
|
||||||
|
$this->controlPropertiesParameters($data, $autoLogin, $activationReturnLink);
|
||||||
|
|
||||||
|
if( ! empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
$joinData = $data;
|
||||||
|
$data = $data[$this->tableName] ?? [$this->tableName];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isset($data[$this->usernameColumn]) || ! isset($data[$this->passwordColumn]) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('registerUsernameError');
|
||||||
|
}
|
||||||
|
|
||||||
|
$loginUsername = $data[$this->usernameColumn];
|
||||||
|
$loginPassword = $data[$this->passwordColumn];
|
||||||
|
$encodePassword = $this->getEncryptionPassword($loginPassword);
|
||||||
|
$usernameControl = $this->getTotalRowsByUsername($loginUsername);
|
||||||
|
|
||||||
|
if( empty($usernameControl) )
|
||||||
|
{
|
||||||
|
$data[$this->passwordColumn] = $encodePassword;
|
||||||
|
|
||||||
|
if( ! $this->registerUserInformations($data) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('registerUnknownError');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
$this->insertJoinUserDataByUsername($loginUsername, $joinData);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setSuccessMessage('registerSuccess');
|
||||||
|
|
||||||
|
if( ! empty($this->activationColumn) )
|
||||||
|
{
|
||||||
|
if( ! IS::email($loginUsername) )
|
||||||
|
{
|
||||||
|
$email = $data[$this->emailColumn] ?? NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$email = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( empty($activationReturnLink) )
|
||||||
|
{
|
||||||
|
throw new Exception\ActivationReturnLinkNotFoundException;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendActivationEmail($loginUsername, $encodePassword, $activationReturnLink, $email);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( $autoLogin === true )
|
||||||
|
{
|
||||||
|
$this->doLogin($loginUsername, $loginPassword);
|
||||||
|
}
|
||||||
|
elseif( is_string($autoLogin) )
|
||||||
|
{
|
||||||
|
$this->redirectAutoLogin($autoLogin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('registerError');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activation complete.
|
||||||
|
*
|
||||||
|
* 5.7.3[changed]
|
||||||
|
*
|
||||||
|
* @param string|int $userUriKey = 'user
|
||||||
|
* @param string|int|callable $decryptor = 'pass'
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function activationComplete($userUriKey = 'user', $decryptor = 'pass') : bool
|
||||||
|
{
|
||||||
|
# Return link values.
|
||||||
|
# 5.7.3[added]
|
||||||
|
if( is_scalar($userUriKey) )
|
||||||
|
{
|
||||||
|
$user = URI::get($userUriKey);
|
||||||
|
}
|
||||||
|
# invalid usage
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidArgumentException(NULL, '1.');
|
||||||
|
}
|
||||||
|
|
||||||
|
# 5.7.3[added]
|
||||||
|
# scalar
|
||||||
|
if( is_scalar($decryptor) )
|
||||||
|
{
|
||||||
|
$pass = URI::get($decryptor);
|
||||||
|
}
|
||||||
|
# callable
|
||||||
|
elseif( is_callable($decryptor) )
|
||||||
|
{
|
||||||
|
$pass = $decryptor();
|
||||||
|
}
|
||||||
|
# invalid usage
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidArgumentException(NULL, '2.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($user) && ! empty($pass) )
|
||||||
|
{
|
||||||
|
$row = $this->getUserDataByUsernameAndPassword($user, $pass);
|
||||||
|
|
||||||
|
if( ! empty($row) )
|
||||||
|
{
|
||||||
|
$this->updateUserActivationColumnByUsername($user);
|
||||||
|
|
||||||
|
return $this->setSuccessMessage('activationComplete');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('activationCompleteError');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('activationCompleteError');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resend activation e-mail.
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $returnLink
|
||||||
|
* @param string $email = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function resendActivationEmail(string $username, string $returnLink, ?string $email = NULL) : bool
|
||||||
|
{
|
||||||
|
if( empty($this->activationColumn) )
|
||||||
|
{
|
||||||
|
throw new Exception\ActivationColumnException;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->isResendActivationEmailByValue($email ?? $username);
|
||||||
|
|
||||||
|
if( empty($data) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('resendActivationError');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sendActivationEmail($username, $data->{$this->passwordColumn}, $returnLink, $email);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected send activation email
|
||||||
|
*
|
||||||
|
* @param string $user
|
||||||
|
* @param string $pass
|
||||||
|
* @param string $activationReturnLink
|
||||||
|
* @param string $email
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function sendActivationEmail($user, $pass, $activationReturnLink, $email)
|
||||||
|
{
|
||||||
|
$url = Base::suffix($activationReturnLink);
|
||||||
|
|
||||||
|
if( ! IS::url($url) )
|
||||||
|
{
|
||||||
|
$url = URL::site($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
# 5.7.3[added]
|
||||||
|
# Sets activation email content
|
||||||
|
$message = $this->getEmailTemplate
|
||||||
|
([
|
||||||
|
'url' => $url,
|
||||||
|
'user' => $user,
|
||||||
|
'pass' => $pass
|
||||||
|
], 'Activation');
|
||||||
|
|
||||||
|
$user = $email ?? $user;
|
||||||
|
|
||||||
|
if( ! IS::email($user) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidEmailException(NULL, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$emailclass = Singleton::class('ZN\Email\Sender');
|
||||||
|
|
||||||
|
$emailclass->sender($this->senderMail, $this->senderName)
|
||||||
|
->receiver($user, $user)
|
||||||
|
->subject(Properties::$setEmailTemplateSubject ?? $this->getLang['activationProcess'])
|
||||||
|
->content($message);
|
||||||
|
|
||||||
|
Properties::$setEmailTemplateSubject = NULL;
|
||||||
|
|
||||||
|
if( $emailclass->send() )
|
||||||
|
{
|
||||||
|
return $this->setSuccessMessage('activationEmail');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('emailError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected is resend activation email by value
|
||||||
|
*/
|
||||||
|
protected function isResendActivationEmailByValue($value)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $value, 'and')
|
||||||
|
->where($this->activationColumn, '0')
|
||||||
|
->get($this->tableName)
|
||||||
|
->row();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data by username and password
|
||||||
|
*/
|
||||||
|
protected function getUserDataByUsernameAndPassword($username, $password)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username, 'and')
|
||||||
|
->where($this->passwordColumn, $password)
|
||||||
|
->get($this->tableName)
|
||||||
|
->row();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected update user activation column by username
|
||||||
|
*/
|
||||||
|
protected function updateUserActivationColumnByUsername($username)
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->usernameColumn, $username)
|
||||||
|
->update($this->tableName, [$this->activationColumn => '1']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected redirect auto login
|
||||||
|
*/
|
||||||
|
protected function redirectAutoLogin($path)
|
||||||
|
{
|
||||||
|
new Redirect($path, 0, [], Properties::$redirectExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get total rows by username
|
||||||
|
*/
|
||||||
|
protected function getTotalRowsByUsername($username)
|
||||||
|
{
|
||||||
|
return $this->getUserTableByUsername($username)->totalRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get join column by username
|
||||||
|
*/
|
||||||
|
protected function getJoinColumnByUsername($username)
|
||||||
|
{
|
||||||
|
return $this->getUserTableByUsername($username)->row()->{$this->joinColumn};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected insert join user data by username
|
||||||
|
*/
|
||||||
|
protected function insertJoinUserDataByUsername($username, &$joinData)
|
||||||
|
{
|
||||||
|
$joinCol = $this->getJoinColumnByUsername($username);
|
||||||
|
|
||||||
|
foreach( $this->joinTables as $table => $joinColumn )
|
||||||
|
{
|
||||||
|
$joinData[$table][$this->joinTables[$table]] = $joinCol;
|
||||||
|
|
||||||
|
$this->dbClass->insert($table, $joinData[$table]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected register user informations
|
||||||
|
*/
|
||||||
|
protected function registerUserInformations($data)
|
||||||
|
{
|
||||||
|
return $this->dbClass->insert($this->tableName, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected do login
|
||||||
|
*/
|
||||||
|
protected function doLogin($username, $password)
|
||||||
|
{
|
||||||
|
(new Login)->do($username, $password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected control properties parameters
|
||||||
|
*/
|
||||||
|
protected function controlPropertiesParameters(&$data, &$autoLogin, &$activationReturnLink)
|
||||||
|
{
|
||||||
|
$data = Properties::$parameters['column'] ?? $data;
|
||||||
|
$autoLogin = Properties::$parameters['autoLogin'] ?? $autoLogin;
|
||||||
|
$activationReturnLink = Properties::$parameters['returnLink'] ?? $activationReturnLink;
|
||||||
|
|
||||||
|
Properties::$parameters = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php $lang = ZN\Lang::default('ZN\Authentication\AuthenticationDefaultLanguage')::select('Authentication'); ?>
|
||||||
|
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th><?php echo $lang['activationProcess']?></th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="<?php echo $url.'user/'.$user.'/pass/'.$pass; ?>"> <?php echo $lang['activation']?> </a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
<?php $lang = ZN\Lang::default('ZN\Authentication\AuthenticationDefaultLanguage')::select('Authentication'); ?>
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th colspan="2"><?php echo $lang['verificationEmail']?></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $lang['username']?></td>
|
||||||
|
<td><?php echo $user; ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $lang['password']?></td>
|
||||||
|
<td><?php echo $pass; ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<a href="<?php echo $url; ?>"><?php echo $lang['learnNewPassword']; ?></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</pre>
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\IS;
|
||||||
|
use ZN\Singleton;
|
||||||
|
|
||||||
|
class SendEmail extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps email class
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
protected $emailClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic construct
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->emailClass = Singleton::class('ZN\Email\Sender');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attachment
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $disposition = NULL
|
||||||
|
* @param string $newName = NULL
|
||||||
|
* @param mixed $mime = NULL
|
||||||
|
*/
|
||||||
|
public function attachment(string $file, ?string $disposition = NULL, ?string $newName = NULL, $mime = NULL)
|
||||||
|
{
|
||||||
|
$this->emailClass->attachment($file, $disposition, $newName, $mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send
|
||||||
|
*
|
||||||
|
* @param string $subject
|
||||||
|
* @param string $body
|
||||||
|
* @param int $count = 35
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function send(string $subject, string $body, int $count = 35)
|
||||||
|
{
|
||||||
|
if( empty($this->usernameColumn) )
|
||||||
|
{
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = array_chunk($this->getUserDataResult(), $count);
|
||||||
|
$sendCount = count($users);
|
||||||
|
|
||||||
|
$this->emailClass->sender($this->senderMail, $this->senderName);
|
||||||
|
|
||||||
|
for( $i = 0; $i < $sendCount; $i++ )
|
||||||
|
{
|
||||||
|
foreach( $users[$i] as $user )
|
||||||
|
{
|
||||||
|
$username = $user->{$this->usernameColumn};
|
||||||
|
|
||||||
|
$email = IS::email($username)
|
||||||
|
? $username
|
||||||
|
: ($user->{$this->emailColumn} ?? '');
|
||||||
|
|
||||||
|
if( IS::email($email) )
|
||||||
|
{
|
||||||
|
$this->emailClass->bcc($email, $username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->emailClass->send($subject, $body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data result
|
||||||
|
*/
|
||||||
|
protected function getUserDataResult()
|
||||||
|
{
|
||||||
|
if( ! empty($this->bannedColumn) )
|
||||||
|
{
|
||||||
|
$this->dbClass->where($this->bannedColumn, 0); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->dbClass->get($this->tableName)->result();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Update extends UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Controls old password
|
||||||
|
*
|
||||||
|
* @param string $oldPassword
|
||||||
|
*/
|
||||||
|
public function oldPassword(string $oldPassword)
|
||||||
|
{
|
||||||
|
Properties::$parameters['oldPassword'] = $oldPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New Password
|
||||||
|
*
|
||||||
|
* @param string $newPassword
|
||||||
|
*/
|
||||||
|
public function newPassword(string $newPassword)
|
||||||
|
{
|
||||||
|
Properties::$parameters['newPassword'] = $newPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password Again
|
||||||
|
*
|
||||||
|
* @param string $passwordAgain
|
||||||
|
*/
|
||||||
|
public function passwordAgain(string $passwordAgain)
|
||||||
|
{
|
||||||
|
Properties::$parameters['passwordAgain'] = $passwordAgain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do Update
|
||||||
|
*
|
||||||
|
* @param string $old = NULL
|
||||||
|
* @param string $new = NULL
|
||||||
|
* @param string $newAgain = NULL
|
||||||
|
* @param string|array $data = []
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function do(?string $old = NULL, ?string $new = NULL, ?string $newAgain = NULL, $data = []) : bool
|
||||||
|
{
|
||||||
|
if( $this->isLogin() )
|
||||||
|
{
|
||||||
|
$this->autoMatchColumns($data);
|
||||||
|
$this->controlPropertiesParameters($old, $new, $newAgain, $data);
|
||||||
|
|
||||||
|
if( empty($newAgain) )
|
||||||
|
{
|
||||||
|
$newAgain = $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldPassword = $this->getEncryptionPassword($old);
|
||||||
|
$newPassword = $this->getEncryptionPassword($new);
|
||||||
|
$newPasswordAgain = $this->getEncryptionPassword($newAgain);
|
||||||
|
|
||||||
|
if( ! empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
$joinData = $data;
|
||||||
|
$data = $data[$this->tableName] ?? [$this->tableName];
|
||||||
|
}
|
||||||
|
|
||||||
|
$getUserData = $this->getUserData();
|
||||||
|
$username = $getUserData->{$this->usernameColumn};
|
||||||
|
$password = $getUserData->{$this->passwordColumn};
|
||||||
|
|
||||||
|
if( $oldPassword != $password )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('oldPasswordError');
|
||||||
|
}
|
||||||
|
elseif( $newPassword != $newPasswordAgain )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('passwordNotMatchError');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$data[$this->passwordColumn] = $newPassword;
|
||||||
|
$data[$this->usernameColumn] = $username;
|
||||||
|
|
||||||
|
if( ! empty($this->joinTables) )
|
||||||
|
{
|
||||||
|
$joinCol = $this->getJoinColumnByUsername($username);
|
||||||
|
|
||||||
|
foreach( $this->joinTables as $table => $joinColumn )
|
||||||
|
{
|
||||||
|
if( isset($joinData[$table]) )
|
||||||
|
{
|
||||||
|
$this->updateUserData($table, $joinColumn, $joinCol, $joinData[$table]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ! $this->updateUserData($this->tableName, $this->usernameColumn, $username, $data) )
|
||||||
|
{
|
||||||
|
return $this->setErrorMessage('registerUnknownError'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setSuccessMessage('updateProcessSuccess');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected update user data
|
||||||
|
*/
|
||||||
|
protected function updateUserData($table, $column, $value, $data)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($column, $value)->update($table, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get join column by username
|
||||||
|
*/
|
||||||
|
protected function getJoinColumnByUsername($username)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username)->get($this->tableName)->row()->{$this->joinColumn};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected is login
|
||||||
|
*/
|
||||||
|
protected function isLogin()
|
||||||
|
{
|
||||||
|
return (new Login)->is();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user data
|
||||||
|
*/
|
||||||
|
protected function getUserData()
|
||||||
|
{
|
||||||
|
return (new Data)->get($this->tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected control properties parameters
|
||||||
|
*/
|
||||||
|
protected function controlPropertiesParameters(&$old, &$new, &$newAgain, &$data)
|
||||||
|
{
|
||||||
|
$old = Properties::$parameters['oldPassword'] ?? $old;
|
||||||
|
$new = Properties::$parameters['newPassword'] ?? $new;
|
||||||
|
$newAgain = Properties::$parameters['passwordAgain'] ?? $newAgain;
|
||||||
|
$data = Properties::$parameters['column'] ?? $data;
|
||||||
|
|
||||||
|
Properties::$parameters = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Controller\Factory;
|
||||||
|
|
||||||
|
class User extends Factory
|
||||||
|
{
|
||||||
|
const factory =
|
||||||
|
[
|
||||||
|
'methods' =>
|
||||||
|
[
|
||||||
|
'register' => 'Register::do',
|
||||||
|
'autologin' => 'Register::autoLogin:this',
|
||||||
|
'activationcomplete' => 'Register::activationComplete',
|
||||||
|
'resendactivationemail' => 'Register::resendActivationEmail',
|
||||||
|
'returnlink' => 'UserExtends::returnLink:this',
|
||||||
|
'column' => 'UserExtends::column:this',
|
||||||
|
'setactivationemail' => 'UserExtends::setEmailTemplate:this',
|
||||||
|
'setforgotpasswordemail'=> 'UserExtends::setEmailTemplate:this',
|
||||||
|
'getencryptionpassword' => 'UserExtends::getEncryptionPassword',
|
||||||
|
'update' => 'Update::do',
|
||||||
|
'oldpassword' => 'Update::oldPassword:this',
|
||||||
|
'newpassword' => 'Update::newPassword:this',
|
||||||
|
'passwordagain' => 'Update::passwordAgain:this',
|
||||||
|
'username' => 'Login::username:this',
|
||||||
|
'password' => 'Login::password:this',
|
||||||
|
'remember' => 'Login::remember:this',
|
||||||
|
'login' => 'Login::do',
|
||||||
|
'islogin' => 'Login::is',
|
||||||
|
'logout' => 'Logout::do',
|
||||||
|
'forgotpassword' => 'ForgotPassword::do',
|
||||||
|
'verification' => 'ForgotPassword::verification:this',
|
||||||
|
'email' => 'ForgotPassword::email:this',
|
||||||
|
'passwordchangeprocess' => 'ForgotPassword::passwordChangeProcess:this',
|
||||||
|
'passwordchangecomplete'=> 'ForgotPassword::passwordChangeComplete',
|
||||||
|
'data' => 'Data::get',
|
||||||
|
'activecount' => 'Data::activeCount',
|
||||||
|
'bannedcount' => 'Data::bannedCount',
|
||||||
|
'count' => 'Data::count',
|
||||||
|
'error' => 'Information::error',
|
||||||
|
'success' => 'Information::success',
|
||||||
|
'attachment' => 'SendEmail::attachment:this',
|
||||||
|
'sendemailall' => 'SendEmail::send',
|
||||||
|
'ipv4' => 'IP::v4',
|
||||||
|
'ip' => 'IP::v4',
|
||||||
|
'agent' => 'Agent::get'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
<?php namespace ZN\Authentication;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Lang;
|
||||||
|
use ZN\Config;
|
||||||
|
use ZN\Inclusion;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Request\Method;
|
||||||
|
use ZN\Cryptography\Encode;
|
||||||
|
|
||||||
|
class UserExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get user config
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $getConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps config variables
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $encodeType,
|
||||||
|
$spectator,
|
||||||
|
$tableName,
|
||||||
|
$usernameColumn,
|
||||||
|
$passwordColumn,
|
||||||
|
$emailColumn,
|
||||||
|
$bannedColumn,
|
||||||
|
$activeColumn,
|
||||||
|
$activationColumn,
|
||||||
|
$verificationColumn,
|
||||||
|
$otherLoginColumns,
|
||||||
|
$joinTables,
|
||||||
|
$joinColumn,
|
||||||
|
$senderMail,
|
||||||
|
$senderName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps references
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
protected $getLang,
|
||||||
|
$dbClass,
|
||||||
|
$sessionClass,
|
||||||
|
$cookieClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
# If no configuration file is found, predefined settings will be enabled.
|
||||||
|
$this->getConfig = array_merge
|
||||||
|
(
|
||||||
|
Config::default('ZN\Authentication\AuthenticationDefaultConfiguration')::get('Authentication') ?: [],
|
||||||
|
Config::get('Auth') ?: []
|
||||||
|
);
|
||||||
|
|
||||||
|
# When the user is registered in,
|
||||||
|
# the algorithm to encrypt the password is set.
|
||||||
|
$this->encodeType = $this->getConfig['encode'];
|
||||||
|
|
||||||
|
# Spectator for users profile
|
||||||
|
$this->spectator = $this->getConfig['spectator'] ?: NULL;
|
||||||
|
|
||||||
|
# Table name where user information will be stored.
|
||||||
|
$this->tableName = $this->getConfig['matching']['table'];
|
||||||
|
|
||||||
|
# The User class contains matching information for column
|
||||||
|
# information that is required for some operations.
|
||||||
|
$matchingColumn = $this->getConfig['matching']['columns'];
|
||||||
|
|
||||||
|
$this->usernameColumn = $matchingColumn['username'];
|
||||||
|
$this->passwordColumn = $matchingColumn['password'];
|
||||||
|
$this->emailColumn = $matchingColumn['email'];
|
||||||
|
$this->activeColumn = $matchingColumn['active'];
|
||||||
|
$this->activationColumn = $matchingColumn['activation'];
|
||||||
|
$this->bannedColumn = $matchingColumn['banned'];
|
||||||
|
$this->verificationColumn = $matchingColumn['verification'];
|
||||||
|
$this->otherLoginColumns = $matchingColumn['otherLogin'];
|
||||||
|
|
||||||
|
# If the user's information is stored in more than one tablature,
|
||||||
|
# this table is used so that it can be accessed by the User class.
|
||||||
|
$joining = $this->getConfig['joining'];
|
||||||
|
|
||||||
|
$this->joinTables = $joining['tables'];
|
||||||
|
$this->joinColumn = $joining['column'];
|
||||||
|
|
||||||
|
# It contains pre-defined e-mail and name information
|
||||||
|
# for user class's e-mail sending methods.
|
||||||
|
$emailSenderInfo = $this->getConfig['emailSenderInfo'];
|
||||||
|
|
||||||
|
$this->senderMail = $emailSenderInfo['mail'];
|
||||||
|
$this->senderName = $emailSenderInfo['name'];
|
||||||
|
|
||||||
|
# If no language file is found, predefined settings will be enabled.
|
||||||
|
$this->getLang = Lang::default('ZN\Authentication\AuthenticationDefaultLanguage')
|
||||||
|
::select('Authentication');
|
||||||
|
|
||||||
|
# PThe necessary classes are called for the User class.
|
||||||
|
$this->dbClass = Singleton::class('ZN\Database\DB');
|
||||||
|
$this->sessionClass = Singleton::class('ZN\Storage\Session');
|
||||||
|
$this->cookieClass = Singleton::class('ZN\Storage\Cookie');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get unique username key
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUniqueUsernameKey()
|
||||||
|
{
|
||||||
|
return CONTAINER_PROJECT . $this->usernameColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get unique password key
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUniquePasswordKey()
|
||||||
|
{
|
||||||
|
return CONTAINER_PROJECT . $this->passwordColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set column
|
||||||
|
*
|
||||||
|
* @param string $column
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function column(string $column, $value)
|
||||||
|
{
|
||||||
|
Properties::$parameters['column'][$column] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return link
|
||||||
|
*
|
||||||
|
* @param string $returnLink
|
||||||
|
*/
|
||||||
|
public function returnLink(string $returnLink)
|
||||||
|
{
|
||||||
|
Properties::$parameters['returnLink'] = $returnLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get encryption password
|
||||||
|
*
|
||||||
|
* @param string $password
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptionPassword($password)
|
||||||
|
{
|
||||||
|
return ! empty($this->encodeType) ? Encode\Type::create($password ?? '', $this->encodeType) : $password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets activation email
|
||||||
|
*
|
||||||
|
* 5.7.3[added]
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @param string $subject = NULL [6.7.0]
|
||||||
|
*/
|
||||||
|
public function setEmailTemplate(string $message, ?string $subject = NULL)
|
||||||
|
{
|
||||||
|
Properties::$setEmailTemplate = $message;
|
||||||
|
Properties::$setEmailTemplateSubject = $subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected activation email data
|
||||||
|
*/
|
||||||
|
protected function replaceActivationEmailData(array $replace)
|
||||||
|
{
|
||||||
|
$data = Properties::$setEmailTemplate;
|
||||||
|
|
||||||
|
Properties::$setEmailTemplate = NULL;
|
||||||
|
|
||||||
|
$preg =
|
||||||
|
[
|
||||||
|
'/\{user\}/' => $replace['user'],
|
||||||
|
'/\{pass\}/' => $replace['pass'],
|
||||||
|
'/\{url\}/' => $replace['url']
|
||||||
|
];
|
||||||
|
|
||||||
|
return preg_replace_callback('/\[(.*?)\]/', function($match) use($replace)
|
||||||
|
{
|
||||||
|
return $replace['url'] . $match[1];
|
||||||
|
|
||||||
|
}, preg_replace(array_keys($preg), array_values($preg), $data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get email template
|
||||||
|
*/
|
||||||
|
protected function getEmailTemplate($data, $template)
|
||||||
|
{
|
||||||
|
# 5.7.3[added]
|
||||||
|
# Sets activation email content
|
||||||
|
if( ! empty(Properties::$setEmailTemplate) )
|
||||||
|
{
|
||||||
|
return $this->replaceActivationEmailData($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default activation email template
|
||||||
|
return Inclusion\View::use($template, $data, true, __DIR__ . '/Resources/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected auto match columns
|
||||||
|
*/
|
||||||
|
protected function autoMatchColumns(&$data)
|
||||||
|
{
|
||||||
|
if( is_string($data) && in_array($data, ['post', 'get', 'request']) )
|
||||||
|
{
|
||||||
|
$columns = array_flip($this->getUserTableColumns());
|
||||||
|
$data = array_intersect_key(Method::$data(), $columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get user table columns
|
||||||
|
*/
|
||||||
|
protected function getUserTableColumns()
|
||||||
|
{
|
||||||
|
return $this->dbClass->get($this->tableName)->columns();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user table by username
|
||||||
|
*/
|
||||||
|
protected function getUserTableByUsername($username)
|
||||||
|
{
|
||||||
|
return $this->dbClass->where($this->usernameColumn, $username)->get($this->tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected set error message
|
||||||
|
*/
|
||||||
|
protected function setErrorMessage($string)
|
||||||
|
{
|
||||||
|
return ! (bool) (Properties::$error = $this->getLang[$string]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected set error message
|
||||||
|
*/
|
||||||
|
protected function setSuccessMessage($string)
|
||||||
|
{
|
||||||
|
return (bool) (Properties::$success = $this->getLang[$string]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected multi username columns
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function _multiUsernameColumns($value)
|
||||||
|
{
|
||||||
|
if( ! empty($this->otherLoginColumns) )
|
||||||
|
{
|
||||||
|
foreach( $this->otherLoginColumns as $column )
|
||||||
|
{
|
||||||
|
$this->dbClass->where($column, $value, 'or');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Configuration
|
||||||
|
*
|
||||||
|
* Enabled when the configuration file can not be accessed.
|
||||||
|
*/
|
||||||
|
class AuthorizationDefaultConfiguration
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Permission
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Includes configurations for the Permission library.
|
||||||
|
|
|
||||||
|
| method : It is used to set which id value will use which method of sending.
|
||||||
|
| page : It is used to set which id value will use which page.
|
||||||
|
| process: It is used to set which id value will use which object.
|
||||||
|
|
|
||||||
|
| Example Usage
|
||||||
|
|
|
||||||
|
| [
|
||||||
|
| '1' => 'any',
|
||||||
|
| '2' => ['noperm' => ['delete', 'update']],
|
||||||
|
| '3' => ['perm' => ['delete', 'update']],
|
||||||
|
| '4' => ['noperm' => ['delete', 'update', 'add']],
|
||||||
|
| '5' => 'all'
|
||||||
|
| ]
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $method = [];
|
||||||
|
public $page = [];
|
||||||
|
public $process = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Method extends PermissionExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Post
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = NULL
|
||||||
|
* @param array $table = NULL
|
||||||
|
* @param mixed $callback = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function post($roleId = NULL, ?array $table = NULL, $callback = NULL) : bool
|
||||||
|
{
|
||||||
|
return self::use($roleId, __FUNCTION__, $table, $callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = NULL
|
||||||
|
* @param array $table = NULL
|
||||||
|
* @param mixed $callback = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function get($roleId = NULL, ?array $table = NULL, $callback = NULL) : bool
|
||||||
|
{
|
||||||
|
return self::use($roleId, __FUNCTION__, $table, $callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = NULL
|
||||||
|
* @param array $table = NULL
|
||||||
|
* @param mixed $callback = NULL
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function request($roleId = NULL, ?array $table = NULL, $callback = NULL) : bool
|
||||||
|
{
|
||||||
|
return self::use($roleId, __FUNCTION__, $table, $callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = NULL
|
||||||
|
* @param string $method = 'post'
|
||||||
|
* @param array $table = NULL
|
||||||
|
* @param mixed $callback = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function use($roleId = NULL, $method = 'post', ?array $table = NULL, $callback = NULL) : bool
|
||||||
|
{
|
||||||
|
if( $roleId !== NULL && $table !== NULL )
|
||||||
|
{
|
||||||
|
return self::predefinedPermissionConfiguration($roleId, $table, $callback, 'method', [$roleId, $method, NULL, 'method']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::common(self::$roleId ?? $roleId, $method, NULL, 'method');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Page extends PermissionExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Real path
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public static $realpath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Real path
|
||||||
|
*/
|
||||||
|
public static function realpath($realpath = CURRENT_CFURI)
|
||||||
|
{
|
||||||
|
self::$realpath = $realpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = NULL
|
||||||
|
* @param array $table = NULL
|
||||||
|
* @param mixed $callback = NULL
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function use($roleId = NULL, ?array $table = NULL, $callback = NULL)
|
||||||
|
{
|
||||||
|
$realpath = self::$realpath; self::$realpath = NULL;
|
||||||
|
|
||||||
|
if( $roleId !== NULL && $table !== NULL )
|
||||||
|
{
|
||||||
|
return self::predefinedPermissionConfiguration($roleId, $table, $callback, 'page', [$roleId, NULL, NULL, 'page', $realpath]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::common(self::$roleId ?? $roleId, NULL, NULL, 'page', $realpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Controller\Factory;
|
||||||
|
|
||||||
|
class Permission extends Factory
|
||||||
|
{
|
||||||
|
const factory =
|
||||||
|
[
|
||||||
|
'methods' =>
|
||||||
|
[
|
||||||
|
'start' => 'Process::start',
|
||||||
|
'end' => 'Process::end',
|
||||||
|
'process' => 'Process::use',
|
||||||
|
'page' => 'Page::use',
|
||||||
|
'realpath' => 'Page::realpath:this',
|
||||||
|
'post' => 'Method::post',
|
||||||
|
'get' => 'Method::get',
|
||||||
|
'request' => 'Method::request',
|
||||||
|
'method' => 'Method::use',
|
||||||
|
'roleid' => 'PermissionExtends::roleId',
|
||||||
|
'setpermrules' => 'RoleRules::setPermRules',
|
||||||
|
'setnopermrules' => 'RoleRules::setNopermRules',
|
||||||
|
'getpermrules' => 'RoleRules::getPermRules',
|
||||||
|
'getnopermrules' => 'RoleRules::getNopermRules',
|
||||||
|
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,318 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Base;
|
||||||
|
use ZN\Config;
|
||||||
|
use ZN\Response;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Request\Method;
|
||||||
|
use ZN\Protection\Json;
|
||||||
|
|
||||||
|
class PermissionExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Permission
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $permission = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected static $result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected static $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Role ID
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
public static $roleId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Role ID
|
||||||
|
*
|
||||||
|
* @param mixed $roleId
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function roleId($roleId)
|
||||||
|
{
|
||||||
|
self::$roleId = $roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get permission rules
|
||||||
|
*
|
||||||
|
* @param string $type = 'page'
|
||||||
|
* @param int|string $ruleId = NULL
|
||||||
|
*
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
public static function getPermRules(string $type = 'page', $roleId = NULL)
|
||||||
|
{
|
||||||
|
return self::getNopermRules($type, $roleId, 'perm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get no permission rules
|
||||||
|
*
|
||||||
|
* @param string $type = 'page'
|
||||||
|
* @param int|string $ruleId = NULL
|
||||||
|
*
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
public static function getNopermRules(string $type = 'page', $roleId = NULL, $ptype = 'noperm')
|
||||||
|
{
|
||||||
|
$rules = self::getConfigByType($type);
|
||||||
|
|
||||||
|
$roleId = $roleId ?? self::$roleId;
|
||||||
|
|
||||||
|
if( is_array($return = ($rules[$roleId] ?? NULL)) )
|
||||||
|
{
|
||||||
|
return $return[$ptype];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set permission rules
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @param int|string $ruleId = NULL
|
||||||
|
*
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
protected static function setPermRules(array $config, $roleId = NULL, $ptype = 'perm')
|
||||||
|
{
|
||||||
|
$roleId = $roleId ?? self::$roleId;
|
||||||
|
$configs = array_keys(self::getConfigByType(NULL));
|
||||||
|
$newRules = [];
|
||||||
|
|
||||||
|
foreach( $configs as $con )
|
||||||
|
{
|
||||||
|
if( $subconfig = ($config[$con] ?? NULL) )
|
||||||
|
{
|
||||||
|
if( is_string(self::getJsonDataToDatabaseAfterConvertArray($subconfig, $roleId)) )
|
||||||
|
{
|
||||||
|
$add = $subconfig; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$add = [$ptype => $subconfig];
|
||||||
|
}
|
||||||
|
|
||||||
|
$newRules[$con] = [$roleId => $add];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::set('Auth', $newRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set no permission rules
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @param int|string $ruleId = NULL
|
||||||
|
*
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
protected static function setNopermRules(array $config, $roleId = NULL)
|
||||||
|
{
|
||||||
|
self::setPermRules($config, $roleId, 'noperm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permission Common
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = 6
|
||||||
|
* @param mixed $process = NULL
|
||||||
|
* @param mixed $object = NULL
|
||||||
|
* @param mixed $function = NULL
|
||||||
|
* @param mixed $realpath = NULL
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected static function common($roleId = 6, $process = NULL, $object = NULL, $function = NULL, $realpath = NULL)
|
||||||
|
{
|
||||||
|
self::$permission = self::getConfigByType($function);
|
||||||
|
|
||||||
|
if( isset(self::$permission[$roleId]) )
|
||||||
|
{
|
||||||
|
$rules = self::$permission[$roleId];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( $function === 'method' )
|
||||||
|
{
|
||||||
|
$currentUrl = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$currentUrl = $process ?? $realpath ?? Base::currentPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = $object ?? true;
|
||||||
|
|
||||||
|
switch( $rules ?? NULL )
|
||||||
|
{
|
||||||
|
case 'all': return $object;
|
||||||
|
case 'any': return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pages = current($rules); $type = key($rules);
|
||||||
|
|
||||||
|
foreach( $pages as $page )
|
||||||
|
{
|
||||||
|
$page = trim((string) $page);
|
||||||
|
|
||||||
|
$rule = strpos((string) $page[0], '!') === 0 ? substr((string) $page, 1) : $page;
|
||||||
|
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
if( $type === 'perm' )
|
||||||
|
{
|
||||||
|
if( self::control($currentUrl, $rule, $process, $function) )
|
||||||
|
{
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::$result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if( self::control($currentUrl, $rule, $process, $function) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::$result = $object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control Permission
|
||||||
|
*
|
||||||
|
* @param string $currentUrl
|
||||||
|
* @param string $page
|
||||||
|
* @param string $process
|
||||||
|
* @param string $function
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function control($currentUrl, $page, $process, $function)
|
||||||
|
{
|
||||||
|
if( $function === 'method' )
|
||||||
|
{
|
||||||
|
return Method::$process($page);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strpos(strtolower((string) $currentUrl), strtolower((string) $page)) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get config by type
|
||||||
|
*/
|
||||||
|
protected static function getConfigByType($type)
|
||||||
|
{
|
||||||
|
$config = Config::default('ZN\Authorization\AuthorizationDefaultConfiguration')::get('Auth');
|
||||||
|
|
||||||
|
if( $type === NULL )
|
||||||
|
{
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $config[$type] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected predefined Permission Configuration
|
||||||
|
*/
|
||||||
|
protected static function predefinedPermissionConfiguration($roleId, $table, $callback, $ctype, $code)
|
||||||
|
{
|
||||||
|
self::selectSetPermissionType($roleId, $table, $ctype);
|
||||||
|
|
||||||
|
if( ! self::common(...$code) )
|
||||||
|
{
|
||||||
|
if( is_callable($callback) )
|
||||||
|
{
|
||||||
|
return $callback();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Response::redirect($callback); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected select set permission type
|
||||||
|
*/
|
||||||
|
protected static function selectSetPermissionType($roleId, $table, $ctype)
|
||||||
|
{
|
||||||
|
self::roleId($roleId);
|
||||||
|
|
||||||
|
$type = key($table);
|
||||||
|
$rules = current($table);
|
||||||
|
$func = $type === 'perm' ? 'setPermRules' : 'setNopermRules';
|
||||||
|
|
||||||
|
self::$func([$ctype => $rules]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected get json data to databse after convert array
|
||||||
|
*/
|
||||||
|
protected static function getJsonDataToDatabaseAfterConvertArray(&$subconfig, $roleId)
|
||||||
|
{
|
||||||
|
if( preg_match('/(?<table>\w+)\[(?<column>\w+)\]\:(?<select>\w+)/', $subconfig, $match) )
|
||||||
|
{
|
||||||
|
$json = Singleton::class('ZN\Database\DB')
|
||||||
|
->where($match['column'], $roleId)
|
||||||
|
->select($match['select'])
|
||||||
|
->get($match['table'])
|
||||||
|
->value();
|
||||||
|
|
||||||
|
if( Json::check($json) )
|
||||||
|
{
|
||||||
|
$subconfig = json_decode($json);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$subconfig = $json; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $subconfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<?php namespace ZN\Authorization;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Process extends PermissionExtends
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Start
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = 0
|
||||||
|
* @param mixed $process = NULL
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function start($roleId = 0, $process = NULL)
|
||||||
|
{
|
||||||
|
self::$content = self::use($roleId, $process, 'object');
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function end()
|
||||||
|
{
|
||||||
|
if( ! empty(self::$content) )
|
||||||
|
{
|
||||||
|
$content = ob_get_contents(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$content = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
self::$content = NULL;
|
||||||
|
|
||||||
|
echo $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process
|
||||||
|
*
|
||||||
|
* @param mixed $roleId = 0
|
||||||
|
* @param mixed $process = NULL
|
||||||
|
* @param mixed $object = NULL
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function use($roleId = 0, $process = NULL, $object = NULL)
|
||||||
|
{
|
||||||
|
if( is_array($process) )
|
||||||
|
{
|
||||||
|
return self::selectSetPermissionType($roleId, $process, 'process');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( self::$roleId !== NULL )
|
||||||
|
{
|
||||||
|
$object = $process;
|
||||||
|
$process = $roleId;
|
||||||
|
$roleId = self::$roleId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::common($roleId, $process, $object, 'process');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Buffering;
|
||||||
|
|
||||||
|
class Callback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Buffer code
|
||||||
|
*
|
||||||
|
* @param string $randomBufferClassCallbackCode
|
||||||
|
* @param array $randomBufferClassCallbackData
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function code(string $randomBufferClassCallbackCode, ?array $randomBufferClassCallbackData = NULL)
|
||||||
|
{
|
||||||
|
return Buffering::code($randomBufferClassCallbackCode, $randomBufferClassCallbackData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer closure
|
||||||
|
*
|
||||||
|
* @param callable $func
|
||||||
|
* @param array $params = []
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function do(callable $func, array $params = [])
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
echo $func(...$params);
|
||||||
|
|
||||||
|
$contents = ob_get_contents();
|
||||||
|
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Delete extends Singleton
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param mixed $name
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function do($name) : bool
|
||||||
|
{
|
||||||
|
if( is_array($name) )
|
||||||
|
{
|
||||||
|
foreach( $name as $delete )
|
||||||
|
{
|
||||||
|
self::$session->delete(md5('OB_DATAS_'.$delete));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
elseif( is_scalar($name) )
|
||||||
|
{
|
||||||
|
return self::$session->delete(md5('OB_DATAS_'.$name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Buffering\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class InvalidFileParameterException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => '`%` parameter should contain the file data type!',
|
||||||
|
'tr' => '`%` parametresi dosya bilgisi içermelidir!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Buffering;
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Buffer file
|
||||||
|
*
|
||||||
|
* @param string $randomBufferClassPagePath
|
||||||
|
* @param array $randomBufferClassDataVariable
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function do(string $randomBufferClassPagePath, ?array $randomBufferClassDataVariable = NULL) : string
|
||||||
|
{
|
||||||
|
if( ! is_file($randomBufferClassPagePath) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidFileParameterException(NULL, '1.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffering::file($randomBufferClassPagePath, $randomBufferClassDataVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Insert extends Singleton
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param mixed $data
|
||||||
|
* @param array $params = []
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function do(string $name, $data, array $params = []) : bool
|
||||||
|
{
|
||||||
|
$systemObData = md5('OB_DATAS_'.$name);
|
||||||
|
|
||||||
|
if( is_callable($data) )
|
||||||
|
{
|
||||||
|
return self::$session->insert($systemObData, Callback::do($data, (array) $params));
|
||||||
|
}
|
||||||
|
elseif( is_file($data) )
|
||||||
|
{
|
||||||
|
return self::$session->insert($systemObData, File::do($data));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self::$session->insert($systemObData, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Controller\Factory;
|
||||||
|
|
||||||
|
class Process extends Factory
|
||||||
|
{
|
||||||
|
const factory =
|
||||||
|
[
|
||||||
|
'methods' =>
|
||||||
|
[
|
||||||
|
'file' => 'File::do',
|
||||||
|
'func' => 'Callback::do',
|
||||||
|
'function' => 'Callback::do',
|
||||||
|
'callback' => 'Callback::do',
|
||||||
|
'closure' => 'Callback::do',
|
||||||
|
'code' => 'Callback::code',
|
||||||
|
'insert' => 'Insert::do',
|
||||||
|
'select' => 'Select::do',
|
||||||
|
'delete' => 'Delete::do'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Select extends Singleton
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function do(string $name)
|
||||||
|
{
|
||||||
|
return self::$session->select(md5('OB_DATAS_'.$name));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php namespace ZN\Buffering;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Singleton as Single;
|
||||||
|
|
||||||
|
class Singleton
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keep session library
|
||||||
|
*
|
||||||
|
* @var ZN\Storage\Session
|
||||||
|
*/
|
||||||
|
protected static $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic construct
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
self::$session = Single::class('ZN\Storage\Session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php namespace ZN\Cache;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Configuration
|
||||||
|
*
|
||||||
|
* Enabled when the configuration file can not be accessed.
|
||||||
|
*/
|
||||||
|
class CacheDefaultConfiguration
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cache
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Includes configurations for the Cache library.
|
||||||
|
|
|
||||||
|
| drivers : apc, memcache, wincache, file, redis
|
||||||
|
| driverSettings: Configurations by driver
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $driver = 'file';
|
||||||
|
public $driverSettings =
|
||||||
|
[
|
||||||
|
'memcache' =>
|
||||||
|
[
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'port' => '11211',
|
||||||
|
'weight' => '1',
|
||||||
|
],
|
||||||
|
'redis' =>
|
||||||
|
[
|
||||||
|
'password' => NULL,
|
||||||
|
'socketType' => 'tcp',
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'port' => 6379,
|
||||||
|
'timeout' => 0
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
<?php namespace ZN\Cache;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Config;
|
||||||
|
|
||||||
|
abstract class DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps cache config
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->config = Config::default('ZN\Cache\CacheDefaultConfiguration')
|
||||||
|
::get('Storage', 'cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
abstract public function select($key, $compressed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param int $time
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function insert($key, $var, $time, $compressed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function delete($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
abstract public function increment($key, $increment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
abstract public function decrement($key, $decrement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function clean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
abstract public function info($type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close
|
||||||
|
*/
|
||||||
|
public function close()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<?php namespace ZN\Cache\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Cache\DriverMappingAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
class ApcDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps apc type
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $apc = 'apcu';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
Support::extension('Apcu', 'Apcu');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select($key, $compressed = NULL)
|
||||||
|
{
|
||||||
|
return $this->apc('fetch', $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param int $time
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert($key, $var, $time, $compressed)
|
||||||
|
{
|
||||||
|
return $this->apc('store', $key, $var, $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete($key)
|
||||||
|
{
|
||||||
|
return $this->apc('delete', $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment($key, $increment)
|
||||||
|
{
|
||||||
|
return $this->apc('inc', $key, $increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement($key, $decrement)
|
||||||
|
{
|
||||||
|
return $this->apc('dec', $key, $decrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean()
|
||||||
|
{
|
||||||
|
return $this->apc('clear_cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($type = NULL)
|
||||||
|
{
|
||||||
|
return $this->apc('cache_info', $type) ?: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apc type
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param mixed ...$args
|
||||||
|
*/
|
||||||
|
protected function apc(string $type, ...$args)
|
||||||
|
{
|
||||||
|
$method = $this->apc . '_' . $type;
|
||||||
|
|
||||||
|
return $method(...$args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
<?php namespace ZN\Cache\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Filesystem;
|
||||||
|
use ZN\Cache\DriverMappingAbstract;
|
||||||
|
|
||||||
|
class FileDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps path
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $path = STORAGE_DIR . 'Cache/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps compression class
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
protected $compress;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->createCacheDirectoryIfNotExists();
|
||||||
|
|
||||||
|
Support::writable($this->path);
|
||||||
|
|
||||||
|
$this->compress = Singleton::class('ZN\Compression\Force');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select($key, $compressed)
|
||||||
|
{
|
||||||
|
$data = $this->selectCacheKey($key);
|
||||||
|
|
||||||
|
if( ! empty($data['data']) )
|
||||||
|
{
|
||||||
|
if( $compressed !== false )
|
||||||
|
{
|
||||||
|
$data['data'] = $this->compress->driver($compressed)->undo($data['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param int $time
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert($key, $var, $time, $compressed = false)
|
||||||
|
{
|
||||||
|
if( $compressed !== false )
|
||||||
|
{
|
||||||
|
$var = $this->compress->driver($compressed)->do($var);
|
||||||
|
}
|
||||||
|
|
||||||
|
$datas =
|
||||||
|
[
|
||||||
|
'time' => time(),
|
||||||
|
'ttl' => $time,
|
||||||
|
'data' => $var
|
||||||
|
];
|
||||||
|
|
||||||
|
if( file_put_contents($pathKey = $this->path . $key, serialize($datas)) )
|
||||||
|
{
|
||||||
|
chmod($pathKey, 0640);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete($key)
|
||||||
|
{
|
||||||
|
if( is_file($path = $this->path . $key) )
|
||||||
|
{
|
||||||
|
return unlink($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment($key, $increment)
|
||||||
|
{
|
||||||
|
$data = $this->selectCacheKey($key);
|
||||||
|
|
||||||
|
if( $data === false )
|
||||||
|
{
|
||||||
|
$data = ['data' => 0, 'ttl' => 60];
|
||||||
|
}
|
||||||
|
elseif( ! is_numeric($data['data']) )
|
||||||
|
{
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$newValue = $data['data'] + $increment;
|
||||||
|
|
||||||
|
return ( $this->insert($key, $newValue, $data['ttl']) )
|
||||||
|
? $newValue
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement($key, $decrement)
|
||||||
|
{
|
||||||
|
$data = $this->selectCacheKey($key);
|
||||||
|
|
||||||
|
if( $data === false )
|
||||||
|
{
|
||||||
|
$data = ['data' => 0, 'ttl' => 60];
|
||||||
|
}
|
||||||
|
elseif( ! is_numeric($data['data']) )
|
||||||
|
{
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$newValue = $data['data'] - $decrement;
|
||||||
|
|
||||||
|
return $this->insert($key, $newValue, $data['ttl'])
|
||||||
|
? $newValue
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean()
|
||||||
|
{
|
||||||
|
foreach( Filesystem\Folder::files($this->path, NULL, true) as $file )
|
||||||
|
{
|
||||||
|
if( is_file($file) )
|
||||||
|
{
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($type = NULL)
|
||||||
|
{
|
||||||
|
$info = Filesystem\Info::fileInfo($this->path);
|
||||||
|
|
||||||
|
if( $type === NULL )
|
||||||
|
{
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
elseif( ! empty($info[$type]) )
|
||||||
|
{
|
||||||
|
return $info[$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected create cache directory if not exists
|
||||||
|
*/
|
||||||
|
protected function createCacheDirectoryIfNotExists()
|
||||||
|
{
|
||||||
|
if( ! is_dir($this->path) )
|
||||||
|
{
|
||||||
|
mkdir($this->path, 0755); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function selectCacheKey($key)
|
||||||
|
{
|
||||||
|
if( ! file_exists($pathKey = $this->path . $key) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = unserialize(file_get_contents($pathKey));
|
||||||
|
|
||||||
|
if( $data['ttl'] > 0 && time() > $data['time'] + $data['ttl'] )
|
||||||
|
{
|
||||||
|
unlink($pathKey); // @codeCoverageIgnore
|
||||||
|
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
<?php namespace ZN\Cache\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Memcached;
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\ErrorHandling\Errors;
|
||||||
|
use ZN\Cache\DriverMappingAbstract;
|
||||||
|
use ZN\Cache\Exception\ConnectionRefusedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
class MemcacheDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps memcahce class
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
|
protected $memcache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(?array $settings = NULL)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
Support::library('Memcached', 'Memcached');
|
||||||
|
|
||||||
|
$this->memcache = new Memcached;
|
||||||
|
|
||||||
|
$config = $this->config['driverSettings'];
|
||||||
|
|
||||||
|
$config = ! empty($settings)
|
||||||
|
? $settings
|
||||||
|
: $config['memcache'];
|
||||||
|
|
||||||
|
if( ! $this->memcache->addServer($config['host'], $config['port'], $config['weight']) )
|
||||||
|
{
|
||||||
|
throw new ConnectionRefusedException(NULL, 'Memcached connection error!'); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select($key, $compressed = NULL)
|
||||||
|
{
|
||||||
|
return $this->memcache->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param int $time
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert($key, $var, $time, $compressed)
|
||||||
|
{
|
||||||
|
return $this->memcache->set($key, $var, $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete($key)
|
||||||
|
{
|
||||||
|
return $this->memcache->delete($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment($key, $increment)
|
||||||
|
{
|
||||||
|
return $this->memcache->increment($key, $increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement($key, $decrement)
|
||||||
|
{
|
||||||
|
return $this->memcache->decrement($key, $decrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean()
|
||||||
|
{
|
||||||
|
return $this->memcache->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($type = NULL)
|
||||||
|
{
|
||||||
|
return $this->memcache->getStats() ?: [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
<?php namespace ZN\Cache\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Redis;
|
||||||
|
use RedisException;
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\ErrorHandling\Errors;
|
||||||
|
use ZN\Cache\Exception\ConnectionRefusedException;
|
||||||
|
use ZN\Cache\Exception\AuthenticationFailedException;
|
||||||
|
use ZN\Cache\DriverMappingAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
class RedisDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps redis class
|
||||||
|
*
|
||||||
|
* @var Redis
|
||||||
|
*/
|
||||||
|
protected $redis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param array $settings = NULL
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(?array $settings = NULL)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
Support::extension('redis');
|
||||||
|
|
||||||
|
$config = $settings ?: $this->config['driverSettings']['redis'];
|
||||||
|
|
||||||
|
$this->redis = new Redis();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$success = $this->redis->connect($config['host'], $config['port'], $config['timeout']);
|
||||||
|
|
||||||
|
if ( empty($success) )
|
||||||
|
{
|
||||||
|
throw new ConnectionRefusedException(NULL, 'Connection');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( RedisException $e )
|
||||||
|
{
|
||||||
|
throw new ConnectionRefusedException(NULL, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $config['password'] && ! $this->redis->auth($config['password']) )
|
||||||
|
{
|
||||||
|
throw new AuthenticationFailedException; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select($key, $compressed = NULL)
|
||||||
|
{
|
||||||
|
return $this->redis->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param int $time
|
||||||
|
* @param mixed $compressed
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert($key, $data, $time, $compressed)
|
||||||
|
{
|
||||||
|
return $this->redis->set($key, $data, $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete($key)
|
||||||
|
{
|
||||||
|
return $this->redis->delete($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment($key, $increment)
|
||||||
|
{
|
||||||
|
return $this->redis->incr($key, $increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement($key, $decrement)
|
||||||
|
{
|
||||||
|
return $this->redis->decr($key, $decrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean()
|
||||||
|
{
|
||||||
|
return $this->redis->flushDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($type = NULL)
|
||||||
|
{
|
||||||
|
return $this->redis->info();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close
|
||||||
|
*/
|
||||||
|
public function close()
|
||||||
|
{
|
||||||
|
$this->redis->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Cache\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class AuthenticationFailedException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => 'Authentication failed!',
|
||||||
|
'tr' => 'Geçersiz giriş!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Cache\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class ConnectionRefusedException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => 'Connection refused! Error:`%`',
|
||||||
|
'tr' => 'Bağlantı sağlanamadı! Hata:`%`'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Cache\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class InvalidTimeException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => '[%] information is invalid time format!',
|
||||||
|
'tr' => '[%] bilgisi geçersiz zaman formatıdır!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php namespace ZN\Cache\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class UnsupportedDriverException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Exception language settings
|
||||||
|
*
|
||||||
|
* @param string en
|
||||||
|
* @param string tr
|
||||||
|
*/
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => '`%` must be loaded to use the driver!!',
|
||||||
|
'tr' => '`%` sürücüsünü kullanmak için yüklenmesi gerekmektedir!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
<?php namespace ZN\Cache;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Buffering;
|
||||||
|
use ZN\Inclusion;
|
||||||
|
use ZN\Ability\Driver;
|
||||||
|
use ZN\Helpers\Converter;
|
||||||
|
|
||||||
|
class Processor implements ProcessorInterface
|
||||||
|
{
|
||||||
|
use Driver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver settings
|
||||||
|
*
|
||||||
|
* @param array options
|
||||||
|
* @param string namespace
|
||||||
|
*/
|
||||||
|
const driver =
|
||||||
|
[
|
||||||
|
'options' => ['file', 'apc', 'memcache', 'redis'],
|
||||||
|
'namespace' => 'ZN\Cache\Drivers',
|
||||||
|
'config' => 'Storage:cache',
|
||||||
|
'default' => 'ZN\Cache\CacheDefaultConfiguration'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $codeCount = 0;
|
||||||
|
protected $refresh = false;
|
||||||
|
protected $key = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
$this->refresh = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set data
|
||||||
|
*
|
||||||
|
* @param array $data = NULL
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function data(?array $data = NULL)
|
||||||
|
{
|
||||||
|
Inclusion\Properties::data($data);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set key
|
||||||
|
*
|
||||||
|
* @param string $key = NULL
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function key(?string $key = NULL) : Processor
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache code
|
||||||
|
*
|
||||||
|
* @param callable $function
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compressed = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function code(callable $function, $time = 60, string $compress = 'gz') : string
|
||||||
|
{
|
||||||
|
$this->codeCount++;
|
||||||
|
|
||||||
|
if( $this->key === NULL )
|
||||||
|
{
|
||||||
|
$name = 'code-' . $this->codeCount . '-' . CURRENT_CONTROLLER . '-' . CURRENT_CFUNCTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$name = $this->key;
|
||||||
|
|
||||||
|
$this->key = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->refreshCacheData($name);
|
||||||
|
|
||||||
|
if( ! $select = $this->select($name, $compress) )
|
||||||
|
{
|
||||||
|
$output = Buffering\Callback::do($function);
|
||||||
|
|
||||||
|
$this->insert($name, $output, $time, $compress);
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $select;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache view
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compress = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function view(string $file, $time = 60, string $compress = 'gz') : string
|
||||||
|
{
|
||||||
|
return $this->file($file, $time, $compress, 'view');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compress = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function file(string $file, $time = 60, string $compress = 'gz', $type = 'something') : string
|
||||||
|
{
|
||||||
|
$name = Converter::slug($file);
|
||||||
|
|
||||||
|
$this->refreshCacheData($name);
|
||||||
|
|
||||||
|
if( ! $select = $this->select($name, $compress) )
|
||||||
|
{
|
||||||
|
Inclusion\Properties::usable();
|
||||||
|
|
||||||
|
if( $type === 'shomething' )
|
||||||
|
{
|
||||||
|
$output = Inclusion\Something::use($file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$output = Inclusion\View::use($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->insert($name, $output, $time, $compress);
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $select; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed = false
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select(string $key, $compressed = false)
|
||||||
|
{
|
||||||
|
return $this->driver->select($key, $compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param mixed $compressed = false
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert(string $key, $var, $time = 60, $compressed = false) : bool
|
||||||
|
{
|
||||||
|
if( ! preg_match('/(?<count>[0-9]+)\s*(?<type>second|minute|hour|day|week|month|year)*s*/', $time, $match) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidTimeException(NULL, $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
$time = Converter::time($match['count'], $match['type'] ?? 'second', 'second');
|
||||||
|
|
||||||
|
return $this->driver->insert($key, $var, $time, $compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete(string $key) : bool
|
||||||
|
{
|
||||||
|
return $this->driver->delete($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment(string $key, int $increment = 1) : int
|
||||||
|
{
|
||||||
|
return $this->driver->increment($key, $increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement(string $key, int $decrement = 1) : int
|
||||||
|
{
|
||||||
|
return $this->driver->decrement($key, $decrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean() : bool
|
||||||
|
{
|
||||||
|
return $this->driver->clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($type = NULL) : array
|
||||||
|
{
|
||||||
|
return $this->driver->info($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor magic method
|
||||||
|
*/
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
$this->driver->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected refresh
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function refreshCacheData($data)
|
||||||
|
{
|
||||||
|
if( $this->refresh === true )
|
||||||
|
{
|
||||||
|
$this->delete($data);
|
||||||
|
$this->refresh = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<?php namespace ZN\Cache;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface ProcessorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Refresh cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function refresh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set data
|
||||||
|
*
|
||||||
|
* @param array $data = NULL
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function data(?array $data = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set key
|
||||||
|
*
|
||||||
|
* @param string $key = NULL
|
||||||
|
*
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function key(?string $key = NULL) : Processor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache code
|
||||||
|
*
|
||||||
|
* @param callable $function
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compressed = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function code(callable $function, $time = 60, string $compress = 'gz') : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache view
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compress = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function view(string $file, $time = 60, string $compress = 'gz') : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param string $compress = 'gz'
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function file(string $file, $time = 60, string $compress = 'gz', $type = 'something') : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $compressed = false
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function select(string $key, $compressed = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $var
|
||||||
|
* @param mixed $time = 60
|
||||||
|
* @param mixed $compressed = false
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function insert(string $key, $var, $time = 60, $compressed = false) : bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete(string $key) : bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $increment = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function increment(string $key, int $increment = 1) : int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param int $decrement = 1
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function decrement(string $key, int $decrement = 1) : int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all cache
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clean() : bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info
|
||||||
|
*
|
||||||
|
* @param mixed $type
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function info($info) : array;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php namespace ZN\Captcha;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Configuration
|
||||||
|
*
|
||||||
|
* Enabled when the configuration file can not be accessed.
|
||||||
|
*/
|
||||||
|
class CaptchaDefaultConfiguration
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Captcha
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Includes default settings for the captcha.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $text =
|
||||||
|
[
|
||||||
|
'type' => 'alnum',
|
||||||
|
'length' => 6,
|
||||||
|
'color' => '255|255|255',
|
||||||
|
'size' => 10,
|
||||||
|
'x' => 65,
|
||||||
|
'y' => 13,
|
||||||
|
'angle' => 0,
|
||||||
|
'ttf' => []
|
||||||
|
];
|
||||||
|
public $background =
|
||||||
|
[
|
||||||
|
'color' => '80|80|80',
|
||||||
|
'image' => []
|
||||||
|
];
|
||||||
|
public $border =
|
||||||
|
[
|
||||||
|
'status' => false,
|
||||||
|
'color' => '0|0|0'
|
||||||
|
];
|
||||||
|
public $size =
|
||||||
|
[
|
||||||
|
'width' => 180,
|
||||||
|
'height' => 40
|
||||||
|
];
|
||||||
|
public $grid =
|
||||||
|
[
|
||||||
|
'status' => true,
|
||||||
|
'color' => '50|50|50',
|
||||||
|
'spaceX' => 12,
|
||||||
|
'spaceY' => 4
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,616 @@
|
|||||||
|
<?php namespace ZN\Captcha;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Base;
|
||||||
|
use ZN\Image;
|
||||||
|
use ZN\Config;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Filesystem;
|
||||||
|
use ZN\Request\URL;
|
||||||
|
use ZN\DataTypes\Arrays;
|
||||||
|
use ZN\Cryptography\Encode;
|
||||||
|
|
||||||
|
class Render implements RenderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps settings.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $sets = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $path = FILES_DIR ?? 'captcha/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps session class
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
protected $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps session key
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps config variables
|
||||||
|
*/
|
||||||
|
protected $sizeWidthC,
|
||||||
|
$sizeHeightC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->session = Singleton::class('ZN\Storage\Session');
|
||||||
|
$this->key = md5('SystemCaptchaCodeData');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The image specifies the path to save.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function path(string $path) : Render
|
||||||
|
{
|
||||||
|
$this->path = Base::suffix($path);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the size of the captcha.
|
||||||
|
*
|
||||||
|
* @param int $width
|
||||||
|
* @param int $height
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function size(int $width, int $height) : Render
|
||||||
|
{
|
||||||
|
$this->sets['size']['width'] = $width;
|
||||||
|
$this->sets['size']['height'] = $height;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character type.
|
||||||
|
*
|
||||||
|
* @param string $type = 'alnum' - options[alnum|numeric|string|alpha|special|all]
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function type(string $type = 'alnum') : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['type'] = $type;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character width.
|
||||||
|
*
|
||||||
|
* @param int $param
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function length(int $param) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['length'] = $param;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character angle.
|
||||||
|
*
|
||||||
|
* @param int $param
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function angle(Float $param) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['angle'] = $param;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add ttf fonts.
|
||||||
|
*
|
||||||
|
* @param array $fonts
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function ttf(array $fonts) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['ttf'] = $fonts;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the border color.
|
||||||
|
*
|
||||||
|
* @param string $color = NULL
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function borderColor(?string $color = NULL) : Render
|
||||||
|
{
|
||||||
|
$this->sets['border']['status'] = true;
|
||||||
|
|
||||||
|
if( ! empty($color) )
|
||||||
|
{
|
||||||
|
$this->sets['border']['color'] = $this->convertColor($color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color.
|
||||||
|
*
|
||||||
|
* @param string $color = NULL
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function bgColor(string $color) : Render
|
||||||
|
{
|
||||||
|
$this->sets['background']['color'] = $this->convertColor($color);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add background pictures.
|
||||||
|
*
|
||||||
|
* @param array $image
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function bgImage(array $image) : Render
|
||||||
|
{
|
||||||
|
$this->sets['background']['image'] = $image;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text size.
|
||||||
|
*
|
||||||
|
* @param int $size
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textSize(int $size) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['size'] = $size;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text coordiante.
|
||||||
|
*
|
||||||
|
* @param int $x
|
||||||
|
* @param int $y
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textCoordinate(int $x = 0, int $y = 0) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['x'] = $x;
|
||||||
|
$this->sets['text']['y'] = $y;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text color.
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textColor(string $color) : Render
|
||||||
|
{
|
||||||
|
$this->sets['text']['color'] = $this->convertColor($color);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the grid color.
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function gridColor(?string $color = NULL) : Render
|
||||||
|
{
|
||||||
|
$this->sets['grid']['status'] = true;
|
||||||
|
|
||||||
|
if( ! empty($color) )
|
||||||
|
{
|
||||||
|
$this->sets['grid']['color'] = $this->convertColor($color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the grid space.
|
||||||
|
*
|
||||||
|
* @param int $x = 0
|
||||||
|
* @param int $y = 0
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function gridSpace(int $x = 0, int $y = 0) : Render
|
||||||
|
{
|
||||||
|
if( ! empty($x) )
|
||||||
|
{
|
||||||
|
$this->sets['grid']['spaceX'] = $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! empty($y) )
|
||||||
|
{
|
||||||
|
$this->sets['grid']['spaceY'] = $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes the captcha creation process.
|
||||||
|
*
|
||||||
|
* @param bool $img = false
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function create(bool $img = false) : string
|
||||||
|
{
|
||||||
|
# Create Session
|
||||||
|
$this->session();
|
||||||
|
|
||||||
|
if( ! $this->getCode() )
|
||||||
|
{
|
||||||
|
return ''; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean Captcha Images
|
||||||
|
$this->clean();
|
||||||
|
|
||||||
|
# Create Directory
|
||||||
|
$this->directory();
|
||||||
|
|
||||||
|
# Create Color
|
||||||
|
$this->color($file);
|
||||||
|
|
||||||
|
# Background Image
|
||||||
|
$this->background($file);
|
||||||
|
|
||||||
|
# Text
|
||||||
|
$this->text($file);
|
||||||
|
|
||||||
|
# Grid
|
||||||
|
$this->grid($file);
|
||||||
|
|
||||||
|
# Border
|
||||||
|
$this->border($file);
|
||||||
|
|
||||||
|
# Output
|
||||||
|
return $this->output($img, $file);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current captcha code.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCode() : string
|
||||||
|
{
|
||||||
|
return $this->session->select($this->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Color
|
||||||
|
*/
|
||||||
|
protected function color(& $file = NULL)
|
||||||
|
{
|
||||||
|
$sizeset = $this->sets['size'];
|
||||||
|
|
||||||
|
$this->sizeWidthC = $sizeset['width'] ?? 100;
|
||||||
|
$this->sizeHeightC = $sizeset['height'] ?? 30;
|
||||||
|
|
||||||
|
$file = imagecreatetruecolor($this->sizeWidthC, $this->sizeHeightC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Create Directory
|
||||||
|
*/
|
||||||
|
protected function directory()
|
||||||
|
{
|
||||||
|
if( ! is_dir($this->path) )
|
||||||
|
{
|
||||||
|
mkdir($this->path); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Session Insert
|
||||||
|
*/
|
||||||
|
protected function session()
|
||||||
|
{
|
||||||
|
$this->sets = array_merge
|
||||||
|
(
|
||||||
|
Config::default('ZN\Captcha\CaptchaDefaultConfiguration')
|
||||||
|
::get('ViewObjects', 'captcha'),
|
||||||
|
$this->sets
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->session->insert($this->key, Encode\RandomPassword::create($this->sets['text']['length'] ?? 6, $this->sets['text']['type'] ?? 'alnum'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Output
|
||||||
|
*/
|
||||||
|
protected function output($img, & $file)
|
||||||
|
{
|
||||||
|
$filePath = $this->path . $this->name();
|
||||||
|
|
||||||
|
imagepng($file, $filePath);
|
||||||
|
|
||||||
|
$baseUrl = URL::base($filePath);
|
||||||
|
|
||||||
|
if( $img === true )
|
||||||
|
{
|
||||||
|
$captcha = '<img src="'.$baseUrl.'">';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$captcha = $baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
imagedestroy($file);
|
||||||
|
|
||||||
|
$this->sets = [];
|
||||||
|
|
||||||
|
return $captcha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Border
|
||||||
|
*/
|
||||||
|
protected function border(& $file)
|
||||||
|
{
|
||||||
|
$borderset = $this->sets['border'];
|
||||||
|
|
||||||
|
$borderStatusC = $borderset['status'] ?? true;
|
||||||
|
|
||||||
|
if( $borderStatusC === true )
|
||||||
|
{
|
||||||
|
$bordercolorC = $borderset['color'] ?? '200|200|200';
|
||||||
|
$borderColor = imagecolorallocate($file, ...explode('|', $bordercolorC));
|
||||||
|
|
||||||
|
# Top
|
||||||
|
imageline($file, 0, 0, $this->sizeWidthC, 0, $borderColor);
|
||||||
|
|
||||||
|
# Right
|
||||||
|
imageline($file, $this->sizeWidthC - 1, 0, $this->sizeWidthC - 1, $this->sizeHeightC, $borderColor);
|
||||||
|
|
||||||
|
# Bottom
|
||||||
|
imageline($file, 0, $this->sizeHeightC - 1, $this->sizeWidthC, $this->sizeHeightC - 1, $borderColor);
|
||||||
|
|
||||||
|
# Left
|
||||||
|
imageline($file, 0, 0, 0, $this->sizeHeightC - 1, $borderColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Grid
|
||||||
|
*/
|
||||||
|
protected function grid(& $file)
|
||||||
|
{
|
||||||
|
$gridset = $this->sets['grid'];
|
||||||
|
$gridStatusC = $gridset['status'] ?? false;
|
||||||
|
|
||||||
|
if( $gridStatusC === true )
|
||||||
|
{
|
||||||
|
$gridSpaceXC = $gridset['spaceX'] ?? 12;
|
||||||
|
$gridSpaceYC = $gridset['spaceY'] ?? 4;
|
||||||
|
$gridColorC = $gridset['color'] ?? '240|240|240';
|
||||||
|
|
||||||
|
$gridIntervalX = $this->sizeWidthC / $gridSpaceXC;
|
||||||
|
|
||||||
|
if( ! isset($gridSpaceYC))
|
||||||
|
{
|
||||||
|
$gridIntervalY = (($this->sizeHeightC / $gridSpaceXC) * $gridIntervalX / 2); // @codeCoverageIgnore
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$gridIntervalY = $this->sizeHeightC / $gridSpaceYC;
|
||||||
|
}
|
||||||
|
|
||||||
|
$gridColor = imagecolorallocate($file, ...explode('|', $gridColorC));
|
||||||
|
|
||||||
|
for( $x = 0 ; $x <= $this->sizeWidthC ; $x += $gridIntervalX )
|
||||||
|
{
|
||||||
|
imageline($file, $x, 0, $x, $this->sizeHeightC - 1, $gridColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( $y = 0 ; $y <= $this->sizeWidthC; $y += $gridIntervalY )
|
||||||
|
{
|
||||||
|
imageline($file, 0, $y, $this->sizeWidthC, $y, $gridColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Text
|
||||||
|
*/
|
||||||
|
protected function text(& $file)
|
||||||
|
{
|
||||||
|
$textset = $this->sets['text'];
|
||||||
|
|
||||||
|
$textSizeC = $textset['size'] ?? 10;
|
||||||
|
$textXC = $textset['x'] ?? 23;
|
||||||
|
$textYC = $textset['y'] ?? 9;
|
||||||
|
$textAngleC = $textset['angle'] ?? 0;
|
||||||
|
$textTTFC = $textset['ttf'] ?? [];
|
||||||
|
$textColorC = $textset['color'] ?? '0|0|0';
|
||||||
|
$fontColor = imagecolorallocate($file, ...explode('|', $textColorC));
|
||||||
|
|
||||||
|
if( ! empty($textTTFC) )
|
||||||
|
{
|
||||||
|
$textTTFC = $textTTFC[rand(0, count($textTTFC) - 1)];
|
||||||
|
|
||||||
|
$textTTFC = Base::suffix($textTTFC, '.ttf');
|
||||||
|
|
||||||
|
if( is_file($textTTFC) )
|
||||||
|
{
|
||||||
|
imagettftext
|
||||||
|
(
|
||||||
|
$file,
|
||||||
|
$textSizeC,
|
||||||
|
$textAngleC,
|
||||||
|
$textXC,
|
||||||
|
$textYC + $textSizeC,
|
||||||
|
$fontColor,
|
||||||
|
$textTTFC,
|
||||||
|
$this->getCode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imagestring($file, $textSizeC, $textXC, $textYC, $this->getCode(), $fontColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected Background Image
|
||||||
|
*/
|
||||||
|
protected function background(& $file)
|
||||||
|
{
|
||||||
|
$bgset = $this->sets['background'];
|
||||||
|
|
||||||
|
$backgroundImageC = $bgset['image'] ?? [];
|
||||||
|
|
||||||
|
if( ! empty($backgroundImageC) )
|
||||||
|
{
|
||||||
|
if( is_array($backgroundImageC) )
|
||||||
|
{
|
||||||
|
$backgroundImageC = $backgroundImageC[rand(0, count($backgroundImageC) - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( is_file($backgroundImageC) )
|
||||||
|
{
|
||||||
|
$infoExtension = strtolower(pathinfo($backgroundImageC, PATHINFO_EXTENSION));
|
||||||
|
|
||||||
|
switch( $infoExtension )
|
||||||
|
{
|
||||||
|
case 'jpeg':
|
||||||
|
case 'jpg' : $file = imagecreatefromjpeg($backgroundImageC); break;
|
||||||
|
case 'webp': $file = imagecreatefromwebp($backgroundImageC); break;
|
||||||
|
case 'png' : $file = imagecreatefrompng($backgroundImageC); break;
|
||||||
|
case 'gif' : $file = imagecreatefromgif($backgroundImageC); break; // @codeCoverageIgnore
|
||||||
|
default : $file = imagecreatefromjpeg($backgroundImageC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$backgroundColorC = $bgset['color'] ?? '255|255|255';
|
||||||
|
|
||||||
|
$color = imagecolorallocate($file, ...explode('|', $backgroundColorC));
|
||||||
|
|
||||||
|
imagefill($file, 0, 0, $color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected clean captcha
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function clean()
|
||||||
|
{
|
||||||
|
$captcha = $this->path . $this->name();
|
||||||
|
|
||||||
|
$getCaptchaImages = preg_grep('/captcha\-\w+\.png/', Filesystem::getFiles($this->path, 'png'));
|
||||||
|
|
||||||
|
foreach( $getCaptchaImages as $image)
|
||||||
|
{
|
||||||
|
if( $this->name() !== $image )
|
||||||
|
{
|
||||||
|
$captcha = $this->path . $image;
|
||||||
|
|
||||||
|
if( is_file($captcha) )
|
||||||
|
{
|
||||||
|
unlink($captcha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected captcha name
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function name()
|
||||||
|
{
|
||||||
|
return 'captcha-' . $this->getCode() . '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protected conver color
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function convertColor($color)
|
||||||
|
{
|
||||||
|
if( $convert = (Image\Properties::$colors[$color] ?? NULL) )
|
||||||
|
{
|
||||||
|
return $convert; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<?php namespace ZN\Captcha;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface RenderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The image specifies the path to save.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function path(string $path) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the size of the captcha.
|
||||||
|
*
|
||||||
|
* @param int $width
|
||||||
|
* @param int $height
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function size(int $width, int $height) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character type.
|
||||||
|
*
|
||||||
|
* @param string $type = 'alnum' - options[alnum|numeric|]
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function type(string $type = 'alnum') : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character width.
|
||||||
|
*
|
||||||
|
* @param int $param
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function length(int $param) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character angle.
|
||||||
|
*
|
||||||
|
* @param int $param
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function angle(Float $param) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add ttf fonts.
|
||||||
|
*
|
||||||
|
* @param array $fonts
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function ttf(array $fonts) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the border color.
|
||||||
|
*
|
||||||
|
* @param string $color = NULL
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function borderColor(?string $color = NULL) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color.
|
||||||
|
*
|
||||||
|
* @param string $color = NULL
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function bgColor(string $color) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add background pictures.
|
||||||
|
*
|
||||||
|
* @param array $image
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function bgImage(array $image) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text size.
|
||||||
|
*
|
||||||
|
* @param int $size
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textSize(int $size) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text coordiante.
|
||||||
|
*
|
||||||
|
* @param int $x
|
||||||
|
* @param int $y
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textCoordinate(int $x, int $y) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text color.
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function textColor(string $color) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the grid color.
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function gridColor(?string $color = NULL) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the grid space.
|
||||||
|
*
|
||||||
|
* @param int $x = 0
|
||||||
|
* @param int $y = 0
|
||||||
|
*
|
||||||
|
* @return Captcha
|
||||||
|
*/
|
||||||
|
public function gridSpace(int $x = 0, int $y = 0) : Render;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes the captcha creation process.
|
||||||
|
*
|
||||||
|
* @param bool $img = false
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function create(bool $img = false) : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current captcha code.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCode() : string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Controller\Factory;
|
||||||
|
|
||||||
|
class Benchmark extends Factory
|
||||||
|
{
|
||||||
|
const factory =
|
||||||
|
[
|
||||||
|
'methods' =>
|
||||||
|
[
|
||||||
|
'run' => 'Run::test',
|
||||||
|
'cycle' => 'Run::cycle',
|
||||||
|
'result' => 'Run::result',
|
||||||
|
'start' => 'Testing::start',
|
||||||
|
'end' => 'Testing::end',
|
||||||
|
'elapsedtime' => 'ElapsedTime::calculate',
|
||||||
|
'usedfiles' => 'FileUsage::list',
|
||||||
|
'usedfilecount' => 'FileUsage::count',
|
||||||
|
'calculatedmemory' => 'MemoryUsage::calculate',
|
||||||
|
'memoryusage' => 'MemoryUsage::normal',
|
||||||
|
'maxmemoryusage' => 'MemoryUsage::maximum'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ElapsedTime
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Calculate elapsed time
|
||||||
|
*
|
||||||
|
* @param string $result
|
||||||
|
* @param int $decimal = 4
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function calculate(string $result, int $decimal = 4) : Float
|
||||||
|
{
|
||||||
|
$resend = $result."_end";
|
||||||
|
$restart = $result."_start";
|
||||||
|
|
||||||
|
if( ! isset(Properties::$tests[$restart]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'elapsedTime', '%' => $result, 'start']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isset(Properties::$tests[$resend]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'elapsedTime', '%' => $result, 'end']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return round(((float) Properties::$tests[$resend] - (float) Properties::$tests[$restart]), $decimal);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php namespace ZN\Comparison\Exception;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Exception;
|
||||||
|
|
||||||
|
class InvalidParameterException extends Exception
|
||||||
|
{
|
||||||
|
const lang =
|
||||||
|
[
|
||||||
|
'en' => '[Benchmark::&(\'%\')] -> The parameter is not a valid test key!',
|
||||||
|
'tr' => '[Benchmark::&(\'%\')] -> Parametre geçerli bir test anahtarı değildir!'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class FileUsage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Usage file list
|
||||||
|
*
|
||||||
|
* @param string $result = NULL
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function list(?string $result = NULL) : array
|
||||||
|
{
|
||||||
|
if( empty($result) )
|
||||||
|
{
|
||||||
|
return get_required_files();
|
||||||
|
}
|
||||||
|
|
||||||
|
$resend = $result."_end";
|
||||||
|
$restart = $result."_start";
|
||||||
|
|
||||||
|
if( ! isset(Properties::$usedtests[$restart]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'usedFiles', '%' => $result, 'start']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isset(Properties::$usedtests[$resend]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'usedFiles', '%' => $result, 'end']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_diff(Properties::$usedtests[$resend], Properties::$usedtests[$restart]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used file count
|
||||||
|
*
|
||||||
|
* @param string $result = NULL
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function count(?string $result = NULL) : int
|
||||||
|
{
|
||||||
|
if( empty($result) )
|
||||||
|
{
|
||||||
|
return count(get_required_files());
|
||||||
|
}
|
||||||
|
|
||||||
|
$resend = $result."_end";
|
||||||
|
$restart = $result."_start";
|
||||||
|
|
||||||
|
if( ! isset(Properties::$usedtests[$restart]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'usedFileCount', '%' => $result, 'start']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isset(Properties::$usedtests[$resend]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'usedFileCount', '%' => $result, 'end']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count(Properties::$usedtests[$resend]) - count(Properties::$usedtests[$restart]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MemoryUsage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Calculate memory
|
||||||
|
*
|
||||||
|
* @param string $result
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function calculate(string $result) : Float
|
||||||
|
{
|
||||||
|
$resend = $result."_end";
|
||||||
|
$restart = $result."_start";
|
||||||
|
|
||||||
|
if( ! isset(Properties::$memtests[$restart]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'calculatedMemory', '%' => $result, 'start']); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! isset(Properties::$memtests[$resend]) )
|
||||||
|
{
|
||||||
|
throw new Exception\InvalidParameterException(NULL, ['&' => 'calculatedMemory', '%' => $result, 'end']); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
return Properties::$memtests[$resend] - Properties::$memtests[$restart];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage memory
|
||||||
|
*
|
||||||
|
* @param bool $realMemory = false
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function normal(bool $realMemory = false) : int
|
||||||
|
{
|
||||||
|
return memory_get_usage($realMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage max memory
|
||||||
|
*
|
||||||
|
* @param bool $realMemory = false
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function maximum(bool $realMemory = false) : int
|
||||||
|
{
|
||||||
|
return memory_get_peak_usage($realMemory);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Properties
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Keeps test names
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $tests = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps memory results
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $memtests = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps used tests
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $usedtests = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class Run
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run test
|
||||||
|
*
|
||||||
|
* @param callable $test
|
||||||
|
*
|
||||||
|
* @return Run
|
||||||
|
*/
|
||||||
|
public function test(callable $test) : Run
|
||||||
|
{
|
||||||
|
Testing::start('run');
|
||||||
|
$test();
|
||||||
|
Testing::end('run');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run cycle
|
||||||
|
*
|
||||||
|
* @param callable $test
|
||||||
|
*
|
||||||
|
* @return Run
|
||||||
|
*/
|
||||||
|
public function cycle($count, callable $test) : Run
|
||||||
|
{
|
||||||
|
Testing::start('run');
|
||||||
|
|
||||||
|
for( $i = 0; $i < $count; $i++ )
|
||||||
|
{
|
||||||
|
$test();
|
||||||
|
}
|
||||||
|
|
||||||
|
Testing::end('run');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result test
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return stdClass
|
||||||
|
*/
|
||||||
|
public function result() : stdClass
|
||||||
|
{
|
||||||
|
return (object)
|
||||||
|
[
|
||||||
|
'elapsedTime' => ElapsedTime::calculate('run'),
|
||||||
|
'calculatedMemory' => MemoryUsage::calculate('run'),
|
||||||
|
'usedFileCount' => FileUsage::count('run'),
|
||||||
|
'usedFiles' => FileUsage::list('run')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php namespace ZN\Comparison;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Testing
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Start test
|
||||||
|
*
|
||||||
|
* @param string $test
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function start(string $test)
|
||||||
|
{
|
||||||
|
$test = $test."_start";
|
||||||
|
|
||||||
|
Properties::$tests[$test] = microtime(true);
|
||||||
|
Properties::$usedtests[$test] = get_required_files();
|
||||||
|
Properties::$memtests[$test] = memory_get_usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End test
|
||||||
|
*
|
||||||
|
* @param string $test
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function end(string $test)
|
||||||
|
{
|
||||||
|
$getMemoryUsage = memory_get_usage();
|
||||||
|
$test = $test."_end";
|
||||||
|
|
||||||
|
Properties::$tests[$test] = microtime(true);
|
||||||
|
Properties::$usedtests[$test] = get_required_files();
|
||||||
|
Properties::$memtests[$test] = $getMemoryUsage;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php namespace ZN\Compression;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Configuration
|
||||||
|
*
|
||||||
|
* Enabled when the configuration file can not be accessed.
|
||||||
|
*/
|
||||||
|
class CompressionDefaultConfiguration
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Compression
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Includes default settings for the compress.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public $driver = 'gz';
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php namespace ZN\Compression;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function extract($source, $target, $password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function write($file, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function read($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function do($data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function undo($data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Compression\Exception\FileNotFoundException;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
class BzDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::func('bzopen', 'BZ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
$open = bzopen($file, 'w');
|
||||||
|
|
||||||
|
if( empty($open) )
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(NULL, $file); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = bzwrite($open, $data, strlen($data));
|
||||||
|
|
||||||
|
bzclose($open);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
$open = bzopen($file, 'r');
|
||||||
|
|
||||||
|
if( empty($open) )
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(NULL, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = bzread($open, 8096);
|
||||||
|
|
||||||
|
bzclose($open);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return bzcompress($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return bzdecompress($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Compression\Exception\FileNotFoundException;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
class GzDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::func('gzopen', 'GZ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
$open = gzopen($file, 'w');
|
||||||
|
|
||||||
|
if( empty($open) )
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(NULL, $file); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = gzwrite($open, $data, strlen($data));
|
||||||
|
|
||||||
|
gzclose($open);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
$open = gzopen($file, 'r');
|
||||||
|
|
||||||
|
if( empty($open) )
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(NULL, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = gzread($open, 8096);
|
||||||
|
|
||||||
|
gzclose($open);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return gzcompress($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return gzuncompress($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
class LzfDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::func('lzf_compress', 'LZF');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
$data = $this->do($data);
|
||||||
|
|
||||||
|
return file_put_contents($file, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
|
||||||
|
return $this->undo($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return lzf_compress($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return lzf_decompress($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Base;
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
class RarDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::func('rar_open', 'RAR');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password)
|
||||||
|
{
|
||||||
|
$rarFile = rar_open(Base::suffix($source, '.rar'), $password);
|
||||||
|
$list = rar_list($rarFile);
|
||||||
|
|
||||||
|
if( ! empty($list) ) foreach( $list as $file )
|
||||||
|
{
|
||||||
|
$entry = rar_entry_get($rarFile, $file);
|
||||||
|
$entry->extract($target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rar_close($rarFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->write($file, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->read($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->do($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->undo($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Singleton;
|
||||||
|
use ZN\Filesystem;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
class ZipDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::library('ZipArchive', 'ZIP Archive');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password = NULL)
|
||||||
|
{
|
||||||
|
return Filesystem\Forge::zipExtract($source, $target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->write($file, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->read($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->do($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return Singleton::class('ZN\Compression\Drivers\GzDriver')->undo($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?php namespace ZN\Compression\Drivers;
|
||||||
|
/**
|
||||||
|
* ZN PHP Web Framework
|
||||||
|
*
|
||||||
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
||||||
|
*
|
||||||
|
* @package ZN
|
||||||
|
* @license MIT [http://opensource.org/licenses/MIT]
|
||||||
|
* @author Ozan UYKUN [ozan@znframework.com]
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ZN\Support;
|
||||||
|
use ZN\Compression\DriverMappingAbstract;
|
||||||
|
|
||||||
|
class ZlibDriver extends DriverMappingAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Magic constructor
|
||||||
|
*
|
||||||
|
* Checking if your driver is supported.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Support::func('zlib_encode', 'ZLIB');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target = NULL
|
||||||
|
* @param string $password = NULL
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function extract($source, $target, $password)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function write($file, $data)
|
||||||
|
{
|
||||||
|
$data = $this->do($data);
|
||||||
|
|
||||||
|
return file_put_contents($file, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function read($file)
|
||||||
|
{
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
|
||||||
|
return $this->undo($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force do
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function do($data)
|
||||||
|
{
|
||||||
|
return zlib_encode($data, ZLIB_ENCODING_GZIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force undo
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function undo($data)
|
||||||
|
{
|
||||||
|
return zlib_decode($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user