Blame view

framework/model/HasManyList.php 3.13 KB
0084d336   Administrator   Importers CRUD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  <?php
  
  /**
   * Subclass of {@link DataList} representing a has_many relation.
   *
   * @package framework
   * @subpackage model
   */
  class HasManyList extends RelationList {
  
  	protected $foreignKey;
  	
  	/**
  	 * Create a new HasManyList object.
  	 * Generation of the appropriate record set is left up to the caller, using the normal
  	 * {@link DataList} methods.  Addition arguments are used to support {@@link add()}
  	 * and {@link remove()} methods.
  	 * 
  	 * @param string $dataClass The class of the DataObjects that this will list.
  	 * @param string $foreignKey The name of the foreign key field to set the ID filter against.
  	 */
  	public function __construct($dataClass, $foreignKey) {
  		parent::__construct($dataClass);
  
  		$this->foreignKey = $foreignKey;
  	}
  
  	/**
  	 * Gets the field name which holds the related object ID.
  	 *
  	 * @return string
  	 */
  	public function getForeignKey() {
  		return $this->foreignKey;
  	}
  
  	protected function foreignIDFilter($id = null) {
  		if ($id === null) $id = $this->getForeignID();
  
  		// Apply relation filter
  		if(is_array($id)) {
  			return "\"$this->foreignKey\" IN ('" .
  				implode("', '", array_map('Convert::raw2sql', $id)) . "')";
  		} else if($id !== null){
  			return "\"$this->foreignKey\" = '" . 
  				Convert::raw2sql($id) . "'";
  		}
  	}
  
  	/**
  	 * Adds the item to this relation.
  	 *
  	 * It does so by setting the relationFilters.
  	 *
  	 * @param $item The DataObject to be added, or its ID 
  	 */
  	public function add($item) {
  		if(is_numeric($item)) {
  			$item = DataObject::get_by_id($this->dataClass, $item);
  		} else if(!($item instanceof $this->dataClass)) {
  			user_error("HasManyList::add() expecting a $this->dataClass object, or ID value", E_USER_ERROR);
  		}
  
  		$foreignID = $this->getForeignID();
  
  		// Validate foreignID
  		if(!$foreignID) {
  			user_error("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
  			return;
  		}
  		if(is_array($foreignID)) {
  			user_error("ManyManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
  			return;
  		}
  
  		$fk = $this->foreignKey;
  		$item->$fk = $foreignID;
  
  		$item->write();
  	}
  
  	/**
  	 * Remove an item from this relation.
  	 *
  	 * Doesn't actually remove the item, it just clears the foreign key value.
  	 *
  	 * @param $itemID The ID of the item to be removed.
  	 */
  	public function removeByID($itemID) {
  		$item = $this->byID($itemID);
  
  		return $this->remove($item);
  	}
  	
  	/**
  	 * Remove an item from this relation.
  	 * Doesn't actually remove the item, it just clears the foreign key value.
  	 * 
  	 * @param $item The DataObject to be removed
  	 * @todo Maybe we should delete the object instead? 
  	 */
  	public function remove($item) {
  		if(!($item instanceof $this->dataClass)) {
  			throw new InvalidArgumentException("HasManyList::remove() expecting a $this->dataClass object, or ID",
  				E_USER_ERROR);
  		}
  
  		// Don't remove item which doesn't belong to this list
  		$foreignID = $this->getForeignID();
  		$foreignKey = $this->getForeignKey();
  
  		if(	empty($foreignID)
  			|| (is_array($foreignID) && in_array($item->$foreignKey, $foreignID))
  			|| $foreignID == $item->$foreignKey
  		) {
  			$item->$foreignKey = null;
  			$item->write();
  		}
  
  	}
  }