1 : <?php
2 : /**
3 : * Roman de Renart
4 : *
5 : * PHP version 5
6 : *
7 : * @category Rdr
8 : * @package Edit
9 : * @author Michel Corne <mcorne@yahoo.com>
10 : * @copyright 2010 Michel Corne
11 : * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
12 : * @link http://roman-de-renart.blogspot.com/
13 : * @version SVN: $Id$
14 : */
15 :
16 : require_once 'Base.php';
17 :
18 : /**
19 : * File and URL processing
20 : *
21 : * @category Rdr
22 : * @package Edit
23 : * @author Michel Corne <mcorne@yahoo.com>
24 : * @copyright 2010 Michel Corne
25 : * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
26 : */
27 :
28 : class InputOutput extends Base
29 : {
30 : /**
31 : * The name template of a backup file
32 : */
33 : const BACKUP_FILE = '%s-%s.%s';
34 :
35 : /**
36 : * The domain name of the Roman de Renart
37 : */
38 : const BLOG_DOMAIN = 'http://roman-de-renart.blogspot.com/';
39 :
40 : /**
41 : * The error message reported when a file cannot be backed up
42 : */
43 : const ERR_BACKUP_FILE = 'cannot backup file: %s';
44 :
45 : /**
46 : * The error message reported when a config file key is missing
47 : */
48 : const ERR_CONFIG_KEY = 'expecting config file key: %s';
49 :
50 : /**
51 : * The error message reported when a file does not exists
52 : */
53 : const ERR_FILE_EXISTS = 'file does not exists: %s';
54 :
55 : /**
56 : * The error message reported when a file cannot be read
57 : */
58 : const ERR_READ_FILE = 'cannot read file: %s';
59 :
60 : /**
61 : * The error message reported when a URL cannot be read
62 : */
63 : const ERR_READ_URL = 'cannot read URL or file: %s';
64 :
65 : /**
66 : * The error message reported when a file cannot be written
67 : */
68 : const ERR_WRITE_FILE = 'cannot write file: %s';
69 :
70 : /**
71 : * The template for a PHP export file
72 : */
73 : const EXPORT =
74 : '<?php
75 : // Generated %s
76 : return %s;
77 : ';
78 :
79 : /**
80 : * The configuration directives
81 : * @var array
82 : */
83 : protected $config = array();
84 :
85 : /**
86 : * Constructor
87 : *
88 : * @param array $config the configuration directives
89 : * @return void
90 : */
91 : public function __construct($config = array())
92 : {
93 92 : $config and $this->config = $config;
94 92 : }
95 :
96 : /**
97 : * Creates a file backup
98 : *
99 : * @param string $fileName the name of the file to backup
100 : * @return string the name of the backup file
101 : * @throws Exception an exception is thrown by abort() if the file cannot be backed up
102 : */
103 : public function backupFile($fileName)
104 : {
105 56 : $this->fileExists($fileName);
106 :
107 56 : $info = pathinfo($fileName);
108 56 : $backupName = sprintf(self::BACKUP_FILE, $info['filename'], time(), $info['extension']);
109 56 : $backupName = $this->makeFilePath($backupName, 'backup-dir');
110 :
111 56 : @copy($fileName, $backupName) or $this->abort(sprintf(self::ERR_BACKUP_FILE, $fileName));
112 :
113 : // returns the name of the backup file
114 : // as a convenience for testing purposes
115 56 : return $backupName;
116 : }
117 :
118 : /**
119 : * Verifies if a file or directory exists
120 : *
121 : * @param string $fileName the name of the file or directory
122 : * @param string $message the error message to return if the file does not exist
123 : * @return bool true
124 : * @throws Exception an exception is thrown by abort() if the file or directory does not exist
125 : */
126 : public function fileExists($fileName, $message = null)
127 : {
128 81 : $message or $message = sprintf(self::ERR_FILE_EXISTS, $fileName);
129 81 : file_exists($fileName) or $this->abort($message);
130 :
131 : // always returns true
132 : // as a convenience for testing purposes
133 81 : return true;
134 : }
135 :
136 : /**
137 : * Includes a file
138 : *
139 : * @param string $fileName the name of the file to include
140 : * @return array an array returned from the included file
141 : */
142 : public function includeFile($fileName)
143 : {
144 69 : $this->fileExists($fileName);
145 :
146 69 : return include $fileName;
147 : }
148 :
149 : /**
150 : * Makes the full path name of a file
151 : *
152 : * @param array $fileName the name of the file as a string,
153 : * @param array $dirConfigKey the configuration key of the file directory
154 : * @param array $format the format to apply to the file name
155 : * @return string the full path name of the file
156 : */
157 : public function makeFilePath($fileName, $dirConfigKey, $format = '')
158 : {
159 : // adds the package and directory sub path names to the path name
160 74 : $pathName = $this->makeFileSubPath('package-dir');
161 74 : $pathName .= $this->makeFileSubPath($dirConfigKey);
162 :
163 : // applies a format to the file name, adds the file name to the path name
164 74 : $format and $fileName = sprintf($format, $fileName);
165 74 : $pathName .= $fileName;
166 :
167 : // verifies the file directory exists
168 74 : $this->fileExists(dirname($pathName));
169 :
170 74 : return $pathName;
171 : }
172 :
173 : /**
174 : * Makes the sub path name of a file
175 : *
176 : * @param array $dirConfigKey the configuration key of the file directory
177 : * @return string the sub path name of the file
178 : */
179 : public function makeFileSubPath($dirConfigKey)
180 : {
181 75 : isset($this->config[$dirConfigKey]) or
182 1 : $this->abort(sprintf(self::ERR_CONFIG_KEY, $dirConfigKey));
183 :
184 75 : return $this->config[$dirConfigKey]?
185 75 : $this->tidyDirName($this->config[$dirConfigKey]) : '';
186 : }
187 :
188 : /**
189 : * Reads a blog message
190 : *
191 : * @param string $path the relative path to the blog message
192 : * @param string $domain the domain name
193 : * @return string the HTML content of the message
194 : * @throws Exception an exception is thrown by abort() if the URL cannot be read
195 : */
196 : public function readBlog($path = null, $domain = null)
197 : {
198 3 : is_null($path) and $path = '';
199 3 : is_null($domain) and $domain = self::BLOG_DOMAIN;
200 :
201 3 : $url = $domain . $path;
202 3 : $content = file_get_contents($url) or $this->abort(sprintf(self::ERR_READ_URL, $url));
203 :
204 3 : return $content;
205 : }
206 :
207 : /**
208 : * Reads a file
209 : *
210 : * @param string $fileName the name of the file to read
211 : * @param boolean $splitLines splits the content into lines if true,
212 : * leaves the content as a string if false
213 : * @return mixed the file content as an array of strings or a string
214 : */
215 : public function readFile($fileName, $splitLines = false)
216 : {
217 11 : $this->fileExists($fileName);
218 :
219 11 : $content = $splitLines?
220 7 : @file($fileName, FILE_IGNORE_NEW_LINES) :
221 11 : @file_get_contents($fileName);
222 :
223 11 : $content or $this->abort(sprintf(self::ERR_READ_FILE, $fileName));
224 :
225 11 : return $content;
226 : }
227 :
228 : /**
229 : * Tidies a directory name
230 : *
231 : * @param string $dirName the directory name to tidy
232 : * @return string the tidy directory name
233 : */
234 : public function tidyDirName($dirName)
235 : {
236 76 : $dirName = rtrim($dirName, '/');
237 :
238 76 : return $dirName . '/';
239 : }
240 :
241 : /**
242 : * Returns a parsable string representation of an array or string
243 : *
244 : * The exported array or string is typically written into a file that is to be
245 : * included to get the content of that array or string.
246 : * The current time is added as a comment
247 : *
248 : * @param mixed $mixed the array or string to export
249 : * @return string a the "returned" exported array or string
250 : */
251 : public function toPhp($mixed)
252 : {
253 51 : date_default_timezone_set('UTC');
254 51 : $date = date(DATE_COOKIE);
255 51 : $string = var_export($mixed, true);
256 :
257 51 : return sprintf(self::EXPORT, $date, $string);
258 : }
259 :
260 : /**
261 : * Writes content into a file
262 : *
263 : * The file is backed up before being written into.
264 : * The content is imploded into a string separated by line breaks
265 : * if it is an array of strings.
266 : *
267 : * @param string $fileName the name of the file to write
268 : * @param mixed $content an array of strings or a string to write
269 : * @param boolean $toPhp exports the content as a parsable string
270 : * representation of an array or string
271 : * @return void
272 : */
273 : public function writeFile($fileName, $content, $toPhp = false)
274 : {
275 56 : file_exists($fileName) and $this->backupFile($fileName);
276 :
277 56 : $toPhp and $content = $this->toPhp($content);
278 56 : is_array($content) and $content = implode("\n", $content);
279 56 : $content = trim($content, "\n");
280 :
281 56 : @file_put_contents($fileName, $content) or
282 1 : $this->abort(sprintf(self::ERR_WRITE_FILE, $fileName));
283 56 : }
|