diff options
| author | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2023-02-17 16:11:12 +0000 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2023-02-17 16:11:12 +0000 |
| commit | 64887e7a9f8874de012f4298e6f9c45ae38aefc5 (patch) | |
| tree | ccab2186d149a141634766565e15b126a9ba71fa /lib/models/SimpleORMap.class.php | |
| parent | b04360fa8ebaa98f015bbb2b15649c1362c1d899 (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.php | 68 |
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; |
