File: find_orphans.php

package info (click to toggle)
gallery 1.5-1sarge2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 21,172 kB
  • ctags: 4,516
  • sloc: php: 26,456; sh: 427; perl: 188; makefile: 58; xml: 48
file content (325 lines) | stat: -rw-r--r-- 10,251 bytes parent folder | download
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
<?php
/*
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2005 Bharat Mediratta
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id: find_orphans.php,v 1.21.2.2 2005/03/10 02:36:37 cryptographite Exp $
 */
?>
<?php

if (!isset($gallery->version)) {
        require_once(dirname(dirname(__FILE__)) . '/init.php');
}

$action = getRequestVar('action');

// Security check
if (!$gallery->user->isAdmin()) {
	header("Location: " . makeAlbumHeaderUrl());
	exit;
}

$albumDB = new AlbumDB();

function attachOrphanedAlbums($orphans) {
	global $albumDB;
	foreach ($orphans as $childname => $parentname) {
		if ($parentname == 0) {
			// Parent was deleted - attach it to root
			$child = $albumDB->getAlbumByName($childname);
			$child->fields['parentAlbumName'] = 0;
			while ($child->save() != true);
			continue;
		}
		
		$parent = $albumDB->getAlbumByName($parentname);
		$parent->addNestedAlbum($childname);
	
		// Set a default highlight if appropriate, for the parent
		if ($parent->numPhotos(1) == 1) {
			$parent->setHighlight(1);
		}
	
		// If the machine is fast, it can find a new album before it
		// has time to finish physically saving the last one.
		// Keep trying to save until it works.
		while ($parent->save() != true);
	}
}

function findOrphanedAlbums() {
	global $albumDB;
	$orphaned = Array();
	foreach ($albumDB->albumList as $album) {
		
		// Root albums can't be orphans
		if ($album->isRoot()) {
			continue;
		}
	
		$parent = $album->getParentAlbum();
	
		if (!isset($parent) || !isset($parent->fields['name'])) {
			// Orphaned, but the parent album is missing - link it to root
			$orphaned[$album->fields['name']] = 0;
			continue;
		}
	
		// Search for a filename match in the parent album
		if (!empty($parent->photos)) {
			foreach ($parent->photos as $photo) {
				if ($photo->isAlbum() && ($photo->getAlbumName() == $album->fields['name'])) {
					// Found a matching name - this is not an orphaned album
					// continue from outer loop
					continue 2;
				}
			}
		}
	
		// "Orphaned Album => Parent Album"
		$orphaned[$album->fields['name']] = $parent->fields['name'];
	}
	
	// Sort the array by value (parent) so it can be displayed to the user
	asort($orphaned);
	return $orphaned;
}

function findOrphanedImages() {
	global $gallery, $albumDB;

	$orphans = Array();

	// "." covers the "." and ".." dir entries
	$ignoreFiles = array('.', 'dat', 'bak', 'lock');

	foreach ($albumDB->albumList as $album) {

		// Get the album name, build the album path, open the directory
		$albumName = $album->fields['name'];
		$albumDir = $gallery->app->albumDir . "/" . $albumName;
		$dirhandle = fs_opendir($albumDir);

		// Storage array
		$albumFiles = array();

		// Retrieve each file until the directory ends
		// Skip the files which have arrays in the ignoreFiles array
		while (false !== ($file = readdir($dirhandle))) { 
			$file = pathinfo($file);

			if (empty($file['extension']) || in_array($file['extension'], $ignoreFiles))
				continue;

			$albumFiles[$file['basename']] = 1;
		} 

		// Don't bother doing anything if there are no orphans
		if (sizeof($albumFiles)) {

			// Only check subkeys if the album has photos
			if (!empty($album->photos)) {
				foreach ($album->photos as $photo) {
					foreach ($photo as $image) {

						// Theoretically we know which keys hold image locations, 
						// however this is to be absolutely safe as we go forward
						// in case any new keys are added

   						// Since we're iterating through the entire AlbumItem class looking for files
						// we know we can skip any objects that aren't of the class "Image"
						if (strcasecmp(get_class($image), "Image")) {
							continue;
	
						// If we encounter a file that's in the AlbumItem, and in the file array
						// purge it, because it's valid
						} elseif (isset($albumFiles[$image->name . "." . $image->type])) {
							unset($albumFiles[$image->name . "." . $image->type]);
						}

						// Resized files have to be handled separately
						if (!empty($image->resizedName) && isset($albumFiles[$image->resizedName . "." . $image->type])) {
							unset($albumFiles[$image->resizedName . "." . $image->type]);
						}
					}
				}
			}

			// Make sure the array isn't empty
			// It is valid to get here even if the album has no _valid_ photos
			if (sizeof($albumFiles)) {
				$orphans[$albumName] = $albumFiles;
			}
		}
	}

	asort($orphans);
	return $orphans;
}

function deleteOrphanedImages($orphans) {
	global $gallery;
	$unwriteableFiles = array();

	foreach ($orphans as $albumName => $imageVal) {
		foreach (array_keys($imageVal) as $fileName) {
			$deleteFile = $gallery->app->albumDir . "/" . $albumName . "/" . $fileName;
			if (! fs_unlink($deleteFile)) {
				$unwriteableFiles[] = $deleteFile;
			}
		}
	}
	return $unwriteableFiles;
}

clearstatcache() ;
$orphanAlbums = findOrphanedAlbums();
$orphanImages = findOrphanedImages();

