1<?php 2/** 3 * Extension of the Horde_Share_Object class for storing share information in 4 * the Sqlng driver. 5 * 6 * @author Jan Schneider <jan@horde.org> 7 * @package Share 8 */ 9class Horde_Share_Object_Sqlng extends Horde_Share_Object_Sql 10{ 11 /** 12 * Serializable version. 13 */ 14 const VERSION = 1; 15 16 /** 17 * A list of available permission. 18 * 19 * This is necessary to unset certain permission when updating existing 20 * share objects. 21 * 22 * @param array 23 */ 24 public $availablePermissions = array(); 25 26 /** 27 * Constructor. 28 * 29 * @param array $data Share data array. 30 */ 31 public function __construct($data) 32 { 33 parent::__construct($data); 34 $this->_setAvailablePermissions(); 35 } 36 37 /** 38 * Serialize this object. 39 * 40 * @return string The serialized data. 41 */ 42 public function serialize() 43 { 44 return serialize(array( 45 self::VERSION, 46 $this->data, 47 $this->_shareCallback, 48 $this->availablePermissions, 49 )); 50 } 51 52 /** 53 * Reconstruct the object from serialized data. 54 * 55 * @param string $data The serialized data. 56 */ 57 public function unserialize($data) 58 { 59 $data = @unserialize($data); 60 if (!is_array($data) || 61 !isset($data[0]) || 62 ($data[0] != self::VERSION)) { 63 throw new Exception('Cache version change'); 64 } 65 66 $this->data = $data[1]; 67 if (empty($data[2])) { 68 throw new Exception('Missing callback for Horde_Share_Object unserializing'); 69 } 70 $this->_shareCallback = $data[2]; 71 $this->availablePermissions = $data[3]; 72 } 73 74 /** 75 * Saves the current attribute values. 76 */ 77 protected function _save() 78 { 79 $db = $this->getShareOb()->getStorage(); 80 $table = $this->getShareOb()->getTable(); 81 82 // Build the parameter arrays for the sql statement. 83 $fields = $params = array(); 84 foreach ($this->getShareOb()->toDriverCharset($this->data) as $key => $value) { 85 if ($key != 'share_id' && $key != 'perm' && $key != 'share_flags') { 86 $fields[] = $key; 87 $params[] = $value; 88 } 89 } 90 91 $fields[] = 'share_flags'; 92 $flags = 0; 93 if (!empty($this->data['perm']['users'])) { 94 $flags |= Horde_Share_Sql::SQL_FLAG_USERS; 95 } 96 if (!empty($this->data['perm']['groups'])) { 97 $flags |= Horde_Share_Sql::SQL_FLAG_GROUPS; 98 } 99 $params[] = $flags; 100 101 // Insert new share record, or update existing 102 if (empty($this->data['share_id'])) { 103 foreach ($this->data['perm'] as $base => $perms) { 104 if ($base == 'type' || $base == 'users' || $base == 'groups') { 105 continue; 106 } 107 foreach (Horde_Share_Sqlng::convertBitmaskToArray($perms) as $perm) { 108 $fields[] = 'perm_' . $base . '_' . $perm; 109 $params[] = true; 110 } 111 } 112 $sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (?' . str_repeat(', ?', count($fields) - 1) . ')'; 113 try { 114 $this->data['share_id'] = $db->insert($sql, $params); 115 } catch (Horde_Db_Exception $e) { 116 throw new Horde_Share_Exception($e); 117 } 118 } else { 119 foreach ($this->data['perm'] as $base => $perms) { 120 if ($base == 'type' || $base == 'users' || $base == 'groups') { 121 continue; 122 } 123 $perms = array_flip(Horde_Share_Sqlng::convertBitmaskToArray($perms)); 124 foreach ($this->availablePermissions as $perm) { 125 $fields[] = 'perm_' . $base . '_' . $perm; 126 $params[] = isset($perms[$perm]) ? true : false; 127 } 128 } 129 $sql = 'UPDATE ' . $table . ' SET ' . implode(' = ?, ', $fields) . ' = ? WHERE share_id = ?'; 130 $params[] = $this->data['share_id']; 131 try { 132 $db->update($sql, $params); 133 } catch (Horde_Db_Exception $e) { 134 throw new Horde_Share_Exception($e); 135 } 136 } 137 138 // Update the share's user permissions 139 $db->delete('DELETE FROM ' . $table . '_users WHERE share_id = ?', array($this->data['share_id'])); 140 if (!empty($this->data['perm']['users'])) { 141 $data = array(); 142 foreach ($this->data['perm']['users'] as $user => $perms) { 143 $fields = $params = array(); 144 foreach (Horde_Share_Sqlng::convertBitmaskToArray($perms) as $perm) { 145 $fields[] = 'perm_' . $perm; 146 $params[] = true; 147 } 148 if (!$fields) { 149 continue; 150 } 151 array_unshift($params, $user); 152 array_unshift($params, $this->data['share_id']); 153 $db->insert('INSERT INTO ' . $table . '_users (share_id, user_uid, ' . implode(', ', $fields) . ') VALUES (?, ?' . str_repeat(', ?', count($fields)) . ')', $params); 154 } 155 } 156 157 // Update the share's group permissions 158 $db->delete('DELETE FROM ' . $table . '_groups WHERE share_id = ?', array($this->data['share_id'])); 159 if (!empty($this->data['perm']['groups'])) { 160 $data = array(); 161 foreach ($this->data['perm']['groups'] as $group => $perms) { 162 $fields = $params = array(); 163 foreach (Horde_Share_Sqlng::convertBitmaskToArray($perms) as $perm) { 164 $fields[] = 'perm_' . $perm; 165 $params[] = true; 166 } 167 if (!$fields) { 168 continue; 169 } 170 array_unshift($params, $group); 171 array_unshift($params, $this->data['share_id']); 172 $db->insert('INSERT INTO ' . $table . '_groups (share_id, group_uid, ' . implode(', ', $fields) . ') VALUES (?, ?' . str_repeat(', ?', count($fields)) . ')', $params); 173 } 174 } 175 176 return true; 177 } 178 179 /** 180 * Sets the permission of this share. 181 * 182 * @param Horde_Perms_Permission $perm Permission object. 183 * @param boolean $update Should the share be saved 184 * after this operation? 185 */ 186 public function setPermission($perm, $update = true) 187 { 188 parent::setPermission($perm, false); 189 $this->_setAvailablePermissions(); 190 if ($update) { 191 $this->save(); 192 } 193 } 194 195 /** 196 * Populates the $availablePermissions property with all seen permissions. 197 * 198 * This is necessary because the share tables might be extended with 199 * arbitrary permissions. 200 */ 201 protected function _setAvailablePermissions() 202 { 203 $available = array(); 204 foreach ($this->availablePermissions as $perm) { 205 $available[$perm] = true; 206 } 207 foreach ($this->data['perm'] as $base => $perms) { 208 if ($base == 'type') { 209 continue; 210 } 211 if ($base != 'users' && $base != 'groups') { 212 $perms = array($perms); 213 } 214 foreach ($perms as $subperms) { 215 foreach (Horde_Share_Sqlng::convertBitmaskToArray($subperms) as $perm) { 216 $available[$perm] = true; 217 } 218 } 219 } 220 $this->availablePermissions = array_keys($available); 221 } 222} 223