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 
194  public function find(array $options = []) {
195  $options['metastring_type'] = 'annotations';
196  $options = QueryOptions::normalizeMetastringOptions($options);
197 
198  return Annotations::find($options);
199  }
200 
215  public function deleteAll(array $options): bool {
216  if (!$this->isValidOptionsForBatchOperation($options)) {
217  return false;
218  }
219 
220  $options['batch'] = true;
221  $options['batch_size'] = 50;
222  $options['batch_inc_offset'] = false;
223 
224  $annotations = Annotations::find($options);
225  $count = $annotations->count();
226 
227  if (!$count) {
228  return true;
229  }
230 
231  $success = 0;
232  foreach ($annotations as $annotation) {
233  if ($annotation->delete()) {
234  $success++;
235  }
236  }
237 
238  return $success === $count;
239  }
240 
248  protected function isValidOptionsForBatchOperation(array $options): bool {
249  $required = [
250  'guid', 'guids',
251  'annotation_owner_guid', 'annotation_owner_guids',
252  'annotation_name', 'annotation_names',
253  'annotation_value', 'annotation_values',
254  ];
255 
256  foreach ($required as $key) {
257  // check that it exists and is something.
258  if (isset($options[$key]) && !elgg_is_empty($options[$key])) {
259  return true;
260  }
261  }
262 
263  return false;
264  }
265 
275  public function exists(int $entity_guid, string $name, int $owner_guid): bool {
276  if (!$owner_guid) {
277  return false;
278  }
279 
280  $qb = Select::fromTable(self::TABLE_NAME);
281  $qb->select('id');
282  $qb->where($qb->compare('owner_guid', '=', $owner_guid, ELGG_VALUE_INTEGER))
283  ->andWhere($qb->compare('entity_guid', '=', $entity_guid, ELGG_VALUE_INTEGER))
284  ->andWhere($qb->compare('name', '=', $name, ELGG_VALUE_STRING));
285 
286  $result = $this->db->getDataRow($qb);
287 
288  return !empty($result) && $result->id;
289  }
290 }
static table(string $table)
Returns a QueryBuilder for updating data in a given table.
Definition: Update.php:17
$deleted
Definition: delete.php:25
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
The Elgg database.
Definition: Database.php:26
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
static intoTable(string $table)
Returns a QueryBuilder for inserting data in a given table.
Definition: Insert.php:17
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
if($who_can_change_language=== 'nobody') elseif($who_can_change_language=== 'admin_only'&&!elgg_is_admin_logged_in()) $options
Definition: language.php:20
$owner_guid
__construct(protected Database $db, protected EventsService $events)
Constructor.
$entity
Definition: reset.php:8
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
static fromTable(string $table)
Returns a QueryBuilder for deleting data from a given table.
Definition: Delete.php:17
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
const ELGG_VALUE_STRING
Definition: constants.php:112
$required
Definition: label.php:12
static fromTable(string $table, string $alias=null)
Returns a QueryBuilder for selecting data from a given table.
Definition: Select.php:18
Interfaces with the database to perform CRUD operations on annotations.
$id
Generic annotation delete action.
Definition: delete.php:6
$qb
Definition: queue.php:12
elgg_delete_annotation_by_id(int $id)
Deletes an annotation using its ID.
Definition: annotations.php:27