1 | <?php |
||
2 | |||
3 | namespace phpbu\App\Backup\Sync; |
||
4 | |||
5 | use Arhitector\Yandex\Disk; |
||
6 | use phpbu\App\Backup\Collector; |
||
7 | use phpbu\App\Backup\Sync; |
||
8 | use phpbu\App\Backup\Target; |
||
9 | use phpbu\App\Result; |
||
10 | use phpbu\App\Util\Arr; |
||
11 | use phpbu\App\Util\Path; |
||
12 | |||
13 | /** |
||
14 | * Yandex.Disk |
||
15 | * |
||
16 | * @package phpbu |
||
17 | * @subpackage Backup |
||
18 | * @author Sebastian Feldmann <[email protected]> |
||
19 | * @author Alexander Palchikov AxelPAL <[email protected]> |
||
20 | * @copyright Sebastian Feldmann <[email protected]> |
||
21 | * @license https://opensource.org/licenses/MIT The MIT License (MIT) |
||
22 | * @link http://phpbu.de/ |
||
23 | */ |
||
24 | class YandexDisk implements Sync\Simulator |
||
25 | { |
||
26 | use Cleanable; |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
27 | /** |
||
28 | * API access token |
||
29 | * Goto https://oauth.yandex.ru/client/new |
||
30 | * create your app |
||
31 | * - Check all Disks permissions |
||
32 | * - generate access token: |
||
33 | * 1) Goto https://oauth.yandex.ru/authorize?response_type=token&client_id=APP_ID |
||
34 | * (replace APP_ID with ID giving to you) |
||
35 | * 2) Then you should get token parameter from GET-parameters of opened page |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | protected $token; |
||
40 | |||
41 | /** |
||
42 | * Remote path |
||
43 | * |
||
44 | * @var \phpbu\App\Backup\Path |
||
45 | */ |
||
46 | protected $path; |
||
47 | |||
48 | /** |
||
49 | * @var Disk |
||
50 | */ |
||
51 | protected $disk; |
||
52 | |||
53 | /** |
||
54 | * Unix timestamp of generating path from placeholder. |
||
55 | * |
||
56 | * @var int |
||
57 | */ |
||
58 | protected $time; |
||
59 | |||
60 | /** |
||
61 | * (non-PHPDoc) |
||
62 | * |
||
63 | * @param array $config |
||
64 | * @throws Exception |
||
65 | * @throws \phpbu\App\Exception |
||
66 | * @see \phpbu\App\Backup\Sync::setup() |
||
67 | 8 | */ |
|
68 | public function setup(array $config): void |
||
69 | 8 | { |
|
70 | if (!class_exists(Disk::class)) { |
||
71 | throw new Exception('Yandex.Disk sdk not loaded: use composer to install "arhitector/yandex"'); |
||
72 | 8 | } |
|
73 | 1 | if (!Arr::isSetAndNotEmptyString($config, 'token')) { |
|
74 | throw new Exception('API access token is mandatory'); |
||
75 | 7 | } |
|
76 | 1 | if (!Arr::isSetAndNotEmptyString($config, 'path')) { |
|
77 | throw new Exception('yandex.disk path is mandatory'); |
||
78 | 6 | } |
|
79 | 6 | $this->token = $config['token']; |
|
80 | $this->path = new \phpbu\App\Backup\Path(Path::withLeadingSlash($config['path']), time()); |
||
81 | 6 | ||
82 | 6 | $this->setUpCleanable($config); |
|
83 | } |
||
84 | |||
85 | /** |
||
86 | * (non-PHPDoc) |
||
87 | * |
||
88 | * @param Target $target |
||
89 | * @param Result $result |
||
90 | * @throws Exception |
||
91 | * @see \phpbu\App\Backup\Sync::sync() |
||
92 | 3 | */ |
|
93 | public function sync(Target $target, Result $result): void |
||
94 | 3 | { |
|
95 | 3 | $sourcePath = $target->getPathname(); |
|
96 | 3 | $yandexDiskPath = $this->path . '/' . $target->getFilename(); |
|
97 | $this->createDisk(); |
||
98 | 3 | ||
99 | 3 | $size = null; |
|
100 | if (stream_is_local($sourcePath) && file_exists($sourcePath)) { |
||
101 | $size = filesize($sourcePath); |
||
102 | } |
||
103 | |||
104 | 3 | try { |
|
105 | 3 | $this->createFolders(); |
|
106 | 3 | $file = $this->createDisk()->getResource($yandexDiskPath); |
|
107 | 2 | $file->upload($sourcePath, true); |
|
108 | if ($file->has()) { |
||
109 | $result->debug('upload: done (' . $size . ')'); |
||
110 | 2 | } else { |
|
111 | $result->debug('upload: error while uploading file'); |
||
112 | 2 | } |
|
113 | 1 | $this->cleanup($target, $result); |
|
114 | 1 | } catch (\Exception $e) { |
|
115 | throw new Exception($e->getMessage(), null, $e); |
||
116 | 2 | } |
|
117 | } |
||
118 | 3 | ||
119 | private function createFolders(): void |
||
120 | 3 | { |
|
121 | 3 | $folderPath = ''; |
|
122 | 3 | $folderPaths = explode('/', $this->path->getPath()); |
|
123 | 3 | if (!empty($folderPaths)) { |
|
124 | 3 | foreach ($folderPaths as $folderPathPart) { |
|
125 | if (!empty($folderPathPart)) { |
||
126 | $folderPath .= "/$folderPathPart"; |
||
127 | $file = $this->createDisk()->getResource($folderPath); |
||
128 | 3 | if (!$file->has()) { |
|
129 | $file->create(); |
||
130 | } |
||
131 | } |
||
132 | } |
||
133 | 3 | } |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * Simulate the sync execution. |
||
138 | * |
||
139 | * @param Target $target |
||
140 | * @param Result $result |
||
141 | 2 | */ |
|
142 | public function simulate(Target $target, Result $result): void |
||
143 | 2 | { |
|
144 | $result->debug('sync backup to yandex disk' . PHP_EOL); |
||
145 | 2 | ||
146 | 2 | $this->isSimulation = true; |
|
147 | 2 | $this->simulateRemoteCleanup($target, $result); |
|
148 | } |
||
149 | |||
150 | /** |
||
151 | * Creates the YandexDisk collector. |
||
152 | * |
||
153 | * @param Target $target |
||
154 | * @return Collector |
||
155 | 1 | */ |
|
156 | protected function createCollector(Target $target): Collector |
||
157 | 1 | { |
|
158 | 1 | $collector = new Collector\YandexDisk($target, $this->path, $this->createDisk()); |
|
159 | $collector->setSimulation($this->isSimulation); |
||
160 | 1 | ||
161 | return $collector; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Create a YandexDisk api client. |
||
166 | * |
||
167 | * @return Disk |
||
168 | */ |
||
169 | protected function createDisk(): Disk |
||
170 | { |
||
171 | if (!$this->disk) { |
||
172 | $this->disk = new Disk($this->token); |
||
173 | } |
||
174 | return $this->disk; |
||
175 | } |
||
176 | } |
||
177 |