ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
ILIAS\News\Persistence\NewsRepository Class Reference

News Repository provides basic CRUD operations and optimized database access for news operations with batch loading and optimized queries. More...

+ Collaboration diagram for ILIAS\News\Persistence\NewsRepository:

Public Member Functions

 __construct (protected readonly \ilDBInterface $db, protected readonly Factory $factory)
 
 findById (int $news_id)
 
 findByIds (array $news_ids)
 
 filterContext (array $contexts, NewsCriteria $criteria)
 
 loadLazyItems (array $news_ids, array $group_context_types)
 
 findByContextsBatch (array $contexts, NewsCriteria $criteria)
 
 findByContextsBatchLazy (array $contexts, NewsCriteria $criteria)
 
 countByContextsBatch (array $contexts)
 

Private Member Functions

 buildFindQuery (?array $news_ids=null)
 
 buildBatchQuery (array $obj_ids, NewsCriteria $criteria, bool $only_id=false)
 

Static Private Member Functions

static parseTimePeriod (string|int $time_period)
 

Detailed Description

News Repository provides basic CRUD operations and optimized database access for news operations with batch loading and optimized queries.

Definition at line 35 of file NewsRepository.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\News\Persistence\NewsRepository::__construct ( protected readonly \ilDBInterface  $db,
protected readonly Factory  $factory 
)

Definition at line 37 of file NewsRepository.php.

40 {
41 }

Member Function Documentation

◆ buildBatchQuery()

ILIAS\News\Persistence\NewsRepository::buildBatchQuery ( array  $obj_ids,
NewsCriteria  $criteria,
bool  $only_id = false 
)
private

Definition at line 238 of file NewsRepository.php.

238 : array
239 {
240 $values = [];
241 $types = [];
242 $joins = '';
243
244 if ($only_id) {
245 $columns = ['il_news_item.id'];
246 } else {
247 $columns = [
248 'il_news_item.*',
249 'COALESCE((SELECT ref_id FROM object_reference WHERE object_reference.obj_id = il_news_item.context_obj_id LIMIT 1), 0) AS ref_id'
250 ];
251 }
252
253 if ($criteria->isIncludeReadStatus()) {
254 if ($criteria->getReadUserId() === null) {
255 throw new \InvalidArgumentException("Read user id is required for read status");
256 }
257
258 $columns[] = 'il_news_read.user_id AS user_read';
259 $joins .= 'LEFT JOIN il_news_read ON il_news_item.id = il_news_read.news_id AND il_news_read.user_id = %s ';
260
261 $values[] = $criteria->getReadUserId();
262 $types[] = ilDBConstants::T_INTEGER;
263 }
264
265 $query = "SELECT " . join(', ', $columns) . " FROM il_news_item {$joins} WHERE "
266 . $this->db->in('context_obj_id', $obj_ids, false, ilDBConstants::T_INTEGER);
267
268 if ($criteria->getPeriod() > 0) {
269 $query .= " AND creation_date >= %s";
270 $values[] = self::parseTimePeriod($criteria->getPeriod());
272 }
273
274 if ($criteria->getStartDate()) {
275 $query .= " AND creation_date >= %s";
276 $values[] = $criteria->getStartDate()->format('Y-m-d H:i:s');
278 }
279
280 if ($criteria->isNoAutoGenerated()) {
281 $query .= " AND priority = 1 AND content_type = 'text'";
282 }
283
284 if ($criteria->getMinPriority() !== null || $criteria->getMaxPriority() !== null) {
285 $operator = $criteria->getMinPriority() !== null ? '>=' : '<=';
286 $query .= " AND n.priority {$operator} %s";
287 $values[] = $criteria->getMinPriority();
288 $types[] = ilDBConstants::T_INTEGER;
289 }
290
291 if ($criteria->isOnlyPublic()) {
292 $query .= " AND visibility = '" . NEWS_PUBLIC . "'";
293 }
294
295 $query .= " ORDER BY creation_date DESC";
296
297 return [$query, $types, $values];
298 }
static parseTimePeriod(string|int $time_period)
const NEWS_PUBLIC

