blob: 73aa6b28b50852996456d52ca472aa664a93d27a [file] [log] [blame]
<?php
/**
* File containing the ezcConfigurationFileWriter class
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Configuration
* @version //autogen//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
* ezcConfigurationFileWriter class provides the functionality for writing
* file based configuration formats.
*
* This class implements most of the interface of ezcConfigurationWriter and
* makes it easier to work on file based configuration. All methods except save()
* are implemented by this class so a subclass only needs to handle the actual
* serialization.
*
* @package Configuration
* @version //autogen//
*/
abstract class ezcConfigurationFileWriter extends ezcConfigurationWriter
{
/**
* The path to the file which will contain the serialized configuration data.
*
* @var string
*/
protected $path = '';
/**
* Contains the file permissions for the file to write the INI settings to.
*
* @var int
*/
protected $permissions = 0666;
/**
* The current location of the config, this is either the path on the filesystem
* or a PHP stream prefix.
*
* @var string
*/
protected $location = '';
/**
* The base name of the configuration file, the suffix will be appended to this
* to find the real filename.
*
* @var string
*/
protected $name = '';
/**
* Current options for the writer.
* See the specific writer to see which options it supports.
*
* @var array
*/
protected $options = array();
/**
* Contains the configuration object to write with the save() method.
*
* @var bool
*/
protected $config = false;
/**
* Controls whether comments are written to the INI file or not.
*
* @var bool
*/
protected $useComments = true;
/**
* Constructs the writer and initializes it with the file to write.
*
* After construction call save() to store the INI file to disk.
*
* @param string $path The relative or absolute path to where the
* configuration should be written to. Using PHP
* streams is also possible, e.g.
* compress.gz://site.ini.gz
* @param ezcConfiguration $config The configuration object which should be
* stored in an INI file.
* @param int $permissions The file permission to use on the newly created
* file, it uses the same values as chmod().
*/
public function __construct( $path = null, ezcConfiguration $config = null, $permissions = 0666 )
{
if ( $path !== null )
{
$this->parseLocationPath( $path, $this->getSuffix() );
}
$this->config = $config;
$this->permissions = $permissions;
}
/**
* Sets the configuration object that will be used for the next call to save().
*
* Pass false if you wish to remove the current configuration object.
*
* @param ezcConfiguration $config
* @return void
*/
public function setConfig( ezcConfiguration $config )
{
$this->config = $config;
}
/**
* Return the current location string.
*
* @return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Return the current name for the configuration to be written.
*
* @return int
*/
public function getName()
{
return $this->name;
}
/**
* Returns the current options for the writer.
*
* @return array
*/
public function getOptions()
{
return array( 'useComments' => $this->useComments, 'permissions' => $this->permissions );
}
/**
* Initializes the writer with a $location and a $name.
*
* These values determine where the configuration will be
* serialized.
*
* The location string can be used to determine the directory
* location for an INI file.
*
* The name parameter can be the basename for the INI file, so
* a value of 'site' would create a file with name 'site.ini'.
*
* @param string $location The main placement for the configuration. It is
* up to the specific writer to interpret this
* value.
* @param string $name The name for the configuration. It is up to the
* specific writer to interpret this value. For a file writer
* it could be the basename for the INI file, so a value of
* 'site' would create a file with name 'site.ini'.
* @param ezcConfiguration $config The current configuration object which
* should be serialized by the current
* writer.
* @param array $options An associative array of options for the writer.
* Which options to use is determined by the specific
* writer class.
* @return void
*/
public function init( $location, $name, ezcConfiguration $config, $options = array() )
{
$this->path = $location . DIRECTORY_SEPARATOR . $name . '.' . $this->getSuffix();
$this->location = $location;
$this->name = $name;
$this->setConfig( $config );
$this->setOptions( $options );
}
/**
* Parses a the path $path and sets the location and name
* properties on this object.
*
* The file is checked if it contains the correct $suffix.
*
* ezcConfigurationFileReader::parseLocationPath() has the same
* code. It is duplicated to prevent complex OO hacks.
*
* @throws ezcConfigurationInvalidSuffixExceptionif the configuration file
* has the wrong suffix.
* @param string $path
* @param string $suffix
* @return void
*/
protected function parseLocationPath( $path, $suffix )
{
$this->path = $path;
$this->location = dirname( $path );
$base = basename( $path );
if ( $suffix[0] != '.' )
{
$suffix = ".$suffix";
}
if ( !preg_match( '@'. preg_quote( $suffix ) . '$@', $path ) )
{
throw new ezcConfigurationInvalidSuffixException( $path, $suffix );
}
$this->name = basename( $base, $suffix );
}
/**
* Saves the current config object.
*
* Saves the current configuration object to a place which can later be
* retrieved with a ezcConfigurationReader.
*
* @throws ezcConfigurationNoConfigObjectException if there is not config
* object set to write.
* @throws ezcConfigurationInvalidSuffixExceptionif the configuration file
* has the wrong suffix.
* @throws ezcConfigurationWriteFailureException if the configuration could
* not be stored in the given location.
* @return void
*/
public function save()
{
if ( !$this->config )
{
throw new ezcConfigurationNoConfigObjectException();
}
// Open the file
$fp = $this->openFile();
// Retrieve settings and comments from configuration object, and write
// them to the file
if ( $this->useComments )
{
$this->writeSettings( $fp, $this->config->getAllSettings(), $this->config->getAllComments() );
}
else
{
$this->writeSettings( $fp, $this->config->getAllSettings() );
}
$this->closeFile( $fp );
}
/**
* Opens a file for writing.
*
* This method opens a file for writing and checks whether it was
* successfully opened.
*
* @throws ezcConfigurationWriteFailedException if it was not possible to
* write to the file.
* @return resource The opened file's filehandler.
*/
protected function openFile()
{
$fp = fopen( $this->path, 'wt' );
if ( !$fp )
{
throw new ezcConfigurationWriteFailedException( $this->path );
}
return $fp;
}
/**
* Closes a file pointed to by $fp and sets file permissions.
*
* This method closes a file with the file pointer that was passed. After
* closing the file the permissions are set as configured with the
* "permissions" option.
*
* @param resource $fp
* @return void
*/
protected function closeFile( $fp )
{
fclose( $fp );
$oldUmask = umask( 0 );
chmod( $this->path, $this->permissions );
umask( $oldUmask );
}
/**
* Sets the options $configurationData.
*
* The options are specified in a associative array in the form 'optionName' => value.
*
* @throws ezcBaseSettingNotFoundException if you try to set a non existent setting.
* @throws ezcBaseSettingValueException if you specify a value out of range for a setting.
* @param array(string=>mixed) $configurationData
* @return void
*/
public function setOptions( $configurationData )
{
foreach ( $configurationData as $name => $value )
{
switch ( $name )
{
case 'useComments':
if ( gettype( $value ) != 'boolean' )
{
throw new ezcBaseSettingValueException( $name, $value, 'bool' );
}
$this->useComments = $value;
break;
case 'permissions':
if ( gettype( $value ) != 'integer' )
{
throw new ezcBaseSettingValueException( $name, $value, 'int, 0 - 0777' );
}
if ( $value < 0 || $value > 0777 )
{
throw new ezcBaseSettingValueException( $name, $value, 'int, 0 - 0777' );
}
$this->permissions = $value;
break;
default:
throw new ezcBaseSettingNotFoundException( $name );
}
}
}
}
?>