function checkAlbumParentid($albumname, $id) { global $gallery; $album = new Album($gallery, $albumname); $oldid = $album->get('parentid'); if ($oldid !== $id) { $album->set('parentid', $id); $album->save(); if (is_null($oldid)) { $oldid = '<em>NULL</em>'; } if (is_null($id)) { $id = '<em>NULL</em>'; } printf('Fixed album <strong>%1$s</strong>: parentid was %2$s should have been %3$s<br />', $albumname, $oldid, $id); } $id = $album->id; $albums = $album->getSubalbums(); foreach ($albums as $albumname) { checkAlbumParentid($albumname, $id); } }
/** * Returns the next news item on a page. * sets $_zp_current_zenpage_news to the next news item * Returns true if there is an new item to be shown * * NOTE: If you set the sortorder and sortdirection parameters you also have to set the same ones * on the next/prevNewsLink/URL functions for the single news article pagination! * * @param string $sortorder "date" for sorting by date (default) * "title" for sorting by title * This parameter is not used for date archives and CombiNews mode. * @param string $sortdirection "desc" (default) for descending sort order * "asc" for ascending sort order * This parameter is not used for date archives and CombiNews mode * * @return bool */ function next_news($sortorder = "date", $sortdirection = "desc") { global $_zp_zenpage, $_zp_current_zenpage_news, $_zp_current_zenpage_news_restore, $_zp_zenpage_articles, $_zp_current_category, $_zp_gallery, $_zp_current_search; $_zp_current_zenpage_news_restore = $_zp_current_zenpage_news; if (is_null($_zp_zenpage_articles)) { if (in_context(ZP_SEARCH)) { $_zp_zenpage->processExpired('news'); $_zp_zenpage_articles = $_zp_current_search->getSearchNews($sortorder, $sortdirection); } else { if (ZP_COMBINEWS and !is_NewsCategory() and !is_NewsArchive()) { $_zp_zenpage_articles = $_zp_zenpage->getCombiNews(ZP_ARTICLES_PER_PAGE); } else { if (in_context(ZP_ZENPAGE_NEWS_CATEGORY)) { $_zp_zenpage_articles = $_zp_current_category->getArticles(ZP_ARTICLES_PER_PAGE, NULL, false, $sortorder, $sortdirection); } else { $_zp_zenpage_articles = $_zp_zenpage->getNewsArticles(ZP_ARTICLES_PER_PAGE, NULL, false, $sortorder, $sortdirection); } } } while (!empty($_zp_zenpage_articles)) { $news = array_shift($_zp_zenpage_articles); if (is_array($news)) { add_context(ZP_ZENPAGE_NEWS_ARTICLE); if (ZP_COMBINEWS and array_key_exists("type", $news) and array_key_exists("albumname", $news)) { if ($news['type'] == "images") { $albumobj = new Album($_zp_gallery, $news['albumname']); $_zp_current_zenpage_news = newImage($albumobj, $news['titlelink']); } else { if ($news['type'] == "albums") { switch (getOption("zenpage_combinews_mode")) { case "latestimagesbyalbum-thumbnail": case "latestimagesbyalbum-thumbnail-customcrop": case "latestimagesbyalbum-sizedimage": $_zp_current_zenpage_news = new Album($_zp_gallery, $news['titlelink']); $_zp_current_zenpage_news->set('date', $news['date']); // in this mode this stores the date of the images to group not the album (inconvenient workaround...) break; default: $_zp_current_zenpage_news = new Album($_zp_gallery, $news['albumname']); break; } } else { $_zp_current_zenpage_news = new ZenpageNews($news['titlelink']); } } } else { $_zp_current_zenpage_news = new ZenpageNews($news['titlelink']); } return true; } else { break; } } } else { $_zp_current_zenpage_news = NULL; while (!empty($_zp_zenpage_articles)) { $news = array_shift($_zp_zenpage_articles); if (is_array($news)) { add_context(ZP_ZENPAGE_NEWS_ARTICLE); if (ZP_COMBINEWS and array_key_exists("type", $news) and array_key_exists("albumname", $news)) { if ($news['type'] == "images") { $albumobj = new Album($_zp_gallery, $news['albumname']); $_zp_current_zenpage_news = newImage($albumobj, $news['titlelink']); } else { if ($news['type'] == "albums") { switch (getOption("zenpage_combinews_mode")) { case "latestimagesbyalbum-thumbnail": case "latestimagesbyalbum-thumbnail-customcrop": case "latestimagesbyalbum-sizedimage": $_zp_current_zenpage_news = new Album($_zp_gallery, $news['titlelink']); $_zp_current_zenpage_news->set('date', $news['date']); // in this mode this stores the date of the images to group not the album (inconvenient workaround...) break; default: $_zp_current_zenpage_news = new Album($_zp_gallery, $news['albumname']); break; } } else { $_zp_current_zenpage_news = new ZenpageNews($news['titlelink']); } } } else { $_zp_current_zenpage_news = new ZenpageNews($news['titlelink']); } return true; } else { break; } } } $_zp_zenpage_articles = NULL; $_zp_current_zenpage_news = $_zp_current_zenpage_news_restore; rem_context(ZP_ZENPAGE_NEWS_ARTICLE); return false; }
/** * Processes the check box bulk actions for albums * */ function processAlbumBulkActions() { global $gallery; $action = sanitize($_POST['checkallaction']); $ids = $_POST['ids']; $total = count($ids); $message = NULL; if ($action != 'noaction') { if ($total > 0) { if ($action == 'addtags' || $action == 'alltags') { foreach ($_POST as $key => $value) { $key = postIndexDecode($key); if (substr($key, 0, 10) == 'mass_tags_') { if ($value) { $tags[] = substr($key, 10); } } } $tags = sanitize($tags, 3); } $n = 0; foreach ($ids as $albumname) { $n++; $albumobj = new Album($gallery, $albumname); switch ($action) { case 'deleteall': $albumobj->remove(); break; case 'showall': $albumobj->setShow(1); break; case 'hideall': $albumobj->setShow(0); break; case 'commentson': $albumobj->setCommentsAllowed(1); break; case 'commentsoff': $albumobj->setCommentsAllowed(0); break; case 'resethitcounter': $albumobj->set('hitcounter', 0); break; case 'addtags': $mytags = array_unique(array_merge($tags, $albumobj->getTags())); $albumobj->setTags($mytags); break; case 'cleartags': $albumobj->setTags(array()); break; case 'alltags': $images = $albumobj->getImages(); foreach ($images as $imagename) { $imageobj = newImage($albumobj, $imagename); $mytags = array_unique(array_merge($tags, $imageobj->getTags())); $imageobj->setTags($mytags); $imageobj->save(); } break; case 'clearalltags': $images = $albumobj->getImages(); foreach ($images as $imagename) { $imageobj = newImage($albumobj, $imagename); $imageobj->setTags(array()); $imageobj->save(); } break; } $albumobj->save(); } } return $action; } }
/** For every album in the gallery, look for its file. Delete from the database * if the file does not exist. Do the same for images. Clean up comments that have * been left orphaned. * * Returns true if the operation was interrupted because it was taking too long * * @param bool $cascade garbage collect every image and album in the gallery. * @param bool $complete garbage collect every image and album in the *database* - completely cleans the database. * @param int $restart Image ID to restart scan from * @return bool */ function garbageCollect($cascade = true, $complete = false, $restart = '') { if (empty($restart)) { setOption('last_garbage_collect', time()); /* clean the comments table */ $this->commentClean('images'); $this->commentClean('albums'); $this->commentClean('news'); $this->commentClean('pages'); // clean up obj_to_tag $dead = array(); $result = query_full_array("SELECT * FROM " . prefix('obj_to_tag')); if (is_array($result)) { foreach ($result as $row) { $dbtag = query_single_row("SELECT * FROM " . prefix('tags') . " WHERE `id`='" . $row['tagid'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } switch ($row['type']) { case 'album': $tbl = 'albums'; break; default: $tbl = $row['type']; break; } $dbtag = query_single_row("SELECT * FROM " . prefix($tbl) . " WHERE `id`='" . $row['objectid'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } } } if (!empty($dead)) { query('DELETE FROM ' . prefix('obj_to_tag') . ' WHERE `id`=' . implode(' OR `id`=', $dead)); } // clean up admin_to_object $dead = array(); $result = query_full_array("SELECT * FROM " . prefix('admin_to_object')); if (is_array($result)) { foreach ($result as $row) { $dbtag = query_single_row("SELECT * FROM " . prefix('administrators') . " WHERE `id`='" . $row['adminid'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } switch ($row['type']) { case 'album': $tbl = 'albums'; break; default: $tbl = $row['type']; break; } $dbtag = query_single_row("SELECT * FROM " . prefix($tbl) . " WHERE `id`='" . $row['objectid'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } } } if (!empty($dead)) { query('DELETE FROM ' . prefix('admin_to_object') . ' WHERE `id`=' . implode(' OR `id`=', $dead)); } // clean up news2cat $dead = array(); $result = query_full_array("SELECT * FROM " . prefix('news2cat')); if (is_array($result)) { foreach ($result as $row) { $dbtag = query_single_row("SELECT * FROM " . prefix('news') . " WHERE `id`='" . $row['news_id'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } $dbtag = query_single_row("SELECT * FROM " . prefix('news_categories') . " WHERE `id`='" . $row['cat_id'] . "'"); if (!$dbtag) { $dead['id'] = $row['id']; } } } if (!empty($dead)) { query('DELETE FROM ' . prefix('news2cat') . ' WHERE `id`=' . implode(' OR `id`=', $dead)); } // Check for the existence of top-level albums (subalbums handled recursively). $sql = "SELECT * FROM " . prefix('albums'); $result = query($sql); $dead = array(); $live = array(''); // purge the root album if it exists $deadalbumthemes = array(); // Load the albums from disk while ($row = db_fetch_assoc($result)) { $valid = file_exists($albumpath = ALBUM_FOLDER_SERVERPATH . internalToFilesystem($row['folder'])) && (hasDynamicAlbumSuffix($albumpath) || is_dir($albumpath) && strpos($albumpath, '/./') === false && strpos($albumpath, '/../') === false); if (!$valid || in_array($row['folder'], $live)) { $dead[] = $row['id']; if ($row['album_theme'] !== '') { // orphaned album theme options table $deadalbumthemes[$row['id']] = $row['folder']; } } else { $live[] = $row['folder']; } } if (count($dead) > 0) { /* delete the dead albums from the DB */ $first = array_pop($dead); $sql1 = "DELETE FROM " . prefix('albums') . " WHERE `id`='{$first}'"; $sql2 = "DELETE FROM " . prefix('images') . " WHERE `albumid`='{$first}'"; $sql3 = "DELETE FROM " . prefix('comments') . " WHERE `type`='albums' AND `ownerid`='{$first}'"; $sql4 = "DELETE FROM " . prefix('obj_to_tag') . " WHERE `type`='albums' AND `objectid`='{$first}'"; foreach ($dead as $albumid) { $sql1 .= " OR `id` = '{$albumid}'"; $sql2 .= " OR `albumid` = '{$albumid}'"; $sql3 .= " OR `ownerid` = '{$albumid}'"; $sql4 .= " OR `objectid` = '{$albumid}'"; } $n = query($sql1); if (!$complete && $n && $cascade) { query($sql2); query($sql3); query($sql4); } } if (count($deadalbumthemes) > 0) { // delete the album theme options tables for dead albums foreach ($deadalbumthemes as $id => $deadtable) { $sql = 'DELETE FROM ' . prefix('options') . ' WHERE `ownerid`=' . $id; query($sql, false); } } } if ($complete) { if (empty($restart)) { /* refresh 'metadata' albums */ $albumids = query_full_array("SELECT `id`, `mtime`, `folder`, `dynamic` FROM " . prefix('albums')); foreach ($albumids as $analbum) { if (($mtime = filemtime(ALBUM_FOLDER_SERVERPATH . internalToFilesystem($analbum['folder']))) > $analbum['mtime']) { // refresh $album = new Album($this, $analbum['folder']); $album->set('mtime', $mtime); if ($album->isDynamic()) { $data = file_get_contents($album->localpath); while (!empty($data)) { $data1 = trim(substr($data, 0, $i = strpos($data, "\n"))); if ($i === false) { $data1 = $data; $data = ''; } else { $data = substr($data, $i + 1); } if (strpos($data1, 'WORDS=') !== false) { $words = "words=" . urlencode(substr($data1, 6)); } if (strpos($data1, 'THUMB=') !== false) { $thumb = trim(substr($data1, 6)); } if (strpos($data1, 'FIELDS=') !== false) { $fields = "&searchfields=" . trim(substr($data1, 7)); } } if (!empty($words)) { if (empty($fields)) { $fields = '&searchfields=tags'; } } $album->set('search_params', $words . $fields); $album->set('thumb', $thumb); } $album->save(); zp_apply_filter('album_refresh', $album); } } /* Delete all image entries that don't belong to an album at all. */ $albumids = query_full_array("SELECT `id` FROM " . prefix('albums')); /* all the album IDs */ $idsofalbums = array(); foreach ($albumids as $row) { $idsofalbums[] = $row['id']; } $imageAlbums = query_full_array("SELECT DISTINCT `albumid` FROM " . prefix('images')); /* albumids of all the images */ $albumidsofimages = array(); foreach ($imageAlbums as $row) { $albumidsofimages[] = $row['albumid']; } $orphans = array_diff($albumidsofimages, $idsofalbums); /* albumids of images with no album */ if (count($orphans) > 0) { /* delete dead images from the DB */ $firstrow = array_pop($orphans); $sql = "DELETE FROM " . prefix('images') . " WHERE `albumid`='" . $firstrow . "'"; foreach ($orphans as $id) { $sql .= " OR `albumid`='" . $id . "'"; } query($sql); // Then go into existing albums recursively to clean them... very invasive. foreach ($this->getAlbums(0) as $folder) { $album = new Album($this, $folder); if (!$album->isDynamic()) { if (is_null($album->getDateTime())) { // see if we can get one from an image $images = $album->getImages(0, 0, 'date', 'DESC'); if (count($images) > 0) { $image = newImage($album, array_shift($images)); $album->setDateTime($image->getDateTime()); } } $album->garbageCollect(true); $album->preLoad(); } $album->save(); zp_apply_filter('album_refresh', $album); } } } /* Look for image records where the file no longer exists. While at it, check for images with IPTC data to update the DB */ $start = array_sum(explode(" ", microtime())); // protect against too much processing. if (!empty($restart)) { $restartwhere = ' WHERE `id`>' . $restart . ' AND `mtime`=0'; } else { $restartwhere = ' WHERE `mtime`=0'; } define('RECORD_LIMIT', 5); $sql = 'SELECT * FROM ' . prefix('images') . $restartwhere . ' ORDER BY `id` LIMIT ' . (RECORD_LIMIT + 2); $images = query_full_array($sql); if (count($images) > 0) { $c = 0; foreach ($images as $image) { $sql = 'SELECT `folder` FROM ' . prefix('albums') . ' WHERE `id`="' . $image['albumid'] . '";'; $row = query_single_row($sql); $imageName = internalToFilesystem(ALBUM_FOLDER_SERVERPATH . $row['folder'] . '/' . $image['filename']); if (file_exists($imageName)) { $mtime = filemtime($imageName); if ($image['mtime'] != $mtime) { // file has changed since we last saw it $imageobj = newImage(new Album($this, $row['folder']), $image['filename']); $imageobj->set('mtime', $mtime); $imageobj->updateMetaData(); // prime the EXIF/IPTC fields $imageobj->updateDimensions(); // update the width/height & account for rotation $imageobj->save(); zp_apply_filter('image_refresh', $imageobj); } } else { $sql = 'DELETE FROM ' . prefix('images') . ' WHERE `id`="' . $image['id'] . '";'; $result = query($sql); $sql = 'DELETE FROM ' . prefix('comments') . ' WHERE `type` IN (' . zp_image_types('"') . ') AND `ownerid` ="' . $image['id'] . '";'; $result = query($sql); } if (++$c >= RECORD_LIMIT) { return $image['id']; // avoide excessive processing } } } } return false; }