global $GALLERY_EMBEDDED_INSIDE;
if (!$GALLERY_EMBEDDED_INSIDE) {
	doctype();
?>
<html>
<head>
<title><?php echo $gallery->app->galleryTitle ?>::<?php echo _("Find Orphans"); ?></title>
<?php 
	common_header();
?>
</head>
<body dir="<?php echo $gallery->direction ?>">
<?php 
} 
        includeHtmlWrap("gallery.header");
?>
<div class="popuphead"><?php echo _("Find Orphans") ?></div>
<?php

$adminCommands = '[<a href="'. makeGalleryUrl("admin-page.php") .'">'. _("return to admin page") .'</a>] ';
$adminCommands .= '[<a href="'. makeAlbumUrl() .'">'. _("return to gallery") .'</a>] ';

$adminbox["commands"] = $adminCommands;
$adminbox["bordercolor"] = $gallery->app->default["bordercolor"];
includeLayout('adminbox.inc');
includeLayout('ml_pulldown.inc');

echo '<div class="popup">';
if (empty($action)) { 
	if (!empty($orphanAlbums)) { ?>
		<p><?php echo _("Orphaned Albums:") . " " . sizeof($orphanAlbums) ?></p>
		<p><?php echo _("Orphaned Albums will be re-attached to their parent albums, if at all possible.  If the parent album is missing, the orphan will be attached to the Gallery Root, and it can be moved to a new location from there.") ?></p>
		<center>
		<table>
		<tr>
			<th><?php echo _("Parent Album") ?></th>
			<th>&nbsp;</th>
			<th><?php echo _("Orphaned Album") ?></th>
		</tr>
<?php
		$current="";
		foreach ($orphanAlbums as $childName => $parentName) {
			echo "\t<tr>";
			if ($current == $parentName) {
				echo "\n\t<td>" . ($parentName ? "<a href='" . makeAlbumUrl($albumName) . "'>" . $albumName . "</a>" : _("Gallery Root")) . "</td>";
				$current = $parentName;
			} else {
				echo "\n\t<td>\------</td>";
			}
			echo "\n\t<td>=&gt;</td>";			
			echo "\n\t<td><a href=\"" . makeAlbumUrl($childName) . "\">" . $childName . "</a></td>";
			echo "\n\t</tr>";
		}
?>
		</table>
		<br>
		<?php echo makeFormIntro("tools/find_orphans.php", array("method" => "GET")); ?>
		<input type="hidden" name="action" value="albums">
		<input type="submit" value="<?php echo _("Re-Attach Orphaned Albums!") ?>">
		</form>
		</center>
<?php
	} elseif (!empty($orphanImages)) {
?>

		<p><?php echo _("Orphaned Files:") . " " . recursiveCount($orphanImages) ?></p>
		<p><?php echo _("Orphaned files will be deleted from the disk.  Orphaned files should never exist - if they do, they are the result of a failed upload attempt, or other more serious issue such as the photos database being overwritten with bad information.") ?></p>
		<center>
		<table>
		<tr>
			<th><?php echo _("Album directory") ?></th>
			<th>&nbsp;</th>
			<th><?php echo _("Orphaned file") ?></th>
		</tr>
<?php
		$current="";
		foreach ($orphanImages as $albumName => $imageVal) {
			foreach (array_keys($imageVal) as $fileName) {
				echo "\n\t\t<tr>";
				if($current != $albumName) {
					echo "\n\t\t\t<td><a href='" . makeAlbumUrl($albumName) . "'>" . $albumName . "</a></td>";
					$current = $albumName;
				} else {
					echo "\n\t\t\t<td>\------</td>";
				} 
				echo "\n\t\t\t<td>=&gt;</td>";
				echo "\n\t\t\t<td><a href='" . $gallery->app->albumDirURL . "/" . $albumName . "/" . $fileName . "'>" . $fileName . "</a></td>";
				echo "\n\t\t</tr>";
			}       
		}       
?>
		</table>
		<br>
		<?php echo makeFormIntro("tools/find_orphans.php", array("method" => "GET")); ?>
		<input type="hidden" name="action" value="images">
		<input type="submit" value="<?php echo _("Delete Orphaned Files!") ?>">
		</form>
		</center>
<?php 
	} else {
		// No Orphans
		echo "\n<p align=\"center\" class=\"warning\">" .  _("No Orphans Found") . "</p>";
		echo "\n<p align=\"center\">". _("There are no orphaned elements in this Gallery.") . "</p>";
	}
} // !isset(update) 
else { 
	echo "\n<p align=\"center\" class=\"warning\">" .  sprintf(_("Orphan %s Repaired"), ($action == "albums") ? _("Albums") : _("Files")) . "</p>";
	if ($action == "albums") {
		attachOrphanedAlbums($orphanAlbums);
	}
	if ($action == "images") {
		$unwriteableFiles = deleteOrphanedImages($orphanImages);
                if (!empty($unwriteableFiles)) {
			echo "<p>". gallery_error(_("The Webserver has not enough permission to delete the following files:")) . "</p>";
			echo "\n<ul>";
			foreach ($unwriteableFiles as $filename) {
				echo "<li>$filename</li>";
			}
			echo "\n</ul>";
			echo "\n<p align=\"center\">". _("Please check the permission of these files and the folder above. chmod them, or ask your admin to do this.") . "<br>";
			echo '<button name="Klickmich" type="button" onClick="location.reload()">'. _("Reload") . '</button></p>';
		}
	}
}

	includeHtmlWrap("gallery.footer"); 
if (!$GALLERY_EMBEDDED_INSIDE) {
?>
</div>
</body>
</html>
<?php } ?>