Elgg  Version master
AnnotationsTable.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Database;
4 
5 use Elgg\Database;
9 
16 
17  use TimeUsing;
18 
19  public const TABLE_NAME = 'annotations';
20 
21  public const DEFAULT_JOIN_ALIAS = 'a_table';
22 
29  public function __construct(protected Database $db, protected EventsService $events) {
30  }
31 
39  public function get(int $id): ?\ElggAnnotation {
40  $qb = Select::fromTable(self::TABLE_NAME);
41  $qb->select('*');
42 
43  $where = new AnnotationWhereClause();
44  $where->ids = $id;
45  $qb->addClause($where);
46 
47  $row = $this->db->getDataRow($qb);
48  return !empty($row) ? new \ElggAnnotation($row) : null;
49  }
50 
58  public function delete(\ElggAnnotation $annotation): bool {
59  if (!$annotation->canEdit()) {
60  return false;
61  }
62 
63  if (!$this->events->trigger('delete', 'annotation', $annotation)) {
64  return false;
65  }
66 
67  $qb = Delete::fromTable(self::TABLE_NAME);
68  $qb->where($qb->compare('id', '=', $annotation->id, ELGG_VALUE_INTEGER));
69  $deleted = $this->db->deleteData($qb);
70 
71  if ($deleted) {
73  'annotation_id' => $annotation->id,
74  'limit' => false,
75  ]);
76  }
77 
78  return $deleted !== false;
79  }
80 
89  public function create(\ElggAnnotation $annotation, \ElggEntity $entity): int|bool {
90  if ($annotation->id) {
91  return $this->update($annotation);
92  }
93 
94  if (is_null($annotation->owner_guid) || is_null($annotation->name) || is_null($annotation->value)) {
95  return false;
96  }
97 
98  $annotation->entity_guid = $entity->guid;
99 
100  // @todo It looks like annotations permissions are not being checked anywhere...
101  // Uncomment once tests have been updated
102  // See #11418
103  //if (!$entity->canAnnotate(0, $annotation->name)) {
104  // return false;
105  //}
106 
107  if (!$this->events->triggerBefore('create', 'annotation', $annotation)) {
108  return false;
109  }
110 
111  $time_created = $this->getCurrentTime()->getTimestamp();
112 
113  $qb = Insert::intoTable(self::TABLE_NAME);
114  $qb->values([
115  'entity_guid' => $qb->param($annotation->entity_guid, ELGG_VALUE_INTEGER),
116  'name' => $qb->param($annotation->name, ELGG_VALUE_STRING),
117  'value' => $qb->param($annotation->value, $annotation->value_type === 'text' ? ELGG_VALUE_STRING : ELGG_VALUE_INTEGER),
118  'value_type' => $qb->param($annotation->value_type, ELGG_VALUE_STRING),
119  'owner_guid' => $qb->param($annotation->owner_guid, ELGG_VALUE_INTEGER),
120  'time_created' => $qb->param($time_created, ELGG_VALUE_INTEGER),
121  'access_id' => $qb->param($annotation->access_id, ELGG_VALUE_INTEGER),
122  ]);
123 
124  $result = $this->db->insertData($qb);
125  if ($result === false) {
126  return false;
127  }
128 
129  $annotation->id = $result;
130  $annotation->time_created = $time_created;
131 
132  if (!$this->events->trigger('create', 'annotation', $annotation)) {
134 
135  return false;
136  }
137 
138  $this->events->triggerAfter('create', 'annotation', $annotation);
139 
140  return $result;
141  }
142 
152  public function update(\ElggAnnotation $annotation): bool {
153  if (!$annotation->canEdit()) {
154  return false;
155  }
156 
157  if (is_null($annotation->owner_guid) || is_null($annotation->name) || is_null($annotation->value)) {
158  return false;
159  }
160 
161  if (!$this->events->triggerBefore('update', 'annotation', $annotation)) {
162  return false;
163  }
164 
165  $qb = Update::table(self::TABLE_NAME);
166  $qb->set('name', $qb->param($annotation->name, ELGG_VALUE_STRING))
167  ->set('value', $qb->param($annotation->value, $annotation->value_type === 'integer' ? ELGG_VALUE_INTEGER : ELGG_VALUE_STRING))
168  ->set('value_type', $qb->param($annotation->value_type, ELGG_VALUE_STRING))
169  ->set('access_id', $qb->param($annotation->access_id, ELGG_VALUE_INTEGER))
170  ->set('owner_guid', $qb->param($annotation->owner_guid, ELGG_VALUE_INTEGER))
171  ->where($qb->compare('id', '=', $annotation->id, ELGG_VALUE_INTEGER));
172 
173  $result = $this->db->updateData($qb);
174 
175  if ($result === false) {
176  return false;
177  }
178 
179  $this->events->trigger('update', 'annotation', $annotation);
180  $this->events->triggerAfter('update', 'annotation', $annotation);
181 
182  return $result;
183  }
184 
193  public function disable(\ElggAnnotation $annotation): bool {
194  if ($annotation->enabled === 'no') {
195  return true;
196  }
197 
198  if (!$annotation->canEdit()) {
199  return false;
200  }
201 
202  if (!_elgg_services()->events->trigger('disable', $annotation->getType(), $annotation)) {
203  return false;
204  }
205 
206  if ($annotation->id) {
207  $qb = Update::table(self::TABLE_NAME);
208  $qb->set('enabled', $qb->param('no', ELGG_VALUE_STRING))
209  ->where($qb->compare('id', '=', $annotation->id, ELGG_VALUE_INTEGER));
210 
211  if (!$this->db->updateData($qb)) {
212  return false;
213  }
214  }
215 
216  $annotation->enabled = 'no';
217 
218  return true;
219  }
220 
229  public function enable(\ElggAnnotation $annotation): bool {
230  if ($annotation->enabled == 'yes') {
231  return true;
232  }
233 
234  if (!$annotation->canEdit()) {
235  return false;
236  }
237 
238  if (!$this->events->trigger('enable', $annotation->getType(), $annotation)) {
239  return false;
240  }
241 
242  if ($annotation->id) {
243  $qb = Update::table(self::TABLE_NAME);
244  $qb->set('enabled', $qb->param('yes', ELGG_VALUE_STRING))
245  ->where($qb->compare('id', '=', $annotation->id, ELGG_VALUE_INTEGER));
246 
247  if (!$this->db->updateData($qb)) {
248  return false;
249  }
250  }
251 
252  $annotation->enabled = 'yes';
253 
254  return true;
255  }
256 
266  public function find(array $options = []) {
267  $options['metastring_type'] = 'annotations';
268  $options = QueryOptions::normalizeMetastringOptions($options);
269 
270  return Annotations::find($options);
271  }
272 
287  public function deleteAll(array $options): bool {
288  if (!$this->isValidOptionsForBatchOperation($options)) {
289  return false;
290  }
291 
292  $options['batch'] = true;
293  $options['batch_size'] = 50;
294  $options['batch_inc_offset'] = false;
295 
296  $annotations = Annotations::find($options);
297  $count = $annotations->count();
298 
299  if (!$count) {
300  return true;
301  }
302 
303  $success = 0;
304  foreach ($annotations as $annotation) {
305  if ($annotation->delete()) {
306  $success++;
307  }
308  }
309 
310  return $success === $count;
311  }
312 
321  public function disableAll(array $options): bool {
322  if (!$this->isValidOptionsForBatchOperation($options)) {
323  return false;
324  }
325 
326  // if we can see hidden (disabled) we need to use the offset
327  // otherwise we risk an infinite loop if there are more than 50
328  $inc_offset = _elgg_services()->session_manager->getDisabledEntityVisibility();
329 
330  $options['batch'] = true;
331  $options['batch_size'] = 50;
332  $options['batch_inc_offset'] = $inc_offset;
333 
334  $annotations = Annotations::find($options);
335  $count = $annotations->count();
336 
337  if (!$count) {
338  return true;
339  }
340 
341  $success = 0;
342  foreach ($annotations as $annotation) {
343  if ($annotation->disable()) {
344  $success++;
345  }
346  }
347 
348  return $success === $count;
349  }
350 
359  public function enableAll(array $options): bool {
360  if (!$this->isValidOptionsForBatchOperation($options)) {
361  return false;
362  }
363 
364  $options['batch'] = true;
365  $options['batch_size'] = 50;
366 
367  $annotations = Annotations::find($options);
368  $count = $annotations->count();
369 
370  if (!$count) {
371  return true;
372  }
373 
374  $success = 0;
375  foreach ($annotations as $annotation) {
376  if ($annotation->enable()) {
377  $success++;
378  }
379  }
380 
381  return $success === $count;
382  }
383 
391  protected function isValidOptionsForBatchOperation(array $options): bool {
392  $required = [
393  'guid', 'guids',
394  'annotation_owner_guid', 'annotation_owner_guids',
395  'annotation_name', 'annotation_names',
396  'annotation_value', 'annotation_values',
397  ];
398 
399  foreach ($required as $key) {
400  // check that it exists and is something.
401  if (isset($options[$key]) && !elgg_is_empty($options[$key])) {
402  return true;
403  }
404  }
405 
406  return false;
407  }
408 
418  public function exists(int $entity_guid, string $name, int $owner_guid): bool {
419  if (!$owner_guid) {
420  return false;
421  }
422 
423  $qb = Select::fromTable(self::TABLE_NAME);
424  $qb->select('id');
425  $qb->where($qb->compare('owner_guid', '=', $owner_guid, ELGG_VALUE_INTEGER))
426  ->andWhere($qb->compare('entity_guid', '=', $entity_guid, ELGG_VALUE_INTEGER))
427  ->andWhere($qb->compare('name', '=', $name, ELGG_VALUE_STRING));
428 
429  $result = $this->db->getDataRow($qb);
430 
431  return !empty($result) && $result->id;
432  }
433 }
getType()
Return a type of extension.
disableAll(array $options)
Disables annotations based on $options.
$deleted
Definition: delete.php:25
enable(\ElggAnnotation $annotation)
Enable the annotation.
exists(int $entity_guid, string $name, int $owner_guid)
Check to see if a user has already created an annotation on an object.
if($id< 1) $annotation
Definition: delete.php:11
static find(array $options=[])
Build and execute a new query from an array of legacy options.
Definition: Repository.php:110
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
static table($table, $alias=null)
{}
Definition: Update.php:13
The Elgg database.
Definition: Database.php:25
isValidOptionsForBatchOperation(array $options)
Checks if there are some constraints on the options array for potentially dangerous operations...
if(!$user instanceof\ElggUser) $time_created
Definition: online.php:13
const ELGG_VALUE_INTEGER
Value types.
Definition: constants.php:111
elgg_delete_river(array $options=[])
Delete river items based on $options.
Definition: river.php:135
Entity Annotation.
Events service.
Builds queries for matching annotations against their properties.
canEdit(int $user_guid=0)
Determines whether or not the user can edit this annotation.
trait TimeUsing
Adds methods for setting the current time (for testing)
Definition: TimeUsing.php:10
$options
Elgg admin footer.
Definition: footer.php:6
elgg_is_empty($value)
Check if a value isn&#39;t empty, but allow 0 and &#39;0&#39;.
Definition: input.php:176
$entity_guid
Action for adding and editing comments.
Definition: save.php:6
getCurrentTime($modifier= '')
Get the (cloned) time.
Definition: TimeUsing.php:25
$owner_guid
__construct(protected Database $db, protected EventsService $events)
Constructor.
static intoTable($table)
{}
Definition: Insert.php:13
$entity
Definition: reset.php:8
disable(\ElggAnnotation $annotation)
Disable the annotation.
deleteAll(array $options)
Deletes annotations based on $options.
foreach($recommendedExtensions as $extension) if(empty(ini_get('session.gc_probability'))||empty(ini_get('session.gc_divisor'))) $db
create(\ElggAnnotation $annotation,\ElggEntity $entity)
Create a new annotation and return its ID.
$count
Definition: ban.php:24
update(\ElggAnnotation $annotation)
Store updated annotation in the database.
find(array $options=[])
Returns annotations.
if($container instanceof ElggGroup &&$container->guid!=elgg_get_page_owner_guid()) $key
Definition: summary.php:44
static fromTable($table, $alias=null)
{}
Definition: Select.php:13
const ELGG_VALUE_STRING
Definition: constants.php:112
$required
Definition: label.php:12
_elgg_services()
Get the global service provider.
Definition: elgglib.php:346
Interfaces with the database to perform CRUD operations on annotations.
enableAll(array $options)
Enables annotations based on $options.
$id
Generic annotation delete action.
Definition: delete.php:6
$qb
Definition: queue.php:12
static fromTable($table, $alias=null)
{}
Definition: Delete.php:13
elgg_delete_annotation_by_id(int $id)
Deletes an annotation using its ID.
Definition: annotations.php:27