1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Tidypics Album class |
4
|
|
|
* |
5
|
|
|
* @package TidypicsAlbum |
6
|
|
|
* @author Cash Costello |
7
|
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
|
11
|
|
|
class TidypicsAlbum extends ElggObject { |
12
|
|
|
/** |
13
|
|
|
* Sets the internal attributes |
14
|
|
|
*/ |
15
|
|
|
protected function initializeAttributes() { |
16
|
|
|
parent::initializeAttributes(); |
17
|
|
|
|
18
|
|
|
$this->attributes['subtype'] = "album"; |
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Constructor |
23
|
|
|
* @param mixed $guid |
24
|
|
|
*/ |
25
|
|
|
public function __construct($guid = null) { |
26
|
|
|
parent::__construct($guid); |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Save an album |
31
|
|
|
* |
32
|
|
|
* @return bool |
33
|
|
|
*/ |
34
|
|
|
public function save() { |
35
|
|
|
|
36
|
|
|
if (!isset($this->new_album)) { |
37
|
|
|
$this->new_album = true; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
if (!isset($this->last_notified)) { |
41
|
|
|
$this->last_notified = 0; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
if (!parent::save()) { |
45
|
|
|
return false; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
mkdir(tp_get_img_dir($this->guid), 0755, true); |
49
|
|
|
|
50
|
|
|
return true; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Delete album |
55
|
|
|
* |
56
|
|
|
* @return bool |
57
|
|
|
*/ |
58
|
|
|
public function delete() { |
59
|
|
|
|
60
|
|
|
$this->deleteImages(); |
61
|
|
|
$this->deleteAlbumDir(); |
62
|
|
|
|
63
|
|
|
return parent::delete(); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Get the title of the photo album |
68
|
|
|
* |
69
|
|
|
* @return string |
70
|
|
|
*/ |
71
|
|
|
public function getTitle() { |
72
|
|
|
return $this->title; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Get the URL for this album |
77
|
|
|
* |
78
|
|
|
* @return string |
79
|
|
|
*/ |
80
|
|
|
public function getURL() { |
81
|
|
|
$title = elgg_get_friendly_title($this->getTitle()); |
82
|
|
|
$url = "photos/album/$this->guid/$title"; |
83
|
|
|
return elgg_normalize_url($url); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Get an array of image objects |
88
|
|
|
* |
89
|
|
|
* @param int $limit |
90
|
|
|
* @param int $offset |
91
|
|
|
* @return array |
92
|
|
|
*/ |
93
|
|
|
public function getImages($limit, $offset = 0) { |
94
|
|
|
$imageList = $this->getImageList(); |
95
|
|
|
if ($offset > count($imageList)) { |
96
|
|
|
return array(); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
$imageList = array_slice($imageList, $offset, $limit); |
100
|
|
|
|
101
|
|
|
$images = array(); |
102
|
|
|
foreach ($imageList as $guid) { |
103
|
|
|
$images[] = get_entity($guid); |
104
|
|
|
} |
105
|
|
|
return $images; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* View a list of images |
110
|
|
|
* |
111
|
|
|
* @param array $options Options to pass to elgg_view_entity_list() |
112
|
|
|
* @return string |
113
|
|
|
*/ |
114
|
|
|
public function viewImages(array $options = array()) { |
115
|
|
|
$count = $this->getSize(); |
116
|
|
|
|
117
|
|
|
if ($count == 0) { |
118
|
|
|
return ''; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
$defaults = array( |
122
|
|
|
'count' => $count, |
123
|
|
|
'limit' => (int)get_input('limit', 16), |
124
|
|
|
'offset' => (int)get_input('offset', 0), |
125
|
|
|
'full_view' => false, |
126
|
|
|
'list_type' => 'gallery', |
127
|
|
|
'list_type_toggle' => false, |
128
|
|
|
'pagination' => true, |
129
|
|
|
'gallery_class' => 'tidypics-gallery', |
130
|
|
|
); |
131
|
|
|
|
132
|
|
|
$options = array_merge($defaults, (array) $options); |
133
|
|
|
$images = $this->getImages($options['limit'], $options['offset']); |
134
|
|
|
|
135
|
|
|
if (count($images) == 0) { |
136
|
|
|
return ''; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
return elgg_view_entity_list($images, $options); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Returns the cover image entity |
144
|
|
|
* @return TidypicsImage |
145
|
|
|
*/ |
146
|
|
|
public function getCoverImage() { |
147
|
|
|
return get_entity($this->getCoverImageGuid()); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Get the GUID of the album cover |
152
|
|
|
* |
153
|
|
|
* @return int |
154
|
|
|
*/ |
155
|
|
|
public function getCoverImageGuid() { |
156
|
|
|
if ($this->getSize() == 0) { |
157
|
|
|
return 0; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
$guid = $this->cover; |
161
|
|
|
$imageList = $this->getImageList(); |
162
|
|
|
if (!in_array($guid, $imageList)) { |
163
|
|
|
// select random photo to be cover |
164
|
|
|
$index = array_rand($imageList, 1); |
165
|
|
|
$guid = $imageList[$index]; |
166
|
|
|
$this->cover = $guid; |
167
|
|
|
} |
168
|
|
|
return $guid; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Set the GUID for the album cover |
173
|
|
|
* |
174
|
|
|
* @param int $guid |
175
|
|
|
* @return bool |
176
|
|
|
*/ |
177
|
|
|
public function setCoverImageGuid($guid) { |
178
|
|
|
$imageList = $this->getImageList(); |
179
|
|
|
if (!in_array($guid, $imageList)) { |
180
|
|
|
return false; |
181
|
|
|
} |
182
|
|
|
$this->cover = $guid; |
183
|
|
|
return true; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Get the number of photos in the album |
188
|
|
|
* |
189
|
|
|
* @return int |
190
|
|
|
*/ |
191
|
|
|
public function getSize() { |
192
|
|
|
return count($this->getImageList()); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Returns an order list of image guids |
197
|
|
|
* |
198
|
|
|
* @return array |
199
|
|
|
*/ |
200
|
|
|
public function getImageList() { |
201
|
|
|
$listString = $this->orderedImages; |
202
|
|
|
if (!$listString) { |
203
|
|
|
return array(); |
204
|
|
|
} |
205
|
|
|
$list = unserialize($listString); |
206
|
|
|
|
207
|
|
|
// if empty don't need to check the permissions. |
208
|
|
|
if (!$list) { |
209
|
|
|
return array(); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
// check access levels |
213
|
|
|
$guidsString = implode(',', $list); |
214
|
|
|
|
215
|
|
|
$options = array( |
216
|
|
|
'wheres' => array("e.guid IN ($guidsString)"), |
217
|
|
|
'order_by' => "FIELD(e.guid, $guidsString)", |
218
|
|
|
'callback' => 'tp_guid_callback', |
219
|
|
|
'limit' => ELGG_ENTITIES_NO_VALUE |
220
|
|
|
); |
221
|
|
|
|
222
|
|
|
$list = elgg_get_entities($options); |
223
|
|
|
return $list; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Sets the album image order |
228
|
|
|
* |
229
|
|
|
* @param array $list An indexed array of image guids |
230
|
|
|
* @return bool |
231
|
|
|
*/ |
232
|
|
|
public function setImageList($list) { |
233
|
|
|
// validate data |
234
|
|
|
foreach ($list as $guid) { |
235
|
|
|
if (!filter_var($guid, FILTER_VALIDATE_INT)) { |
236
|
|
|
return false; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
$listString = serialize($list); |
241
|
|
|
$this->orderedImages = $listString; |
242
|
|
|
return true; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* Add new images to the front of the image list |
247
|
|
|
* |
248
|
|
|
* @param array $list An indexed array of image guids |
249
|
|
|
* @return bool |
250
|
|
|
*/ |
251
|
|
|
public function prependImageList($list) { |
252
|
|
|
$currentList = $this->getImageList(); |
253
|
|
|
$list = array_merge($list, $currentList); |
254
|
|
|
return $this->setImageList($list); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Get the previous image in the album. Wraps around to the last image if given the first. |
259
|
|
|
* |
260
|
|
|
* @param int $guid GUID of the current image |
261
|
|
|
* @return TidypicsImage |
262
|
|
|
*/ |
263
|
|
View Code Duplication |
public function getPreviousImage($guid) { |
|
|
|
|
264
|
|
|
$imageList = $this->getImageList(); |
265
|
|
|
$key = array_search($guid, $imageList); |
266
|
|
|
if ($key === FALSE) { |
267
|
|
|
return null; |
268
|
|
|
} |
269
|
|
|
$key--; |
270
|
|
|
if ($key < 0) { |
271
|
|
|
return get_entity(end($imageList)); |
272
|
|
|
} |
273
|
|
|
return get_entity($imageList[$key]); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* Get the next image in the album. Wraps around to the first image if given the last. |
278
|
|
|
* |
279
|
|
|
* @param int $guid GUID of the current image |
280
|
|
|
* @return TidypicsImage |
281
|
|
|
*/ |
282
|
|
View Code Duplication |
public function getNextImage($guid) { |
|
|
|
|
283
|
|
|
$imageList = $this->getImageList(); |
284
|
|
|
$key = array_search($guid, $imageList); |
285
|
|
|
if ($key === FALSE) { |
286
|
|
|
return null; |
287
|
|
|
} |
288
|
|
|
$key++; |
289
|
|
|
if ($key >= count($imageList)) { |
290
|
|
|
return get_entity($imageList[0]); |
291
|
|
|
} |
292
|
|
|
return get_entity($imageList[$key]); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Get the index into the album for a particular image |
297
|
|
|
* |
298
|
|
|
* @param int $guid GUID of the image |
299
|
|
|
* @return int |
300
|
|
|
*/ |
301
|
|
|
public function getIndex($guid) { |
302
|
|
|
return array_search($guid, $this->getImageList()) + 1; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Remove an image from the album list |
307
|
|
|
* |
308
|
|
|
* @param int $imageGuid |
309
|
|
|
* @return bool |
310
|
|
|
*/ |
311
|
|
|
public function removeImage($imageGuid) { |
312
|
|
|
$imageList = $this->getImageList(); |
313
|
|
|
$key = array_search($imageGuid, $imageList); |
314
|
|
|
if ($key === false) { |
315
|
|
|
return false; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
unset($imageList[$key]); |
319
|
|
|
$this->setImageList($imageList); |
320
|
|
|
|
321
|
|
|
return true; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* Has enough time elapsed between the last_notified and notify_interval setting? |
326
|
|
|
* |
327
|
|
|
* @return bool |
328
|
|
|
*/ |
329
|
|
|
public function shouldNotify() { |
330
|
|
|
return time() - $this->last_notified > elgg_get_plugin_setting('notify_interval', 'tidypics'); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* Delete all the images in this album |
335
|
|
|
*/ |
336
|
|
|
protected function deleteImages() { |
337
|
|
|
$images_count = elgg_get_entities(array( |
338
|
|
|
"type" => "object", |
339
|
|
|
"subtype" => "image", |
340
|
|
|
"container_guid" => $this->guid, |
341
|
|
|
"count" => true, |
342
|
|
|
)); |
343
|
|
|
if ($images_count > 0) { |
344
|
|
|
$images = new ElggBatch('elgg_get_entities', array( |
345
|
|
|
"type" => "object", |
346
|
|
|
"subtype" => "image", |
347
|
|
|
"container_guid" => $this->guid, |
348
|
|
|
"limit" => ELGG_ENTITIES_NO_VALUE, |
349
|
|
|
)); |
350
|
|
|
$images->setIncrementOffset(false); |
351
|
|
|
foreach ($images as $image) { |
352
|
|
|
if ($image) { |
353
|
|
|
$image->delete(); |
354
|
|
|
} |
355
|
|
|
} |
356
|
|
|
} |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* Delete the album directory on disk |
361
|
|
|
*/ |
362
|
|
|
protected function deleteAlbumDir() { |
363
|
|
|
$tmpfile = new ElggFile(); |
364
|
|
|
$tmpfile->setFilename('image/' . $this->guid . '/._tmp_del_tidypics_album_'); |
365
|
|
|
$tmpfile->subtype = 'image'; |
366
|
|
|
$tmpfile->owner_guid = $this->owner_guid; |
367
|
|
|
$tmpfile->container_guid = $this->guid; |
368
|
|
|
$tmpfile->open("write"); |
369
|
|
|
$tmpfile->write(''); |
370
|
|
|
$tmpfile->close(); |
371
|
|
|
$tmpfile->save(); |
372
|
|
|
$albumdir = eregi_replace('/._tmp_del_tidypics_album_', '', $tmpfile->getFilenameOnFilestore()); |
373
|
|
|
$tmpfile->delete(); |
374
|
|
|
|
375
|
|
|
// sanity check: must be a directory |
376
|
|
|
if (!$handle = opendir($albumdir)) { |
377
|
|
|
return false; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
// loop through all files that might still remain undeleted in this directory and delete them |
381
|
|
|
// note: this does not delete the corresponding image entities from the database |
382
|
|
|
while (($file = readdir($handle)) !== false) { |
383
|
|
|
if (in_array($file, array('.', '..'))) { |
384
|
|
|
continue; |
385
|
|
|
} |
386
|
|
|
$path = "$albumdir/$file"; |
387
|
|
|
unlink($path); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
// remove empty directory |
391
|
|
|
closedir($handle); |
392
|
|
|
return rmdir($albumdir); |
393
|
|
|
} |
394
|
|
|
} |
395
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.