mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-11-03 20:54:27 +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;
 | 
						|
    }
 | 
						|
}
 |