[3594] | 1 | <?php |
---|
| 2 | /** |
---|
| 3 | * ProjectManager - Constraints storage object |
---|
| 4 | * |
---|
| 5 | * @link http://www.egroupware.org |
---|
| 6 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 7 | * @package projectmanager |
---|
| 8 | * @copyright (c) 2005 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 9 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
---|
| 10 | * @version $Id: class.soconstraints.inc.php 22355 2006-08-26 16:30:45Z ralfbecker $ |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | include_once(PHPGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php'); |
---|
| 14 | |
---|
| 15 | /** |
---|
| 16 | * Constraints storage object of the projectmanager |
---|
| 17 | * |
---|
| 18 | * There are 3 constraint-types: |
---|
| 19 | * - start: PE has to start after an other PE (own pe_id is in pe_id_start) |
---|
| 20 | * - end: PE has to end before the start an other PE (own pe_id is in pe_id_end) |
---|
| 21 | * - milestone: PE has to end before a milestone (own pe_id is in pe_id_end) |
---|
| 22 | * |
---|
| 23 | * Tables: phpgw_pm_constraints |
---|
| 24 | */ |
---|
| 25 | class soconstraints extends so_sql |
---|
| 26 | { |
---|
| 27 | /** |
---|
| 28 | * Constructor, calls the constructor of the extended class |
---|
| 29 | * |
---|
| 30 | * @param int $pm_id pm_id of the project to use, default null |
---|
| 31 | */ |
---|
| 32 | function soconstraints($pm_id=null) |
---|
| 33 | { |
---|
| 34 | $this->so_sql('projectmanager','phpgw_pm_constraints'); |
---|
| 35 | |
---|
| 36 | if ((int) $pm_id) |
---|
| 37 | { |
---|
| 38 | $this->pm_id = (int) $pm_id; |
---|
| 39 | } |
---|
| 40 | } |
---|
| 41 | |
---|
| 42 | /** |
---|
| 43 | * searches db for rows matching searchcriteria, reimplemented to automatic add $this->pm_id |
---|
| 44 | * |
---|
| 45 | * '*' and '?' are replaced with sql-wildcards '%' and '_' |
---|
| 46 | * |
---|
| 47 | * @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!) |
---|
| 48 | * @param boolean $only_keys=true True returns only keys, False returns all cols |
---|
| 49 | * @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY) |
---|
| 50 | * @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num" |
---|
| 51 | * @param string $wildcard='' appended befor and after each criteria |
---|
| 52 | * @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row |
---|
| 53 | * @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together |
---|
| 54 | * @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num) |
---|
| 55 | * @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards |
---|
| 56 | * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or |
---|
| 57 | * "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join! |
---|
| 58 | * @return array of matching rows (the row is an array of the cols) or False |
---|
| 59 | */ |
---|
| 60 | function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='') |
---|
| 61 | { |
---|
| 62 | if (!$this->pm_id && !isset($criteria['pm_id']) && !isset($filter['pm_id'])) |
---|
| 63 | { |
---|
| 64 | $filter['pm_id'] = $this->pm_id; |
---|
| 65 | } |
---|
| 66 | if (isset($criteria['pe_id']) && (int)$criteria['pe_id']) |
---|
| 67 | { |
---|
| 68 | $pe_id = (int) $criteria['pe_id']; |
---|
| 69 | unset($criteria['pe_id']); |
---|
| 70 | } |
---|
| 71 | if (isset($filter['pe_id']) && (int)$filter['pe_id']) |
---|
| 72 | { |
---|
| 73 | $pe_id = (int) $filter['pe_id']; |
---|
| 74 | unset($filter['pe_id']); |
---|
| 75 | } |
---|
| 76 | if ($pe_id) |
---|
| 77 | { |
---|
| 78 | $filter[] = "(pe_id_end=$pe_id OR pe_id_start=$pe_id)"; |
---|
| 79 | |
---|
| 80 | if ($extra_cols && !is_array($extra_cols)) $extra_cols = explode(',',$extra_cols); |
---|
| 81 | // defines 3 constrain-types: milestone, start and end |
---|
| 82 | $extra_cols[] = "CASE WHEN ms_id != 0 THEN 'milestone' WHEN pe_id_start=$pe_id THEN 'start' ELSE 'end' END AS constraint_type"; |
---|
| 83 | if (!$order_by) $order_by = 'constraint_type'; |
---|
| 84 | } |
---|
| 85 | return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | /** |
---|
| 89 | * reads all constraints of a milestone (ms_id given), an element (pe_id given) or a project (pm_id given) |
---|
| 90 | * |
---|
| 91 | * It calls allways search to retrive the data. The form of the data returned depends on the given keys! |
---|
| 92 | * |
---|
| 93 | * @param array $keys array with keys in form internalName => value, may be a scalar value if only one key |
---|
| 94 | * @param string/array $extra_cols string or array of strings to be added to the SELECT, eg. "count(*) as num" |
---|
| 95 | * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or |
---|
| 96 | * @return array/boolean milestones: array with pe_id's, element: array with subarrays for start, end, milestone, |
---|
| 97 | * or same as search($keys) would return |
---|
| 98 | */ |
---|
| 99 | function read($keys,$extra_cols='',$join='') |
---|
| 100 | { |
---|
| 101 | if (!$search =& $this->search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$keys)) |
---|
| 102 | { |
---|
| 103 | return false; |
---|
| 104 | } |
---|
| 105 | $ret = array(); |
---|
| 106 | |
---|
| 107 | if ((int) $keys['ms_id']) |
---|
| 108 | { |
---|
| 109 | foreach($search as $row) |
---|
| 110 | { |
---|
| 111 | $ret[] = $row['pe_id_end']; |
---|
| 112 | } |
---|
| 113 | } |
---|
| 114 | elseif ((int) $keys['pe_id']) |
---|
| 115 | { |
---|
| 116 | foreach($search as $row) |
---|
| 117 | { |
---|
| 118 | switch($row['constraint_type']) |
---|
| 119 | { |
---|
| 120 | case 'milestone': |
---|
| 121 | $ret['milestone'][] = $row['ms_id']; |
---|
| 122 | break; |
---|
| 123 | case 'start': |
---|
| 124 | $ret['start'][] = $row['pe_id_end']; |
---|
| 125 | break; |
---|
| 126 | case 'end': |
---|
| 127 | $ret['end'][] = $row['pe_id_start']; |
---|
| 128 | break; |
---|
| 129 | } |
---|
| 130 | } |
---|
| 131 | } |
---|
| 132 | else |
---|
| 133 | { |
---|
| 134 | $ret =& $search; |
---|
| 135 | } |
---|
| 136 | if ($this->debug) |
---|
| 137 | { |
---|
| 138 | echo "<p>soconstraints::read(".print_r($keys,true).",'$extra_cols','$join')</p>\n"; |
---|
| 139 | _debug_array($ret); |
---|
| 140 | } |
---|
| 141 | return $ret; |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | /** |
---|
| 145 | * saves the given data to the db |
---|
| 146 | * |
---|
| 147 | * @param array $data with either data for one row or null, or |
---|
| 148 | * for the constraints of an elements the keys pe_id, start, end, milestone, or |
---|
| 149 | * for the constraints of a milestone the keys ms_id, pe_id (pm_id can be given or is taken from $this->pm_id) |
---|
| 150 | * @return int 0 on success and errno != 0 else |
---|
| 151 | */ |
---|
| 152 | function save($data=null) |
---|
| 153 | { |
---|
| 154 | if ($this->debug) { echo "<p>soconstraints::save:"; _debug_array($data); } |
---|
| 155 | |
---|
| 156 | // constraints of an element? |
---|
| 157 | if ($data['pe_id']) |
---|
| 158 | { |
---|
| 159 | $pm_id = $data['pm_id'] ? $data['pm_id'] : $this->pm_id; |
---|
| 160 | unset($data['pm_id']); |
---|
| 161 | $pe_id = $data['pe_id']; |
---|
| 162 | unset($data['pe_id']); |
---|
| 163 | |
---|
| 164 | $this->delete(array( |
---|
| 165 | 'pm_id' => $pm_id, |
---|
| 166 | 'pe_id' => $pe_id, |
---|
| 167 | )); |
---|
| 168 | foreach($data as $type => $ids) |
---|
| 169 | { |
---|
| 170 | foreach(is_array($ids) ? $ids : explode(',',$ids) as $id) |
---|
| 171 | { |
---|
| 172 | if (!$id) continue; |
---|
| 173 | |
---|
| 174 | switch($type) |
---|
| 175 | { |
---|
| 176 | case 'milestone': |
---|
| 177 | $row = array( |
---|
| 178 | 'pe_id_end' => $pe_id, |
---|
| 179 | 'pe_id_start' => 0, |
---|
| 180 | 'ms_id' => $id, |
---|
| 181 | ); |
---|
| 182 | break; |
---|
| 183 | case 'start': |
---|
| 184 | $row = array( |
---|
| 185 | 'pe_id_end' => $id, |
---|
| 186 | 'pe_id_start' => $pe_id, |
---|
| 187 | 'ms_id' => 0, |
---|
| 188 | ); |
---|
| 189 | break; |
---|
| 190 | case 'end': |
---|
| 191 | $row = array( |
---|
| 192 | 'pe_id_end' => $pe_id, |
---|
| 193 | 'pe_id_start' => $id, |
---|
| 194 | 'ms_id' => 0, |
---|
| 195 | ); |
---|
| 196 | break; |
---|
| 197 | } |
---|
| 198 | $row['pm_id'] = $pm_id; |
---|
| 199 | |
---|
| 200 | if (($err = parent::save($row))) |
---|
| 201 | { |
---|
| 202 | return $err; |
---|
| 203 | } |
---|
| 204 | } |
---|
| 205 | } |
---|
| 206 | return 0; |
---|
| 207 | } |
---|
| 208 | // constraints of a milestone |
---|
| 209 | if ($data['ms_id'] && is_array($data['pe_id'])) |
---|
| 210 | { |
---|
| 211 | $keys = array( |
---|
| 212 | 'pm_id' => $data['pm_id'] ? $data['pm_id'] : $this->pm_id, |
---|
| 213 | 'pe_id_start' => 0, |
---|
| 214 | 'ms_id' => $data['ms_id'], |
---|
| 215 | ); |
---|
| 216 | $this->delete($keys); |
---|
| 217 | |
---|
| 218 | foreach($data['pe_id'] as $pe_id); |
---|
| 219 | { |
---|
| 220 | $keys['pe_id_end'] = $pe_id; |
---|
| 221 | |
---|
| 222 | if (($err = parent::save($keys))) |
---|
| 223 | { |
---|
| 224 | return $err; |
---|
| 225 | } |
---|
| 226 | } |
---|
| 227 | return 0; |
---|
| 228 | } |
---|
| 229 | return parent::save($data); |
---|
| 230 | } |
---|
| 231 | |
---|
| 232 | /** |
---|
| 233 | * reimplented to delete all constraints from a project-element if a pe_id is given |
---|
| 234 | * |
---|
| 235 | * @param array/int $keys if given array with col => value pairs to characterise the rows to delete or pe_id |
---|
| 236 | * @return int affected rows, should be 1 if ok, 0 if an error |
---|
| 237 | */ |
---|
| 238 | function delete($keys=null) |
---|
| 239 | { |
---|
| 240 | if ($this->debug) echo "<p>soconstraints::delete(".print_r($keys,true).")</p>\n"; |
---|
| 241 | |
---|
| 242 | if (is_numeric($keys) || is_array($keys) && (int) $keys['pe_id']) |
---|
| 243 | { |
---|
| 244 | if (is_array($keys)) |
---|
| 245 | { |
---|
| 246 | $pe_id = (int) $keys['pe_id']; |
---|
| 247 | unset($keys['pe_id']); |
---|
| 248 | } |
---|
| 249 | else |
---|
| 250 | { |
---|
| 251 | $pe_id = (int) $keys; |
---|
| 252 | $keys = array(); |
---|
| 253 | } |
---|
| 254 | $keys[] = "(pe_id_end=$pe_id OR pe_id_start=$pe_id)"; |
---|
| 255 | return $this->db->delete($this->table_name,$keys,__LINE__,__FILE__); |
---|
| 256 | } |
---|
| 257 | return parent::delete($keys); |
---|
| 258 | } |
---|
| 259 | } |
---|