CMS  Version 3.9
connectable_manager.inc
Go to the documentation of this file.
1 <?php
8 interface Connectable
9 {
10  function getConnectableIcon();
14  function getConnectableTitle();
15  function getConnectableHome();
17 }
18 
26 {
27  static $connectables = array();
28  static $classLookup = array();
29  static $contextRouter = "";
30 
31  function ConnectableManager()
32  {
33 
34  }
35 
36  static function setDefaults()
37  {
38  //TODO: Set default configuration parameters here
39  }
40 
41  static function onInitialize()
42  {
43  ComponentManager::fireEvent("RegisterConnectables");
44  }
45 
51  static function registerConnectable($connectable, $targets)
52  {
54  $obj = new $connectable;
55  ConnectableManager::$classLookup[$obj->getPrimaryKey()] = $connectable;
56  }
57 
63  static function getConnectableFromRequest()
64  {
65  foreach (ConnectableManager::$classLookup as $primaryKey => $class)
66  {
67  if (array_key_exists($primaryKey, $_GET))
68  {
69  $id = checkNumeric($_GET[$primaryKey]);
70  $obj = new $class;
71 
72  if ($id) $obj->load($id);
73  return $obj;
74  }
75  }
76 
77  return null;
78  }
79 
87  static function instantiate($class, $id)
88  {
89  if (!array_key_exists($class, ConnectableManager::$connectables))
90  {
91  throw new FakoliException(htmlSafe($class)." is not a registered Connectable");
92  }
93 
94  checkNumeric($id);
95 
96  $obj = new $class;
97  if ($id) $obj->load($id);
98  return $obj;
99  }
100 
107  static function canConnect($source, $target)
108  {
109  if (is_object($source)) $source = get_class($source);
110  if (is_object($target)) $target = get_class($target);
111 
113 
114  foreach($targets as $t)
115  {
116  if ($t == $target) return true;
117  }
118 
119  return false;
120  }
121 
127  static function connectionExists($source, $target)
128  {
129  return Query::create(ConnectionRecord, "WHERE source_class=:sc AND source_id=:si AND target_class=:tc AND target_id=:ti")
130  ->bind(":sc", get_class($source),
131  ":si", $source->get($source->getPrimaryKey()),
132  ":tc", get_class($target),
133  ":ti", $target->get($target->getPrimaryKey()))
134  ->exists();
135  }
136 
144  static function addConnection($source, $target)
145  {
147 
148  $sourceDefn = ConnectableManager::$connectables[get_class($source)];
149  $targetDefn = ConnectableManager::$connectables[get_class($target)];
150 
151  $sourceClass = get_class($source);
152  $targetClass = get_class($target);
153 
154  if (!$sourceDefn || !$targetDefn)
155  {
156  throw new FakoliException("Attempt to link an object that is not a registered Connectable");
157  }
158 
159  if (!ConnectableManager::canConnect($sourceClass, $targetClass))
160  {
161  throw new FakoliException("Cannot create a link between a $sourceClass and a $targetClass");
162  }
163 
164  $record = new ConnectionRecord();
165  $record->source_class = $sourceClass;
166  $record->source_id = $source->get($source->getPrimaryKey());
167  $record->target_class = $targetClass;
168  $record->target_id = $target->get($target->getPrimaryKey());
169 
170  $record->save();
171 
172  if (ConnectableManager::canConnect($targetClass, $sourceClass))
173  {
174  // Also insert back-link
175  $record = new ConnectionRecord();
176  $record->source_class = $sourceClass;
177  $record->source_id = $target->get($target->getPrimaryKey());
178  $record->target_class = $targetClass;
179  $record->target_id = $source->get($source->getPrimaryKey());
180 
181  $record->save();
182  }
183  }
184 
191  static function removeConnection($source, $target)
192  {
193  $record = new ConnectionRecord();
194  $sourceID = checkNumeric($source->get($source->getPrimaryKey()));
195  $targetID = checkNumeric($target->get($target->getPrimaryKey()));
196 
197  $sourceClass = get_class($source);
198  $targetClass = get_class($target);
199 
200  $record->delete("WHERE (source_class='{$sourceClass}' AND source_id={$sourceID} AND target_class='{$targetClass}' AND target_id={$targetID}') " .
201  "OR (source_class='{$targetClass}' AND source_id={$targetID} AND target_class='{$sourceClass}' AND target_id={$sourceID})");
202  }
203 
210  static function removeConnections($source, $targetClass)
211  {
212  $record = new ConnectionRecord();
213  $sourceClass = get_class($source);
214  $sourceID = checkNumeric($source->get($source->getPrimaryKey()));
215 
216  $record->delete("WHERE (source_class='{$sourceClass}' AND source_id={$sourceID} AND target_class='{$targetClass}') " .
217  "OR (source_class='{$targetClass}' AND target_class='{$sourceClass}' AND target_id={$sourceID})");
218  }
219 
226  static function removeAllConnections($object)
227  {
228  $record = new ConnectionRecord();
229  $objectID = $object->get($object->getPrimaryKey());
230  $class = get_class($object);
231  $record->delete("WHERE (source_class='{$class}' AND source_id={$objectID}) OR (target_class='{$class}' AND target_id={$objectID})");
232  }
233 
240  static function getTargetClasses($sourceItem)
241  {
242  $sourceClass = is_object($sourceItem) ? get_class($sourceItem) : $sourceItem;
243 
244  if (!array_key_exists($sourceClass, ConnectableManager::$connectables))
245  {
246  throw new FakoliException("$sourceClass is not a registered connectable class");
247  }
248 
249  return ConnectableManager::$connectables[$sourceClass];
250 
251  }
252 
253 
262  static function getConnectedItems($sourceItem, $targetClass, $constraint = "")
263  {
264  $query = ConnectableManager::generateConnectedQuery($sourceItem, $targetClass, $constraint);
265  return Query::create($targetClass, $query)
266  ->bind(":sc", get_class($sourceItem), ":si", $sourceItem->get($sourceItem->getPrimaryKey()), ":tc", $targetClass)
267  ->execute();
268  }
269 
278  static function getConnectedItemCount($sourceItem, $targetClass, $constraint = "")
279  {
280  $query = ConnectableManager::generateConnectedQuery($sourceItem, $targetClass, $constraint);
281  return Query::create($targetClass, $query)
282  ->bind(":sc", get_class($sourceItem), ":si", $sourceItem->get($sourceItem->getPrimaryKey()), ":tc", $targetClass)
283  ->executeValue("COUNT(1)");
284  }
285 
286  private static function generateConnectedQuery($sourceItem, $targetClass, $constraint)
287  {
288  $constraint = preg_replace("/^\\s*WHERE/i", " AND", $constraint);
289 
290  $sourceClass = get_class($sourceItem);
291 
292  $targetClasses = ConnectableManager::getTargetClasses($sourceItem);
293 
294  trace(print_r($targetClasses, true), 3);
295 
296  if (!ConnectableManager::canConnect($sourceClass, $targetClass))
297  {
298  throw new FakoliException("$sourceClass cannot be connected to $targetClass");
299  }
300 
301  $obj = new $targetClass;
302  $pk = $obj->getPrimaryKey();
303 
304  return "WHERE $pk in (SELECT target_id FROM connection_record WHERE source_class=:sc AND source_id=:si AND target_class = :tc) $constraint";
305  }
306  static function upgradeComponent($version)
307  {
309  $mgr->upgrade($version);
310  }
311 }
312 ?>
$constraint
static fireEvent($event, $parameter=null, $mustBeConsumed=false)
Fire an event to all subscribers as detailed in their manifests.
Provides a central management class for event handlers and common functionality for the connectable c...
static getConnectableFromRequest()
Create and populate a Connectable DataItem based on its primary key as passed in on the requesting UR...
static canConnect($source, $target)
Determine whether two objects or classes can connect based on the registered connectable map.
static instantiate($class, $id)
Safely instantiate a Connectable.
static addConnection($source, $target)
Add a connection between the given source and target objects.
static removeConnection($source, $target)
Remove any connection that exists between the source and target object (including back-links if they ...
static getConnectedItems($sourceItem, $targetClass, $constraint="")
Returns the connected items for the specified source that are of the specified class.
static removeAllConnections($object)
Remove all the connections to and from the given object.
static removeConnections($source, $targetClass)
Remove any connection that exists between the source and objects of the specified target class (inclu...
static getConnectedItemCount($sourceItem, $targetClass, $constraint="")
Returns the number of connected items for the specified source that are of the specified class.
static registerConnectable($connectable, $targets)
Register a connectable class and the list of classes it can connect with.
static upgradeComponent($version)
static $connectables
Connectable type map defining which items can be connected together.
static connectionExists($source, $target)
Check whether a connection exists between the given source and target objects.
static getTargetClasses($sourceItem)
Return an array of connectable target classes for the specified item.
static $classLookup
Look-up table of connectable classes from their primary keys.
FakoliException is the base exception class for all Fakoli errors.
Definition: core.inc:53
getConnectableLink($source)
getConnectableHome()
getConnectableConstraint()
populateSelectionTable($table)
getConnectableTitle()
getConnectableIcon()
getConnectableDisabledIcon()