doc fixes

This commit is contained in:
Dennis Eichhorn 2022-04-21 23:52:01 +02:00
parent d62475dc69
commit edd4693111
43 changed files with 216 additions and 217 deletions

View File

@ -22,7 +22,8 @@ namespace phpOMS\Ai\NeuralNetwork;
* @link https://karaka.app
* @since 1.0.0
*/
class Neuron {
class Neuron
{
/**
* Neuron inputs
*

View File

@ -107,11 +107,15 @@ final class BasicOcr
if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) {
return []; // @codeCoverageIgnore
}
/** @var int<0, max> $numberOfRows */
$numberOfRows = (int) $unpack[1];
if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) {
return []; // @codeCoverageIgnore
}
/** @var int<0, max> $numberOfColumns */
$numberOfColumns = (int) $unpack[1];
$images = [];

View File

@ -40,14 +40,6 @@ final class Kmeans
*/
private \Closure $metric;
/**
* Amount of different clusters
*
* @var int
* @since 1.0.0
*/
private int $clusters = 1;
/**
* Points of the cluster centers
*
@ -56,14 +48,6 @@ final class Kmeans
*/
private $clusterCenters = [];
/**
* Points to clusterize
*
* @var PointInterface[]
* @since 1.0.0
*/
private array $points = [];
/**
* Constructor
*
@ -75,9 +59,7 @@ final class Kmeans
*/
public function __construct(array $points, int $clusters, \Closure $metric = null)
{
$this->points = $points;
$this->clusters = $clusters;
$this->metric = $metric ?? function (PointInterface $a, PointInterface $b) {
$this->metric = $metric ?? function (PointInterface $a, PointInterface $b) {
$aCoordinates = $a->getCoordinates();
$bCoordinates = $b->getCoordinates();

View File

@ -79,11 +79,11 @@ final class CycleSort implements SortInterface
}
}
while ($item->equals($list[$pos])) {
while (isset($list[$pos]) && $item->equals($list[$pos])) {
++$pos;
}
if (!$item->equals($list[$pos])) {
if (isset($list[$pos])) {
$old = $list[$pos];
$list[$pos] = $item;
$item = $old;

View File

@ -16,7 +16,7 @@ Generally, the development philosophy is result orientated. This means that anyo
Developers are encouraged to pick open tasks with high priorities according to their own skill level. Senior developers may directly assign tasks to developers based on their importance. New developers may find it easier to start with a task that has a low priority as they often also have a lower difficulty.
Open tasks can be found in the project overview: [PROJECT.md](../Project/PROJECT.md)
Open tasks can be found in the project overview: [PROJECT.md](https://github.com/Karaka-Management/Organization-Guide/blob/master/Project/PROJECT.md)
Tasks currently in development are prefixed in the priority column with an asterisk `*` and a name tag in the task description of the developer who is working on the task.

View File

@ -41,7 +41,7 @@ final class ConnectionFactory
*
* Overwrites current connection if existing
*
* @param array{db:string, database:string}|array{db:string, host:string, port:int, login:string, password:string, database:string} $dbdata the basic database information for establishing a connection
* @param array{db:string, host?:string, port?:int, login?:string, password?:string, database:string} $dbdata the basic database information for establishing a connection
*
* @return ConnectionAbstract
*

View File

@ -37,7 +37,7 @@ final class MysqlConnection extends ConnectionAbstract
*
* Creates the database object and overwrites all default values.
*
* @param array{db:string, host:string, port:int, login:string, password:string, database:string} $dbdata the basic database information for establishing a connection
* @param array{db:string, host?:string, port?:int, login?:string, password?:string, database:string} $dbdata the basic database information for establishing a connection
*
* @since 1.0.0
*/

View File

@ -38,7 +38,7 @@ final class PostgresConnection extends ConnectionAbstract
*
* Creates the database object and overwrites all default values.
*
* @param array{db:string, host:string, port:int, login:string, password:string, database:string} $dbdata the basic database information for establishing a connection
* @param array{db:string, host?:string, port?:int, login?:string, password?:string, database:string} $dbdata the basic database information for establishing a connection
*
* @since 1.0.0
*/

View File

@ -38,7 +38,7 @@ final class SqlServerConnection extends ConnectionAbstract
*
* Creates the database object and overwrites all default values.
*
* @param array{db:string, host:string, port:int, login:string, password:string, database:string} $dbdata the basic database information for establishing a connection
* @param array{db:string, host?:string, port?:int, login?:string, password?:string, database:string} $dbdata the basic database information for establishing a connection
*
* @since 1.0.0
*/

View File

@ -91,7 +91,7 @@ class DataMapperFactory
/**
* Belongs to.
*
* @var array<string, array{mapper:string, external:string}>
* @var array<string, array{mapper:string, external:string, column?:string, by?:string}>
* @since 1.0.0
*/
public const BELONGS_TO = [];

View File

@ -287,7 +287,7 @@ final class ReadMapper extends DataMapperAbstract
{
$query = $this->getQuery(null, ['COUNT(*)' => 'count']);
return (int) $query->execute()->fetchColumn();
return (int) $query->execute()?->fetchColumn();
}
/**

View File

@ -143,6 +143,7 @@ final class WriteMapper extends DataMapperAbstract
$query->insert($column['name'])->value($value);
} else {
if (\stripos($column['internal'], '/') !== false) {
/** @var array $tValue */
$path = \substr($column['internal'], \stripos($column['internal'], '/') + 1);
$tValue = ArrayUtils::getArray($path, $tValue, '/');
}

View File

@ -1395,8 +1395,13 @@ class Builder extends BuilderAbstract
*/
public function execute() : ?PDOStatement
{
$sth = null;
try {
$sth = $this->connection->con->prepare($this->toSql());
if ($sth === false) {
return null;
}
foreach ($this->binds as $key => $bind) {
$type = self::getBindParamType($bind);

View File

@ -72,7 +72,7 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
*
* @since 1.0.0
*/
public function open($savePath, $sessionName)
public function open(string $savePath, string $sessionName) : bool
{
$this->savePath = $savePath;
@ -96,17 +96,17 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
*
* @param string $id Session id
*
* @return string
* @return false|string
*
* @since 1.0.0
*/
public function read($id)
public function read(string $id) : string|false
{
if (!\is_file($this->savePath . '/sess_' . $id)) {
return '';
}
return (string) \file_get_contents($this->savePath . '/sess_' . $id);
return \file_get_contents($this->savePath . '/sess_' . $id);
}
/**
@ -119,7 +119,7 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
*
* @since 1.0.0
*/
public function write($id, $data)
public function write(string $id, string $data) : bool
{
return \file_put_contents($this->savePath . '/sess_' . $id, $data) === false ? false : true;
}
@ -133,7 +133,7 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
*
* @since 1.0.0
*/
public function destroy($id)
public function destroy(string $id) : bool
{
$file = $this->savePath . '/sess_' . $id;
if (\is_file($file)) {
@ -148,16 +148,16 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
*
* @param int $maxlifetime Maximum session data life time
*
* @return bool
* @return int|false
*
* @since 1.0.0
*/
public function gc($maxlifetime)
public function gc(int $maxlifetime) : int|false
{
$files = \glob("{$this->savePath}/sess_*");
if ($files === false) {
return false;
return 0;
}
foreach ($files as $file) {
@ -166,6 +166,6 @@ final class FileSessionHandler implements \SessionHandlerInterface, \SessionIdIn
}
}
return true;
return 1;
}
}

View File

@ -269,7 +269,7 @@ class Localization implements \JsonSerializable
}
$json = \json_decode($fileContent, true);
if ($json === false) {
if (!\is_array($json)) {
return;
}
@ -284,7 +284,7 @@ class Localization implements \JsonSerializable
}
$json = \json_decode($fileContent, true);
if ($json === false) {
if (!\is_array($json)) {
return;
}
@ -294,7 +294,7 @@ class Localization implements \JsonSerializable
/**
* Load localization from locale
*
* @param array<string, int|string|array> $locale Locale data
* @param array{language?:string, country?:string, currency?:array{code?:string}, thousand?:string, angle?:string, temperatur?:string, weight?:array, speed?:array, length?:array, area?:array, volume?:array, precision?:array, timezone?:string, datetime?:array} $locale Locale data
*
* @return void
*

View File

@ -207,9 +207,9 @@ final class FileLogger implements LoggerInterface
/**
* Interpolate context
*
* @param string $message Log schema
* @param array<string, string> $context Context to log
* @param string $level Log level
* @param string $message Log schema
* @param array<string, null|int|bool|float|string> $context Context to log
* @param string $level Log level
*
* @return string
*
@ -231,7 +231,12 @@ final class FileLogger implements LoggerInterface
}
}
$backtrace = \str_replace(["\r\n", "\r", "\n"], ' ', \json_encode($backtrace));
$encodedBacktrace = \json_encode($backtrace);
if (!\is_string($encodedBacktrace)) {
$encodedBacktrace = '';
}
$backtrace = \str_replace(["\r\n", "\r", "\n"], ' ', $encodedBacktrace);
$replace['{backtrace}'] = $backtrace;
$replace['{datetime}'] = \sprintf('%--19s', (new \DateTimeImmutable('NOW'))->format('Y-m-d H:i:s'));

View File

@ -27,8 +27,8 @@ interface LoggerInterface
/**
* System is unusable.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -40,8 +40,8 @@ interface LoggerInterface
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -52,8 +52,8 @@ interface LoggerInterface
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -63,8 +63,8 @@ interface LoggerInterface
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -76,8 +76,8 @@ interface LoggerInterface
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -86,8 +86,8 @@ interface LoggerInterface
/**
* Normal but significant events.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -98,8 +98,8 @@ interface LoggerInterface
*
* Example: User logs in, SQL logs.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -108,8 +108,8 @@ interface LoggerInterface
/**
* Detailed debug information.
*
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/
@ -118,9 +118,9 @@ interface LoggerInterface
/**
* Logs with an arbitrary level.
*
* @param string $level Log level/severeness
* @param string $message Logging message schema
* @param array<string, mixed> $context Context to log
* @param string $level Log level/severeness
* @param string $message Logging message schema
* @param array<string, null|int|bool|float|string> $context Context to log
*
* @return void
*/

View File

@ -704,6 +704,10 @@ class Matrix implements \ArrayAccess, \Iterator
*/
public function offsetGet(mixed $offset) : mixed
{
if (!\is_int($offset)) {
return 0;
}
$offset = (int) $offset;
$row = (int) ($offset / $this->m);
@ -737,8 +741,12 @@ class Matrix implements \ArrayAccess, \Iterator
/**
* {@inheritdoc}
*/
public function offsetExists($offset) : bool
public function offsetExists(mixed $offset) : bool
{
if (!\is_int($offset)) {
return false;
}
$offset = (int) $offset;
$row = (int) ($offset / $this->m);
@ -756,8 +764,12 @@ class Matrix implements \ArrayAccess, \Iterator
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value) : void
public function offsetSet(mixed $offset, mixed $value) : void
{
if (!\is_int($offset) || !\is_numeric($value)) {
return;
}
$offset = (int) $offset;
$row = (int) ($offset / $this->m);
$this->matrix[$row][$offset - $row * $this->n] = $value;
@ -766,8 +778,12 @@ class Matrix implements \ArrayAccess, \Iterator
/**
* {@inheritdoc}
*/
public function offsetUnset($offset) : void
public function offsetUnset(mixed $offset) : void
{
if (!\is_int($offset)) {
return;
}
$offset = (int) $offset;
$row = (int) ($offset / $this->m);
unset($this->matrix[$row][$offset - $row * $this->n]);

View File

@ -94,6 +94,7 @@ final class ConsoleRequest extends RequestAbstract
$key = '-' . \mb_strtolower($key);
if ($type === null) {
/** @var string[] $this->data */
return ArrayUtils::getArg($key, $this->data);
}

View File

@ -115,6 +115,7 @@ final class ConsoleResponse extends ResponseAbstract implements RenderableInterf
}
}
/** @var array{0:bool} $data */
return $this->getRaw($data[0] ?? false);
}

View File

@ -139,7 +139,7 @@ final class HttpRequest extends RequestAbstract
}
$json = \json_decode($input, true);
if ($json === false || $json === null) {
if (!\is_array($json)) {
throw new \Exception('Is not valid json ' . $input);
}

View File

@ -94,7 +94,9 @@ final class HttpResponse extends ResponseAbstract implements RenderableInterface
*/
public function getJsonData() : array
{
return \json_decode($this->getRaw(), true) ?? [];
$json = \json_decode($this->getRaw(), true);
return !\is_array($json) ? [] : $json;
}
/**
@ -115,6 +117,7 @@ final class HttpResponse extends ResponseAbstract implements RenderableInterface
}
}
/** @var array{0:bool} $data */
return $this->getRaw(\stripos($type ?? '', MimeType::M_HTML) !== false ? ($data[0] ?? false) : false);
}

View File

@ -37,7 +37,7 @@ abstract class RequestAbstract implements MessageInterface
/**
* Request data.
*
* @var array
* @var array<int|string, mixed>
* @since 1.0.0
*/
protected array $data = [];
@ -80,7 +80,7 @@ abstract class RequestAbstract implements MessageInterface
* @param string $key Data key
* @param string $type Return type
*
* @return null|int|string|float|bool
* @return mixed
*
* @since 1.0.0
*/
@ -133,7 +133,7 @@ abstract class RequestAbstract implements MessageInterface
$json = \json_decode($this->data[$key], true);
return $json === false ? [] : $json ?? [];
return !\is_array($json) ? [] : $json;
}
/**
@ -180,7 +180,7 @@ abstract class RequestAbstract implements MessageInterface
{
$data = [];
foreach ($this->data as $key => $value) {
if (\preg_match('/' . $regex . '/', $key) === 1) {
if (\preg_match('/' . $regex . '/', (string) $key) === 1) {
$data[$key] = $value;
}
}

View File

@ -54,14 +54,6 @@ final class Head implements RenderableInterface
*/
private array $assets = [];
/**
* Is the header set?
*
* @var bool
* @since 1.0.0
*/
private bool $hasContent = false;
/**
* Page meta.
*

View File

@ -147,9 +147,12 @@ final class Dom implements SerializableInterface
*/
public function unserialize(mixed $raw) : void
{
$unserialized = \json_decode($raw, true);
if (!\is_string($raw)) {
return;
}
if ($unserialized === false) {
$unserialized = \json_decode($raw, true);
if (!\is_array($unserialized)) {
return;
}

View File

@ -79,9 +79,12 @@ final class FormValidation implements \JsonSerializable, SerializableInterface
*/
public function unserialize(mixed $raw) : void
{
$unserialized = \json_decode($raw, true);
if (!\is_string($raw)) {
return;
}
if ($unserialized === false) {
$unserialized = \json_decode($raw, true);
if (!\is_array($unserialized)) {
return;
}

View File

@ -183,9 +183,12 @@ final class Notify implements \JsonSerializable, SerializableInterface
*/
public function unserialize(mixed $raw) : void
{
$unserialized = \json_decode($raw, true);
if (!\is_string($raw)) {
return;
}
if ($unserialized === false) {
$unserialized = \json_decode($raw, true);
if (!\is_array($unserialized)) {
return;
}

View File

@ -125,9 +125,12 @@ final class Redirect implements \JsonSerializable, SerializableInterface
*/
public function unserialize(mixed $raw) : void
{
$unserialized = \json_decode($raw, true);
if (!\is_string($raw)) {
return;
}
if ($unserialized === false) {
$unserialized = \json_decode($raw, true);
if (!\is_array($unserialized)) {
return;
}

View File

@ -85,9 +85,12 @@ final class Reload implements \JsonSerializable, SerializableInterface
*/
public function unserialize(mixed $raw) : void
{
$unserialized = \json_decode($raw, true);
if (!\is_string($raw)) {
return;
}
if ($unserialized === false) {
$unserialized = \json_decode($raw, true);
if (!\is_array($unserialized)) {
return;
}

View File

@ -207,12 +207,13 @@ final class ModuleManager
}
$content = \file_get_contents($path);
$json = \json_decode($content === false ? '[]' : $content, true);
if ($json === false) {
return [];
$json = \json_decode($content === false ? '[]' : $content, true);
if (!\is_array($json)) {
return $this->active;
}
/** @var array{name:array{internal:string}} $json */
$this->active[$json['name']['internal']] = $json;
}
}
@ -325,9 +326,10 @@ final class ModuleManager
->execute();
if ($sth === null) {
return [];
return $this->installed;
}
/** @var string[] $installed */
$installed = $sth->fetchAll(\PDO::FETCH_COLUMN);
foreach ($installed as $module) {
@ -754,6 +756,7 @@ final class ModuleManager
if (!isset($this->running[$class])) {
if (Autoloader::exists($class) !== false) {
try {
/** @var ModuleAbstract $obj */
$obj = new $class($this->app);
$this->running[$name] = $obj;
$this->registerRequesting($obj);

View File

@ -123,7 +123,7 @@ final class PackageManager
$contents = \file_get_contents($this->extractPath . '/info.json');
$info = \json_decode($contents === false ? '[]' : $contents, true);
$this->info = $info === false ? [] : $info;
$this->info = !\is_array($info) ? [] : $info;
}
/**

View File

@ -108,7 +108,7 @@ abstract class UninstallerAbstract
}
foreach ($definitions as $name => $definition) {
$builder->dropTable($name ?? '');
$builder->dropTable($name);
}
$builder->execute();

134
README.md
View File

@ -1,119 +1,75 @@
# Karaka
<p align="center"><img src="https://raw.githubusercontent.com/Karaka-Management/Assets/master/art/logo.png" width="256" alt="Logo"></p>
The phpOMS framework is primarily developed for the Karaka application which is a modular web application for small to mid sized companies that need CRM, ERP, Intranet and/or CMS functionalities and much more. The framework is also used in some other tools and websites which compliment the Karaka web application and provides the necessary php functionality.
The **phpOMS** framework is primarily developed for the Karaka application which is a modular web application for small to mid sized companies that need CRM, ERP, Intranet and/or CMS functionalities and much more. The framework is also used in some other tools and websites which compliment the Karaka web application and provides the necessary php functionality.
With Karaka you have one partner who can provide all the tools and software solutions you are used to at fair and reasonable prices even for small organizations and companies/startups. Our solutions can be used independently from each other or fully integrated with other solutions we provide. By choosing Karaka as your partner you'll be able to adjust your software based on the changes in your requirements without worrying about integration and workflow optimization.
## Table of content
## Table of Contents
- [Karaka](#karaka)
- [Table of content](#table-of-content)
- [Installation](#installation)
- [Requirements](#requirements)
- [Setup](#setup)
- [End-User](#end-user)
- [Developer](#developer)
- [Philosophy](#philosophy)
- [Development Status](#development-status)
- [Features](#features)
- [Unit Tests](#unit-tests)
- [Become a contributor](#become-a-contributor)
- [Misc](#misc)
- [Table of Contents](#table-of-contents)
- [Requirements](#requirements)
- [Developer tools](#developer-tools)
- [Installation](#installation)
- [Philosophy & Demo](#philosophy--demo)
- [Development status](#development-status)
- [Tech stack](#tech-stack)
- [Become a contributor](#become-a-contributor)
- [Misc](#misc)
## Requirements
* PHP 8.1
* PHP extension: php8.1-dev php8.1-cli php8.1-common php8.1-mysql php8.1-pgsql php8.1-xdebug php8.1-opcache php8.1-pdo php8.1-sqlite php8.1-mbstring php8.1-curl php8.1-imap php8.1-bcmath php8.1-zip php8.1-dom php8.1-xml php8.1-phar php8.1-gd php-pear
* apache2 (recommended) or nginx
* mysql-server (recommended) or postgresql postgresql-contrib
* Tools: tesseract-ocr, pdftotext, pdftoppm
* Make sure that URL rewriting is active!
### Developer tools
* Php extension: xdebug
* Tools: Composer, Npm
* Composer tools: phpstan, phpunit, phpcs
* Npm tools: eslint
## Installation
### Requirements
Detailed installation instructions can be found at:
Some of the following requirements are only necessary for developers and not for end-users:
* [Developer Setup](https://github.com/Karaka-Management/Developer-Guide/blob/develop/general/setup.md)
* [User Setup](https://github.com/Karaka-Management/User-Guide/blob/develop/setup/install.md)
* PHP 8.0
* PHP extension: php8.1 php8.1-dev php8.1-cli php8.1-common php8.1-mysql php8.1-pgsql php8.1-xdebug php8.1-opcache php8.1-pdo php8.1-sqlite php8.1-mbstring php8.1-curl php8.1-imap php8.1-bcmath php8.1-zip php8.1-dom php8.1-xml php8.1-phar php8.1-gd php-pear
* apache2 (recommended) or nginx
* mysql-server or postgresql postgresql-contrib
* Make sure that URL rewriting is active
* Download the Karaka project or clone the Karaka repository (incl. submodules).
Please note if you are only interested in using the framework without the web application you only have to configure your autoloading correctly for the **phpOMS** framework or use the autoloader provided by the framework in `phpOMS/Autoloader.php` and install the required php extensions mentioned above.
### Setup
#### End-User
After installing the requirements and configuring the web server for the correct path navigate to https://your_url.com/Install and follow the installation process. Afterwards you will be redirected to the installed backend.
For more detailed information please checkout the [Installation Guide](https://karaka.app/dev/guide?page=setup/installation).
#### Developer
https://github.com/karaka-management/Developer-Guide/blob/develop/general/setup.md
## Philosophy
## Philosophy & Demo
We believe software should support a business in it's daily tasks and growth in a very efficient way without frustration. In order to achieve this we constantly take feedback from our customers and expand and improve our software solutions.
Since we believe in our software and transparent business model you can live test parts of our application and it's modules in our demo application at https://karaka.app (user: admin, pass: orange) without any registration or inquiry. This can be done even during the development phase.
You can find a freely available online demo at https://demo.karaka.app (user: admin, pass: orange) without any registration or inquiry.
## Development Status
## Development status
Currently Karaka is still developing the first Alpha version. As soon as we have a running Beta version we are allowing external testers to use our software and a selected amount of inhouse developed modules. The **phpOMS** framework is the component which is developed the furthest and already provides a large amount of functionality which is required by the whole project.
Currently Karaka is still developing the first Alpha version. As soon as we have a running Beta version we are allowing external testers to use our software and a selected amount of inhouse developed modules.
General updates can be found in our info section at https://karaka.app/info and developer updates can be found in our developer section at https://karaka.app/dev. In our developer section you can also check out the automatically generated reports such as code coverage, code style, static analysis etc. as well as our code style guide lines and developer documentation.
![Preview](https://raw.githubusercontent.com/Karaka-Management/Assets/master/art/preview.png)
* [Project Status](https://github.com/Karaka-Management/Organization-Guide/blob/master/Project/PROJECT.md)
## Features
## Tech stack
Features this framework provides are:
* Account/Group management
* Permission management
* Asset management
* Business logic (e.g. sales, marketing, etc.)
* Console support
* WebSocket support
* Event management
* Database management
* Cache management
* Dispatcher
* Router
* Authentication
* Localization
* Logging (console/backend)
* Request/Response management
* Math (e.g. matrix, forecasting, optimization, geometry, stochastics, etc.)
* Module management
* Uri
* Utils (e.g. barcodes, comporession, unit converter, jobqueue, git, etc.)
* Value validation
* View management
* Image processing
* Stdlib (e.g. graph, map, queue, enum, etc.)
## Unit Tests
Run the following command in the **parent** directory of the framework for unit tests:
```
php .\phpunit.phar --bootstrap .\phpOMS\tests\Bootstrap.php .\phpOMS\tests\
```
* Language: php, js, c++, html, css, markdown, shell script
* Database: Maria/MySQL, PostgreSQL, MSSQL, SQLite
* Webserver: apache2, nginx
* Cache: Redis, Memcached
## Become a contributor
Karaka has a very open culture and we always welcome new people who share our philosophy in providing create solutions which just work. Please contact us if you are interested in working together on our application.
* PHP Developer
* JS Developer
* Artist and/or Frontend
* DevOps
Check out https://karaka.app/career and our developer section https://karaka.app/dev for more information.
Karaka has a very open culture and we always welcome new people who share our philosophy in providing create solutions which just work. You can find the development process description which also describes how to become a contributer in the [Organization documentation](https://github.com/Karaka-Management/Organization-Guide/blob/master/Processes/Development.md).
## Misc
* Languages: PHP, JS, HTML, CSS
* End-User documentation: https://github.com/Karaka-Management/Documentation
* Developer documentation: https://github.com/Karaka-Management/Developer-Guide
* Organization documentation: https://github.com/Karaka-Management/Organization-Guide
* Website: [https://karaka.app](https://karaka.app)
* Demo: [https://karaka.app](https://karaka.app) (user: admin, pass: orange)
* Dev: [https://karaka.app/dev](https://karaka.app/dev)
* Contact: dennis@karaka.email
* Contact: dennis@karaka.app

View File

@ -27,7 +27,7 @@ interface HeapItemInterface
/**
* Compare heap items
*
* @param HeapItemInterface $item
* @param HeapItemInterface $item Heap item
*
* @return bool
*

View File

@ -115,9 +115,12 @@ class Iban implements SerializableInterface
private function getSequence(string $sequence) : string
{
$country = $this->getCountry();
$layout = \str_replace(' ', '', IbanEnum::getByName('C_' . $country));
$start = \stripos($layout, $sequence);
$end = \strrpos($layout, $sequence);
/** @var string $iban */
$iban = IbanEnum::getByName('C_' . $country);
$layout = \str_replace(' ', '', $iban);
$start = \stripos($layout, $sequence);
$end = \strrpos($layout, $sequence);
if ($start === false || $end === false) {
return '';

View File

@ -217,6 +217,10 @@ class Location implements \JsonSerializable, SerializableInterface
*/
public function unserialize(mixed $serialized) : void
{
if (!\is_string($serialized)) {
return;
}
$data = \json_decode($serialized, true);
if (!\is_array($data)) {

View File

@ -55,16 +55,15 @@ class Directory extends FileAbstract implements DirectoryInterface
*
* @param HttpUri $http Uri
*
* @return mixed
* @return null|\FTP\Connection
*
* @since 1.0.0
*/
public static function ftpConnect(HttpUri $http) : mixed
public static function ftpConnect(HttpUri $http) : ?\FTP\Connection
{
$con = \ftp_connect($http->host, $http->port, 10);
if ($con === false) {
return false;
return null;
}
\ftp_login($con, $http->user, $http->pass);
@ -79,14 +78,14 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* Constructor.
*
* @param HttpUri $uri Uri
* @param string $filter Filter
* @param bool $initialize Should get initialized during construction
* @param null|resource $con Connection
* @param HttpUri $uri Uri
* @param string $filter Filter
* @param bool $initialize Should get initialized during construction
* @param \FTP\Connection $con Connection
*
* @since 1.0.0
*/
public function __construct(HttpUri $uri, string $filter = '*', bool $initialize = true, $con = null)
public function __construct(HttpUri $uri, string $filter = '*', bool $initialize = true, \FTP\Connection $con = null)
{
$this->uri = $uri;
$this->con = $con ?? self::ftpConnect($uri);
@ -715,7 +714,7 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value) : void
public function offsetSet(mixed $offset, mixed $value) : void
{
if ($offset === null || !isset($this->nodes[$offset])) {
$this->addNode($value);
@ -728,7 +727,7 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetExists($offset) : bool
public function offsetExists(mixed $offset) : bool
{
$offset = isset($this->nodes[$offset]) ? $offset : $this->path . '/' . $offset;
@ -738,7 +737,7 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetUnset($offset) : void
public function offsetUnset(mixed $offset) : void
{
$offset = isset($this->nodes[$offset]) ? $offset : $this->path . '/' . $offset;

View File

@ -71,16 +71,15 @@ class File extends FileAbstract implements FileInterface
*
* @param HttpUri $http Uri
*
* @return mixed
* @return null|\FTP\Connection
*
* @since 1.0.0
*/
public static function ftpConnect(HttpUri $http) : mixed
public static function ftpConnect(HttpUri $http) : ?\FTP\Connection
{
$con = \ftp_connect($http->host, $http->port, 10);
if ($con === false) {
return false;
return null;
}
\ftp_login($con, $http->user, $http->pass);
@ -209,7 +208,7 @@ class File extends FileAbstract implements FileInterface
/**
* {@inheritdoc}
*/
public static function prepend($con, string $path, string $content) : bool
public static function prepend(\FTP\Connection $con, string $path, string $content) : bool
{
return self::put($con, $path, $content, ContentPutMode::PREPEND | ContentPutMode::CREATE);
}

View File

@ -541,8 +541,12 @@ final class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value) : void
public function offsetSet(mixed $offset, mixed $value) : void
{
if (!($value instanceof ContainerInterface)) {
return;
}
if ($offset === null || !isset($this->nodes[$offset])) {
$this->addNode($value);
} else {
@ -554,7 +558,7 @@ final class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetExists($offset) : bool
public function offsetExists(mixed $offset) : bool
{
$offset = isset($this->nodes[$offset]) ? $offset : $this->path . '/' . $offset;
@ -564,7 +568,7 @@ final class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public function offsetUnset($offset) : void
public function offsetUnset(mixed $offset) : void
{
$offset = isset($this->nodes[$offset]) ? $offset : $this->path . '/' . $offset;

View File

@ -260,8 +260,8 @@ final class ArrayUtils
*
* Useful for parsing command line parsing
*
* @param string $id Id to find
* @param string[] $args CLI command list
* @param string $id Id to find
* @param int[]|string[] $args CLI command list
*
* @return string
*
@ -283,8 +283,8 @@ final class ArrayUtils
/**
* Check if flag is set
*
* @param string $id Id to find
* @param string[] $args CLI command list
* @param string $id Id to find
* @param int[]|string[] $args CLI command list
*
* @return int
*

View File

@ -130,6 +130,9 @@ class SpreadsheetDatabaseMapper implements IODatabaseMapper
foreach ($queries as $key => $query) {
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC);
if ($results === null) {
continue;
}
if ($key > $sheetCount - 1) {
$sheet->createSheet($key);

View File

@ -50,7 +50,9 @@ final class Iban extends ValidatorAbstract
return false;
}
$layout = \str_replace(' ', '', IbanEnum::getByName($enumName));
/** @var string $enumVal */
$enumVal = IbanEnum::getByName($enumName);
$layout = \str_replace(' ', '', $enumVal);
if (\strlen($value) !== \strlen($layout)) {
self::$error = IbanErrorType::INVALID_LENGTH;

View File

@ -43,7 +43,7 @@ class BaseModelMapper extends DataMapperFactory
/**
* Belongs to.
*
* @var array<string, array{mapper:string, external:string}>
* @var array<string, array{mapper:string, external:string, column?:string, by?:string}>
* @since 1.0.0
*/
public const BELONGS_TO = [