new pisilinux web sites
This commit is contained in:
@@ -0,0 +1,611 @@
|
||||
<?php namespace ZN\Console;
|
||||
/**
|
||||
* 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 Throwable;
|
||||
use ZN\Base;
|
||||
use ZN\Config;
|
||||
use ZN\Request;
|
||||
use ZN\Buffering;
|
||||
use ZN\Filesystem;
|
||||
use ZN\Protection\Json;
|
||||
use ZN\Helpers\Converter;
|
||||
use ZN\ErrorHandling\Errors;
|
||||
use ZN\ErrorHandling\Exceptions;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Async
|
||||
{
|
||||
/**
|
||||
* Keeps process ID.
|
||||
*
|
||||
* @var string $procId
|
||||
*/
|
||||
protected static $procId = '';
|
||||
|
||||
/**
|
||||
* Keeps process directory.
|
||||
*
|
||||
* @var string $procDir
|
||||
*/
|
||||
protected static $procDir = FILES_DIR;
|
||||
|
||||
/**
|
||||
* Keeps soket URI.
|
||||
*
|
||||
* @var string $socket
|
||||
*/
|
||||
protected static $socketURI = '';
|
||||
|
||||
/**
|
||||
* Keeps socket success
|
||||
*
|
||||
* @var string $success
|
||||
*/
|
||||
protected static $success = '';
|
||||
|
||||
/**
|
||||
* Keeps socket error
|
||||
*
|
||||
* @var string $error
|
||||
*/
|
||||
protected static $error = '';
|
||||
|
||||
/**
|
||||
* Sets process directory.
|
||||
*
|
||||
* @param string $directory
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function setProcDirectory(string $directory) : Async
|
||||
{
|
||||
self::$procDir = $directory;
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets socket URI.
|
||||
*
|
||||
* @param string $directory
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function setSocketURI(string $socketURI) : Async
|
||||
{
|
||||
self::$socketURI = $socketURI;
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get process data.
|
||||
*
|
||||
* @param string $procId = current-process
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getData(string $procId = '') : array
|
||||
{
|
||||
$procFile = self::getProcFile($procId);
|
||||
|
||||
if( is_file($procFile) )
|
||||
{
|
||||
return Json::decodeArray(file_get_contents($procFile));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get process Id.
|
||||
*/
|
||||
public static function getProcId() : string
|
||||
{
|
||||
return self::$procId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run command
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $data = []
|
||||
* @param string $name = NULL
|
||||
*/
|
||||
public static function run(string $command, array $data = [], ?string $name = NULL) : string
|
||||
{
|
||||
self::$procId = $procId = self::$procDir . ($uniq = $name ? preg_replace('/\W+/', '', $name) : uniqid());
|
||||
|
||||
$processor = Config::default('ZN\Prompt\PromptDefaultConfiguration')::get('Services', 'processor');
|
||||
|
||||
if( ! file_exists($processor['path']) )
|
||||
{
|
||||
$path = 'php';
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = $processor['path'];
|
||||
}
|
||||
|
||||
$open = proc_open($path . ' zerocore ' . $command . ' "' . $procId . '"', [], $arr);
|
||||
|
||||
$data['status'] = proc_get_status($open);
|
||||
|
||||
$data['status']['run'] = $command;
|
||||
$data['status']['file'] = $uniq;
|
||||
$data['status']['path'] = self::$procId;
|
||||
|
||||
file_put_contents($procId, Json::encode($data));
|
||||
|
||||
return $procId;
|
||||
}
|
||||
|
||||
/**
|
||||
* List
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function list() : array
|
||||
{
|
||||
$processList = [];
|
||||
|
||||
foreach( Filesystem::getFiles(self::$procDir, NULL, true) as $file )
|
||||
{
|
||||
$processList[] = self::getData($file);
|
||||
}
|
||||
|
||||
return $processList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close proc
|
||||
*
|
||||
* @param string $procId = current-process
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public static function close(string $procId = '')
|
||||
{
|
||||
if( $pid = self::getData($procId)['status']['pid'] ?? NULL )
|
||||
{
|
||||
self::remove($procId);
|
||||
|
||||
return self::closeProcess($pid);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close All Process
|
||||
*
|
||||
*/
|
||||
public static function closeAll()
|
||||
{
|
||||
foreach( self::list() as $proc )
|
||||
{
|
||||
if( isset($proc['file']) )
|
||||
{
|
||||
self::close($proc['file']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Exists
|
||||
*
|
||||
* @param string $procId = current-process
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isExists(string $procId = '') : bool
|
||||
{
|
||||
$procFile = self::getProcFile($procId);
|
||||
|
||||
return is_file($procFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Command process
|
||||
*
|
||||
* @param string $procId
|
||||
* @param callback $callable
|
||||
* @param bool $displayError = false
|
||||
*/
|
||||
public static function process(string $procId, callable $callable, bool $displayError = false) : void
|
||||
{
|
||||
self::$procId = $procId;
|
||||
|
||||
$data = self::getData($procId);
|
||||
|
||||
try
|
||||
{
|
||||
$callable($data, $procId);
|
||||
}
|
||||
catch( Throwable $e )
|
||||
{
|
||||
if( $displayError )
|
||||
{
|
||||
$error =
|
||||
[
|
||||
'code' => $e->getCode(),
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTrace()
|
||||
];
|
||||
|
||||
self::report($error, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
self::close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove process ID
|
||||
*
|
||||
* @param string $procId = current-process
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function remove(string $procId = '') : bool
|
||||
{
|
||||
$procFile = self::getProcFile($procId);
|
||||
|
||||
if( is_file($procFile) )
|
||||
{
|
||||
return unlink($procFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create report
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function report(array $data, string $suffix = 'report') : int
|
||||
{
|
||||
return file_put_contents(self::$procId . '-' . $suffix, Json::encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Output
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function output(array $data) : int
|
||||
{
|
||||
return self::report($data, 'output');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates socket
|
||||
*/
|
||||
public static function socket()
|
||||
{
|
||||
$originFile = self::getProcFile($_POST['procId']);
|
||||
|
||||
$procFile = Base::suffix($originFile, '-output');
|
||||
|
||||
if( is_file($originFile) )
|
||||
{
|
||||
echo json_encode(['status' => 'processing']);
|
||||
}
|
||||
else if( is_file($procFile) )
|
||||
{
|
||||
echo file_get_contents($procFile);
|
||||
|
||||
unlink($procFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode([]);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets socket success
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public static function success(callable $callable)
|
||||
{
|
||||
self::$success = $callable;
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets socket error
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public static function error(callable $callable)
|
||||
{
|
||||
self::$error = $callable;
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $procId
|
||||
* @param int $time = 1000
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function listen($procId, int $time = 1000) : string
|
||||
{
|
||||
$var = 'socket' . uniqid();
|
||||
|
||||
$procData = ( is_scalar($procId) ? '"' . str_replace(self::$procDir, '', $procId) . '"' : Buffering\Callback::do($procId) );
|
||||
|
||||
$return =
|
||||
'
|
||||
var ' . $var . ' = setInterval(function()
|
||||
{
|
||||
$.ajax
|
||||
({
|
||||
url: "' . Request::getSiteURL(self::$socketURI) . '",
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
data: {procId: ' . $procData . '},
|
||||
success: function(data)
|
||||
{
|
||||
' . (self::$success ? Buffering\Callback::do(self::$success) : '') . '
|
||||
|
||||
if( data.status != "processing" )
|
||||
{
|
||||
clearInterval(' . $var . ');
|
||||
}
|
||||
},
|
||||
error: function(data)
|
||||
{
|
||||
' . (self::$error ? Buffering\Callback::do(self::$error) : '') . '
|
||||
}
|
||||
})
|
||||
}, ' . $time . ');
|
||||
';
|
||||
|
||||
self::$success = '';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status
|
||||
*
|
||||
* @param string ...$procIds
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function status(string ...$procIds) : array
|
||||
{
|
||||
$pending = [];
|
||||
|
||||
foreach( $procIds as $procId )
|
||||
{
|
||||
$procFile = self::getProcFile($procId);
|
||||
|
||||
if( is_file($procFile) )
|
||||
{
|
||||
$pending[$procFile] = 1; # pending.
|
||||
}
|
||||
}
|
||||
|
||||
return $pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is finish
|
||||
*
|
||||
* @param string ...$procIds
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isFinish(string ...$procIds) : bool
|
||||
{
|
||||
return ! in_array(1, self::status(...$procIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispay Report
|
||||
*
|
||||
* @param string $errorFile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function displayError(string $errorFile) : string
|
||||
{
|
||||
if( is_file($file = self::$procDir . $errorFile) && ( $fileContent = file_get_contents($file) ) )
|
||||
{
|
||||
$data = Json::decodeArray($fileContent);
|
||||
|
||||
return Buffering\Callback::do(function() use($data)
|
||||
{
|
||||
Exceptions::table($data['code'] ?? NULL, $data['message'], $data['file'], $data['line'], $data['trace']);
|
||||
});
|
||||
}
|
||||
|
||||
return Errors::message('File not found!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop
|
||||
*
|
||||
* @param int $count
|
||||
* @param int $waitSecond
|
||||
* @param callable $callback
|
||||
*/
|
||||
public static function loop(int $count, int $waitSecond, callable $callback)
|
||||
{
|
||||
$i = 1;
|
||||
|
||||
while( true )
|
||||
{
|
||||
$callback($i, $waitSecond);
|
||||
|
||||
if( $i == $count )
|
||||
{
|
||||
self::close();
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
sleep($waitSecond);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop Every Hour
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param bool $firstTrigger = true
|
||||
*/
|
||||
public static function loopEveryHour(callable $callback, bool $firstTrigger = true)
|
||||
{
|
||||
$check = false;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( ! $check )
|
||||
{
|
||||
$minute = (int) date('i');
|
||||
$second = (int) date('s');
|
||||
|
||||
$remaining = ((60 - $minute) * 60) - $second;
|
||||
}
|
||||
else
|
||||
{
|
||||
$remaining = 3600;
|
||||
}
|
||||
|
||||
if( $firstTrigger === true )
|
||||
{
|
||||
$callback();
|
||||
}
|
||||
|
||||
sleep($remaining);
|
||||
|
||||
if( $firstTrigger === false )
|
||||
{
|
||||
$callback();
|
||||
}
|
||||
|
||||
$check = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop Every Minute
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param bool $firstTrigger = true
|
||||
*/
|
||||
public static function loopEveryMinute(callable $callback, bool $firstTrigger = true)
|
||||
{
|
||||
$check = false;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( ! $check )
|
||||
{
|
||||
$second = (int) date('s');
|
||||
|
||||
$remaining = 60 - $second;
|
||||
}
|
||||
else
|
||||
{
|
||||
$remaining = 60;
|
||||
}
|
||||
|
||||
if( $firstTrigger === true )
|
||||
{
|
||||
$callback();
|
||||
}
|
||||
|
||||
sleep($remaining);
|
||||
|
||||
if( $firstTrigger === false )
|
||||
{
|
||||
$callback();
|
||||
}
|
||||
|
||||
$check = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Run
|
||||
*
|
||||
* @param string $procId = current-process
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isRun(string $procId = '') : bool
|
||||
{
|
||||
if( $pid = self::getData($procId)['status']['pid'] ?? NULL )
|
||||
{
|
||||
if( stripos(php_uname('s'), 'win') > -1 )
|
||||
{
|
||||
$output = [];
|
||||
|
||||
exec("tasklist /FI \"PID eq $pid\"", $output);
|
||||
|
||||
foreach( $output as $line)
|
||||
{
|
||||
if( strpos($line, (string)$pid) !== false )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exec("ps -p $pid", $output);
|
||||
|
||||
if( count($output) > 1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* protected get proc file
|
||||
*/
|
||||
protected static function getProcFile(string $procId = '')
|
||||
{
|
||||
return $procId ? Base::prefix($procId, self::$procDir) : self::$procId;
|
||||
}
|
||||
|
||||
/**
|
||||
* protected close process
|
||||
*/
|
||||
protected static function closeProcess($pid)
|
||||
{
|
||||
return stripos(php_uname('s'), 'win') > -1 ? exec("taskkill /F /T /PID $pid") : exec("kill -9 $pid");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user