From 3d8d0abaf68c52a6a9e4bc1458bba00c15fe7ceb Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 30 Sep 2023 17:40:10 +0000 Subject: [PATCH 01/11] add coverage upload --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 41075f01b..aaf12c14e 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,4 +7,5 @@ jobs: uses: Karaka-Management/Karaka/.github/workflows/php_template.yml@develop secrets: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_PAT: ${{ secrets.GH_PAT }} \ No newline at end of file + GH_PAT: ${{ secrets.GH_PAT }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 48de45149b8857ed20d96bcceb022e3bf6b8b103 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 1 Oct 2023 03:14:35 +0000 Subject: [PATCH 02/11] change db credentials --- tests/Bootstrap.php | 84 ++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 88872816d..6042499f6 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -71,9 +71,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -81,9 +81,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -91,9 +91,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -101,9 +101,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -111,9 +111,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -121,9 +121,9 @@ $CONFIG = [ 'db' => 'mysql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '3306', /* db host port */ - 'login' => 'root', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -133,9 +133,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -143,9 +143,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -153,9 +153,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -163,9 +163,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -173,9 +173,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -183,9 +183,9 @@ $CONFIG = [ 'db' => 'pgsql', /* db type */ 'host' => '127.0.0.1', /* db host address */ 'port' => '5432', /* db host port */ - 'login' => 'postgres', /* db login name */ - 'password' => 'root', /* db login password */ - 'database' => 'oms', /* db name */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -235,7 +235,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -245,7 +245,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -255,7 +255,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -265,7 +265,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -275,7 +275,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], @@ -285,7 +285,7 @@ $CONFIG = [ 'port' => '1433', /* db host port */ 'login' => 'sa', /* db login name */ 'password' => 'c0MplicatedP@ssword', /* db login password */ - 'database' => 'oms', /* db name */ + 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', ], From 39a55a590bc37d50c2ec447bdd7f7f498a9e89f6 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 1 Oct 2023 15:52:46 +0000 Subject: [PATCH 03/11] fix vendor autoload loading --- tests/Bootstrap.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 6042499f6..dbb5d4e2b 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -7,7 +7,10 @@ declare(strict_types=1); \error_reporting(\E_ALL); \setlocale(\LC_ALL, 'en_US.UTF-8'); -require_once __DIR__ . '/../vendor/autoload.php'; +if (\is_file(__DIR__ . '/../vendor/autoload.php')) { + require_once __DIR__ . '/../vendor/autoload.php'; +} + require_once __DIR__ . '/Autoloader.php'; use phpOMS\DataStorage\Database\DatabasePool; From 7505eadee1015110fbaf9f54824ea87ccbf6af8b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 1 Oct 2023 16:40:10 +0000 Subject: [PATCH 04/11] string check --- tests/Bootstrap.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index dbb5d4e2b..a95d571cc 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -22,7 +22,7 @@ $IS_GITHUB = false; $temp = \array_keys($_SERVER); foreach ($temp as $key) { - if (\stripos(\strtolower($key), 'github') !== false) { + if (\is_string($key) && \stripos(\strtolower($key), 'github') !== false) { $IS_GITHUB = true; break; @@ -31,7 +31,7 @@ foreach ($temp as $key) { if (!$IS_GITHUB) { foreach ($_SERVER as $value) { - if (\stripos(\strtolower($value), 'github') !== false) { + if (\is_string($value) && \stripos(\strtolower($value), 'github') !== false) { $IS_GITHUB = true; break; @@ -42,7 +42,7 @@ if (!$IS_GITHUB) { $temp = \array_keys(\getenv()); if (!$IS_GITHUB) { foreach ($temp as $key) { - if (\stripos(\strtolower($key), 'github') !== false) { + if (\is_string($key) && \stripos(\strtolower($key), 'github') !== false) { $IS_GITHUB = true; break; @@ -53,7 +53,7 @@ if (!$IS_GITHUB) { $temp = \array_values(\getenv()); if (!$IS_GITHUB) { foreach ($temp as $value) { - if (\stripos(\strtolower($value), 'github') !== false) { + if (\is_string($value) && \stripos(\strtolower($value), 'github') !== false) { $IS_GITHUB = true; break; From bdf238a5223ea6a3d1329d7d72ba902878349edc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 1 Oct 2023 20:41:42 +0000 Subject: [PATCH 05/11] fix link --- tests/Socket/Client/ClientTestHelper.php | 2 +- tests/Socket/Server/ServerTestHelper.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Socket/Client/ClientTestHelper.php b/tests/Socket/Client/ClientTestHelper.php index 7a7dfe45c..84700ab90 100755 --- a/tests/Socket/Client/ClientTestHelper.php +++ b/tests/Socket/Client/ClientTestHelper.php @@ -8,7 +8,7 @@ * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 - * @link http://karaka.com + * @link https://jingga.app */ declare(strict_types=1); diff --git a/tests/Socket/Server/ServerTestHelper.php b/tests/Socket/Server/ServerTestHelper.php index 69e36e4a7..0245e7148 100755 --- a/tests/Socket/Server/ServerTestHelper.php +++ b/tests/Socket/Server/ServerTestHelper.php @@ -8,7 +8,7 @@ * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 - * @link http://karaka.com + * @link https://jingga.app */ declare(strict_types=1); From 69f64f331be6ee5be944ff5eb0cf9916a5fa46af Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 1 Oct 2023 20:47:08 +0000 Subject: [PATCH 06/11] fix mssql login/password --- tests/Bootstrap.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index a95d571cc..1b48ed57b 100755 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -236,8 +236,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', @@ -246,8 +246,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', @@ -256,8 +256,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', @@ -266,8 +266,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', @@ -276,8 +276,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', @@ -286,8 +286,8 @@ $CONFIG = [ 'db' => 'mssql', /* db type */ 'host' => 'localhost', /* db host address */ 'port' => '1433', /* db host port */ - 'login' => 'sa', /* db login name */ - 'password' => 'c0MplicatedP@ssword', /* db login password */ + 'login' => 'test', /* db login name */ + 'password' => 'orange', /* db login password */ 'database' => 'omt', /* db name */ 'weight' => 1000, /* db table prefix */ 'datetimeformat' => 'Y-m-d H:i:s', From 42ca4d66902ed1edc9bb29df43d8d36b050e15ee Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 2 Oct 2023 02:56:47 +0000 Subject: [PATCH 07/11] fix autoloading --- tests/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 58a7cc660..6e249662d 100755 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -79,7 +79,7 @@ class Autoloader $class = \strtr($class, '_\\', '//'); if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) { - $class = \is_dir(__DIR__ . '/Web') ? $class : \str_replace('Web/', 'Karaka/Web/', $class); + $class = \is_dir(__DIR__ . '/Web') ? $class : \str_replace('Web/', 'MainRepository/Web/', $class); } $class2 = $class; From be8ae797db60ff57a434646169c30bbb658c6038 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 2 Oct 2023 04:13:30 +0000 Subject: [PATCH 08/11] fix phpunit config --- tests/phpunit_default.xml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 9399ff8ae..9a4659aba 100644 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -1,17 +1,30 @@ + + ../ + + ../vendor* + ../MainRepository* + ../Karaka* + ../Admin/Install/Application* + ../phpOMS* + ../tests* ../*/tests* + ../**/tests* + */tests* ../* ../* ../* - ./Build - ./Resources - *vendor* - *Testapp* - ./vendor - ../vendor + ../* + ../* + ../**/test* + ../**/Theme* + ../**/Admin/Routes* + ../**/Admin/Hooks* + ../**/Admin/Install* + ../Media/Files* ../Localization/LanguageDetection/resources From cdea41f714665fa34d2762c49eecd5830c098971 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 3 Oct 2023 02:19:22 +0000 Subject: [PATCH 09/11] Reduce reflection usage by forcing private definition in mappers. --- .../Database/Mapper/DataMapperAbstract.php | 4 +- .../Database/Mapper/DataMapperFactory.php | 37 +++-- DataStorage/Database/Mapper/DeleteMapper.php | 58 ++++--- DataStorage/Database/Mapper/ReadMapper.php | 147 +++++++++++------- DataStorage/Database/Mapper/UpdateMapper.php | 59 +++++-- DataStorage/Database/Mapper/WriteMapper.php | 91 ++++++----- 6 files changed, 250 insertions(+), 146 deletions(-) diff --git a/DataStorage/Database/Mapper/DataMapperAbstract.php b/DataStorage/Database/Mapper/DataMapperAbstract.php index fdef771e7..ef2e963db 100755 --- a/DataStorage/Database/Mapper/DataMapperAbstract.php +++ b/DataStorage/Database/Mapper/DataMapperAbstract.php @@ -548,8 +548,8 @@ abstract class DataMapperAbstract return (string) \gzdeflate($value); } elseif ($type === 'Serializable') { return $value->serialize(); - } elseif (\is_object($value) && \method_exists($value, 'getId')) { - return $value->getId(); + } elseif (\is_object($value) && isset($value->id)) { + return $value->id; } return $value; diff --git a/DataStorage/Database/Mapper/DataMapperFactory.php b/DataStorage/Database/Mapper/DataMapperFactory.php index 07fe92c79..c852e9401 100755 --- a/DataStorage/Database/Mapper/DataMapperFactory.php +++ b/DataStorage/Database/Mapper/DataMapperFactory.php @@ -426,38 +426,53 @@ class DataMapperFactory /** * Get id of object * - * @param object $obj Model to create - * @param string $member Member name for the id, if it is not the primary key + * @param object $obj Model to create + * @param string $member Member name for the id, if it is not the primary key + * @param null|\ReflectionClass $refClass Reflection class * * @return mixed * * @since 1.0.0 */ - public static function getObjectId(object $obj, string $member = null) : mixed + public static function getObjectId(object $obj, string $member = null, \ReflectionClass &$refClass = null) : mixed { $propertyName = $member ?? static::COLUMNS[static::PRIMARYFIELD]['internal']; - return $obj->{$propertyName}; + if (static::COLUMNS[static::PRIMARYFIELD]['private'] ?? false) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $refProp = $refClass->getProperty($propertyName); + + return $refProp->getValue($obj); + } else { + return $obj->{$propertyName}; + } } /** * Set id to model * - * @param \ReflectionClass $refClass Reflection class - * @param object $obj Object to create - * @param mixed $objId Id to set + * @param object $obj Object to create + * @param mixed $objId Id to set + * @param null|\ReflectionClass $refClass Reflection class * * @return void * * @since 1.0.0 */ - public static function setObjectId(\ReflectionClass $refClass, object $obj, mixed $objId) : void + public static function setObjectId(object $obj, mixed $objId, \ReflectionClass &$refClass = null) : void { $propertyName = static::COLUMNS[static::PRIMARYFIELD]['internal']; - $refProp = $refClass->getProperty($propertyName); - \settype($objId, static::COLUMNS[static::PRIMARYFIELD]['type']); - if (!$refProp->isPublic()) { + + if (static::COLUMNS[static::PRIMARYFIELD]['private'] ?? false) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $refProp = $refClass->getProperty($propertyName); $refProp->setValue($obj, $objId); } else { $obj->{$propertyName} = $objId; diff --git a/DataStorage/Database/Mapper/DeleteMapper.php b/DataStorage/Database/Mapper/DeleteMapper.php index d155406ce..c68ab7877 100755 --- a/DataStorage/Database/Mapper/DeleteMapper.php +++ b/DataStorage/Database/Mapper/DeleteMapper.php @@ -71,17 +71,17 @@ final class DeleteMapper extends DataMapperAbstract */ public function executeDelete(object $obj) : mixed { - $refClass = new \ReflectionClass($obj); + $refClass = null; $objId = $this->mapper::getObjectId($obj); if (empty($objId)) { return null; } - $this->deleteSingleRelation($obj, $refClass, $this->mapper::BELONGS_TO); - $this->deleteHasMany($refClass, $obj, $objId); + $this->deleteSingleRelation($obj, $this->mapper::BELONGS_TO, $refClass); + $this->deleteHasMany($obj, $objId, $refClass); $this->deleteModel($objId); - $this->deleteSingleRelation($obj, $refClass, $this->mapper::OWNS_ONE); + $this->deleteSingleRelation($obj, $this->mapper::OWNS_ONE, $refClass); return $objId; } @@ -111,15 +111,15 @@ final class DeleteMapper extends DataMapperAbstract /** * Delete ownsOne, belongsTo relations * - * @param object $obj Object to delete - * @param \ReflectionClass $refClass Reflection of object to delete - * @param array $relation Relation data (e.g. ::BELONGS_TO, ::OWNS_ONE) + * @param object $obj Object to delete + * @param array $relation Relation data (e.g. ::BELONGS_TO, ::OWNS_ONE) + * @param null|\ReflectionClass $refClass Reflection of object to delete * * @return void * * @since 1.0.0 */ - private function deleteSingleRelation(object $obj, \ReflectionClass $refClass, array $relation) : void + private function deleteSingleRelation(object $obj, array $relation, \ReflectionClass &$refClass = null) : void { if (empty($relation)) { return; @@ -137,27 +137,36 @@ final class DeleteMapper extends DataMapperAbstract $relMapper = $this->createRelationMapper($mapper::delete(db: $this->db), $member); $relMapper->depth = $this->depth + 1; - $refProp = $refClass->getProperty($member); - if (!$refProp->isPublic()) { - $relMapper->execute($refProp->getValue($obj)); + $isPrivate = $relData['private'] ?? false; + + $value = null; + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $refProp = $refClass->getProperty($member); + $value = $refProp->getValue($obj); } else { - $relMapper->execute($obj->{$member}); + $value = $obj->{$member}; } + + $relMapper->execute($value); } } /** * Delete hasMany * - * @param \ReflectionClass $refClass Reflection of object to delete - * @param object $obj Object to delete - * @param mixed $objId Object id to delete + * @param object $obj Object to delete + * @param mixed $objId Object id to delete + * @param null|\ReflectionClass $refClass Reflection of object to delete * * @return void * * @since 1.0.0 */ - private function deleteHasMany(\ReflectionClass $refClass, object $obj, mixed $objId) : void + private function deleteHasMany(object $obj, mixed $objId, \ReflectionClass &$refClass = null) : void { if (empty($this->mapper::HAS_MANY)) { return; @@ -169,9 +178,20 @@ final class DeleteMapper extends DataMapperAbstract continue; } - $objIds = []; - $refProp = $refClass->getProperty($member); - $values = $refProp->isPublic() ? $obj->{$member} : $refProp->getValue($obj); + $objIds = []; + $isPrivate = $rel['private'] ?? false; + + $values = null; + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $refProp = $refClass->getProperty($member); + $values = $refProp->getValue($obj); + } else { + $values = $obj->{$member}; + } if (!\is_array($values)) { // conditionals diff --git a/DataStorage/Database/Mapper/ReadMapper.php b/DataStorage/Database/Mapper/ReadMapper.php index a5bb79a0d..e05fc5a90 100755 --- a/DataStorage/Database/Mapper/ReadMapper.php +++ b/DataStorage/Database/Mapper/ReadMapper.php @@ -555,7 +555,7 @@ final class ReadMapper extends DataMapperAbstract */ public function populateAbstract(array $result, object $obj) : object { - $refClass = new \ReflectionClass($obj); + $refClass = null; foreach ($this->mapper::COLUMNS as $column => $def) { $alias = $column . '_d' . $this->depth; @@ -569,28 +569,42 @@ final class ReadMapper extends DataMapperAbstract $hasPath = false; $aValue = []; $arrayPath = ''; + $refProp = null; + $isPrivate = $def['private'] ?? false; + $member = ''; + + if ($isPrivate && $refClass === null) { + $refClass = new \ReflectionClass($obj); + } if (\stripos($def['internal'], '/') !== false) { $hasPath = true; $path = \explode('/', \ltrim($def['internal'], '/')); $member = $path[0]; - $refProp = $refClass->getProperty($path[0]); - $isPublic = $refProp->isPublic(); - $aValue = $isPublic ? $obj->{$path[0]} : $refProp->getValue($obj); + if ($isPrivate) { + $refProp = $refClass->getProperty($path[0]); + $aValue = $refProp->getValue($obj); + } else { + $aValue = $obj->{$path[0]}; + } \array_shift($path); $arrayPath = \implode('/', $path); } else { - $refProp = $refClass->getProperty($def['internal']); - $isPublic = $refProp->isPublic(); - $member = $def['internal']; + if ($isPrivate) { + $refProp = $refClass->getProperty($def['internal']); + } + + $member = $def['internal']; } if (isset($this->mapper::OWNS_ONE[$def['internal']])) { $default = null; - if (!isset($this->with[$member]) && $refProp->isInitialized($obj)) { - $default = $isPublic ? $obj->{$def['internal']} : $refProp->getValue($obj); + if (!isset($this->with[$member]) + && ($isPrivate ? $refProp->isInitialized($obj) : isset($obj->{$member})) + ) { + $default = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; } $value = $this->populateOwnsOne($def['internal'], $result, $default); @@ -600,14 +614,16 @@ final class ReadMapper extends DataMapperAbstract $this->mapper::OWNS_ONE[$def['internal']]['mapper']::reader(db: $this->db)->loadHasManyRelations($value); } - if (!empty($value)) { + if (empty($value)) { // @todo: find better solution. this was because of a bug with the sales billing list query depth = 4. The address was set (from the client, referral or creator) but then somehow there was a second address element which was all null and null cannot be asigned to a string variable (e.g. country). The problem with this solution is that if the model expects an initialization (e.g. at lest set the elements to null, '', 0 etc.) this is now not done. - $refProp->setValue($obj, $value); + $value = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; } } elseif (isset($this->mapper::BELONGS_TO[$def['internal']])) { $default = null; - if (!isset($this->with[$member]) && $refProp->isInitialized($obj)) { - $default = $isPublic ? $obj->{$def['internal']} : $refProp->getValue($obj); + if (!isset($this->with[$member]) + && ($isPrivate ? $refProp->isInitialized($obj) : isset($obj->{$member})) + ) { + $default = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; } $value = $this->populateBelongsTo($def['internal'], $result, $default); @@ -616,8 +632,6 @@ final class ReadMapper extends DataMapperAbstract if (\is_object($value) && isset($this->mapper::BELONGS_TO[$def['internal']]['mapper'])) { $this->mapper::BELONGS_TO[$def['internal']]['mapper']::reader(db: $this->db)->loadHasManyRelations($value); } - - $refProp->setValue($obj, $value); } elseif (\in_array($def['type'], ['string', 'compress', 'int', 'float', 'bool'])) { if ($value !== null && $def['type'] === 'compress') { $def['type'] = 'string'; @@ -625,44 +639,44 @@ final class ReadMapper extends DataMapperAbstract $value = \gzinflate($value); } - if ($value !== null || $refProp->getValue($obj) !== null) { + $mValue = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; + if ($value !== null || $mValue !== null) { \settype($value, $def['type']); } if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['type'] === 'DateTime') { - $value = $value === null ? null : new \DateTime($value); + $value ??= new \DateTime($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['type'] === 'DateTimeImmutable') { - $value = $value === null ? null : new \DateTimeImmutable($value); + $value ??= new \DateTimeImmutable($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['type'] === 'Json') { if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - $refProp->setValue($obj, \json_decode($value, true)); + $value = \json_decode($value, true); } elseif ($def['type'] === 'Serializable') { - $member = $isPublic ? $obj->{$def['internal']} : $refProp->getValue($obj); + $mObj = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; - if ($member === null || $value === null) { - $obj->{$def['internal']} = $value; - } else { - $member->unserialize($value); + if ($mObj !== null && $value !== null) { + $mObj->unserialize($value); + $value = $mObj; } } + + if ($isPrivate) { + $refProp->setValue($obj, $value); + } else { + $obj->{$member} = $value; + } } foreach ($this->mapper::HAS_MANY as $member => $def) { @@ -677,54 +691,68 @@ final class ReadMapper extends DataMapperAbstract $hasPath = false; $aValue = null; $arrayPath = '/'; + $refProp = null; + $isPrivate = $def['private'] ?? false; + + if ($isPrivate && $refClass === null) { + $refClass = new \ReflectionClass($obj); + } if (\stripos($member, '/') !== false) { $hasPath = true; $path = \explode('/', $member); - $refProp = $refClass->getProperty($path[0]); - $isPublic = $refProp->isPublic(); + $member = $path[0]; + + if ($isPrivate) { + $refProp = $refClass->getProperty($path[0]); + } \array_shift($path); $arrayPath = \implode('/', $path); - $aValue = $isPublic ? $obj->{$path[0]} : $refProp->getValue($obj); - } else { + $aValue = $isPrivate ? $refProp->getValue($obj) : $obj->{$path[0]}; + } elseif ($isPrivate) { $refProp = $refClass->getProperty($member); - $isPublic = $refProp->isPublic(); } if (\in_array($def['mapper']::COLUMNS[$column]['type'], ['string', 'int', 'float', 'bool'])) { - if ($value !== null || $refProp->getValue($obj) !== null) { + if ($value !== null + || ($isPrivate ? $refProp->getValue($obj) !== null : $obj->{$member} !== null) + ) { \settype($value, $def['mapper']::COLUMNS[$column]['type']); } if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['mapper']::COLUMNS[$column]['type'] === 'DateTime') { - $value = $value === null ? null : new \DateTime($value); + $value ??= new \DateTime($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['mapper']::COLUMNS[$column]['type'] === 'DateTimeImmutable') { - $value = $value === null ? null : new \DateTimeImmutable($value); + $value ??= new \DateTimeImmutable($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - - $refProp->setValue($obj, $value); } elseif ($def['mapper']::COLUMNS[$column]['type'] === 'Json') { if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } - $refProp->setValue($obj, \json_decode($value, true)); + $value = \json_decode($value, true); } elseif ($def['mapper']::COLUMNS[$column]['type'] === 'Serializable') { - $member = $isPublic ? $obj->{$member} : $refProp->getValue($obj); - $member->unserialize($value); + $mObj = $isPrivate ? $refProp->getValue($obj) : $obj->{$member}; + + if ($mObj !== null && $value !== null) { + $mObj->unserialize($value); + $value = $mObj; + } + } + + if ($isPrivate) { + $refProp->setValue($obj, $value); + } else { + $obj->{$member} = $value; } } @@ -867,6 +895,8 @@ final class ReadMapper extends DataMapperAbstract continue; } + $isPrivate = $withData['private'] ?? false; + $objectMapper = $this->createRelationMapper($many['mapper']::get(db: $this->db), $member); if ($many['external'] === null/* same as $many['table'] !== $many['mapper']::TABLE */) { $objectMapper->where($many['mapper']::COLUMNS[$many['self']]['internal'], $primaryKey); @@ -886,12 +916,12 @@ final class ReadMapper extends DataMapperAbstract continue; } - if ($refClass === null) { - $refClass = new \ReflectionClass($obj); - } + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } - $refProp = $refClass->getProperty($member); - if (!$refProp->isPublic()) { + $refProp = $refClass->getProperty($member); $refProp->setValue($obj, !\is_array($objects) && ($many['conditional'] ?? false) === false ? [$many['mapper']::getObjectId($objects) => $objects] : $objects // if conditional === true the obj will be asigned (e.g. has many localizations but only one is loaded for the model) @@ -914,15 +944,16 @@ final class ReadMapper extends DataMapperAbstract continue; } - if ($refClass === null) { - $refClass = new \ReflectionClass($obj); - } - /** @var ReadMapper $relMapper */ $relMapper = $this->createRelationMapper($relation['mapper']::reader($this->db), $member); - $refProp = $refClass->getProperty($member); - if (!$refProp->isPublic()) { + $isPrivate = $withData['private'] ?? false; + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $refProp = $refClass->getProperty($member); $relMapper->loadHasManyRelations($refProp->getValue($obj)); } else { $relMapper->loadHasManyRelations($obj->{$member}); diff --git a/DataStorage/Database/Mapper/UpdateMapper.php b/DataStorage/Database/Mapper/UpdateMapper.php index b6f52e776..881281cc8 100755 --- a/DataStorage/Database/Mapper/UpdateMapper.php +++ b/DataStorage/Database/Mapper/UpdateMapper.php @@ -73,14 +73,14 @@ final class UpdateMapper extends DataMapperAbstract */ public function executeUpdate(object $obj) : mixed { - $refClass = new \ReflectionClass($obj); + $refClass = null; $objId = $this->mapper::getObjectId($obj); if ($this->mapper::isNullModel($obj)) { return $objId === 0 ? null : $objId; } - $this->updateHasMany($refClass, $obj, $objId); + $this->updateHasMany($obj, $objId, $refClass); if (empty($objId)) { return $this->mapper::create(db: $this->db)->execute($obj); @@ -102,7 +102,7 @@ final class UpdateMapper extends DataMapperAbstract * * @since 1.0.0 */ - private function updateModel(object $obj, mixed $objId, \ReflectionClass $refClass = null) : void + private function updateModel(object $obj, mixed $objId, \ReflectionClass &$refClass = null) : void { try { // Model doesn't have anything to update @@ -124,10 +124,20 @@ final class UpdateMapper extends DataMapperAbstract continue; } - $refClass = $refClass ?? new \ReflectionClass($obj); - $property = $refClass->getProperty($propertyName); + $isPrivate = $column['private'] ?? false; + $property = null; + $tValue = null; - $tValue = $property->isPublic() ? $obj->{$propertyName} : $property->getValue($obj); + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $property = $refClass->getProperty($propertyName); + $tValue = $property->getValue($obj); + } else { + $tValue = $obj->{$propertyName}; + } if (isset($this->mapper::OWNS_ONE[$propertyName])) { $id = \is_object($tValue) ? $this->updateOwnsOne($propertyName, $tValue) : $tValue; @@ -218,9 +228,9 @@ final class UpdateMapper extends DataMapperAbstract /** * Update has many relations * - * @param \ReflectionClass $refClass Reflection of the object containing the relations - * @param object $obj Object which contains the relations - * @param mixed $objId Object id which contains the relations + * @param object $obj Object which contains the relations + * @param mixed $objId Object id which contains the relations + * @param null|\ReflectionClass $refClass Reflection of the object containing the relations * * @return void * @@ -228,7 +238,7 @@ final class UpdateMapper extends DataMapperAbstract * * @since 1.0.0 */ - private function updateHasMany(\ReflectionClass $refClass, object $obj, mixed $objId) : void + private function updateHasMany(object $obj, mixed $objId, \ReflectionClass &$refClass = null) : void { if (empty($this->with) || empty($this->mapper::HAS_MANY)) { return; @@ -245,17 +255,33 @@ final class UpdateMapper extends DataMapperAbstract throw new InvalidMapperException(); } - $property = $refClass->getProperty($propertyName); + $isPrivate = $rel['private'] ?? false; + $property = null; + $values = null; - $values = ($isPublic = $property->isPublic()) ? $obj->{$propertyName} : $property->getValue($obj); + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $property = $refClass->getProperty($propertyName); + $values = $property->getValue($obj); + } else { + $values = $obj->{$propertyName}; + } if (!\is_array($values) || empty($values)) { continue; } /** @var class-string $mapper */ - $mapper = $this->mapper::HAS_MANY[$propertyName]['mapper']; - $relReflectionClass = new \ReflectionClass(\reset($values)); + $mapper = $this->mapper::HAS_MANY[$propertyName]['mapper']; + $isPrivateRel = $this->mapper::HAS_MANY[$propertyName]['private'] ?? false; + + if ($isPrivateRel) { + $relReflectionClass = new \ReflectionClass(\reset($values)); + } + $objsIds[$propertyName] = []; foreach ($values as $key => &$value) { @@ -285,9 +311,8 @@ final class UpdateMapper extends DataMapperAbstract if ($this->mapper::HAS_MANY[$propertyName]['table'] === $this->mapper::HAS_MANY[$propertyName]['mapper']::TABLE && isset($mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]) ) { - $relProperty = $relReflectionClass->getProperty($mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal']); - - if (!$isPublic) { + if ($isPrivateRel) { + $relProperty = $relReflectionClass->getProperty($mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal']); $relProperty->setValue($value, $objId); } else { $value->{$mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal']} = $objId; diff --git a/DataStorage/Database/Mapper/WriteMapper.php b/DataStorage/Database/Mapper/WriteMapper.php index 1ba0cf92a..eacf8ca49 100755 --- a/DataStorage/Database/Mapper/WriteMapper.php +++ b/DataStorage/Database/Mapper/WriteMapper.php @@ -74,7 +74,7 @@ final class WriteMapper extends DataMapperAbstract */ public function executeCreate(object $obj) : mixed { - $refClass = new \ReflectionClass($obj); + $refClass = null; if ($this->mapper::isNullModel($obj)) { $objId = $this->mapper::getObjectId($obj); @@ -86,10 +86,10 @@ final class WriteMapper extends DataMapperAbstract $objId = $id; } else { $objId = $this->createModel($obj, $refClass); - $this->mapper::setObjectId($refClass, $obj, $objId); + $this->mapper::setObjectId($obj, $objId, $refClass); } - $this->createHasMany($refClass, $obj, $objId); + $this->createHasMany($obj, $objId, $refClass); return $objId; } @@ -97,21 +97,19 @@ final class WriteMapper extends DataMapperAbstract /** * Create model * - * @param object $obj Object to create - * @param \ReflectionClass $refClass Reflection of the object to create + * @param object $obj Object to create + * @param null|\ReflectionClass $refClass Reflection of the object to create * * @return mixed * * @since 1.0.0 */ - private function createModel(object $obj, \ReflectionClass $refClass) : mixed + private function createModel(object $obj, \ReflectionClass &$refClass = null) : mixed { try { $query = new Builder($this->db); $query->into($this->mapper::TABLE); - $publicProperties = \get_object_vars($obj); - foreach ($this->mapper::COLUMNS as $column) { $propertyName = \stripos($column['internal'], '/') !== false ? \explode('/', $column['internal'])[0] @@ -123,13 +121,16 @@ final class WriteMapper extends DataMapperAbstract continue; } - if (!isset($publicProperties[$propertyName])) { + $tValue = null; + if ($column['private'] ?? false) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + $property = $refClass->getProperty($propertyName); - $property->setAccessible(true); - $tValue = $property->getValue($obj); - $property->setAccessible(false); + $tValue = $property->getValue($obj); } else { - $tValue = $publicProperties[$propertyName]; + $tValue = $obj->{$propertyName}; } if (isset($this->mapper::OWNS_ONE[$propertyName])) { @@ -231,10 +232,13 @@ final class WriteMapper extends DataMapperAbstract if (isset($this->mapper::BELONGS_TO[$propertyName]['by'])) { // has by (obj is stored as a different model e.g. model = profile but reference/db is account) - $refClass = new \ReflectionClass($obj); - $refProp = $refClass->getProperty($this->mapper::BELONGS_TO[$propertyName]['by']); - - $obj = $refProp->isPublic() ? $obj->{$this->mapper::BELONGS_TO[$propertyName]['by']} : $refProp->getValue($obj); + if ($this->mapper::BELONGS_TO[$propertyName]['private']) { + $refClass = new \ReflectionClass($obj); + $refProp = $refClass->getProperty($this->mapper::BELONGS_TO[$propertyName]['by']); + $obj = $refProp->getValue($obj); + } else { + $obj = $obj->{$this->mapper::BELONGS_TO[$propertyName]['by']}; + } } /** @var class-string $mapper */ @@ -248,9 +252,9 @@ final class WriteMapper extends DataMapperAbstract /** * Create has many models * - * @param \ReflectionClass $refClass Reflection of the object to create - * @param object $obj Object to create - * @param mixed $objId Id of the parent object + * @param object $obj Object to create + * @param mixed $objId Id of the parent object + * @param null|\ReflectionClass $refClass Reflection of the object to create * * @return void * @@ -258,15 +262,27 @@ final class WriteMapper extends DataMapperAbstract * * @since 1.0.0 */ - private function createHasMany(\ReflectionClass $refClass, object $obj, mixed $objId) : void + private function createHasMany(object $obj, mixed $objId, \ReflectionClass &$refClass = null) : void { - foreach ($this->mapper::HAS_MANY as $propertyName => $_) { + foreach ($this->mapper::HAS_MANY as $propertyName => $rel) { if (!isset($this->mapper::HAS_MANY[$propertyName]['mapper'])) { throw new InvalidMapperException(); // @codeCoverageIgnore } - $property = $refClass->getProperty($propertyName); - $values = $property->isPublic() ? $obj->{$propertyName} : $property->getValue($obj); + $isPrivate = $rel['private'] ?? false; + $property = null; + $values = null; + + if ($isPrivate) { + if ($refClass === null) { + $refClass = new \ReflectionClass($obj); + } + + $property = $refClass->getProperty($propertyName); + $values = $property->getValue($obj); + } else { + $values = $obj->{$propertyName}; + } /** @var class-string $mapper */ $mapper = $this->mapper::HAS_MANY[$propertyName]['mapper']; @@ -274,17 +290,16 @@ final class WriteMapper extends DataMapperAbstract ? $mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal'] : 'ERROR'; + // @todo: this or $isRelPrivate is wrong, don't know which one. + $isInternalPrivate =$mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['private'] ?? false; + if (\is_object($values)) { // conditionals - $publicProperties = \get_object_vars($values); - - if (!isset($publicProperties[$internalName])) { + if ($isInternalPrivate) { $relReflectionClass = new \ReflectionClass($values); $relProperty = $relReflectionClass->getProperty($internalName); - $relProperty->setAccessible(true); $relProperty->setValue($values, $objId); - $relProperty->setAccessible(false); } else { $values->{$internalName} = $objId; } @@ -297,7 +312,8 @@ final class WriteMapper extends DataMapperAbstract } $objsIds = []; - $relReflectionClass = empty($values) ? null : new \ReflectionClass(\reset($values)); + $isRelPrivate = $mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['private'] ?? false; + $relReflectionClass = $isRelPrivate && !empty($values) ? new \ReflectionClass(\reset($values)) : null; foreach ($values as $key => $value) { if (!\is_object($value)) { @@ -307,7 +323,6 @@ final class WriteMapper extends DataMapperAbstract continue; } - /** @var \ReflectionClass $relReflectionClass */ $primaryKey = $mapper::getObjectId($value); // already in db @@ -319,26 +334,24 @@ final class WriteMapper extends DataMapperAbstract // Setting relation value (id) for relation (since the relation is not stored in an extra relation table) if (!isset($this->mapper::HAS_MANY[$propertyName]['external'])) { - $relProperty = $relReflectionClass->getProperty($internalName); - $isRelPublic = $relProperty->isPublic(); + $relProperty = null; + if ($isRelPrivate) { + $relProperty = $relReflectionClass->getProperty($internalName); + } // todo maybe consider to just set the column type to object, and then check for that (might be faster) if (isset($mapper::BELONGS_TO[$internalName]) || isset($mapper::OWNS_ONE[$internalName])) { - if (!$isRelPublic) { + if ($isRelPrivate) { $relProperty->setValue($value, $this->mapper::createNullModel($objId)); } else { $value->{$internalName} = $this->mapper::createNullModel($objId); } - } elseif (!$isRelPublic) { + } elseif ($isRelPrivate) { $relProperty->setValue($value, $objId); } else { $value->{$internalName} = $objId; } - - if (!$isRelPublic) { - $relProperty->setAccessible(false); - } } $objsIds[$key] = $mapper::create(db: $this->db)->execute($value); From 39418dbe23a154422316afc3b7550c0f5ca1672b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 4 Oct 2023 13:54:38 +0000 Subject: [PATCH 10/11] phpcs fixes --- DataStorage/Database/Mapper/DataMapperFactory.php | 4 ++-- DataStorage/Database/Mapper/ReadMapper.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/DataStorage/Database/Mapper/DataMapperFactory.php b/DataStorage/Database/Mapper/DataMapperFactory.php index c852e9401..18988b8bd 100755 --- a/DataStorage/Database/Mapper/DataMapperFactory.php +++ b/DataStorage/Database/Mapper/DataMapperFactory.php @@ -426,8 +426,8 @@ class DataMapperFactory /** * Get id of object * - * @param object $obj Model to create - * @param string $member Member name for the id, if it is not the primary key + * @param object $obj Model to create + * @param string $member Member name for the id, if it is not the primary key * @param null|\ReflectionClass $refClass Reflection class * * @return mixed diff --git a/DataStorage/Database/Mapper/ReadMapper.php b/DataStorage/Database/Mapper/ReadMapper.php index e05fc5a90..5d015fb0d 100755 --- a/DataStorage/Database/Mapper/ReadMapper.php +++ b/DataStorage/Database/Mapper/ReadMapper.php @@ -699,9 +699,9 @@ final class ReadMapper extends DataMapperAbstract } if (\stripos($member, '/') !== false) { - $hasPath = true; - $path = \explode('/', $member); - $member = $path[0]; + $hasPath = true; + $path = \explode('/', $member); + $member = $path[0]; if ($isPrivate) { $refProp = $refClass->getProperty($path[0]); @@ -711,7 +711,7 @@ final class ReadMapper extends DataMapperAbstract $arrayPath = \implode('/', $path); $aValue = $isPrivate ? $refProp->getValue($obj) : $obj->{$path[0]}; } elseif ($isPrivate) { - $refProp = $refClass->getProperty($member); + $refProp = $refClass->getProperty($member); } if (\in_array($def['mapper']::COLUMNS[$column]['type'], ['string', 'int', 'float', 'bool'])) { From d42fee56afa809bde1d22421a32af6bf6dcc1187 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 4 Oct 2023 15:13:20 +0000 Subject: [PATCH 11/11] fix datetime value bug --- DataStorage/Database/Mapper/ReadMapper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DataStorage/Database/Mapper/ReadMapper.php b/DataStorage/Database/Mapper/ReadMapper.php index 5d015fb0d..e67844987 100755 --- a/DataStorage/Database/Mapper/ReadMapper.php +++ b/DataStorage/Database/Mapper/ReadMapper.php @@ -648,12 +648,12 @@ final class ReadMapper extends DataMapperAbstract $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } } elseif ($def['type'] === 'DateTime') { - $value ??= new \DateTime($value); + $value = $value === null ? null : new \DateTime($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); } } elseif ($def['type'] === 'DateTimeImmutable') { - $value ??= new \DateTimeImmutable($value); + $value = $value === null ? null : new \DateTimeImmutable($value); if ($hasPath) { $value = ArrayUtils::setArray($arrayPath, $aValue, $value, '/', true); }