aboutsummaryrefslogtreecommitdiff
path: root/lib/models/SimpleORMap.class.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2023-02-17 16:11:12 +0000
committerJan-Hendrik Willms <tleilax+studip@gmail.com>2023-02-17 16:11:12 +0000
commit64887e7a9f8874de012f4298e6f9c45ae38aefc5 (patch)
treeccab2186d149a141634766565e15b126a9ba71fa /lib/models/SimpleORMap.class.php
parentb04360fa8ebaa98f015bbb2b15649c1362c1d899 (diff)
clone records before fetching into them so that the after_initialize will always be called on a fresh object
Closes #1081 Merge request studip/studip!646
Diffstat (limited to 'lib/models/SimpleORMap.class.php')
-rw-r--r--lib/models/SimpleORMap.class.php68
1 files changed, 36 insertions, 32 deletions
diff --git a/lib/models/SimpleORMap.class.php b/lib/models/SimpleORMap.class.php
index 7af9dec..b210c39 100644
--- a/lib/models/SimpleORMap.class.php
+++ b/lib/models/SimpleORMap.class.php
@@ -615,26 +615,27 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
public static function findBySQL($sql, $params = [])
{
$db_table = static::db_table();
- $class = get_called_class();
- $record = new $class();
- $db = DBManager::get();
+
$has_join = stripos($sql, 'JOIN ');
if ($has_join === false || $has_join > 10) {
$sql = 'WHERE ' . $sql;
}
$sql = "SELECT `" . $db_table . "`.* FROM `" . $db_table . "` " . $sql;
- $ret = [];
$stmt = DBManager::get()->prepare($sql);
$stmt->execute($params);
- $stmt->setFetchMode(PDO::FETCH_INTO , $record);
- $record->setNew(false);
- while ($record = $stmt->fetch()) {
- // Reset all relations
- $record->cleanup();
- $record->applyCallbacks('after_initialize');
- $ret[] = clone $record;
- }
+ $record = static::build([], false);
+
+ $ret = [];
+ do {
+ $clone = clone $record;
+ $stmt->setFetchMode(PDO::FETCH_INTO, $clone);
+
+ if ($clone = $stmt->fetch()) {
+ $clone->applyCallbacks('after_initialize');
+ $ret[] = $clone;
+ }
+ } while ($clone);
return $ret;
}
@@ -670,24 +671,25 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
$assoc_foreign_key = $options['assoc_foreign_key'];
$db_table = static::db_table();
- $class = get_called_class();
- $record = new $class();
+
$sql = "SELECT `$db_table`.* FROM `$thru_table`
INNER JOIN `$db_table` ON `$thru_table`.`$thru_assoc_key` = `$db_table`.`$assoc_foreign_key`
WHERE `$thru_table`.`$thru_key` = ? " . ($options['order_by'] ?? '');
- $db = DBManager::get();
- $st = $db->prepare($sql);
+ $st = DBManager::get()->prepare($sql);
$st->execute([$foreign_key_value]);
+
+ $record = static::build([], false);
+
$ret = [];
- $st->setFetchMode(PDO::FETCH_INTO , $record);
- $record->setNew(false);
- while ($record = $st->fetch()) {
- // Reset all relations
- $record->cleanup();
+ do {
+ $clone = clone $record;
+ $st->setFetchMode(PDO::FETCH_INTO, $clone);
- $record->applyCallbacks('after_initialize');
- $ret[] = clone $record;
- }
+ if ($clone = $st->fetch()) {
+ $clone->applyCallbacks('after_initialize');
+ $ret[] = $clone;
+ }
+ } while ($clone);
return $ret;
}
@@ -713,20 +715,22 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
$db_table = static::db_table();
$st = DBManager::get()->prepare("SELECT `{$db_table}`.* FROM `{$db_table}` {$sql}");
$st->execute($params);
- $st->setFetchMode(PDO::FETCH_INTO , $record);
// Indicate that we are performing a batch operation
static::$performs_batch_operation = true;
+ $record = static::build([], false);
+
$ret = 0;
- while ($record = $st->fetch()) {
- // Reset all relations
- $record->cleanup();
- $record->applyCallbacks('after_initialize');
+ do {
+ $clone = clone $record;
+ $st->setFetchMode(PDO::FETCH_INTO, $clone);
- // Execute callable on current record
- $callable(clone $record, $ret++);
- }
+ if ($clone = $st->fetch()) {
+ $clone->applyCallbacks('after_initialize');
+ $callable($clone, $ret++);
+ }
+ } while ($clone);
// Reset batch operation indicator
static::$performs_batch_operation = false;