1: <?php
2:
3: App::uses('UndoableOperation', 'Operations.Lib');
4: App::uses('CommitableOperation', 'Operations.Lib');
5:
6: class FileOperations {
7:
8: public static function touch($fileName) {
9: return new FileOperations_Touch($fileName);
10: }
11:
12: public static function unlink($fileName) {
13: return new FileOperations_Unlink($fileName);
14: }
15:
16: public static function rename($oldFile, $newFile) {
17: return new FileOperations_Rename($oldFile, $newFile);
18: }
19:
20: public static function symLink($target, $link) {
21: return new FileOperations_SymLink($target, $link);
22: }
23:
24: }
25:
26: class FileOperations_Touch implements UndoableOperation {
27:
28: private $fileName;
29:
30: 31: 32: 33:
34: private $alreadyExists;
35:
36: public function __construct($fileName) {
37: $this->fileName = $fileName;
38: }
39:
40: public function run() {
41: $this->alreadyExists = file_exists($this->fileName);
42: return touch($this->fileName);
43: }
44:
45: public function undo() {
46: if (!$this->alreadyExists) {
47: @unlink($this->fileName);
48: }
49: }
50:
51: public function __toString() {
52: return __CLASS__ . "({$this->fileName})";
53: }
54:
55: }
56:
57: class FileOperations_Unlink implements CommitableOperation {
58:
59: private $fileName;
60: private $tempFile = null;
61:
62: public function __construct($fileName) {
63: $this->fileName = $fileName;
64: }
65:
66: public function run() {
67: if ($this->tempFile) {
68: throw new Exception("Temporary file already generated");
69: }
70: $this->tempFile = tempnam(dirname($this->fileName), '.FileOperations_Unlink_TempFile');
71: @unlink($this->tempFile);
72: return @rename($this->fileName, $this->tempFile);
73: }
74:
75: public function undo() {
76: if ($this->tempFile) {
77: @rename($this->tempFile, $this->fileName);
78: }
79: }
80:
81: public function commit() {
82: if ($this->tempFile) {
83: @unlink($this->tempFile);
84: }
85: }
86:
87: public function __toString() {
88: return __CLASS__ . "({$this->fileName})";
89: }
90:
91: }
92:
93: class FileOperations_Rename implements UndoableOperation {
94:
95: private $oldFile;
96: private $newFile;
97:
98: public function __construct($oldFile, $newFile) {
99: $this->oldFile = $oldFile;
100: $this->newFile = $newFile;
101: }
102:
103: public function run() {
104: return rename($this->oldFile, $this->newFile);
105: }
106:
107: public function undo() {
108: return rename($this->newFile, $this->oldFile);
109: }
110:
111: public function __toString() {
112: return __CLASS__ . "({$this->oldFile} => {$this->newFile})";
113: }
114:
115: }
116:
117: class FileOperations_SymLink implements UndoableOperation {
118:
119: private $target;
120: private $link;
121:
122: public function __construct($target, $link) {
123: $this->target = $target;
124: $this->link = $link;
125: }
126:
127: public function run() {
128: return symlink($this->target, $this->link);
129: }
130:
131: public function undo() {
132: @unlink($this->link);
133: }
134:
135: public function __toString() {
136: return __CLASS__ . "({$this->target} => {$this->link})";
137: }
138:
139: }