diff --git a/lib/models/BlubberThread.php b/lib/models/BlubberThread.php index d0f2f89ecd7fd76b95e955b3f38e0b7e9b9dcb5b..f266223bdc3b1687c3984af7d875094ddf1df033 100644 --- a/lib/models/BlubberThread.php +++ b/lib/models/BlubberThread.php @@ -101,11 +101,11 @@ class BlubberThread extends SimpleORMap implements PrivacyObject /** * @return BlubberThread[] */ - public static function findBySQL($sql, $params = []) + public static function findBySQL($condition, $params = []) { - return parent::findAndMapBySQL(function ($thread) { + return parent::findAndMapBySQL(function (BlubberThread $thread) { return self::upgradeThread($thread); - }, $sql, $params); + }, $condition, $params); } /** diff --git a/lib/models/OERHost.php b/lib/models/OERHost.php index d0b1f6928a68fd0db5a5ae37e1929659679d232f..f4303e33f181a64c07f69fa89e49f74022ac9191 100644 --- a/lib/models/OERHost.php +++ b/lib/models/OERHost.php @@ -46,9 +46,9 @@ class OERHost extends OERIdentity ]); } - public static function findBySQL($sql, $params = []) + public static function findBySQL($condition, $params = []) { - $hosts = parent::findBySQL($sql, $params); + $hosts = parent::findBySQL($condition, $params); foreach ($hosts as $key => $host) { $class = $host['sorm_class']; if ($class && ($class !== 'OERHost') && is_subclass_of($class, 'OERHost')) { diff --git a/lib/models/SimpleORMap.class.php b/lib/models/SimpleORMap.class.php index 7af9dece8403d0177084cb8d8957e2af06813448..80925c32dada9a031d2e46dc6a2542223081b200 100644 --- a/lib/models/SimpleORMap.class.php +++ b/lib/models/SimpleORMap.class.php @@ -484,22 +484,29 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate /** * returns number of records * - * @param ?string $sql sql clause to use on the right side of WHERE - * @param ?array $params params for query + * @param string $condition sql clause to use on the right side of WHERE + * @param array $params params for query * @return int */ - public static function countBySql($sql = '1', $params = []) + public static function countBySql($condition = '1', $params = []) { $db_table = static::db_table(); - $db = DBManager::get(); - $has_join = stripos($sql, 'JOIN '); + + $has_join = stripos($condition, 'JOIN '); if ($has_join === false || $has_join > 10) { - $sql = 'WHERE ' . $sql; + $sql = "SELECT COUNT(*) FROM `{$db_table}` WHERE {$condition}"; + } else { + $pk = implode(',', array_map( + function ($key) use ($db_table) { + return "`{$db_table}`.`{$key}`"; + }, + static::pk() + )); + + $sql = "SELECT COUNT(DISTINCT {$pk}) FROM `{$db_table}` {$condition}"; } - $sql = "SELECT count(*) FROM `" . $db_table . "` " . $sql; - $st = $db->prepare($sql); - $st->execute($params); - return (int)$st->fetchColumn(); + + return (int) DBManager::get()->fetchColumn($sql, $params); } /** @@ -608,26 +615,31 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate /** * returns array of instances of given class filtered by given sql - * @param string $sql sql clause to use on the right side of WHERE - * @param ?array $params parameters for query + * @param string $condition sql clause to use on the right side of WHERE + * @param array $params parameters for query * @return array array of "self" objects */ - public static function findBySQL($sql, $params = []) + public static function findBySQL($condition, $params = []) { $db_table = static::db_table(); - $class = get_called_class(); - $record = new $class(); - $db = DBManager::get(); - $has_join = stripos($sql, 'JOIN '); + + $has_join = stripos($condition, 'JOIN '); if ($has_join === false || $has_join > 10) { - $sql = 'WHERE ' . $sql; + $condition = "WHERE {$condition}"; + $distinct = ''; + } else { + $distinct = 'DISTINCT'; } - $sql = "SELECT `" . $db_table . "`.* FROM `" . $db_table . "` " . $sql; - $ret = []; + $sql = "SELECT {$distinct} `{$db_table}`.* FROM `{$db_table}` {$condition}"; + + $record = new static(); + $record->setNew(false); + $stmt = DBManager::get()->prepare($sql); $stmt->execute($params); $stmt->setFetchMode(PDO::FETCH_INTO , $record); - $record->setNew(false); + + $ret = []; while ($record = $stmt->fetch()) { // Reset all relations $record->cleanup(); @@ -695,23 +707,27 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate * passes objects for given sql through given callback * * @param callable $callable callback which gets the current record as param - * @param string $sql where clause of sql + * @param string $condition where clause of sql * @param ?array $params sql statement parameters * @return integer number of found records */ - public static function findEachBySQL($callable, $sql, $params = []) + public static function findEachBySQL($callable, $condition, $params = []) { - $has_join = stripos($sql, 'JOIN '); + $db_table = static::db_table(); + + $has_join = stripos($condition, 'JOIN '); if ($has_join === false || $has_join > 10) { - $sql = "WHERE {$sql}"; + $condition = "WHERE {$condition}"; + $distinct = ''; + } else { + $distinct = 'DISTINCT'; } + $sql = "SELECT {$distinct} `{$db_table}`.* FROM `{$db_table}` {$condition}"; - $class = get_called_class(); - $record = new $class(); + $record = new static(); $record->setNew(false); - $db_table = static::db_table(); - $st = DBManager::get()->prepare("SELECT `{$db_table}`.* FROM `{$db_table}` {$sql}"); + $st = DBManager::get()->prepare($sql); $st->execute($params); $st->setFetchMode(PDO::FETCH_INTO , $record);