Remote::isWritable()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: egorov
5
 * Date: 23.01.2015
6
 * Time: 13:13
7
 */
8
namespace samsonphp\deploy;
9
10
/**
11
 * Implementation of remote connection logic
12
 * @package samsonphp\deploy
13
 */
14
class Remote
15
{
16
    /** @var resource  */
17
    protected $handle;
18
19
    /** @var string Current remote folder path */
20
    protected $currentFolder;
21
22
    /** @var integer Time difference between remote and local */
23
    protected $timeDiff;
24
25
    /**
26
     * Generic log function for further modification
27
     * @param string $message
28
     * @return mixed
29
     */
30
    public function log($message)
31
    {
32
        // Get passed vars
33
        $vars = func_get_args();
34
        // Remove first message var
35
        array_shift($vars);
36
37
        // Render debug message
38
        trace(debug_parse_markers($message, $vars));
39
40
        return false;
41
    }
42
43
    /**
44
     * Constructor
45
     * @param string $host
46
     * @param string $login
47
     * @param string $pwd
48
     */
49
    public function __construct($host, $login, $pwd)
50
    {
51
        // Connect to remote
52
        $this->handle = ftp_connect($host);
53
54
        // Login
55
        if (!ftp_login($this->handle, $login, $pwd) !== false) {
56
            $this->log('Cannot login to remote server [##:##@##]', $login, $pwd, $host);
57
        }
58
59
        // Switch to passive mode
60
        ftp_pasv($this->handle, true);
61
62
        // Get time difference
63
        $this->timeDiff = $this->getTimeDifference();
64
    }
65
66
    /**
67
     * Compare local file with remote file
68
     * @param string $fullPath Full local file path
69
     * @param int $maxAge File maximum possible age
70
     * @return bool True if file is old and must be updated
71
     */
72
    public function isOld($fullPath, $maxAge = 1)
73
    {
74
        // Read ftp file modification time and count age of file and check if it is valid
75
        return (filemtime($fullPath) - (ftp_mdtm($this->handle, basename($fullPath)) + $this->timeDiff)) > $maxAge;
76
    }
77
78
    /** Destructor */
79
    public function __destruct()
80
    {
81
        ftp_close($this->handle);
82
    }
83
84
    /**
85
     * Write temp file to remote system and count difference
86
     * @param string $localPath Path to local file
87
     * @return int Time difference between systems
88
     */
89
    private function writeTempFile($localPath)
90
    {
91
        // Remote file name
92
        $tsFileName = basename($localPath);
93
94
        // Copy file to remote
95
        if ($this->write($localPath)) {
96
            // Get difference
97
            $diff = abs(filemtime($localPath) - ftp_mdtm($this->handle, $tsFileName));
98
99
            $this->log('Time difference between servers is [##]', $diff);
100
101
            ftp_delete($this->handle, $tsFileName);
102
103
            // Convert to hours
104
            return (integer)($diff > 3600 ? (floor($diff / 3600) * 3600 + $diff % 3600) : 0);
105
        }
106
107
        return 0;
108
    }
109
110
    /**
111
     * Get time difference between servers
112
     * @return integer Time difference between servers
113
     */
114
    protected function getTimeDifference()
115
    {
116
        // Create temp file
117
        $localPath = tempnam(sys_get_temp_dir(), 'test');
118
119
        // Count time difference
120
        $diff = $this->writeTempFile($localPath);
121
122
        // Remove local temp file
123
        unlink($localPath);
124
125
        return $diff;
126
    }
127
128
    /**
129
     * Go one level up in directory
130
     */
131
    public function cdup()
132
    {
133
        ftp_cdup($this->handle);
134
    }
135
136
    /**
137
     * Change current remote folder
138
     * @param string $path Path to folder
139
     * @return bool False if we cannot change folder
140
     */
141
    public function cd($path)
142
    {
143
        // Go to root folder
144
        if (!ftp_chdir($this->handle, $path)) {
145
            return $this->log('Remote folder[##] not found', $path);
146
        }
147
148
        // Check if we can write there
149
        if (!$this->isWritable()) {
150
            return $this->log('Remote path [##] is not writable', $path);
151
        }
152
153
        $this->log('Switching to [##] folder', $path);
154
155
        // Store current folder
156
        $this->currentFolder = ftp_pwd($this->handle);
157
158
        return true;
159
    }
160
161
    /**
162
     * Try to write to remote
163
     * @return bool True if we can write to remote
164
     */
165
    public function isWritable()
166
    {
167
        // Create temp file
168
        $path = tempnam(sys_get_temp_dir(), 'test');
169
170
        // Get temp file name
171
        $fileName = basename($path);
172
173
        // Copy temp file to remote
174
        if (ftp_put($this->handle, $fileName, $path, FTP_ASCII)) {
175
            // Remove temp file
176
            ftp_delete($this->handle, $fileName);
177
            return true;
178
        }
179
180
        return false;
181
    }
182
183
    /**
184
     * Create remote directory and get into it
185
     * @param $path
186
     */
187
    public function mkDir($path)
188
    {
189
        // Try get into this dir, maybe it already there
190
        if (!@ftp_chdir($this->handle, $path)) {
191
            // Create dir
192
            ftp_mkdir($this->handle, $path);
193
            // Change rights
194
            ftp_chmod($this->handle, 0755, $path);
195
            // Go to it
196
            ftp_chdir($this->handle, $path);
197
        }
198
    }
199
200
    /**
201
     * Write remote file
202
     * @param string $fullPath Local file path
203
     * @return bool True if success
204
     */
205
    public function write($fullPath)
206
    {
207
        $fileName = basename($fullPath);
208
209
        $this->log('Uploading file [##]', $fullPath);
210
211
        // Copy file to remote
212
        if (ftp_put($this->handle, $fileName, $fullPath, FTP_BINARY)) {
213
            // Change rights
214
            ftp_chmod($this->handle, 0755, $fileName);
215
216
            $this->log('-- Success [##]', $fullPath);
217
218
            return true;
219
        } else {
220
            $this->log('-- Failed [##]', $fullPath);
221
        }
222
223
        return false;
224
    }
225
}
226