1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\Streams;
/**
* Wrapper that provides callbacks for url actions such as fopen, unlink, rename
*
* Usage:
*
* $path = UrlCallBack('/path/so/source', function(){
* echo 'fopen';
* }, function(){
* echo 'opendir';
* }, function(){
* echo 'mkdir';
* }, function(){
* echo 'rename';
* }, function(){
* echo 'rmdir';
* }, function(){
* echo 'unlink';
* }, function(){
* echo 'stat';
* });
*
* mkdir($path);
* ...
*
* All callbacks are called after the operation is executed on the source stream
*/
class UrlCallback extends Wrapper implements Url {
/**
* @param string $source
* @param callable $fopen
* @param callable $opendir
* @param callable $mkdir
* @param callable $rename
* @param callable $rmdir
* @param callable $unlink
* @param callable $stat
* @return \Icewind\Streams\Path
*
* @throws \BadMethodCallException
* @throws \Exception
*/
public static function wrap($source, $fopen = null, $opendir = null, $mkdir = null, $rename = null, $rmdir = null,
$unlink = null, $stat = null) {
$options = array(
'source' => $source,
'fopen' => $fopen,
'opendir' => $opendir,
'mkdir' => $mkdir,
'rename' => $rename,
'rmdir' => $rmdir,
'unlink' => $unlink,
'stat' => $stat
);
return new Path('\Icewind\Streams\UrlCallBack', $options);
}
protected function loadContext($url) {
list($protocol) = explode('://', $url);
$options = stream_context_get_options($this->context);
return $options[$protocol];
}
protected function callCallBack($context, $callback) {
if (is_callable($context[$callback])) {
call_user_func($context[$callback]);
}
}
public function stream_open($path, $mode, $options, &$opened_path) {
$context = $this->loadContext($path);
$this->callCallBack($context, 'fopen');
$this->setSourceStream(fopen($context['source'], $mode));
return true;
}
public function dir_opendir($path, $options) {
$context = $this->loadContext($path);
$this->callCallBack($context, 'opendir');
$this->setSourceStream(opendir($context['source']));
return true;
}
public function mkdir($path, $mode, $options) {
$context = $this->loadContext($path);
$this->callCallBack($context, 'mkdir');
return mkdir($context['source'], $mode, $options & STREAM_MKDIR_RECURSIVE);
}
public function rmdir($path, $options) {
$context = $this->loadContext($path);
$this->callCallBack($context, 'rmdir');
return rmdir($context['source']);
}
public function rename($source, $target) {
$context = $this->loadContext($source);
$this->callCallBack($context, 'rename');
list(, $target) = explode('://', $target);
return rename($context['source'], $target);
}
public function unlink($path) {
$context = $this->loadContext($path);
$this->callCallBack($context, 'unlink');
return unlink($context['source']);
}
public function url_stat($path, $flags) {
throw new \Exception('stat is not supported due to php bug 50526');
}
}
|