1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\Config\Writer;
11
12use Traversable;
13use Zend\Config\Exception;
14use Zend\Stdlib\ArrayUtils;
15
16abstract class AbstractWriter implements WriterInterface
17{
18    /**
19     * toFile(): defined by Writer interface.
20     *
21     * @see    WriterInterface::toFile()
22     * @param  string  $filename
23     * @param  mixed   $config
24     * @param  bool $exclusiveLock
25     * @return void
26     * @throws Exception\InvalidArgumentException
27     * @throws Exception\RuntimeException
28     */
29    public function toFile($filename, $config, $exclusiveLock = true)
30    {
31        if (empty($filename)) {
32            throw new Exception\InvalidArgumentException('No file name specified');
33        }
34
35        $flags = 0;
36        if ($exclusiveLock) {
37            $flags |= LOCK_EX;
38        }
39
40        set_error_handler(
41            function ($error, $message = '') use ($filename) {
42                throw new Exception\RuntimeException(
43                    sprintf('Error writing to "%s": %s', $filename, $message),
44                    $error
45                );
46            },
47            E_WARNING
48        );
49
50        try {
51            file_put_contents($filename, $this->toString($config), $flags);
52        } catch (\Exception $e) {
53            restore_error_handler();
54            throw $e;
55        }
56
57        restore_error_handler();
58    }
59
60    /**
61     * toString(): defined by Writer interface.
62     *
63     * @see    WriterInterface::toString()
64     * @param  mixed   $config
65     * @return string
66     * @throws Exception\InvalidArgumentException
67     */
68    public function toString($config)
69    {
70        if ($config instanceof Traversable) {
71            $config = ArrayUtils::iteratorToArray($config);
72        } elseif (!is_array($config)) {
73            throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable config');
74        }
75
76        return $this->processConfig($config);
77    }
78
79    /**
80     * @param array $config
81     * @return string
82     */
83    abstract protected function processConfig(array $config);
84}
85