File   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 4
dl 0
loc 198
c 0
b 0
f 0
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get_pathname() 0 16 4
A get_short_hash() 0 4 2
A get_file_storage() 0 4 1
B save() 0 23 4
A delete() 0 11 2
A save_file_before() 0 12 2
A save_file_after() 0 12 2
B url() 0 26 4
1
<?php
2
3
/*
4
 * This file is part of the Icybee package.
5
*
6
* (c) Olivier Laviale <[email protected]>
7
*
8
* For the full copyright and license information, please view the LICENSE
9
* file that was distributed with this source code.
10
*/
11
12
namespace Icybee\Modules\Files;
13
14
use ICanBoogie\HTTP\File as HTTPFile;
15
16
use Icybee\Binding\Core\PrototypedBindings;
17
use Icybee\Modules\Files\Storage\Pathname;
18
use Icybee\Modules\Nodes\Node;
19
20
/**
21
 * Representation of a managed file.
22
 *
23
 * @property-read \ICanBoogie\Core|\Icybee\Binding\Core\CoreBindings|Binding\CoreBindings $app
24
 * @property-read Storage\FileStorage $file_storage
25
 * @property-read Pathname $pathname Absolute path to the file.
26
 * @property-read string $short_hash
27
 */
28
class File extends Node
29
{
30
	use PrototypedBindings;
31
32
	const MODEL_ID = 'files';
33
34
	const MIME = 'mime';
35
	const SIZE = 'size';
36
	const EXTENSION = 'extension';
37
	const DESCRIPTION = 'description';
38
	const HTTP_FILE = 'file';
39
40
	/**
41
	 * Size of the file.
42
	 *
43
	 * @var int
44
	 */
45
	public $size;
46
47
	/**
48
	 * MIME type of the file.
49
	 *
50
	 * @var string
51
	 */
52
	public $mime;
53
54
	/**
55
	 * File extension, including the dot ".".
56
	 *
57
	 * @var string
58
	 */
59
	public $extension = '';
60
61
	/**
62
	 * Description of the file.
63
	 *
64
	 * @var string
65
	 */
66
	public $description = '';
67
68
	/**
69
	 * @return Pathname|null
70
	 */
71
	protected function get_pathname()
72
	{
73
		if (!$this->nid && !$this->uuid)
74
		{
75
			return null;
76
		}
77
78
		$pathname = $this->file_storage->find($this->uuid);
79
80
		if (!$pathname)
81
		{
82
			throw new \LogicException("Unable to retrieve pathname for {$this->uuid}.");
83
		}
84
85
		return $pathname;
86
	}
87
88
	/**
89
	 * @var string
90
	 */
91
	protected $short_hash;
92
93
	/**
94
	 * Returns the short hash of the file.
95
	 *
96
	 * @return string
97
	 */
98
	protected function get_short_hash()
99
	{
100
		return $this->short_hash ?: $this->pathname->short_hash;
101
	}
102
103
	/**
104
	 * @return Storage\FileStorage
105
	 */
106
	protected function get_file_storage()
107
	{
108
		return $this->app->file_storage;
109
	}
110
111
	/**
112
	 * If {@link HTTP_FILE} is defined, the {@link HTTPFile} instance is used to
113
	 * set the {@link $mime}, {@link $size} and {@link $extension} properties.
114
	 * The {@link $title} property is updated as well if it is empty.
115
	 *
116
	 * After the record is saved, the {@link HTTP_FILE} property is removed.
117
	 *
118
	 * @inheritdoc
119
	 */
120
	public function save(array $options = [])
121
	{
122
		/* @var $file HTTPFile */
123
124
		$file = null;
125
126
		if (isset($this->{ self::HTTP_FILE }))
127
		{
128
			$file = $this->{ self::HTTP_FILE };
129
			$this->save_file_before($file);
130
		}
131
132
		$rc = parent::save($options);
133
134
		if ($rc && $file)
135
		{
136
			unset($this->{ self::HTTP_FILE });
137
138
			$this->save_file_after($file);
139
		}
140
141
		return $rc;
142
	}
143
144
	public function delete()
145
	{
146
		$rc = parent::delete();
147
148
		if ($rc)
149
		{
150
			$this->file_storage->release($this->uuid);
151
		}
152
153
		return $rc;
154
	}
155
156
	/**
157
	 * Begins saving the HTTP file.
158
	 *
159
	 * @param HTTPFile $file
160
	 */
161
	protected function save_file_before(HTTPFile $file)
162
	{
163
		$this->mime = $file->type;
164
		$this->size = $file->size;
165
		$this->extension = $file->extension;
166
		$this->short_hash = Pathname::short_hash($file->pathname);
167
168
		if (!$this->title)
169
		{
170
			$this->title = $file->unsuffixed_name;
171
		}
172
	}
173
174
	/**
175
	 * Finishes saving the HTTP file.
176
	 *
177
	 * @param HTTPFile $file
178
	 */
179
	protected function save_file_after(HTTPFile $file)
180
	{
181
		$storage = $this->file_storage;
182
		$pathname = $storage->create_pathname($file->pathname);
183
184
		if (!file_exists($pathname))
185
		{
186
			$file->move($pathname);
187
		}
188
189
		$storage->index($this->nid, $this->uuid, $pathname->hash);
190
	}
191
192
	/**
193
	 * Returns a URL for this record.
194
	 *
195
	 * @param string $type
196
	 *
197
	 * @return \ICanBoogie\Routing\FormattedRoute|string
198
	 */
199
	public function url($type = 'view')
200
	{
201
		$routes = $this->app->routes;
202
		$route_id = "{$this->constructor}/$type";
203
204
		if (isset($routes[$route_id]))
205
		{
206
			return $routes[$route_id]->format($this);
207
		}
208
209
		$route_id = "{$this->constructor}:$type";
210
211
		if (isset($routes[$route_id]))
212
		{
213
			return $routes[$route_id]->format($this);
214
		}
215
216
		$route_id = "files:$type";
217
218
		if (isset($routes[$route_id]))
219
		{
220
			return $routes[$route_id]->format($this);
221
		}
222
223
		return parent::url($type);
224
	}
225
}
226