Elgg  Version 3.0
RelationshipsTable.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Database;
3 
4 use Elgg\Database;
10 
21 
23 
27  protected $db;
28 
32  protected $entities;
33 
37  protected $metadata;
38 
42  protected $events;
43 
53  $this->db = $db;
54  $this->entities = $entities;
55  $this->metadata = $metadata;
56  $this->events = $events;
57  }
58 
66  public function get($id) {
67  $row = $this->getRow($id);
68  if (!$row) {
69  return false;
70  }
71 
72  return new \ElggRelationship($row);
73  }
74 
82  public function getRow($id) {
83  $sql = "SELECT * FROM {$this->db->prefix}entity_relationships WHERE id = :id";
84  $params = [
85  ':id' => (int) $id,
86  ];
87  return $this->db->getDataRow($sql, null, $params);
88  }
89 
98  public function delete($id, $call_event = true) {
99  $id = (int) $id;
100 
101  $relationship = $this->get($id);
102 
103  if ($call_event && !$this->events->trigger('delete', 'relationship', $relationship)) {
104  return false;
105  }
106 
107  $sql = "DELETE FROM {$this->db->prefix}entity_relationships WHERE id = :id";
108  $params = [
109  ':id' => $id,
110  ];
111  return (bool) $this->db->deleteData($sql, $params);
112  }
113 
128  public function add($guid_one, $relationship, $guid_two, $return_id = false) {
129  if (strlen($relationship) > \ElggRelationship::RELATIONSHIP_LIMIT) {
130  $msg = "relationship name cannot be longer than " . \ElggRelationship::RELATIONSHIP_LIMIT;
131  throw new \InvalidArgumentException($msg);
132  }
133 
134  // Check for duplicates
135  // note: escape $relationship after this call, we don't want to double-escape
136  if ($this->check($guid_one, $relationship, $guid_two)) {
137  return false;
138  }
139 
140  $sql = "
141  INSERT INTO {$this->db->prefix}entity_relationships
142  (guid_one, relationship, guid_two, time_created)
143  VALUES (:guid1, :relationship, :guid2, :time)
144  ";
145  $params = [
146  ':guid1' => (int) $guid_one,
147  ':guid2' => (int) $guid_two,
148  ':relationship' => $relationship,
149  ':time' => $this->getCurrentTime()->getTimestamp(),
150  ];
151 
152  try {
153  $id = $this->db->insertData($sql, $params);
154  if (!$id) {
155  return false;
156  }
157  } catch (\DatabaseException $e) {
158  $prev = $e->getPrevious();
159  if ($prev instanceof UniqueConstraintViolationException) {
160  // duplicate key error see https://github.com/Elgg/Elgg/issues/9179
161  return false;
162  }
163  throw $e;
164  }
165 
166  $obj = $this->get($id);
167 
168  $result = $this->events->trigger('create', 'relationship', $obj);
169  if (!$result) {
170  $this->delete($id, false);
171  return false;
172  }
173 
174  return $return_id ? $obj->id : true;
175  }
176 
188  public function check($guid_one, $relationship, $guid_two) {
189  $query = "
190  SELECT * FROM {$this->db->prefix}entity_relationships
191  WHERE guid_one = :guid1
192  AND relationship = :relationship
193  AND guid_two = :guid2
194  LIMIT 1
195  ";
196  $params = [
197  ':guid1' => (int) $guid_one,
198  ':guid2' => (int) $guid_two,
199  ':relationship' => $relationship,
200  ];
201  $row = $this->rowToElggRelationship($this->db->getDataRow($query, null, $params));
202  if ($row) {
203  return $row;
204  }
205 
206  return false;
207  }
208 
220  public function remove($guid_one, $relationship, $guid_two) {
221  $obj = $this->check($guid_one, $relationship, $guid_two);
222  if (!$obj instanceof \ElggRelationship) {
223  return false;
224  }
225 
226  return $this->delete($obj->id);
227  }
228 
240  public function removeAll($guid, $relationship = "", $inverse_relationship = false, $type = '') {
241  $guid = (int) $guid;
242  $params = [];
243 
244  if (!empty($relationship)) {
245  $where = "AND er.relationship = :relationship";
246  $params[':relationship'] = $relationship;
247  } else {
248  $where = "";
249  }
250 
251  if (!empty($type)) {
252  if (!$inverse_relationship) {
253  $join = "JOIN {$this->db->prefix}entities e ON e.guid = er.guid_two";
254  } else {
255  $join = "JOIN {$this->db->prefix}entities e ON e.guid = er.guid_one";
256  $where .= " AND ";
257  }
258  $where .= " AND e.type = :type";
259  $params[':type'] = $type;
260  } else {
261  $join = "";
262  }
263 
264  $guid_col = $inverse_relationship ? "guid_two" : "guid_one";
265 
266  $this->db->deleteData("
267  DELETE er FROM {$this->db->prefix}entity_relationships AS er
268  $join
269  WHERE $guid_col = $guid
270  $where
271  ", $params);
272 
273  return true;
274  }
275 
285  public function getAll($guid, $inverse_relationship = false) {
286  $where = ($inverse_relationship ? "guid_two = :guid" : "guid_one = :guid");
287 
288  $query = "SELECT *
289  FROM {$this->db->prefix}entity_relationships
290  WHERE {$where}";
291  $params = [
292  ':guid' => (int) $guid,
293  ];
294 
295  return $this->db->getData($query, [$this, 'rowToElggRelationship'], $params);
296  }
297 
307  public function getEntitiesFromCount(array $options = []) {
308  $options['selects'][] = new SelectClause("COUNT(e.guid) AS total");
309  $options['group_by'][] = new GroupByClause('r.guid_two');
310  $options['order_by'][] = new OrderByClause('total', 'desc');
311 
312  return Entities::find($options);
313  }
314 
322  public function rowToElggRelationship($row) {
323  if ($row instanceof \stdClass) {
324  return new \ElggRelationship($row);
325  }
326 
327  return false;
328  }
329 }
$query
Definition: groups.php:8
$params
Saves global plugin settings.
Definition: save.php:13
static find(array $options=[])
Build and execute a new query from an array of legacy options.
Definition: Repository.php:85
getRow($id)
Get a database row from the relationship table.
rowToElggRelationship($row)
Convert a database row to a new .
getAll($guid, $inverse_relationship=false)
Get all the relationships for a given GUID.
Events service.
check($guid_one, $relationship, $guid_two)
Check if a relationship exists between two entities.
Extends QueryBuilder with SELECT clauses.
getCurrentTime($modifier= '')
Get the (cloned) time.
Definition: TimeUsing.php:27
$guid
Removes an admin notice.
$type
Definition: delete.php:21
Extends QueryBuilder with GROUP BY statements.
$options
Elgg admin footer.
Definition: footer.php:6
$id
River item delete action.
Definition: delete.php:6
add($guid_one, $relationship, $guid_two, $return_id=false)
Create a relationship between two entities.
removeAll($guid, $relationship="", $inverse_relationship=false, $type= '')
Removes all relationships originating from a particular entity.
getEntitiesFromCount(array $options=[])
Gets the number of entities by a the number of entities related to them in a particular way...
__construct(Database $db, EntityTable $entities, MetadataTable $metadata, EventsService $events)
Constructor.
Extends QueryBuilder with ORDER BY clauses.
trait TimeUsing
Adds methods for setting the current time (for testing)
Definition: TimeUsing.php:12
This class interfaces with the database to perform CRUD operations on metadata.
WARNING: API IN FLUX.
Definition: EntityTable.php:38