References ILIAS\News\Data\NewsCriteria\getMaxPriority(), ILIAS\News\Data\NewsCriteria\getMinPriority(), ILIAS\News\Data\NewsCriteria\getPeriod(), ILIAS\News\Data\NewsCriteria\getReadUserId(), ILIAS\News\Data\NewsCriteria\getStartDate(), ILIAS\News\Data\NewsCriteria\isIncludeReadStatus(), ILIAS\News\Data\NewsCriteria\isNoAutoGenerated(), ILIAS\News\Data\NewsCriteria\isOnlyPublic(), NEWS_PUBLIC, ILIAS\News\Persistence\NewsRepository\parseTimePeriod(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TIMESTAMP.

Referenced by ILIAS\News\Persistence\NewsRepository\findByContextsBatch(), and ILIAS\News\Persistence\NewsRepository\findByContextsBatchLazy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildFindQuery()

ILIAS\News\Persistence\NewsRepository::buildFindQuery ( ?array  $news_ids = null)
private

Definition at line 140 of file NewsRepository.php.

140 : string
141 {
142 $query = "
143 SELECT il_news_item.*,
144 COALESCE(
145 (SELECT ref_id FROM object_reference WHERE object_reference.obj_id = il_news_item.context_obj_id LIMIT 1),
146 0
147 ) AS ref_id
148 FROM il_news_item ";
149
150 if ($news_ids !== null) {
151 $query .= "WHERE " . $this->db->in('id', $news_ids, false, \ilDBConstants::T_INTEGER);
152 }
153
154 return $query;
155 }

References ilDBConstants\T_INTEGER.

Referenced by ILIAS\News\Persistence\NewsRepository\findByIds(), and ILIAS\News\Persistence\NewsRepository\loadLazyItems().

+ Here is the caller graph for this function:

◆ countByContextsBatch()

ILIAS\News\Persistence\NewsRepository::countByContextsBatch ( array  $contexts)
Parameters
NewsContext[]$contexts
Returns
array{0: NewsContext, 1: int}[]

Definition at line 216 of file NewsRepository.php.

216 : array
217 {
218 $context_map = [];
219 foreach ($contexts as $context) {
220 $context_map[$context->getObjId()] = $context;
221 }
222
223 $in_clause = $this->db->in('context_obj_id', array_keys($context_map), false, ilDBConstants::T_INTEGER);
224 $query = "SELECT context_obj_id, count(context_obj_id) as count FROM il_news_item WHERE {$in_clause} GROUP BY context_obj_id";
225 $result = $this->db->query($query);
226
227 $count = [];
228 foreach ($this->db->fetchAll($result) as $row) {
229 $count[] = [
230 $context_map[$row['context_obj_id']],
231 $row['count']
232 ];
233 }
234
235 return $count;
236 }

References ilDBConstants\T_INTEGER.

◆ filterContext()

ILIAS\News\Persistence\NewsRepository::filterContext ( array  $contexts,
NewsCriteria  $criteria 
)
Parameters
NewsContext[]$contexts
Returns
NewsContext[]

Definition at line 71 of file NewsRepository.php.

71 : array
72 {
73 $obj_ids = array_map(fn($context) => $context->getObjId(), $contexts);
74
75 $values = [];
76 $types = [];
77 $query = "SELECT DISTINCT (context_obj_id) AS obj_id FROM il_news_item WHERE ";
78 $query .= $this->db->in('context_obj_id', $obj_ids, false, \ilDBConstants::T_INTEGER);
79
80 if ($criteria->getPeriod() > 0) {
81 $query .= " AND creation_date >= %s";
82 $values[] = self::parseTimePeriod($criteria->getPeriod());
84 }
85
86 if ($criteria->getStartDate()) {
87 $query .= " AND creation_date >= %s";
88 $values[] = $criteria->getStartDate()->format('Y-m-d H:i:s');
90 }
91
92 $result = $this->db->queryF($query, $types, $values);
93 $needed_obj_ids = array_column($this->db->fetchAll($result), 'obj_id', 'obj_id');
94
95 return array_filter($contexts, fn($context) => isset($needed_obj_ids[$context->getObjId()]));
96 }

References ILIAS\News\Data\NewsCriteria\getPeriod(), ILIAS\News\Data\NewsCriteria\getStartDate(), ILIAS\News\Persistence\NewsRepository\parseTimePeriod(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TIMESTAMP.

+ Here is the call graph for this function:

◆ findByContextsBatch()

ILIAS\News\Persistence\NewsRepository::findByContextsBatch ( array  $contexts,
NewsCriteria  $criteria 
)
Parameters
NewsContext[]$contexts

Definition at line 160 of file NewsRepository.php.

160 : NewsCollection
161 {
162 if (empty($contexts)) {
163 return new NewsCollection();
164 }
165
166 $obj_ids = array_map(fn($context) => $context->getObjId(), $contexts);
167 $result = $this->db->queryF(...$this->buildBatchQuery($obj_ids, $criteria));
168
169 $items = [];
170 $user_read = [];
171
172 while ($row = $this->db->fetchAssoc($result)) {
173 $items[] = $this->factory->newsItem($row);
174 $user_read[$row['id']] = isset($row['user_read']) && $row['user_read'] !== 0;
175 }
176
177 $collection = new NewsCollection($items);
178 if ($criteria->isIncludeReadStatus()) {
179 $collection->setUserReadStatus($criteria->getReadUserId(), $user_read);
180 }
181
182 return $collection;
183 }
factory()
buildBatchQuery(array $obj_ids, NewsCriteria $criteria, bool $only_id=false)

References ILIAS\News\Persistence\NewsRepository\buildBatchQuery(), factory(), ILIAS\News\Data\NewsCriteria\getReadUserId(), and ILIAS\News\Data\NewsCriteria\isIncludeReadStatus().

+ Here is the call graph for this function:

◆ findByContextsBatchLazy()

ILIAS\News\Persistence\NewsRepository::findByContextsBatchLazy ( array  $contexts,
NewsCriteria  $criteria 
)
Parameters
NewsContext[]$contexts

Definition at line 188 of file NewsRepository.php.

188 : NewsCollection
189 {
190 if (empty($contexts)) {
191 return new NewsCollection();
192 }
193
194 $obj_ids = array_map(fn($context) => $context->getObjId(), $contexts);
195 $result = $this->db->queryF(...$this->buildBatchQuery($obj_ids, $criteria, true));
196
197 $items = [];
198 $user_read = [];
199 while ($row = $this->db->fetchAssoc($result)) {
200 $items[] = $row['id'];
201 $user_read[$row['id']] = isset($row['user_read']) && $row['user_read'] !== 0;
202 }
203
204 $collection = new LazyNewsCollection($items, fn(...$args) => $this->loadLazyItems(...$args));
205 if ($criteria->isIncludeReadStatus()) {
206 $collection->setUserReadStatus($criteria->getReadUserId(), $user_read);
207 }
208
209 return $collection;
210 }
loadLazyItems(array $news_ids, array $group_context_types)

References ILIAS\News\Persistence\NewsRepository\buildBatchQuery(), ILIAS\News\Data\NewsCriteria\getReadUserId(), ILIAS\News\Data\NewsCriteria\isIncludeReadStatus(), and ILIAS\News\Persistence\NewsRepository\loadLazyItems().

+ Here is the call graph for this function:

◆ findById()

ILIAS\News\Persistence\NewsRepository::findById ( int  $news_id)

Definition at line 43 of file NewsRepository.php.

43 : ?NewsItem
44 {
45 $query = "SELECT * FROM il_news_item WHERE id = %s";
46 $result = $this->db->queryF($query, [\ilDBConstants::T_INTEGER], [$news_id]);
47
48 return $result->numRows()
49 ? $this->factory->newsItem($this->db->fetchAssoc($result))
50 : null;
51 }

References factory(), and ilDBConstants\T_INTEGER.

+ Here is the call graph for this function:

◆ findByIds()

ILIAS\News\Persistence\NewsRepository::findByIds ( array  $news_ids)
Parameters
int[]$news_ids
Returns
NewsItem[]

Definition at line 57 of file NewsRepository.php.

57 : array
58 {
59 if (empty($news_ids)) {
60 return [];
61 }
62
63 $result = $this->db->query($this->buildFindQuery($news_ids));
64 return array_map(fn($row) => $this->factory->newsItem($row), $this->db->fetchAll($result));
65 }

References ILIAS\News\Persistence\NewsRepository\buildFindQuery(), and factory().

+ Here is the call graph for this function:

◆ loadLazyItems()

ILIAS\News\Persistence\NewsRepository::loadLazyItems ( array  $news_ids,
array  $group_context_types 
)
Parameters
int[]$news_ids
string[]$group_context_types
Returns
NewsItem[]

Definition at line 104 of file NewsRepository.php.

104 : array
105 {
106 if (empty($news_ids)) {
107 return [];
108 }
109
110 $result = $this->db->query($this->buildFindQuery($news_ids));
111 $news_items = [];
112 $additional_obj_ids = [];
113
114 foreach ($this->db->fetchAll($result) as $row) {
115 $news_item = $this->factory->newsItem($row);
116
117 if (in_array($news_item->getContextObjType(), $group_context_types)) {
118 $additional_obj_ids[] = $news_item->getContextObjId();
119 }
120
121 $news_items[] = $news_item;
122 }
123
124 if (empty($additional_obj_ids)) {
125 return $news_items;
126 }
127
128 // Fetch all additional items with same context_obj_id for grouping
129 $query = $this->buildFindQuery()
130 . " WHERE " . $this->db->in('context_obj_id', $additional_obj_ids, false, \ilDBConstants::T_INTEGER)
131 . " AND " . $this->db->in('id', $news_ids, true, \ilDBConstants::T_INTEGER);
132 $result = $this->db->query($query);
133
134 return array_merge(
135 $news_items,
136 array_map(fn($row) => $this->factory->newsItem($row), $this->db->fetchAll($result))
137 );
138 }

References ILIAS\News\Persistence\NewsRepository\buildFindQuery(), factory(), and ilDBConstants\T_INTEGER.

Referenced by ILIAS\News\Persistence\NewsRepository\findByContextsBatchLazy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseTimePeriod()

static ILIAS\News\Persistence\NewsRepository::parseTimePeriod ( string|int  $time_period)
staticprivate

Definition at line 300 of file NewsRepository.php.

300 : string
301 {
302 // time period is a number of days
303 if (is_numeric($time_period) && $time_period > 0) {
304 return date('Y-m-d H:i:s', time() - ($time_period * 24 * 60 * 60));
305 }
306
307 // time period is datetime (string)
308 if (preg_match("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/", $time_period)) {
309 return $time_period;
310 }
311
312 return '';
313 }

Referenced by ILIAS\News\Persistence\NewsRepository\buildBatchQuery(), and ILIAS\News\Persistence\NewsRepository\filterContext().

+ Here is the caller graph for this function:

The documentation for this class was generated from the following file: