ILIAS  trunk Revision v12.0_alpha-399-g579a087ced2
LazyNewsCollection.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\News\Data;
22
33{
34 private bool $group_files = false;
35 private int $group_forums = 0;
36
37 public function __construct(
38 array $news_ids = [],
39 protected ?\Closure $fetch_callback = null
40 ) {
42
43 foreach ($news_ids as $news_id) {
44 $this->news_items[$news_id] = null;
45 }
46 }
47
51 public function withFetchCallback(\Closure $callback): static
52 {
53 $clone = clone $this;
54 $clone->fetch_callback = $callback;
55 return $clone;
56 }
57
58 public function addNewsItems(array $news_items): static
59 {
60 foreach ($news_items as $id => $item) {
61 if ($item !== null) {
62 $this->addNewsItem($item);
63 } else {
64 $this->news_items[$id] = null;
65 }
66
67 }
68 return $this;
69 }
70
77 public function load(array $news_ids = []): static
78 {
79 if ($this->fetch_callback === null) {
80 throw new \RuntimeException('No fetch callback provided');
81 }
82
83 if (empty($news_ids)) {
84 $news_ids = array_keys(array_filter($this->news_items, fn($item) => $item === null));
85 } else {
86 $news_ids = array_intersect($news_ids, array_keys($this->news_items));
87 }
88
89 if (empty($news_ids)) {
90 return $this;
91 }
92
93 // Check if grouping was requested
94 $context_types = [];
95 if ($this->group_files === true) {
96 $context_types[] = 'file';
97 }
98 if ($this->group_forums > 0) {
99 $context_types[] = 'frm';
100 }
101
102 // Load items from a repository
103 $items = call_user_func($this->fetch_callback, $news_ids, $context_types);
104 $this->addNewsItems($items);
105
106 // Perform re-grouping if necessary
107 $this->regroup($items);
108
109 return $this;
110 }
111
112 /*
113 Grouping
114 */
115
116 public function groupFiles(): static
117 {
118 $this->group_files = true;
119 return $this;
120 }
121
122 public function groupForums(bool $group_posting_sequence): static
123 {
124 $this->group_forums = $group_posting_sequence ? 2 : 1;
125 return $this;
126 }
127
128 private function regroup(array $items): void
129 {
130 // Check if re-grouping is required
131 $needs_file_grouping = false;
132 $needs_forum_grouping = false;
133 foreach ($items as $item) {
134 if ($this->group_files === true && $item->getContextObjType() === 'file') {
135 $needs_file_grouping = true;
136 }
137 if ($this->group_forums > 0 && $item->getContextObjType() === 'frm') {
138 $needs_forum_grouping = true;
139 }
140 }
141
142 // Perform re-grouping
143 if ($needs_file_grouping) {
144 parent::groupFiles();
145 }
146 if ($needs_forum_grouping) {
147 parent::groupForums($this->group_forums === 2);
148 }
149 }
150
151 /*
152 Access & Lazy Loading
153 */
154
159 public function contains(int $news_id): bool
160 {
161 return array_key_exists($news_id, $this->news_items);
162 }
163
167 public function has(int $news_id): bool
168 {
169 return isset($this->news_items[$news_id]);
170 }
171
179 public function getById(int $news_id): ?NewsItem
180 {
181 if (!$this->has($news_id)) {
182 $this->load([$news_id]);
183 }
184
185 return $this->news_items[$news_id] ?? null;
186 }
187
195 public function pick(int $offset): ?NewsItem
196 {
197 $index = max(0, $offset);
198 $news_id = array_keys($this->news_items)[$index] ?? null;
199
200 return $news_id !== null ? $this->getById($news_id) : null;
201 }
202
206 public function pluck(string $key, bool $wrap = false): array
207 {
208 if ($key === 'id') {
209 return $wrap ? array_map(fn($item) => [$item], array_keys($this->news_items)) : array_keys($this->news_items);
210 }
211
212 $this->load();
213 return parent::pluck($key, $wrap);
214 }
215
219 public function toArray(): array
220 {
221 $this->load();
222 return parent::toArray();
223 }
224
228 public function getAggregatedNews(
229 bool $aggregate_files = false,
230 bool $aggregate_forums = false,
231 bool $group_posting_sequence = false
232 ): array {
233 $this->load();
234 return parent::getAggregatedNews($aggregate_files, $aggregate_forums, $group_posting_sequence);
235 }
236
237 public function merge(NewsCollection $other): static
238 {
239 return parent::merge($other)->withFetchCallback($this->fetch_callback);
240 }
241
242 public function exclude(array $news_ids): static
243 {
244 return parent::exclude($news_ids)->withFetchCallback($this->fetch_callback);
245 }
246
247 public function limit(?int $limit): static
248 {
249 return parent::limit($limit)->withFetchCallback($this->fetch_callback);
250 }
251}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
This class is a special implementation of a NewsCollection that is designed to load the complete News...
load(array $news_ids=[])
This method loads the provided NewsItems from the database.
limit(?int $limit)
Limit the number of news items and returns it as a new collection.
contains(int $news_id)
This method returns true if the NewsItem exists in this collection.
addNewsItems(array $news_items)
Add multiple news items efficiently.
pick(int $offset)
This method returns the NewsItem of the given offset of the collection.
groupForums(bool $group_posting_sequence)
exclude(array $news_ids)
Returns a new collection with only the news items that are not in the provided list.
has(int $news_id)
This method returns true if the NewsItem exists in this collection and has been loaded.
toArray()
INFO: This method will load all NewsItems into the collection.
__construct(array $news_ids=[], protected ?\Closure $fetch_callback=null)
merge(NewsCollection $other)
Merge with another collection and returns it as a new collection.
pluck(string $key, bool $wrap=false)
INFO: This method will load all NewsItems into the collection.
getAggregatedNews(bool $aggregate_files=false, bool $aggregate_forums=false, bool $group_posting_sequence=false)
INFO: This method will load all NewsItems into the collection.
getById(int $news_id)
This method returns the NewsItem with the given id or null if it does not exist.
Optimized News Collection with memory-efficient data structures to support large news feeds.
addNewsItem(NewsItem $item)
Add a single news item with indexing.
News Item DTO for transfer of news items.
Definition: NewsItem.php:29
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc