Blame view

sources/apps/updater/lib/location.php 2.77 KB
d1bafeea1   Kload   [fix] Upgrade to ...
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
122
123
124
125
126
127
128
129
  <?php
  
  /**
   * ownCloud - Updater plugin
   *
   * @author Victor Dubiniuk
   * @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com
   *
   * This file is licensed under the Affero General Public License version 3 or
   * later.
   */
  
  namespace OCA\Updater;
  
  abstract class Location {
  
  	// Path to current instance sources
  	protected $oldBase;
  	// Path to new instance sources
  	protected $newBase;
  	// Type of sources (3rdparty | apps | core)
  	protected $type = 'generic';
  	// Already moved items are collected here;
  	protected $done = array();
  
  	public function __construct($oldBase, $newBase) {
  		$this->oldBase = $oldBase;
  		$this->newBase = $newBase;
  	}
  
  	public function check() {
  		$errors = array();
  
  		if ($this->oldBase && !is_writable($this->oldBase)) {
  			$errors[] = $this->oldBase;
  		}
  
  		$collected = $this->collect(true);
  		foreach ($collected['old'] as $item) {
  			if (!is_writable($item)) {
  				$errors[] = $item;
  			}
  		}
  		
  		return $errors;
  	}
  
  	// Move sources 
  	public function update($tmpDir = '') {
  		Helper::mkdir($tmpDir, true);
  		$collected = $this->collect();
  
  		try {
  			foreach ($collected['old'] as $src) {
  				$dst = str_replace($this->oldBase, $tmpDir, $src);
  				Helper::move($src, $dst);
  
  				// ! reverted intentionally
  				$this->done [] = array(
  					'dst' => $src,
  					'src' => $dst
  				);
  			}
  
  			foreach ($collected['new'] as $src) {
  				$dst = str_replace($this->newBase, $this->oldBase, $src);
  				Helper::move($src, $dst);
  			}
  
  			$this->finalize();
  		} catch (\Exception $e) {
  			$this->rollback(true);
  			throw $e;
  		}
  	}
  
  	// Extra steps needed
  	protected function finalize() {
  		App::log('Success: ' . $this->type, \OC_Log::INFO);
  	}
  
  	// Move sources back on Error
  	public final function rollback($log = false) {
  		if ($log) {
  			App::log('Something went wrong for ' . $this->type . '. Rolling back.');
  		}
  		foreach ($this->done as $item) {
  			Helper::copyr($item['src'], $item['dst'], false);
  		}
  	}
  
  	// Aggregate current sources
  	public function collect($dryRun = false) {
  		$oldSources = $this->filterOld(
  				Helper::scandir($this->oldBase)
  		);
  
  		$collected = array(
  			'old' => $this->toAbsolute($this->oldBase, $oldSources),
  			'new' => array()
  		);
  
  		if (!$dryRun) {
  			$newSources = $this->filterNew(
  					Helper::scandir($this->newBase)
  			);
  			$collected['new'] = $this->toAbsolute($this->newBase, $newSources);
  		}
  
  		return $collected;
  	}
  
  	protected function toAbsolute($base, $pathArray) {
  		$result = array();
  		foreach ($pathArray as $path) {
  			// There is a little sense to make these entries absolute
  			if (!in_array($path, array('.', '..'))) {
  				$result [$path] = $base . '/' . $path;
  			}
  		}
  		return $result;
  	}
  
  	// Filter input 
  	abstract protected function filterOld($pathArray);
  
  	// Filter input 
  	abstract protected function filterNew($pathArray);
  }