FRED™  3.0
FRED™: Framework for Rapid and Easy Development
Wrapper.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi\Fred\Stream;
4 
5 /**
6  * Stream wrapper.
7  * @see http://www.php.net/manual/en/class.streamwrapper.php
8  */
9 class Wrapper extends \Rsi\Thing{
10 
11  public $context = null;
12 
13  protected $_fred = null;
14  protected $_handlers = [];
15  protected $_filename = null;
16  protected $_params = [];
17  protected $_dir = null;
18  protected $_readOnly = false;
19  protected $_modified = false;
20  protected $_position = 0;
21  protected $_data = null;
22 
23  /**
24  * Split the path in protocol, handlers, filename and optional parameters (all stored in properties).
25  * @param string $path Path of the form fred://handler1/handler2/file.ext?key1=value1&key2=value2 (where 'fred' is the name
26  * of the global var with the framework handle).
27  * @return bool True when successful.
28  */
29  protected function splitPath($path){
30  if($result = preg_match('/^(\\w+):\\/\\/((\\w+\\/)+)([\\w\\-\\.]+)(?:\\?(.*))?$/',$path,$matches)){
31  if(!$this->_fred){
32  if(array_key_exists($key = $matches[1],$GLOBALS)) $this->_fred = $GLOBALS[$key];
33  else foreach($GLOBALS as $value) if($value instanceof \Rsi\Fred) $this->_fred = $value;
34  }
35  $result = $this->_fred->stream->handlersExist($this->_handlers = explode('/',substr($matches[2],0,-1)));
36  $this->_filename = $matches[4];
37  parse_str(count($matches) < 6 ? null : $matches[5],$this->_params);
38  }
39  return $result;
40  }
41 
42  public function dir_closedir(){
43  $this->_dir = null;
44  return true;
45  }
46 
47  public function dir_opendir($path,$options){
48  if(!$this->splitPath(\Rsi\File::addDirSeparator($path) . '.')) return false;
49  $this->_dir = $this->_fred->stream->search($this->_handlers);
50  return true;
51  }
52 
53  public function dir_readdir(){
54  $name = current($this->_dir);
55  next($this->_dir);
56  return $name;
57  }
58 
59  public function dir_rewinddir(){
60  reset($this->_dir);
61  return true;
62  }
63 
64  public function mkdir($path,$mode,$options){
65  return true;
66  }
67 
68  public function rename($path_from,$path_to){
69  if($this->splitPath($path_from) && ($this->data !== false) && $this->splitPath($path_to)){
70  $this->_modified = true;
71  $this->stream_flush();
72  return $this->unlink($path_from);
73  }
74  return false;
75  }
76 
77  public function rmdir($path,$options){
78  return $this->splitPath(\Rsi\File::addDirSeparator($path) . '.') && !$this->_fred->stream->search($this->_handlers);
79  }
80 
81 //TODO: public function stream_cast($cast_as)
82 
83  public function stream_close(){
84  }
85 
86  public function stream_eof(){
87  return $this->_position >= strlen($this->data);
88  }
89 
90  public function stream_flush(){
91  if($this->_modified) $this->_fred->stream->save($this->_handlers,$this->_filename,$this->_params,$this->_data);
92  }
93 
94 //TODO: public function stream_lock($operation)
95 
96  public function stream_metadata($path,$option,$value){
97  switch($option){
98  case STREAM_META_TOUCH:
99  if(!$this->_data) $this->_data = '';
100  break;
101  default:
102  return false;
103  }
104  return true;
105  }
106 
107  public function stream_open($path,$mode,$options,&$opened_path){
108  $this->_position = 0;
109  if(!$this->splitPath($path)) return false;
110  $this->_data = null;
111  $this->_readOnly = $this->_modified = $exclusive = false;
112  switch(substr($mode,0,1)){
113  case 'r':
114  if(substr($mode,-1) != '+') $this->_readOnly = true;
115  break;
116  case 'x':
117  $exclusive = true;
118  case 'a':
119  if($this->data !== false){
120  if($exclusive) return false;
121  $this->_position = strlen($this->_data);
122  break;
123  }
124  case 'w':
125  $this->_data = null;
126  case 'c':
127  $this->_modified = true;
128  break;
129  }
130  return true;
131  }
132 
133  public function stream_read($count){
134  $data = substr($this->data,$this->_position,$count);
135  $this->_position += strlen($data);
136  return $data;
137  }
138 
139  public function stream_seek($offset,$whence){
140  switch($whence){
141  case SEEK_SET:
142  if(($offset < 0) || ($offset >= strlen($this->data))) return false;
143  $this->_position = $offset;
144  break;
145  case SEEK_CUR:
146  if($offset < 0) return false;
147  $this->_position += $offset;
148  break;
149  case SEEK_END:
150  if(($length = strlen($this->data)) + $offset < 0) return false;
151  $this->_position = $length + $offset;
152  break;
153  default:
154  return false;
155  }
156  return true;
157  }
158 
159  public function stream_set_option($option,$arg1,$arg2){
160  return false;
161  }
162 
163  public function stream_stat(){
164  return [
165  'dev' => 0,
166  'ino' => 0,
167  'mode' => 0777 | 0100000,
168  'nlink' => 0,
169  'uid' => 0,
170  'gid' => 0,
171  'rdev' => 0,
172  'size' => strlen($this->data),
173  'atime' => 0,
174  'mtime' => 0,
175  'ctime' => 0,
176  'blksize' => -1,
177  'blocks' => -1
178  ];
179  }
180 
181  public function stream_tell(){
182  return $this->_position;
183  }
184 
185  public function stream_truncate($new_size){
186  $this->_data = substr($this->data,0,$new_size);
187  }
188 
189  public function stream_write($data){
190  if($this->_readOnly) return false;
191  if($length = strlen($data)){
192  $this->_data = substr($this->data,0,$this->_position) . $data . substr($this->data,$this->_position += $length);
193  $this->_modified = true;
194  }
195  return $length;
196  }
197 
198  public function unlink($path){
199  return $this->splitPath($path) ? $this->_fred->stream->delete($this->_handlers,$this->_filename,$this->_params) : false;
200  }
201 
202  public function url_stat($path,$flags){
203  return $this->splitPath($path) && $this->_fred->stream->exists($this->_handlers,$this->_filename,$this->_params)
204  ? [
205  'dev' => 0,
206  'ino' => 0,
207  'mode' => 0100777,
208  'nlink' => 0,
209  'uid' => 0,
210  'gid' => 0,
211  'rdev' => 0,
212  'size' => strlen($this->data),
213  'atime' => 0,
214  'mtime' => $this->_fred->stream->time($this->_handlers,$this->_filename,$this->_params),
215  'ctime' => 0,
216  'blksize' => -1,
217  'blocks' => -1
218  ]
219  : false;
220  }
221 
222  protected function getData(){
223  if($this->_data === null) $this->_data = $this->_fred->stream->read($this->_handlers,$this->_filename,$this->_params);
224  return $this->_data;
225  }
226 
227 }
splitPath($path)
Split the path in protocol, handlers, filename and optional parameters (all stored in properties)...
Definition: Wrapper.php:29
stream_set_option($option, $arg1, $arg2)
Definition: Wrapper.php:159
mkdir($path, $mode, $options)
Definition: Wrapper.php:64
stream_open($path, $mode, $options, &$opened_path)
Definition: Wrapper.php:107
rename($path_from, $path_to)
Definition: Wrapper.php:68
Basic object.
Definition: Thing.php:13
Framework for Rapid and Easy Development.
Definition: Fred.php:18
Stream wrapper.
Definition: Wrapper.php:9
stream_metadata($path, $option, $value)
Definition: Wrapper.php:96
url_stat($path, $flags)
Definition: Wrapper.php:202
stream_seek($offset, $whence)
Definition: Wrapper.php:139
stream_truncate($new_size)
Definition: Wrapper.php:185
dir_opendir($path, $options)
Definition: Wrapper.php:47
rmdir($path, $options)
Definition: Wrapper.php:77