mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-31 03:14:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
 | |
| 
 | |
| namespace Icinga\Repository;
 | |
| 
 | |
| use Exception;
 | |
| use Icinga\Application\Config;
 | |
| use Icinga\Data\Extensible;
 | |
| use Icinga\Data\Filter\Filter;
 | |
| use Icinga\Data\Updatable;
 | |
| use Icinga\Data\Reducible;
 | |
| use Icinga\Exception\ProgrammingError;
 | |
| use Icinga\Exception\StatementException;
 | |
| 
 | |
| /**
 | |
|  * Abstract base class for concrete INI repository implementations
 | |
|  *
 | |
|  * Additionally provided features:
 | |
|  * <ul>
 | |
|  *  <li>Insert, update and delete capabilities</li>
 | |
|  * </ul>
 | |
|  */
 | |
| abstract class IniRepository extends Repository implements Extensible, Updatable, Reducible
 | |
| {
 | |
|     /**
 | |
|      * The datasource being used
 | |
|      *
 | |
|      * @var Config
 | |
|      */
 | |
|     protected $ds;
 | |
| 
 | |
|     /**
 | |
|      * Create a new INI repository object
 | |
|      *
 | |
|      * @param   Config  $ds         The data source to use
 | |
|      *
 | |
|      * @throws  ProgrammingError    In case the given data source does not provide a valid key column
 | |
|      */
 | |
|     public function __construct(Config $ds)
 | |
|     {
 | |
|         parent::__construct($ds); // First! Due to init().
 | |
| 
 | |
|         if (! $ds->getConfigObject()->getKeyColumn()) {
 | |
|             throw new ProgrammingError('INI repositories require their data source to provide a valid key column');
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Insert the given data for the given target
 | |
|      *
 | |
|      * $data must provide a proper value for the data source's key column.
 | |
|      *
 | |
|      * @param   string  $target
 | |
|      * @param   array   $data
 | |
|      *
 | |
|      * @throws  StatementException  In case the operation has failed
 | |
|      */
 | |
|     public function insert($target, array $data)
 | |
|     {
 | |
|         $newData = $this->requireStatementColumns($target, $data);
 | |
|         $section = $this->extractSectionName($newData);
 | |
| 
 | |
|         if ($this->ds->hasSection($section)) {
 | |
|             throw new StatementException(t('Cannot insert. Section "%s" does already exist'), $section);
 | |
|         }
 | |
| 
 | |
|         $this->ds->setSection($section, $newData);
 | |
| 
 | |
|         try {
 | |
|             $this->ds->saveIni();
 | |
|         } catch (Exception $e) {
 | |
|             throw new StatementException(t('Failed to insert. An error occurred: %s'), $e->getMessage());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Update the target with the given data and optionally limit the affected entries by using a filter
 | |
|      *
 | |
|      * @param   string  $target
 | |
|      * @param   array   $data
 | |
|      * @param   Filter  $filter
 | |
|      *
 | |
|      * @throws  StatementException  In case the operation has failed
 | |
|      */
 | |
|     public function update($target, array $data, Filter $filter = null)
 | |
|     {
 | |
|         $newData = $this->requireStatementColumns($target, $data);
 | |
|         $keyColumn = $this->ds->getConfigObject()->getKeyColumn();
 | |
|         if ($filter === null && isset($newData[$keyColumn])) {
 | |
|             throw new StatementException(
 | |
|                 t('Cannot update. Column "%s" holds a section\'s name which must be unique'),
 | |
|                 $keyColumn
 | |
|             );
 | |
|         }
 | |
| 
 | |
|         if ($filter !== null) {
 | |
|             $filter = $this->requireFilter($target, $filter);
 | |
|         }
 | |
| 
 | |
|         $newSection = null;
 | |
|         foreach (iterator_to_array($this->ds) as $section => $config) {
 | |
|             if ($filter !== null && !$filter->matches($config)) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             if ($newSection !== null) {
 | |
|                 throw new StatementException(
 | |
|                     t('Cannot update. Column "%s" holds a section\'s name which must be unique'),
 | |
|                     $keyColumn
 | |
|                 );
 | |
|             }
 | |
| 
 | |
|             foreach ($newData as $column => $value) {
 | |
|                 if ($column === $keyColumn) {
 | |
|                     $newSection = $value;
 | |
|                 } else {
 | |
|                     $config->$column = $value;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if ($newSection) {
 | |
|                 if ($this->ds->hasSection($newSection)) {
 | |
|                     throw new StatementException(t('Cannot update. Section "%s" does already exist'), $newSection);
 | |
|                 }
 | |
| 
 | |
|                 $this->ds->removeSection($section)->setSection($newSection, $config);
 | |
|             } else {
 | |
|                 $this->ds->setSection($section, $config);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         try {
 | |
|             $this->ds->saveIni();
 | |
|         } catch (Exception $e) {
 | |
|             throw new StatementException(t('Failed to update. An error occurred: %s'), $e->getMessage());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Delete entries in the given target, optionally limiting the affected entries by using a filter
 | |
|      *
 | |
|      * @param   string  $target
 | |
|      * @param   Filter  $filter
 | |
|      *
 | |
|      * @throws  StatementException  In case the operation has failed
 | |
|      */
 | |
|     public function delete($target, Filter $filter = null)
 | |
|     {
 | |
|         if ($filter !== null) {
 | |
|             $filter = $this->requireFilter($target, $filter);
 | |
|         }
 | |
| 
 | |
|         foreach (iterator_to_array($this->ds) as $section => $config) {
 | |
|             if ($filter === null || $filter->matches($config)) {
 | |
|                 $this->ds->removeSection($section);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         try {
 | |
|             $this->ds->saveIni();
 | |
|         } catch (Exception $e) {
 | |
|             throw new StatementException(t('Failed to delete. An error occurred: %s'), $e->getMessage());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Extract and return the section name off of the given $data
 | |
|      *
 | |
|      * @param   array   $data
 | |
|      *
 | |
|      * @return  string
 | |
|      *
 | |
|      * @throws  ProgrammingError    In case no valid section name is available
 | |
|      */
 | |
|     protected function extractSectionName(array & $data)
 | |
|     {
 | |
|         $keyColumn = $this->ds->getConfigObject()->getKeyColumn();
 | |
|         if (! isset($data[$keyColumn])) {
 | |
|             throw new ProgrammingError('$data does not provide a value for key column "%s"', $keyColumn);
 | |
|         }
 | |
| 
 | |
|         $section = $data[$keyColumn];
 | |
|         unset($data[$keyColumn]);
 | |
|         return $section;
 | |
|     }
 | |
| }
 |