BAOBAB
tco_collection.interface.php
Go to the documentation of this file.
1 <?php
2 /***************************************************************************************************************************/
26 defined( 'LGV_DBF_CATCHER' ) or die ( 'Cannot Execute Directly' ); // Makes sure that this file is in the correct context.
27 
28 require_once(CO_Config::db_classes_class_dir().'/co_ll_location.class.php');
29 
30 /***************************************************************************************************************************/
38  protected $_container;
39 
40  /***********************/
45  protected function _scrub() {
46  if (isset($this->context['children_ids'])) {
47  $children_ids = $this->context['children_ids'];
48 
49  if (isset($children_ids) && is_array($children_ids) && count($children_ids)) {
50  $new_ids = Array();
51  foreach ($children_ids as $id) {
52  $id = intval($id); // Belt and suspenders.
53  if ($this->get_access_object()->item_exists($id)) {
54  $new_ids[] = $id;
55  }
56  }
57  $new_ids = array_unique($new_ids);
58  sort($new_ids);
59  $this->context['children_ids'] = $new_ids;
60  $this->update_db();
61  }
62  } else {
63  $this->_container = Array();
64  }
65  }
66 
67  /***********************/
73  protected function _set_up_container() {
74  if (isset($this->context['children_ids'])) {
75  $children_ids = $this->context['children_ids'];
76 
77  if (isset($children_ids) && is_array($children_ids) && count($children_ids)) {
78  $this->_container = $this->get_access_object()->get_multiple_data_records_by_id($children_ids);
79  }
80  }
81  }
82 
83  /***********************/
87  public function reload_collection() {
88  $this->_scrub(); // Garbage collection.
89  $this->_set_up_container();
90  }
91 
92  /***********************/
102  public function insertElement( $in_element,
103  $in_before_index = -1,
104  $dont_update = false
105  ) {
106  $ret = false;
107 
108  if ($in_element instanceof A_CO_DB_Table_Base) {
109  if ($this->user_can_write() ) { // You cannot add to a collection if you don't have write privileges.
110  if (!(method_exists($in_element, 'insertElement') && $this->areYouMyDaddy($in_element))) { // Make sure that a collection isn't already in the woodpile somewhere.
111  $id = intval($in_element->id());
112  if (!isset($this->_container) || !is_array($this->_container)) {
113  $this->_container = [];
114  }
115 
116  if (!isset($this->context['children_ids']) || !is_array($this->context['children_ids'])) {
117  $this->context['children_ids'] = [];
118  }
119 
120  if (!in_array($id, $this->context['children_ids'])) {
121  if ((-1 == $in_before_index) || (NULL == $in_before_index) || !isset($in_before_index)) {
122  $in_before_index = count($this->_container);
123  }
124 
125  $before_array = Array();
126 
127  if ($in_before_index) {
128  $before_array = array_slice($this->_container, 0, $in_before_index, false);
129  }
130 
131  $after_array = Array();
132 
133  if ($in_before_index < count($this->_container)) {
134  $end_count = count($this->_container) - $in_before_index;
135  $after_array = array_slice($this->_container, $end_count, false);
136  }
137 
138  $element_array = Array($in_element);
139 
140  $merged = array_merge($before_array, $element_array, $after_array);
141 
142  $this->_container = $merged;
143 
144  $ret = true;
145  if (!isset($this->context['children_ids'])) {
146  $this->context['children_ids'] = Array();
147  }
148 
149  $ids = array_map('intval', $this->context['children_ids']);
150  if (!in_array($id, $ids)) {
151  $ids[] = $id;
152  $ids = array_unique($ids);
153  sort($ids);
154  $this->context['children_ids'] = $ids;
155  }
156  }
157  }
158 
159  if ($ret && !$dont_update) {
160  $ret = $this->update_db();
161  }
162  } else {
166  }
167  }
168 
169  return $ret;
170  }
171 
172  /***********************/
182  public function insertElements( $in_element_array,
183  $in_before_index = -1
184  ) {
185  $ret = false;
186 
187  if ($this->user_can_write() ) { // You cannot add to a collection if you don't have write privileges.
188  $i_have_a_daddy = false;
189 
190  if (is_array($in_element_array) && count($in_element_array)) {
191  foreach ($in_element_array as $element) {
192  // We can't insert nested collections.
193  if (method_exists($element, 'insertElement') && $this->areYouMyDaddy($element)) {
194  $i_have_a_daddy = true;
195  break;
196  }
197  }
198  }
199 
200  if (!$i_have_a_daddy) { // DON'T CROSS THE STREAMS!
201  if (!isset($this->_container) || !is_array($this->_container)) {
202  $this->_container = Array();
203  }
204 
205  if ((-1 == $in_before_index) || (NULL == $in_before_index) || !isset($in_before_index)) {
206  $in_before_index = count($this->_container);
207  }
208 
209  $before_array = Array();
210 
211  if ($in_before_index) {
212  $before_array = array_slice($this->_container, 0, $in_before_index, false);
213  }
214 
215  $after_array = Array();
216 
217  if ($in_before_index < count($this->_container)) {
218  $end_count = count($this->_container) - $in_before_index;
219  $after_array = array_slice($this->_container, $end_count, false);
220  }
221 
222  if (!isset($in_element_array) || !is_array($in_element_array) || !count($in_element_array)) {
223  $in_element_array = [];
224  }
225 
226  $merged = array_merge($before_array, $in_element_array, $after_array);
227 
228  $unique = array();
229 
230  if (is_array($merged) && count($merged)) {
231  foreach ($merged as $current) {
232  if (!in_array($current, $unique)) {
233  $unique[] = $current;
234  }
235  }
236  }
237 
238  $this->_container = $unique;
239 
240  $ret = true;
241 
242  if (!isset($this->context['children_ids'])) {
243  $this->context['children_ids'] = Array();
244  }
245 
246  foreach ($in_element_array as $element) {
247  $id = intval($element->id());
248  $ids = array_map('intval', $this->context['children_ids']);
249  if (!in_array($id, $ids)) {
250  $ids[] = $id;
251  $ids = array_unique($ids);
252  sort($ids);
253  $this->context['children_ids'] = $ids;
254  }
255  }
256  }
257 
258  if ($ret) {
259  $ret = $this->update_db();
260  }
261  } else {
265  }
266 
267  return $ret;
268  }
269 
270  /***********************/
279  public function deleteElements( $in_first_index,
280  $in_deletion_length
281  ) {
282  $ret = false;
283 
284  if ($this->user_can_write() ) { // You cannot add to a collection if you don't have write privileges.
285  $element_ids = Array(); // We will keep track of which IDs we delete, so we can delete them from our context variable.
286 
287  // If negative, we're going backwards.
288  if (0 > $in_deletion_length) {
289  $in_deletion_length = abs($in_deletion_length);
290  $in_first_index -= ($in_deletion_length - 1);
291  $in_first_index = max(0, $in_first_index); // Make sure we stay within the lane markers.
292  }
293 
294  $last_index_plus_one = min(count($this->_container), $in_first_index + $in_deletion_length);
295 
296  // We simply record the IDs of each of the elements we'll be deleting.
297  for ($i = $in_first_index; $i < $last_index_plus_one; $i++) {
298  $element = $this->_container[$i];
299  $element_ids[] = $element->id();
300  }
301 
302  if ($in_deletion_length == count($element_ids)) { // Belt and suspenders. Make sure we are actually deleting the requested elements.
303  $new_container = Array();
304 
305  // We build a new container that doesn't have the deleted elements.
306  foreach ($this->_container as $element) {
307  $element_id = $element->id();
308 
309  if (!in_array($element_id, $element_ids)) {
310  $new_container[] = $element_id;
311  }
312  }
313 
314  $new_list = Array();
315 
316  // We build a new list that doesn't have the deleted element IDs.
317  while ($element_id = array_shift($this->context['children_ids'])) {
318  if (!in_array($element_id, $element_ids)) {
319  $new_list[] = $element_id;
320  }
321  }
322 
323  $new_list = array_unique($new_list);
324  sort($new_list);
325  $this->context['children_ids'] = $new_list;
326 
327  $ret = $this->update_db();
328  if (!$this->_batch_mode) {
329  $this->_scrub();
330  }
331  }
332  } else {
336  }
337 
338  return $ret;
339  }
340 
341  /***********************/
348  public function deleteElement( $in_index
349  ) {
350  return $this->deleteElements($in_index, 1);
351  }
352 
353  /***********************/
360  public function deleteThisElement( $in_element
361  ) {
362  $ret = false;
363  $index = $this->indexOfThisElement($in_element);
364 
365  if (false !== $index) {
366  $ret = $this->deleteElement(intval($index));
367  }
368 
369  return $ret;
370  }
371 
372  /***********************/
383  public function appendElement( $in_element
384  ) {
385  return $this->insertElement($in_element, -1);
386  }
387 
388  /***********************/
396  public function appendElements( $in_element_array
397  ) {
398  return $this->insertElements($in_element_array, -1);
399  }
400 
401  /***********************/
408  public function deleteAllChildren() {
409  if ($this->user_can_write() ) { // You cannot delete from a collection if you don't have write privileges.
410  $new_list = [];
411 
412  if (isset($this->context['children_ids']) && is_array($this->context['children_ids']) && count($this->context['children_ids'])) {
413  foreach ($this->context['children_ids'] as $child_id) {
414  // We save items in the list that we can't see.
415  if ($this->get_access_object()->item_exists($child_id) && !$this->get_access_object()->can_i_see_this_data_record($child_id)) {
416  $new_list[] = $child_id;
417  }
418  }
419  }
420 
421  $this->_children = Array();
422  $this->context['children_ids'] = $new_list;
423  return $this->update_db();
424  }
425 
426  return false;
427  }
428 
429  /***********************/
433  public function indexOfThisElement( $in_element
434  ) {
435  return array_search($in_element, $this->children());
436  }
437 
438  /***********************/
445  public function whosYourDaddy( $in_element
446  ) {
447  $ret = NULL;
448  $id = intval($in_element->id());
449 
450  $ret_array = $this->recursiveMap(function($instance, $hierarchy_level, $parent){
451  $id = intval($instance->id());
452  return Array($id, $parent);
453  });
454 
455  if (isset($ret_array) && is_array($ret_array) && count($ret_array)) {
456  $ret = Array();
457  foreach ($ret_array as $item) {
458  if ($item[0] == $id) {
459  $ret[] = $item[1];
460  }
461  }
462  }
463 
464  return $ret;
465  }
466 
467  /***********************/
473  public function areYouMyDaddy( $in_element,
474  $full_hierachy = true
475  ) {
476  $ret = false;
477 
478  $children = $this->children();
479 
480  if (isset($children) && is_array($children) && count($children)) {
481  foreach ($children as $object) {
482  if ($object == $in_element) {
483  $ret = true;
484  break;
485  } else {
486  if ($full_hierachy && method_exists($object, 'areYouMyDaddy')) {
487  if ($object->areYouMyDaddy($in_element)) {
488  $ret = true;
489  break;
490  }
491  }
492  }
493  }
494  }
495 
496  return $ret;
497  }
498 
499  /***********************/
506  public function map( $in_function
507  ) {
508  $ret = Array();
509 
510  $children = $this->children();
511 
512  foreach ($children as $child) {
513  $result = $in_function($child);
514  $ret[] = $result;
515  }
516 
517  return self::class;
518  }
519 
520  /***********************/
527  public function recursiveMap( $in_function,
528  $in_hierarchy_level = 0,
529  $in_parent_object = NULL,
530  $loop_stopper = Array()
536  ) {
537  $in_hierarchy_level = intval($in_hierarchy_level);
538  $ret = Array($in_function($this, $in_hierarchy_level, $in_parent_object));
539  $children = $this->children();
540 
541  foreach ($children as $child) {
542  if (method_exists($child, 'recursiveMap')) {
543  if (!in_array($child->id(), $loop_stopper)) {
544  $loop_stopper[] = $child->id();
545  $result = $child->recursiveMap($in_function, ++$in_hierarchy_level, $this, $loop_stopper);
546  }
547  } else {
548  $result = Array($in_function($child, ++$in_hierarchy_level, $this));
549  }
550  $ret = array_merge($ret, $result);
551  }
552 
553  return $ret;
554  }
555 
556  /***********************/
564  public function count( $is_recursive = false
565  ) {
566  $children = $this->children();
567  $my_count = 0;
568 
569  if (isset($children) && is_array($children)) {
570  $my_count = count($children);
571 
572  if ($is_recursive) {
573  foreach ($children as $child) {
574  if (method_exists($child, 'count')) {
575  $my_count += $child->count($is_recursive);
576  }
577  }
578  }
579  }
580 
581  return $my_count;
582  }
583 
584  /***********************/
591  public function children() {
592  if (!isset($this->_container) || !$this->_container || (!count($this->_container))) {
593  $this->_scrub();
594  $this->_set_up_container();
595  }
596  return $this->_container;
597  }
598 
599  /***********************/
606  public function children_ids( $in_raw = false
607  ) {
608  $ret = [];
609  if ($in_raw && $this->get_access_object()->god_mode()) { // God gets it all.
610  if (isset($this->context['children'])) {
611  return (array_map('intval', explode(',', $this->context['children'])));
612  } else {
613  return [];
614  }
615  }
616 
617  $this->_scrub();
618  if (isset($this->context['children_ids']) && is_array($this->context['children_ids']) && count ($this->context['children_ids'])) {
619  $ids = $this->context['children_ids'];
620  if ($this->get_access_object()->god_mode()) { // God gets it all.
621  $ret = $ids;
622  } else {
623  foreach ($ids as $id) {
624  if ($this->get_access_object()->item_exists($id, true)) {
625  $ret[] = intval($id);
626  }
627  }
628  }
629  }
630 
631  return $ret;
632  }
633 
634  /***********************/
640  public function set_children_ids( $in_new_ids
641  ) {
642  $ret = false;
643 
644  if ($this->get_access_object()->god_mode()) {
645  $this->_children = Array();
646  $this->context['children'] = implode(',', $in_new_ids);
647  unset($this->context['children_ids']);
648  $ret = $this->update_db();
649  }
650 
651  return $ret;
652  }
653 
654  /***********************/
658  public function who_are_my_parents() {
659  $ret = [];
660 
661  $result = $this->get_access_object()->generic_search(Array('access_class' => Array('%_Collection%', 'use_like' => 1)));
662 
663  if (isset($result) && is_array($result) && count($result)) {
664  foreach ($result as $object) {
665  if (($object instanceof CO_Main_DB_Record) && method_exists($object, 'areYouMyDaddy')) {
666  if ($object->areYouMyDaddy($this, false)) {
667  $ret[] = $object;
668  }
669  }
670  }
671  }
672 
673  return $ret;
674  }
675 
676  /***********************/
683  public function getHierarchy( $loop_stopper = Array()
689  ) {
690  $this->_scrub();
691 
692  $instance = Array('object' => $this);
693 
694  if (method_exists($this, 'children') && count($this->children())) {
695  $children = $this->children();
696  $instance['children'] = Array();
697 
698  foreach ($children as $child) {
699  if (method_exists($child, 'getHierarchy')) {
700  if (!in_array($child->id(), $loop_stopper)) {
701  $loop_stopper[] = $child->id();
702  $instance['children'][] = $child->getHierarchy($loop_stopper);
703  }
704  } else {
705  $instance['children'][] = Array('object' => $child);
706  }
707  }
708  }
709 
710  return $instance;
711  }
712 }
appendElements( $in_element_array)
set_children_ids( $in_new_ids)
areYouMyDaddy( $in_element, $full_hierachy=true)
getHierarchy( $loop_stopper=Array())
deleteElements( $in_first_index, $in_deletion_length)
children_ids( $in_raw=false)
count( $is_recursive=false)
$_container
This contains instances of the records referenced by the IDs stored in the object.
indexOfThisElement( $in_element)
insertElement( $in_element, $in_before_index=-1, $dont_update=false)
deleteThisElement( $in_element)
insertElements( $in_element_array, $in_before_index=-1)
recursiveMap( $in_function, $in_hierarchy_level=0, $in_parent_object=NULL, $loop_stopper=Array())
static $co_collection_error_code_user_not_authorized
Definition: common.inc.php:60
static $co_collection_error_desc_user_not_authorized
Definition: en.php:42
static $co_collection_error_name_user_not_authorized
Definition: en.php:41
This class provides a general error report, with file, method and error information.
Definition: error.class.php:32