Overview

Packages

  • Beatnik
  • None

Classes

  • Autogenerate
  • Beatnik
  • Beatnik_Driver
  • Beatnik_Driver_ldap2dns
  • Beatnik_Driver_pdnsgsql
  • Beatnik_Driver_sql
  • DeleteRecord
  • EditRecord
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Beatnik_Driver:: defines an API implementing astorage backends for Beatnik.
  4:  *
  5:  * Copyright 2005-2007 Alkaloid Networks <http://www.alkaloid.net>
  6:  *
  7:  * See the enclosed file COPYING for license information (GPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  9:  *
 10:  * @author  Ben Klang <ben@alkaloid.net>
 11:  * @package Beatnik
 12:  */
 13: class Beatnik_Driver {
 14: 
 15:     /**
 16:      * Hash containing connection parameters.
 17:      *
 18:      * @var array $_params
 19:      */
 20:     var $_params = array();
 21: 
 22:     function Beatnik_Driver($params = array())
 23:     {
 24:         $this->_params = $params;
 25:     }
 26: 
 27:     /**
 28:      * Get any record types  available specifically in this driver.
 29:      *
 30:      * @return array Records available only to this driver
 31:      */
 32:     function getRecDriverTypes()
 33:     {
 34:         return array();
 35:     }
 36: 
 37: 
 38:     /**
 39:      * Get any fields available specifically in this driver by record type.
 40:      *
 41:      * @param string $type Record type for which fields should be returned
 42:      *
 43:      * @return array Fields specific to this driver
 44:      */
 45:     function getRecDriverFields($type) {
 46: 
 47:         return array();
 48:     }
 49: 
 50:     /**
 51:      * Gets domains from driver for which the user has the specified
 52:      * permission.
 53:      *
 54:      * @param int $perms  Permissions filter for domain result set
 55:      *
 56:      * @return array  Possibly empty array of domain information
 57:      */
 58:     function getDomains($perms = Horde_Perms::SHOW)
 59:     {
 60:         try {
 61:             $domains = $this->_getDomains();
 62:         } catch (Exception $e) {
 63:             $GLOBALS['notification']->push($e->getMessage(), 'horde.warning');
 64:             return array();
 65:         }
 66: 
 67:         if (!$GLOBALS['registry']->isAdmin() &&
 68:             !$GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission('beatnik:domains', $GLOBALS['registry']->getAuth(), $perms)) {
 69:             foreach ($domains as $id => $domain) {
 70:                 if (!$GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission('beatnik:domains:' . $domain['zonename'], $GLOBALS['registry']->getAuth(), $perms)) {
 71:                     unset($domains[$id]);
 72:                 }
 73:             }
 74:         }
 75: 
 76:         if (empty($domains)) {
 77:             $GLOBALS['notification']->push(_("You are not permitted to view any domains."), 'horde.warning');
 78:             return array();
 79:         }
 80: 
 81:         // Sort the resulting list by domain name
 82:         // TODO: Allow sorting by other columns
 83:         require_once 'Horde/Array.php';
 84:         Horde_Array::arraySort($domains, 'zonename');
 85: 
 86:         return $domains;
 87:     }
 88: 
 89:     /**
 90:      * Return SOA for a single domain
 91:      *
 92:      * @param string $domain   Domain for which to return SOA information
 93:      *
 94:      * @return mixed           Array of SOA information for domain
 95:      */
 96:     function getDomain($domainname)
 97:     {
 98:         $domains = $this->getDomains(Horde_Perms::SHOW | Horde_Perms::READ);
 99: 
100:         foreach ($domains as $domain) {
101:             if ($domain['zonename'] == $domainname) {
102:                 return $domain;
103:             }
104:         }
105:         throw new Beatnik_Exception(sprintf(_("Unable to read requested domain %s"), $domainname));
106:     }
107: 
108:     /**
109:      * Gets a specific record from the backend.  This method may be overridden
110:      * in specific backend drivers if there is a performance or other benefit
111:      * for doing so.
112:      *
113:      * @return array  Array of type and record information
114:      */
115:     function getRecord($id)
116:     {
117:         if ($id === null) {
118:             return false;
119:         }
120: 
121:         $zonedata = $this->getRecords($_SESSION['beatnik']['curdomain']['zonename']);
122:         // Search for the requested record id
123:         foreach ($zonedata as $type => $records) {
124:             foreach ($records as $record) {
125:                 if ($record['id'] == $id) {
126:                     // Found the record we're looking for
127:                     break;
128:                 }
129:                 $type = false;
130:                 $record = false;
131:             }
132:             if ($record) {
133:                 // Record found in nested loop.  Break out of this one too.
134:                 break;
135:             }
136:         }
137: 
138:         if (!$record) {
139:             // We may be editing the SOA.  See if it matches
140:             $record = $this->getDomain($_SESSION['beatnik']['curdomain']['zonename']);
141:             if ($record['id'] == $id) {
142:                 $type = 'soa';
143:             } else {
144:                 $GLOBALS['notification']->push(_("Unable to locate requested record."), 'horde.error');
145:                 $type = false;
146:                 $record = false;
147:             }
148:         }
149: 
150:         return array($type, $record);
151:     }
152: 
153:     /**
154:      * Try to determinate if the autogenerated record
155:      * already exits.  This method may be overridden in the backend driver
156:      * for performance or other reasons.
157:      *
158:      * @param array $record record to check
159:      *
160:      * @return boolean if records exits or or not
161:      */
162:     function recordExists($record, $rectype)
163:     {
164:         try {
165:             $zonedata = $this->getRecords($_SESSION['beatnik']['curdomain']['zonename']);
166:         } catch (Exception $e) {
167:             $notification->push($e, 'horde.error');
168:             Horde::url('listzones.php')->redirect;
169:         }
170: 
171:         if (isset($zonedata[$rectype])) {
172:             foreach ($zonedata[$rectype] as $row) {
173:                 // Prune empty values from $row to aid in comparison
174:                 foreach ($row as $key => $value) {
175:                     if (empty($value)) {
176:                         unset($row[$key]);
177:                     }
178:                 }
179: 
180:                 $same_values = array_intersect_assoc($row, $record);
181:                 if (count($same_values) == count($record)) {
182:                     return true;
183:                 }
184:             }
185:         }
186: 
187:         return false;
188:     }
189: 
190:     /**
191:      * Saves a record fo the configured driver and checks/sets needCommit()
192:      * Also first checks to ensure permission to save record is available.
193:      *
194:      * @param array $info  Data to be passed to backend driver for storage
195:      *
196:      * @return mixed  True on success, PEAR::Error on error
197:      */
198:     function saveRecord(&$info)
199:     {
200:         // Check to see if this is a new domain
201:         if ($info['rectype'] == 'soa' && $info['zonename'] != $_SESSION['beatnik']['curdomain']['zonename']) {
202:             // Make sure the user has permissions to add domains
203:             if (!Beatnik::hasPermission('beatnik:domains', Horde_Perms::EDIT)) {
204:                 throw new Beatnik_Exception(_('You do not have permission to create new domains.'));
205:             }
206: 
207:             // Create a dummy old domain for comparison purposes
208:             $oldsoa['serial'] = 0;
209: 
210:         } else {
211:             $oldsoa =& $_SESSION['beatnik']['curdomain'];
212: 
213:             // Check for permissions to edit the record in question
214:             if ($info['rectype'] == 'soa') {
215:                 $node = 'beatnik:domains:' . $info['zonename'];
216:                 if (!Beatnik::hasPermission($node, Horde_Perms::EDIT, 1)) {
217:                     throw new Beatnik_Exception(_('You do not have permssion to edit the SOA of this zone.'));
218:                 }
219:             } else {
220:                 $node = 'beatnik:domains:' . $_SESSION['beatnik']['curdomain']['zonename'];
221:                 if (!Beatnik::hasPermission($node, Horde_Perms::EDIT, 2)) {
222:                     throw new Beatnik_Exception(_('You do not have permssion to edit this record.'));
223:                 }
224:             }
225:         }
226: 
227:         // Save the changes to the backend
228:         // FIXME: Modify saveRecord() to return the new (possibly changed) ID of the
229:         // record and then use that ID to update permissions
230:         $return = $this->_saveRecord($info);
231:         $oldsoa =& $_SESSION['beatnik']['curdomain'];
232:         if ($info['rectype'] == 'soa' &&
233:            ($oldsoa['serial'] < $info['serial'])) {
234:             // Clear the commit flag (if set)
235:             Beatnik::needCommit($oldsoa['zonename'], false);
236:         } else {
237:             Beatnik::needCommit($oldsoa['zonename'], true);
238:         }
239: 
240:         // Check to see if an SOA was just added or updated.
241:         // If so, make it the current domain.
242:         if ($info['rectype'] == 'soa') {
243:             $_SESSION['beatnik']['curdomain'] = $this->getDomain($info['zonename']);
244:         }
245: 
246:         return true;
247:     }
248: 
249:     /**
250:      * Delete record from backend
251:      *
252:      * @access private
253:      *
254:      * @param array $info  Reference to array of record information for deletion
255:      *
256:      * @return boolean true on success
257:      */
258:     function deleteRecord(&$info)
259:     {
260:         $return = $this->_deleteRecord($info);
261:         $oldsoa =& $_SESSION['beatnik']['curdomain'];
262: 
263:         // No need to commit if the whole zone is gone
264:         if ($info['rectype'] != 'soa') {
265:             Beatnik::needCommit($oldsoa['zonename'], true);
266:         }
267:     }
268: 
269:     /**
270:      * Attempts to return a concrete Beatnik_Driver instance based on
271:      * $driver.
272:      *
273:      * @param string $driver  The type of the concrete Beatnik_Driver subclass
274:      *                        to return.  The class name is based on the storage
275:      *                        driver ($driver).  The code is dynamically
276:      *                        included.
277:      *
278:      * @param array  $params  (optional) A hash containing any additional
279:      *                        configuration or connection parameters a
280:      *                        subclass might need.
281:      *
282:      * @return mixed  The newly created concrete Beatnik_Driver instance, or
283:      *                false on an error.
284:      */
285:     function factory($driver = null, $params = null)
286:     {
287:         if ($driver === null) {
288:             $driver = $GLOBALS['conf']['storage']['driver'];
289:         }
290: 
291:         $driver = basename($driver);
292:         if (empty($driver) || ($driver == 'none')) {
293:             return new Horde_Lock();
294:         }
295: 
296:         if (is_null($params)) {
297:             // Since we have more than one backend that uses SQL make sure
298:             // all of them have a chance to inherit the site-wide config.
299:             $sqldrivers = array('sql', 'pdnsgsql');
300:             if (in_array($driver, $sqldrivers)) {
301:                 $params = Horde::getDriverConfig('storage', 'sql');
302:             } else {
303:                 $params = Horde::getDriverConfig('storage', $driver);
304:             }
305:         }
306: 
307:         require_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
308:         $class = 'Beatnik_Driver_' . $driver;
309:         if (class_exists($class)) {
310:             return new $class($params);
311:         } else {
312:             throw new Beatnik_Exception(_('Driver not found.'));
313:         }
314:     }
315: 
316: }
317: 
API documentation generated by ApiGen