1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Web;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
30: class Ftp extends Nette\Object
31: {
32:
33: const ASCII = FTP_ASCII;
34: const TEXT = FTP_TEXT;
35: const BINARY = FTP_BINARY;
36: const IMAGE = FTP_IMAGE;
37: const TIMEOUT_SEC = FTP_TIMEOUT_SEC;
38: const AUTOSEEK = FTP_AUTOSEEK;
39: const AUTORESUME = FTP_AUTORESUME;
40: const FAILED = FTP_FAILED;
41: const FINISHED = FTP_FINISHED;
42: const MOREDATA = FTP_MOREDATA;
43:
44:
45:
46: private $resource;
47:
48:
49: private $state;
50:
51:
52:
53: 54:
55: public function __construct()
56: {
57: if (!extension_loaded('ftp')) {
58: throw new \Exception("PHP extension FTP is not loaded.");
59: }
60: }
61:
62:
63:
64: 65: 66: 67: 68: 69: 70: 71:
72: public function __call($name, $args)
73: {
74: $name = strtolower($name);
75: $silent = strncmp($name, 'try', 3) === 0;
76: $func = $silent ? substr($name, 3) : $name;
77: static $aliases = array(
78: 'sslconnect' => 'ssl_connect',
79: 'getoption' => 'get_option',
80: 'setoption' => 'set_option',
81: 'nbcontinue' => 'nb_continue',
82: 'nbfget' => 'nb_fget',
83: 'nbfput' => 'nb_fput',
84: 'nbget' => 'nb_get',
85: 'nbput' => 'nb_put',
86: );
87: $func = 'ftp_' . (isset($aliases[$func]) ? $aliases[$func] : $func);
88:
89: if (!function_exists($func)) {
90: return parent::__call($name, $args);
91: }
92:
93:
94: Nette\Tools::tryError();
95:
96: if ($func === 'ftp_connect' || $func === 'ftp_ssl_connect') {
97: $this->state = array($name => $args);
98: $this->resource = call_user_func_array($func, $args);
99: $res = NULL;
100:
101: } elseif (!is_resource($this->resource)) {
102: Nette\Tools::catchError($msg);
103: throw new FtpException("Not connected to FTP server. Call connect() or ssl_connect() first.");
104:
105: } else {
106: if ($func === 'ftp_login' || $func === 'ftp_pasv') {
107: $this->state[$name] = $args;
108: }
109:
110: array_unshift($args, $this->resource);
111: $res = call_user_func_array($func, $args);
112:
113: if ($func === 'ftp_chdir' || $func === 'ftp_cdup') {
114: $this->state['chdir'] = array(ftp_pwd($this->resource));
115: }
116: }
117:
118: if (Nette\Tools::catchError($msg) && !$silent) {
119: throw new FtpException($msg);
120: }
121:
122: return $res;
123: }
124:
125:
126:
127: 128: 129: 130:
131: public function reconnect()
132: {
133: @ftp_close($this->resource);
134: foreach ($this->state as $name => $args) {
135: call_user_func_array(array($this, $name), $args);
136: }
137: }
138:
139:
140:
141: 142: 143: 144: 145:
146: public function fileExists($file)
147: {
148: return is_array($this->nlist($file));
149: }
150:
151:
152:
153: 154: 155: 156: 157:
158: public function isDir($dir)
159: {
160: $current = $this->pwd();
161: try {
162: $this->chdir($dir);
163: } catch (FtpException $e) {
164: }
165: $this->chdir($current);
166: return empty($e);
167: }
168:
169:
170:
171: 172: 173: 174: 175:
176: public function mkDirRecursive($dir)
177: {
178: $parts = explode('/', $dir);
179: $path = '';
180: while (!empty($parts)) {
181: $path .= array_shift($parts);
182: try {
183: if ($path !== '') $this->mkdir($path);
184: } catch (FtpException $e) {
185: if (!$this->isDir($path)) {
186: throw new FtpException("Cannot create directory '$path'.");
187: }
188: }
189: $path .= '/';
190: }
191: }
192:
193: }
194:
195:
196:
197: 198: 199: 200:
201: class FtpException extends \Exception
202: {
203: }
204: