mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-23 23:08:39 +00:00
add todos from github
This commit is contained in:
parent
41bca90452
commit
4414fad940
|
|
@ -21,6 +21,10 @@ namespace phpOMS\Account;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#200
|
||||
* Implement remove permission functionality
|
||||
* Currently only adding permissions is possible but it should also be possible to remove permissions from an account.
|
||||
*/
|
||||
trait PermissionHandlingTrait
|
||||
{
|
||||
|
|
@ -136,7 +140,7 @@ trait PermissionHandlingTrait
|
|||
int $element = null,
|
||||
int $component = null
|
||||
) : bool {
|
||||
$app = $app !== null ? \strtolower($app) : $app; // @todo: maybe don't do this because this function get's called so often.
|
||||
$app = $app !== null ? \strtolower($app) : $app;
|
||||
|
||||
for ($i = 0; $i < $this->pLength; ++$i) {
|
||||
if ($this->permissions[$i]->hasPermission($permission, $unit, $app, $module, $type, $element, $component)) {
|
||||
|
|
|
|||
|
|
@ -193,7 +193,8 @@ class ApplicationAbstract
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo replace with proper setter (faster)
|
||||
* @todo Orange-Management/phpOMS#218
|
||||
* As soon as readonly member variables are possible the magic methods should be removed.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
|
@ -213,7 +214,8 @@ class ApplicationAbstract
|
|||
*
|
||||
* @return mixed Returns the value of the application member
|
||||
*
|
||||
* @todo replace with proper getter (faster)
|
||||
* @todo Orange-Management/phpOMS#218
|
||||
* As soon as readonly member variables are possible the magic methods should be removed.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,6 +23,20 @@ use phpOMS\DataStorage\DataStorageConnectionInterface;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#184
|
||||
* Add more functions:
|
||||
* * exists - Checks if the key exists
|
||||
* * getLike - Get all by pattern
|
||||
* * removeLike - Remove all by pattern
|
||||
* * getMult - Get multiple results
|
||||
* * removeMult - Remove multiple
|
||||
* * setMult - Set multiple
|
||||
* * updateExpiration - Update expiration
|
||||
* * increment - Increment numeric value
|
||||
* * decrement - Decrement numeric value
|
||||
* * rename - Rename key
|
||||
* * save - Save cache (to hard drive or somewhere else)
|
||||
*/
|
||||
interface ConnectionInterface extends DataStorageConnectionInterface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@ use phpOMS\System\File\Local\File;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#182
|
||||
* Create file locking
|
||||
* The file caching should implement a locking solution for the cache files.
|
||||
* Without it a different process may try to read it while the cache is still getting created.
|
||||
* A solution could be to create a directory or file called _lock which is getting checked
|
||||
* (if this file exists reading from cache, modifying or creating it is not allowed except the _lock file is 5 minutes or so old).
|
||||
* File and or directory creation should be atomic, right?
|
||||
*/
|
||||
final class FileCache extends ConnectionAbstract
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,8 +43,6 @@ interface DataStorageConnectionInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo make private, reason was that not everyone wants to connect during initialization?!
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function connect(array $data) : void;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ use phpOMS\DataStorage\Database\Schema\Grammar\Grammar as SchemaGrammar;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/Modules#100
|
||||
* Init only when used
|
||||
* The database connection should only get initialized when used.
|
||||
* Setup happens before but initialization should only happen on the first usage.
|
||||
*/
|
||||
abstract class ConnectionAbstract implements ConnectionInterface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,14 @@ final class MysqlConnection extends ConnectionAbstract
|
|||
$this->type = DatabaseType::MYSQL;
|
||||
$this->grammar = new MysqlGrammar();
|
||||
$this->schemaGrammar = new MysqlSchemaGrammar();
|
||||
$this->connect($dbdata); // todo: remove since this is a side effect that doesn't belong to constructor
|
||||
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#219
|
||||
* Don't automatically connect to the database during initialization. This should be done in a separate step.
|
||||
* This also requires to adjust some other framework code which currently expects the database connection to be established after initialization.
|
||||
* Sometimes DB connections may not be needed and should only be connected to once required.
|
||||
*/
|
||||
$this->connect($dbdata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,7 +47,14 @@ final class PostgresConnection extends ConnectionAbstract
|
|||
$this->type = DatabaseType::PGSQL;
|
||||
$this->grammar = new PostgresGrammar();
|
||||
$this->schemaGrammar = new PostgresSchemaGrammar();
|
||||
$this->connect($dbdata); // todo: remove since this is a side effect that doesn't belong to constructor
|
||||
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#219
|
||||
* Don't automatically connect to the database during initialization. This should be done in a separate step.
|
||||
* This also requires to adjust some other framework code which currently expects the database connection to be established after initialization.
|
||||
* Sometimes DB connections may not be needed and should only be connected to once required.
|
||||
*/
|
||||
$this->connect($dbdata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,6 +47,13 @@ final class SQLiteConnection extends ConnectionAbstract
|
|||
$this->type = DatabaseType::SQLITE;
|
||||
$this->grammar = new SQLiteGrammar();
|
||||
$this->schemaGrammar = new SQLiteSchemaGrammar();
|
||||
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#219
|
||||
* Don't automatically connect to the database during initialization. This should be done in a separate step.
|
||||
* This also requires to adjust some other framework code which currently expects the database connection to be established after initialization.
|
||||
* Sometimes DB connections may not be needed and should only be connected to once required.
|
||||
*/
|
||||
$this->connect($dbdata);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,13 @@ final class SqlServerConnection extends ConnectionAbstract
|
|||
$this->type = DatabaseType::SQLSRV;
|
||||
$this->grammar = new MysqlGrammar();
|
||||
$this->schemaGrammar = new MysqlSchemaGrammar();
|
||||
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#219
|
||||
* Don't automatically connect to the database during initialization. This should be done in a separate step.
|
||||
* This also requires to adjust some other framework code which currently expects the database connection to be established after initialization.
|
||||
* Sometimes DB connections may not be needed and should only be connected to once required.
|
||||
*/
|
||||
$this->connect($dbdata);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,106 @@ use Throwable;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
* @todo: currently hasmany, owns one etc. are not using joins. In some cases this could improve the performance instead of separately querying the database
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#220
|
||||
* Use joins.
|
||||
* The datamapper is not using any joins currently which could significantly improve the performance of the queries.
|
||||
* Joins should be used for:
|
||||
* * composite models (models built from multiple tables)
|
||||
* * owns one
|
||||
* * has one
|
||||
* * belongs to one
|
||||
* * conditionals
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#222
|
||||
* Implement conditionals.
|
||||
* Conditionals are hardcoded or dynamically passed parameters based on which a model is found.
|
||||
* The best example is the language of a model (e.g. news article), which is stored as foreign key in the model.
|
||||
* With conditionals it's possible to reference other tables and also return elements based on the value in these tables/columns.
|
||||
* Possible solution:
|
||||
* 1. join tables/columns which have conditionals
|
||||
* 2. perform the select based on the match
|
||||
* ```php
|
||||
* TestMapper::getByConditional(['l11n' => 'en']);
|
||||
* ```
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#73
|
||||
* Implement extending
|
||||
* Allow a data mapper to extend another data mapper.
|
||||
* This way the object will be inserted first with one data mapper and the remaining fields will be filled by the extended data mapper.
|
||||
* How can wen solve a mapper extending a mapper ... extending a mapper?
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#102
|
||||
* Solve N+1 problem
|
||||
* Currently the datamapper generates separate queries for objects that have relationships defined.
|
||||
* Most of these relationships could be defined MUCH smarter and reduce the amout of sub-queries e.g. selecting a task and all its comments.
|
||||
* The get method accepts an array of keys but doesn't select them in bulk but one at a time.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#122
|
||||
* Split/Refactor.
|
||||
* Child extends parent. Parent creates GetMapper, CreateMapper etc.
|
||||
* Example:
|
||||
* ```User::get(...)```
|
||||
* The get() function (defined in an abstract class) creates internally an instance of GetMapper.
|
||||
* The GetMapper receives all information such as primaryField, columns etc internally from the get().
|
||||
* This transfer of knowledge to the GetMapper could be done in the abstract class as a setup() function.
|
||||
* Now all mappers are split. The overhead is one additional function call and the setup() function.
|
||||
* Alternatively, think about using traits in the beginning.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#162
|
||||
* Relations by other than primary key
|
||||
* Currently relations are always defined by the primary key. It would be very helpful to also define relations by other values.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#189
|
||||
* Allow model creation with ids
|
||||
* The datamapper checks if the model has an non-empty id before it creates the mode.
|
||||
* Some models however can have custom primary keys.
|
||||
* In this case this check should not be done and therefore a $force flag got implemented in order to force the creation of the mode.
|
||||
* This should be changed by checking if the primary key is autoincrement or not.
|
||||
* If it isn't autoincrement the model should be created without an additional flag.
|
||||
* The problem that arises is that now you need to check if the model is already in the database.
|
||||
* This could be done based on the database response (error).
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#212
|
||||
* Replace nested models which are represented as scalar/id with NullModel
|
||||
* Currently there is a default limit on dependency nesting when you request a model from the database.
|
||||
* This means a model may have a model as member and that model in return also has some model as member and so on.
|
||||
* In order to prevent very deep nesting either the default nesting level is used to limit the amount of nesting or the user can specify a nesting depth.
|
||||
* Once the lowest nesting level is reached the mapper only stores the id in the member variable and NOT the model.
|
||||
* As a result the member variable can be of type null, int (= primary key of the model), or the model type.
|
||||
* This results in many special cases which a coder may has to consider.
|
||||
* It might make sense to only store null and the model in the member variable.
|
||||
* In order to still restrict the nesting the mapper could create a null model and only populate the id.
|
||||
* This could reduce the complexity for the user and simplify the use cases.
|
||||
* Additionally, it would now be possible to type hint the return value of many getter functions ?NullModelName.
|
||||
* If this gets implemented we also need to adjust some setter functions.
|
||||
* Many setter functions allow to only specify a id of the model.
|
||||
* Either this needs to be prevented and a Null model needs to be provided (all null models must have a __construct(int $id = 0) function which allows to pass the id) or the setter function needs to create the null model based on the id.
|
||||
* Implementing the above mentioned things will take some time but could improve the simplicity and overall code quality by a lot (at least from my personal opinion).
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#213 & Orange-Management/phpOMS#224
|
||||
* Implement composite models
|
||||
* All references such as ownsOne, hasMany etc. are based on the mappers for these objects. It should be possible to define single columns only.
|
||||
* One example where this could be useful is the Address/Localization model.
|
||||
* In here the country is stored by ID but you probably don't want to load an entire object and only the country name from the country table.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#214
|
||||
* Allow to define the model class
|
||||
* Currently the DataMapper uses the mapper name to find the correct model class.
|
||||
* This can remain but there should be a member variable or const which allows to define the model::class manually in case the model is different.
|
||||
* One example could be the Address/Location model in the Address module and phpOMS Localization directory.
|
||||
*
|
||||
* @todo Orange-Management/Modules#99
|
||||
* Use binds
|
||||
* Currently databinds are not used. Currently injections are possible.
|
||||
*
|
||||
* @todo Orange-Management/Modules#179
|
||||
* Replace int models with NullModels
|
||||
* In many cases int is allowed to represent another model if not the whole model is supposed to be loaded.
|
||||
* This means we have to check for null, int and model type.
|
||||
* Instead of using int the NullModel should be used which has a constructor that allows to define the int.
|
||||
* As a result the datamapper has to be rewritten for the select and insert/update.
|
||||
* The select needs to set the null model as value and the insert/update needs to extract the id from the null and ignore all other empty values from the null model which obviously are the default values.
|
||||
*/
|
||||
class DataMapperAbstract implements DataMapperInterface
|
||||
{
|
||||
|
|
@ -488,9 +587,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
try {
|
||||
self::$db->con->prepare($query->toSql())->execute();
|
||||
} catch (Throwable $t) {
|
||||
// @todo: remove after debugging
|
||||
// @fix: really remove it
|
||||
// @critical: after we found the bug we MUST remove it!
|
||||
// only for debugging
|
||||
//var_dump($t->getMessage());
|
||||
//var_dump($query->toSql());
|
||||
return -1;
|
||||
|
|
@ -710,16 +807,9 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
}
|
||||
|
||||
// Setting relation value (id) for relation (since the relation is not stored in an extra relation table)
|
||||
/**
|
||||
* @todo: this if comparison is correct, trust me. however,
|
||||
* manybe it makes more sense to simply check if 'src' isset(static::$hasMany[$propertyName]['src'])
|
||||
* source shouldn't be set if the relation is stored in the object itself
|
||||
*/
|
||||
/** @var string $table */
|
||||
/** @var array $columns */
|
||||
if (static::$hasMany[$propertyName]['table'] === static::$hasMany[$propertyName]['mapper']::$table
|
||||
&& isset($mapper::$columns[static::$hasMany[$propertyName]['dst']])
|
||||
) {
|
||||
if (!isset(static::$hasMany[$propertyName]['src'])) {
|
||||
$relProperty = $relReflectionClass->getProperty($mapper::$columns[static::$hasMany[$propertyName]['dst']]['internal']);
|
||||
|
||||
if (!$isPublic) {
|
||||
|
|
@ -927,12 +1017,8 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
private static function createRelationTable(string $propertyName, array $objsIds, $objId) : void
|
||||
{
|
||||
/** @todo: see hasMany implementation, checking isset(src) might be enough. although second condition MUST remain. */
|
||||
/** @var string $table */
|
||||
if (!empty($objsIds)
|
||||
&& static::$hasMany[$propertyName]['table'] !== static::$table
|
||||
&& static::$hasMany[$propertyName]['table'] !== static::$hasMany[$propertyName]['mapper']::$table
|
||||
) {
|
||||
if (!empty($objsIds) && isset(static::$hasMany[$propertyName]['src'])) {
|
||||
$relQuery = new Builder(self::$db);
|
||||
$relQuery->prefix(self::$db->getPrefix())
|
||||
->into(static::$hasMany[$propertyName]['table'])
|
||||
|
|
@ -1853,7 +1939,10 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
return $objId;
|
||||
}
|
||||
|
||||
// @todo: implement array delete
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#221
|
||||
* Create the delete functionality for arrays (deleteArray, deleteArrayModel).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Populate data.
|
||||
|
|
@ -1947,7 +2036,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
public static function populateManyToMany(array $result, &$obj, int $depth = 3) : void
|
||||
{
|
||||
// todo: maybe pass reflectionClass as optional parameter for performance increase
|
||||
$refClass = new \ReflectionClass($obj);
|
||||
|
||||
foreach ($result as $member => $values) {
|
||||
|
|
@ -2002,8 +2090,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo accept reflection class as parameter
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function populateOwnsOne(&$obj, int $depth = 3) : void
|
||||
|
|
@ -2011,30 +2097,27 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$refClass = new \ReflectionClass($obj);
|
||||
|
||||
foreach (static::$ownsOne as $member => $one) {
|
||||
// todo: is that if necessary? performance is suffering for sure!
|
||||
if ($refClass->hasProperty($member)) {
|
||||
$refProp = $refClass->getProperty($member);
|
||||
$refProp = $refClass->getProperty($member);
|
||||
|
||||
if (!($accessible = $refProp->isPublic())) {
|
||||
$refProp->setAccessible(true);
|
||||
}
|
||||
if (!($accessible = $refProp->isPublic())) {
|
||||
$refProp->setAccessible(true);
|
||||
}
|
||||
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$ownsOne[$member]['mapper'];
|
||||
$id = $refProp->getValue($obj);
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$ownsOne[$member]['mapper'];
|
||||
$id = $refProp->getValue($obj);
|
||||
|
||||
if (self::isNullObject($id)) {
|
||||
continue;
|
||||
}
|
||||
if (self::isNullObject($id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = \is_object($id) ? self::getObjectId($id) : $id;
|
||||
$value = self::getInitialized($mapper, $id) ?? $mapper::get($id, RelationType::ALL, null, $depth);
|
||||
$id = \is_object($id) ? self::getObjectId($id) : $id;
|
||||
$value = self::getInitialized($mapper, $id) ?? $mapper::get($id, RelationType::ALL, null, $depth);
|
||||
|
||||
$refProp->setValue($obj, $value);
|
||||
$refProp->setValue($obj, $value);
|
||||
|
||||
if (!$accessible) {
|
||||
$refProp->setAccessible(false);
|
||||
}
|
||||
if (!$accessible) {
|
||||
$refProp->setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2043,7 +2126,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo accept reflection class as parameter
|
||||
* @todo do this in the getRaw() part as a join. check if has conditionals and then join the data an then everything can be done in the getModel function.
|
||||
*
|
||||
* @since 1.0.0
|
||||
|
|
@ -2078,8 +2160,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo accept reflection class as parameter
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function populateOwnsOneArray(array &$obj, int $depth = 3) : void
|
||||
|
|
@ -2102,8 +2182,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo accept reflection class as parameter
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function populateBelongsTo(&$obj, int $depth = 3) : void
|
||||
|
|
@ -2111,30 +2189,27 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$refClass = new \ReflectionClass($obj);
|
||||
|
||||
foreach (static::$belongsTo as $member => $one) {
|
||||
// todo: is that if necessary? performance is suffering for sure!
|
||||
if ($refClass->hasProperty($member)) {
|
||||
$refProp = $refClass->getProperty($member);
|
||||
$refProp = $refClass->getProperty($member);
|
||||
|
||||
if (!($accessible = $refProp->isPublic())) {
|
||||
$refProp->setAccessible(true);
|
||||
}
|
||||
if (!($accessible = $refProp->isPublic())) {
|
||||
$refProp->setAccessible(true);
|
||||
}
|
||||
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$belongsTo[$member]['mapper'];
|
||||
$id = $refProp->getValue($obj);
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$belongsTo[$member]['mapper'];
|
||||
$id = $refProp->getValue($obj);
|
||||
|
||||
if (self::isNullObject($id)) {
|
||||
continue;
|
||||
}
|
||||
if (self::isNullObject($id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = \is_object($id) ? self::getObjectId($id) : $id;
|
||||
$value = self::getInitialized($mapper, $id) ?? $mapper::get($id, RelationType::ALL, null, $depth);
|
||||
$id = \is_object($id) ? self::getObjectId($id) : $id;
|
||||
$value = self::getInitialized($mapper, $id) ?? $mapper::get($id, RelationType::ALL, null, $depth);
|
||||
|
||||
$refProp->setValue($obj, $value);
|
||||
$refProp->setValue($obj, $value);
|
||||
|
||||
if (!$accessible) {
|
||||
$refProp->setAccessible(false);
|
||||
}
|
||||
if (!$accessible) {
|
||||
$refProp->setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2147,8 +2222,6 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo accept reflection class as parameter
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function populateBelongsToArray(array &$obj, int $depth = 3) : void
|
||||
|
|
@ -2180,7 +2253,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$refClass = new \ReflectionClass($obj);
|
||||
|
||||
foreach ($result as $column => $value) {
|
||||
if (!isset($columns[$column]['internal']) /* && $refClass->hasProperty($columns[$column]['internal']) */) {
|
||||
if (!isset($columns[$column]['internal'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2293,7 +2366,10 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @todo: implement language
|
||||
* @todo Orange-Management/phpOMS#161
|
||||
* Reconsider get*() parameter order
|
||||
* Check if the parameter order of all of the get functions makes sense or if another order would be better.
|
||||
* Especially the fill parameter probably should be swapped with the depth filter.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#33
|
||||
* Implement missing grammar & builder functions
|
||||
* Missing elements are e.g. sum, merge etc.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#194
|
||||
* Automatically set prefix during construction
|
||||
* When constructing the QueryBuilder or SchemaBuilder the connection is passed.
|
||||
* The connection holds information about the table prefix, yet I force developers to pass a prefix after the builder initialization.
|
||||
* This should be done automatically!
|
||||
*/
|
||||
class Builder extends BuilderAbstract
|
||||
{
|
||||
|
|
@ -70,10 +80,10 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Into.
|
||||
*
|
||||
* @var \Closure|string
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public $into = null;
|
||||
public string $into = '';
|
||||
|
||||
/**
|
||||
* Into columns.
|
||||
|
|
@ -267,8 +277,6 @@ class Builder extends BuilderAbstract
|
|||
*
|
||||
* @return Builder
|
||||
*
|
||||
* @todo Closure is not working this way, needs to be evaluated befor assigning
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function select(...$columns) : self
|
||||
|
|
@ -276,7 +284,7 @@ class Builder extends BuilderAbstract
|
|||
$this->type = QueryType::SELECT;
|
||||
|
||||
foreach ($columns as $key => $column) {
|
||||
if (\is_string($column) || $column instanceof self || $column instanceof \Closure) {
|
||||
if (\is_string($column) || $column instanceof self) {
|
||||
$this->selects[] = $column;
|
||||
} else {
|
||||
throw new \InvalidArgumentException();
|
||||
|
|
@ -311,8 +319,6 @@ class Builder extends BuilderAbstract
|
|||
*
|
||||
* @return Builder
|
||||
*
|
||||
* @todo Closure is not working this way, needs to be evaluated befor assigning
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function random(...$columns) : self
|
||||
|
|
@ -338,7 +344,7 @@ class Builder extends BuilderAbstract
|
|||
{
|
||||
if (\is_array($binds)) {
|
||||
$this->binds += $binds;
|
||||
} elseif (\is_string($binds) || $binds instanceof \Closure) {
|
||||
} elseif (\is_string($binds)) {
|
||||
$this->binds[] = $binds;
|
||||
} else {
|
||||
throw new \InvalidArgumentException();
|
||||
|
|
@ -451,7 +457,7 @@ class Builder extends BuilderAbstract
|
|||
public function from(...$tables) : self
|
||||
{
|
||||
foreach ($tables as $key => $table) {
|
||||
if (\is_string($table) || $table instanceof self || $table instanceof \Closure) {
|
||||
if (\is_string($table) || $table instanceof self) {
|
||||
$this->from[] = $table;
|
||||
} else {
|
||||
throw new \InvalidArgumentException();
|
||||
|
|
@ -481,10 +487,10 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where.
|
||||
*
|
||||
* @param array|\Closure|string|Where $columns Columns
|
||||
* @param array|string $operator Operator
|
||||
* @param mixed $values Values
|
||||
* @param array|string $boolean Boolean condition
|
||||
* @param array|string|Where $columns Columns
|
||||
* @param array|string $operator Operator
|
||||
* @param mixed $values Values
|
||||
* @param array|string $boolean Boolean condition
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -540,9 +546,9 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where and sub condition.
|
||||
*
|
||||
* @param array|\Closure|string|Where $where Where sub condition
|
||||
* @param mixed $operator Operator
|
||||
* @param mixed $values Values
|
||||
* @param array|string|Where $where Where sub condition
|
||||
* @param mixed $operator Operator
|
||||
* @param mixed $values Values
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -556,9 +562,9 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where or sub condition.
|
||||
*
|
||||
* @param array|\Closure|string|Where $where Where sub condition
|
||||
* @param mixed $operator Operator
|
||||
* @param mixed $values Values
|
||||
* @param array|string|Where $where Where sub condition
|
||||
* @param mixed $operator Operator
|
||||
* @param mixed $values Values
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -572,9 +578,9 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where in.
|
||||
*
|
||||
* @param array|\Closure|string|Where $column Column
|
||||
* @param mixed $values Values
|
||||
* @param string $boolean Boolean condition
|
||||
* @param array|string|Where $column Column
|
||||
* @param mixed $values Values
|
||||
* @param string $boolean Boolean condition
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -590,8 +596,8 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where null.
|
||||
*
|
||||
* @param array|\Closure|string|Where $column Column
|
||||
* @param string $boolean Boolean condition
|
||||
* @param array|string|Where $column Column
|
||||
* @param string $boolean Boolean condition
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -607,8 +613,8 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Where not null.
|
||||
*
|
||||
* @param array|\Closure|string|Where $column Column
|
||||
* @param string $boolean Boolean condition
|
||||
* @param array|string|Where $column Column
|
||||
* @param string $boolean Boolean condition
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -624,7 +630,7 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Group by.
|
||||
*
|
||||
* @param array|\Closure|string ...$columns Grouping result
|
||||
* @param array|string ...$columns Grouping result
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -633,7 +639,7 @@ class Builder extends BuilderAbstract
|
|||
public function groupBy(...$columns) : self
|
||||
{
|
||||
foreach ($columns as $key => $column) {
|
||||
if (\is_string($column) || $column instanceof self || $column instanceof \Closure) {
|
||||
if (\is_string($column) || $column instanceof self) {
|
||||
$this->groups[] = $column;
|
||||
} else {
|
||||
throw new \InvalidArgumentException();
|
||||
|
|
@ -646,13 +652,13 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Order by newest.
|
||||
*
|
||||
* @param \Closure|string $column Column
|
||||
* @param string $column Column
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function newest($column) : self
|
||||
public function newest(string $column) : self
|
||||
{
|
||||
$this->orderBy($column, 'DESC');
|
||||
|
||||
|
|
@ -662,13 +668,13 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Order by oldest.
|
||||
*
|
||||
* @param \Closure|string $column Column
|
||||
* @param string $column Column
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function oldest($column) : self
|
||||
public function oldest(string $column) : self
|
||||
{
|
||||
$this->orderBy($column, 'ASC');
|
||||
|
||||
|
|
@ -678,8 +684,8 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Order by oldest.
|
||||
*
|
||||
* @param array|\Closure|string $columns Columns
|
||||
* @param string|string[] $order Orders
|
||||
* @param array|string $columns Columns
|
||||
* @param string|string[] $order Orders
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
|
|
@ -687,7 +693,7 @@ class Builder extends BuilderAbstract
|
|||
*/
|
||||
public function orderBy($columns, $order = 'DESC') : self
|
||||
{
|
||||
if (\is_string($columns) || $columns instanceof \Closure) {
|
||||
if (\is_string($columns)) {
|
||||
if (!\is_string($order)) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
|
@ -893,13 +899,13 @@ class Builder extends BuilderAbstract
|
|||
/**
|
||||
* Table to insert into.
|
||||
*
|
||||
* @param \Closure|string $table Table
|
||||
* @param string $table Table
|
||||
*
|
||||
* @return Builder
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function into($table) : self
|
||||
public function into(string $table) : self
|
||||
{
|
||||
$this->into = $table;
|
||||
|
||||
|
|
@ -1011,7 +1017,7 @@ class Builder extends BuilderAbstract
|
|||
$this->type = QueryType::UPDATE;
|
||||
|
||||
foreach ($tables as $key => $table) {
|
||||
if (\is_string($table) || $table instanceof self || $table instanceof \Closure) {
|
||||
if (\is_string($table) || $table instanceof self) {
|
||||
$this->updates[] = $table;
|
||||
} else {
|
||||
throw new \InvalidArgumentException();
|
||||
|
|
@ -1074,7 +1080,7 @@ class Builder extends BuilderAbstract
|
|||
*/
|
||||
public function join($table, string $type = JoinType::JOIN, string $alias = null) : self
|
||||
{
|
||||
if (!\is_string($table)&& !($table instanceof self) && !($table instanceof \Closure)) {
|
||||
if (!\is_string($table)&& !($table instanceof self)) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
|
|
@ -1292,7 +1298,8 @@ class Builder extends BuilderAbstract
|
|||
throw new \InvalidArgumentException('Unknown operator.');
|
||||
}
|
||||
|
||||
// @todo: this is bad! ons needs to have the same key as the join for the grammar to work. since alias are possible this is nec3essary.
|
||||
// ons needs to have the same key as the join for the grammar to work
|
||||
// since alias are possible this is necessary
|
||||
$this->ons[\array_keys($this->joins)[$joinCount]][] = [
|
||||
'column' => $column,
|
||||
'operator' => $operator[$i],
|
||||
|
|
@ -1407,8 +1414,6 @@ class Builder extends BuilderAbstract
|
|||
return $column;
|
||||
} elseif ($column instanceof Column) {
|
||||
return $column->getColumn();
|
||||
} elseif ($column instanceof \Closure) {
|
||||
return $column();
|
||||
} elseif ($column instanceof \Serializable) {
|
||||
return $column->serialize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ use phpOMS\DataStorage\Database\Query\Where;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#33
|
||||
* Implement missing grammar & builder functions
|
||||
* Missing elements are e.g. sum, merge etc.
|
||||
*/
|
||||
class Grammar extends GrammarAbstract
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ use phpOMS\DataStorage\Database\Query\Builder as QueryBuilder;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#32
|
||||
* Implement schema grammar
|
||||
* Basic create/drop schema grammar created. Next step is to be able to update existing schema and read existing schema.
|
||||
*/
|
||||
class Builder extends QueryBuilder
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ use phpOMS\DataStorage\Database\Schema\QueryType;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#32
|
||||
* Implement schema grammar
|
||||
* Basic create/drop schema grammar created. Next step is to be able to update existing schema and read existing schema.
|
||||
*/
|
||||
class Grammar extends QueryGrammar
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ use phpOMS\DataStorage\Database\Query\Builder;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#32
|
||||
* Implement schema grammar
|
||||
* Basic create/drop schema grammar created. Next step is to be able to update existing schema and read existing schema.
|
||||
*/
|
||||
class MysqlGrammar extends Grammar
|
||||
{
|
||||
|
|
|
|||
|
|
@ -136,8 +136,7 @@ final class CubicSplineInterpolation implements InterpolationInterface
|
|||
$this->solveC->setV($n - 1, 3.0 * $this->solveA->getV($n - 2) * $h ** 2 + 2.0 * $this->solveB->get($n - 2) * $h + $this->solveC->getV($n - 2));
|
||||
|
||||
/**
|
||||
* @todo: consider linear extrapolation at start and end point
|
||||
*
|
||||
* linear extrapolation at start and end point
|
||||
* $this->solveB->setV($n - 1, 0.0)
|
||||
*/
|
||||
}
|
||||
|
|
@ -164,8 +163,7 @@ final class CubicSplineInterpolation implements InterpolationInterface
|
|||
if ($x < $this->points[0]['x']) {
|
||||
return ($this->solveB->get(0) * $h + $this->solveC->getV(0)) * $h + $this->points[0]['y'];
|
||||
/**
|
||||
* @todo: consider linear extrapolation at start and end point
|
||||
*
|
||||
* linear extrapolation at start and end point
|
||||
* ($this->solveC->getV(0)) * $h + $this->points[0]['y'];
|
||||
*/
|
||||
} elseif ($x > $this->points[$n - 1]['x']) {
|
||||
|
|
|
|||
|
|
@ -272,6 +272,10 @@ final class Average
|
|||
\sort($values);
|
||||
|
||||
if ($offset > 0) {
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#175
|
||||
* Create unit test.
|
||||
*/
|
||||
$values = \array_slice($values, $offset, -$offset);
|
||||
}
|
||||
|
||||
|
|
@ -339,6 +343,10 @@ final class Average
|
|||
\sort($angles);
|
||||
|
||||
if ($offset > 0) {
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#176
|
||||
* Create unit test.
|
||||
*/
|
||||
$angles = \array_slice($angles, $offset, -$offset);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#167
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getAkaikeInformationCriterion(float $sse, int $observations, int $predictors) : float
|
||||
|
|
@ -252,6 +255,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#168
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getSchwarzBayesianInformationCriterion(float $sse, int $observations, int $predictors) : float
|
||||
|
|
@ -267,6 +273,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#169
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getMeanAbsolutePercentageError(array $observed, array $forecasted) : float
|
||||
|
|
@ -282,6 +291,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#170
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getSymmetricMeanAbsolutePercentageError(array $observed, array $forecasted) : float
|
||||
|
|
@ -303,6 +315,9 @@ final class Error
|
|||
*
|
||||
* @return array
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#172
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getCrossSectionalScaledErrorArray(array $errors, array $observed) : array
|
||||
|
|
@ -325,6 +340,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#171
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getCrossSectionalScaledError(float $error, array $observed) : float
|
||||
|
|
@ -360,6 +378,9 @@ final class Error
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#173
|
||||
* Create unit test.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getMeanSquaredScaledError(array $scaledErrors) : float
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getPmf(int $K, int $N, int $k, int $n) : float
|
||||
|
|
@ -53,8 +51,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getMean(int $K, int $N, int $n) : float
|
||||
|
|
@ -71,8 +67,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return int
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getMode(int $K, int $N, int $n) : int
|
||||
|
|
@ -89,8 +83,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getVariance(int $K, int $N, int $n) : float
|
||||
|
|
@ -107,13 +99,11 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getStandardDeviation(int $K, int $N, int $n) : float
|
||||
{
|
||||
return \sqrt(self::getVariance($K, $N, $n));
|
||||
return \sqrt($n * $K / $N * ($N - $K) / $N * ($N - $n) / ($N - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,8 +115,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getSkewness(int $K, int $N, int $n) : float
|
||||
|
|
@ -144,8 +132,6 @@ final class HypergeometricDistribution
|
|||
*
|
||||
* @return float
|
||||
*
|
||||
* @todo: this can be heavily optimized
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getExKurtosis(int $K, int $N, int $n) : float
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ final class Request extends RequestAbstract
|
|||
if (!isset($this->uri)) {
|
||||
$this->initCurrentRequest();
|
||||
$this->lock();
|
||||
$this->cleanupGlobals();
|
||||
self::cleanupGlobals();
|
||||
$this->setupUriBuilder();
|
||||
}
|
||||
|
||||
|
|
@ -247,11 +247,9 @@ final class Request extends RequestAbstract
|
|||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo: consider making this function static.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private function cleanupGlobals() : void
|
||||
public static function cleanupGlobals() : void
|
||||
{
|
||||
unset($_FILES);
|
||||
unset($_GET);
|
||||
|
|
@ -463,11 +461,9 @@ final class Request extends RequestAbstract
|
|||
*
|
||||
* @throws \OutOfRangeException This exception is thrown if the port is out of range
|
||||
*
|
||||
* @todo: consider making this static
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function isHttps(int $port = 443) : bool
|
||||
public static function isHttps(int $port = 443) : bool
|
||||
{
|
||||
if ($port < 1 || $port > 65535) {
|
||||
throw new \OutOfRangeException('Value "' . $port . '" is out of range.');
|
||||
|
|
|
|||
|
|
@ -166,41 +166,32 @@ final class Response extends ResponseAbstract implements RenderableInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @todo: this whole workflow with json got improved a little bit but this part looks bad. do i really need so much code or could i simplify it
|
||||
*/
|
||||
public function toArray() : array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
try {
|
||||
foreach ($this->response as $key => $response) {
|
||||
if ($response instanceof View) {
|
||||
$result[] = $response->toArray();
|
||||
} elseif (\is_array($response)) {
|
||||
$result[] = $response;
|
||||
} elseif (\is_scalar($response)) {
|
||||
$result[] = $response;
|
||||
} elseif ($response instanceof \JsonSerializable) {
|
||||
$result[] = $response->jsonSerialize();
|
||||
} elseif ($response === null) {
|
||||
continue;
|
||||
} else {
|
||||
throw new \Exception('Wrong response type');
|
||||
}
|
||||
foreach ($this->response as $response) {
|
||||
if ($response instanceof View) {
|
||||
$result[] = $response->toArray();
|
||||
} elseif (\is_array($response) || \is_scalar($response)) {
|
||||
$result[] = $response;
|
||||
} elseif ($response instanceof \JsonSerializable) {
|
||||
$result[] = $response->jsonSerialize();
|
||||
} elseif ($response === null) {
|
||||
continue;
|
||||
} else {
|
||||
FileLogger::getInstance('', false)
|
||||
->error(
|
||||
FileLogger::MSG_FULL, [
|
||||
'message' => 'Unknown type.',
|
||||
'line' => __LINE__,
|
||||
'file' => self::class,
|
||||
]
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
FileLogger::getInstance('', false)
|
||||
->error(
|
||||
FileLogger::MSG_FULL, [
|
||||
'message' => $e->getMessage(),
|
||||
'line' => __LINE__,
|
||||
'file' => self::class,
|
||||
]
|
||||
);
|
||||
|
||||
$result = [];
|
||||
} finally {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ namespace phpOMS\Message\Mail;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#34
|
||||
* Implement!!!
|
||||
*/
|
||||
class EmailAbstract
|
||||
{
|
||||
|
|
|
|||
|
|
@ -148,41 +148,32 @@ final class Response extends ResponseAbstract implements RenderableInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @todo: this whole workflow with json got improved a little bit but this part looks bad. do i really need so much code or could i simplify it
|
||||
*/
|
||||
public function toArray() : array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
try {
|
||||
foreach ($this->response as $key => $response) {
|
||||
if ($response instanceof View) {
|
||||
$result[] = $response->toArray();
|
||||
} elseif (\is_array($response)) {
|
||||
$result[] = $response;
|
||||
} elseif (\is_scalar($response)) {
|
||||
$result[] = $response;
|
||||
} elseif ($response instanceof \JsonSerializable) {
|
||||
$result[] = $response->jsonSerialize();
|
||||
} elseif ($response === null) {
|
||||
continue;
|
||||
} else {
|
||||
throw new \Exception('Wrong response type');
|
||||
}
|
||||
foreach ($this->response as $response) {
|
||||
if ($response instanceof View) {
|
||||
$result[] = $response->toArray();
|
||||
} elseif (\is_array($response) || \is_scalar($response)) {
|
||||
$result[] = $response;
|
||||
} elseif ($response instanceof \JsonSerializable) {
|
||||
$result[] = $response->jsonSerialize();
|
||||
} elseif ($response === null) {
|
||||
continue;
|
||||
} else {
|
||||
FileLogger::getInstance('', false)
|
||||
->error(
|
||||
FileLogger::MSG_FULL, [
|
||||
'message' => 'Unknown type.',
|
||||
'line' => __LINE__,
|
||||
'file' => self::class,
|
||||
]
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
FileLogger::getInstance('', false)
|
||||
->error(
|
||||
FileLogger::MSG_FULL, [
|
||||
'message' => $e->getMessage(),
|
||||
'line' => __LINE__,
|
||||
'file' => self::class,
|
||||
]
|
||||
);
|
||||
|
||||
$result = [];
|
||||
} finally {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ use phpOMS\System\MimeType;
|
|||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo: maybe move to Modules because this is very project specific and not general enough for a framework
|
||||
* @todo: maybe move all of the Module\classes parts to the Modules\?
|
||||
* @todo Orange-Management/Modules#113
|
||||
* Don't use name but id for identification
|
||||
*/
|
||||
abstract class ModuleAbstract
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ use phpOMS\System\File\PathException;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/Modules#113
|
||||
* Don't use name but id for identification
|
||||
*/
|
||||
final class ModuleManager
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,26 @@ namespace phpOMS\Router;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#191
|
||||
* Implement routing parameters
|
||||
* Most routing implementations have parameters in their route e.g.
|
||||
* 'route' => '/your/url/{@id}/something'
|
||||
* This is very easy to read but slows down performance.
|
||||
* 'route' => [
|
||||
* 'match' => '/your/url/.*?/something',
|
||||
* 'parameters'=> [
|
||||
* 'id' => ['type' => 'path', 'index' => 2]
|
||||
* ]
|
||||
* ]
|
||||
* The parameters should then be passed to the method in the $data = [] variable.
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#192
|
||||
* Implement form/api data validation
|
||||
* Similar to permission validation it could be possible to add data constraints which are expected for certain routes which then could be checked during routing and dispatching.
|
||||
* For example it would be possible to define required data fields, their type, their pattern etc.
|
||||
* This would make the routing definitions much bigger but also dramatically reduce the work which needs to be done in the controllers.
|
||||
* It could even be written in a way which hardly effects performance.
|
||||
*/
|
||||
final class WebRouter implements RouterInterface
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ namespace phpOMS\Stdlib\Graph;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo : there is a bug with Hungary ibans since they have two k (checksums) in their definition
|
||||
*/
|
||||
class BinaryTree extends Tree
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ namespace phpOMS\Stdlib\Graph;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo : there is a bug with Hungary ibans since they have two k (checksums) in their definition
|
||||
*/
|
||||
class Node
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ namespace phpOMS\Utils;
|
|||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#154
|
||||
* Create excel operations on arrays
|
||||
* In many cases there are values stored inside of arrays which need simple math operators performed on them.
|
||||
* Instead of writing the expression it should be possible to do this in good old excel fasion.
|
||||
*/
|
||||
final class ArrayUtils
|
||||
{
|
||||
|
|
@ -386,6 +391,9 @@ final class ArrayUtils
|
|||
*
|
||||
* @return array<float>
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#223
|
||||
* In the ArrayUtils class the power* functions should be combined once union types become available.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function powerFloat(array $values, float $exp = 2.0) : array
|
||||
|
|
@ -407,6 +415,9 @@ final class ArrayUtils
|
|||
*
|
||||
* @return array<float|int>
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#223
|
||||
* In the ArrayUtils class the power* functions should be combined once union types become available.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function powerInt(array $values, int $exp = 2) : array
|
||||
|
|
|
|||
|
|
@ -210,8 +210,6 @@ class Markdown
|
|||
/**
|
||||
* Some definition data for elements
|
||||
*
|
||||
* @todo: figure out what it is for
|
||||
*
|
||||
* @var string[]
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ use phpOMS\Contract\RenderableInterface;
|
|||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#119
|
||||
* Create jaro winkler distance
|
||||
* https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
|
||||
*/
|
||||
final class StringUtils
|
||||
|
|
|
|||
|
|
@ -202,7 +202,10 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals($this->model->datetime->format('Y-m-d'), $modelR->datetime->format('Y-m-d'));
|
||||
self::assertNull($modelR->datetime_null);
|
||||
|
||||
// todo implement these
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#227
|
||||
* Serializable and JsonSerializable data can be inserted and updated in the database but it's not possible to correctly populate a model with the data in its original format.
|
||||
*/
|
||||
//self::assertEquals('123', $modelR->serializable);
|
||||
//self::assertEquals($this->model->json, $modelR->json);
|
||||
//self::assertEquals([1, 2, 3], $modelR->jsonSerializable);
|
||||
|
|
@ -281,7 +284,10 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals($modelR->datetime->format('Y-m-d'), $modelR2->datetime->format('Y-m-d'));
|
||||
self::assertNull($modelR2->datetime_null);
|
||||
|
||||
// todo test update relations
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#226
|
||||
* Test the update of a model with relations (update relations).
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -313,7 +319,10 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals($modelR['datetime']->format('Y-m-d'), $modelR2['datetime']->format('Y-m-d'));
|
||||
self::assertNull($modelR2['datetime_null']);
|
||||
|
||||
// todo test update relations
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#226
|
||||
* Test the update of a model with relations (update relations).
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -329,6 +338,9 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
self::assertInstanceOf('phpOMS\tests\DataStorage\Database\TestModel\NullBaseModel', $modelR);
|
||||
|
||||
// todo test if relations also deleted
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#225
|
||||
* Test the deletion of a model with relations (deleting relations).
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,15 +59,6 @@ class BuilderTest extends \PHPUnit\Framework\TestCase
|
|||
$sql = 'SELECT `a`.`test`, `b`.`test` FROM `a`, `b` WHERE `a`.`test` = \'' . $datetime->format('Y-m-d H:i:s') . '\';';
|
||||
self::assertEquals($sql, $query->select('a.test', 'b.test')->from('a', 'b')->where('a.test', '=', $datetime)->toSql());
|
||||
|
||||
$query = new Builder($this->con);
|
||||
$sql = 'SELECT `a`.`test`, `b`.`test` FROM `a`, `b` WHERE `a`.`test` = \'abc\' AND `b`.`test` = 2;';
|
||||
$systemIdentifier = '`';
|
||||
self::assertEquals($sql, $query->select('a.test', function () {
|
||||
return '`b`.`test`';
|
||||
})->from('a', function () use ($systemIdentifier) {
|
||||
return $systemIdentifier . 'b' . $systemIdentifier;
|
||||
})->where(['a.test', 'b.test'], ['=', '='], ['abc', 2], ['and', 'and'])->toSql());
|
||||
|
||||
$query = new Builder($this->con);
|
||||
$sql = 'SELECT `a`.`test`, `b`.`test` FROM `a`, `b` WHERE `a`.`test` = \'abc\' ORDER BY `a`.`test` ASC, `b`.`test` DESC;';
|
||||
self::assertEquals($sql,
|
||||
|
|
|
|||
|
|
@ -269,7 +269,12 @@ class MatrixTest extends \PHPUnit\Framework\TestCase
|
|||
]);
|
||||
|
||||
self::markTestIncomplete();
|
||||
// todo: result column 0 and 1 are swapped. why? still correct?
|
||||
|
||||
/**
|
||||
* @todo Orange-Management/phpOMS#179
|
||||
* Create unit test for inverse.
|
||||
* It seems like some columns are ordered in a different way
|
||||
*/
|
||||
/*self::assertEquals([
|
||||
[-0.9, -0.5, 2.2],
|
||||
[0.7, 0.5, -1.6],
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class RequestTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals(BrowserType::UNKNOWN, $request->getBrowser());
|
||||
self::assertEquals(OSType::UNKNOWN, $request->getOS());
|
||||
self::assertEquals('127.0.0.1', $request->getOrigin());
|
||||
self::assertFalse($request->isHttps());
|
||||
self::assertFalse(Request::isHttps());
|
||||
self::assertEquals([], $request->getHash());
|
||||
self::assertEmpty($request->getBody());
|
||||
self::assertEmpty($request->getFiles());
|
||||
|
|
|
|||
|
|
@ -215,6 +215,10 @@ class ArrayUtilsTest extends \PHPUnit\Framework\TestCase
|
|||
/**
|
||||
* @testdox All array values in an array can be potentiated by an integer
|
||||
* @covers phpOMS\Utils\ArrayUtils
|
||||
*
|
||||
* @todo Orange-Management/phpOMS#223
|
||||
* In the ArrayUtils class the power* functions should be combined once union types become available.
|
||||
*
|
||||
* @group framework
|
||||
*/
|
||||
public function testPowerInt() : void
|
||||
|
|
@ -227,7 +231,9 @@ class ArrayUtilsTest extends \PHPUnit\Framework\TestCase
|
|||
* @testdox All array values in an array can be potentiated by a float
|
||||
* @covers phpOMS\Utils\ArrayUtils
|
||||
*
|
||||
* @todo combine with int as soon as union types exist
|
||||
* @todo Orange-Management/phpOMS#223
|
||||
* In the ArrayUtils class the power* functions should be combined once union types become available.
|
||||
*
|
||||
* @group framework
|
||||
*/
|
||||
public function testPowerFloat() : void
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ use phpOMS\Utils\Git\Repository;
|
|||
* @testdox phpOMS\tests\Utils\Git\RepositoryTest: Git repository
|
||||
*
|
||||
* @internal
|
||||
* @todo create tests for other functions
|
||||
*/
|
||||
class RepositoryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ class ScheduleTest extends \PHPUnit\Framework\TestCase
|
|||
/**
|
||||
* @testdox A task can be created from an array and rendered
|
||||
* @covers phpOMS\Utils\TaskSchedule\Schedule
|
||||
*
|
||||
* @todo the interval has to be implemented!
|
||||
*
|
||||
* @group framework
|
||||
*/
|
||||
public function testCreateJobWithData() : void
|
||||
|
|
|
|||
|
|
@ -33,10 +33,5 @@ class SchedulerFactoryTest extends \PHPUnit\Framework\TestCase
|
|||
public function testCreate() : void
|
||||
{
|
||||
self::assertTrue((SchedulerFactory::create() instanceof Cron) || (SchedulerFactory::create() instanceof TaskScheduler));
|
||||
|
||||
// todo: make full test here by defining schtask or crontab path
|
||||
// todo: create task
|
||||
// todo: get task
|
||||
// todo: remove task
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user