Changes the ConfirmDelete page and updates database code.

The ConfirmDelete page now uses parts of the photopage. The
Confirmation dialog is its own template which is based on Alert.

The database now updates the album thumb to the most recent
addition to the album, when the album thumb asset is being deleted.
When there are no pictures left in the album 0 will be set.
This commit is contained in:
Dennis Brentjes 2018-07-08 08:19:37 +00:00
parent e40c05c1f8
commit 16ec547064
12 changed files with 197 additions and 113 deletions

View File

@ -1,43 +0,0 @@
<?php
/*****************************************************************************
* ConfirmDelete.php
* Contains the ConfirmDelete controller
*
* Kabuki CMS (C) 2013-2016, Aaron van Geffen
*****************************************************************************/
class ConfirmDelete extends HTMLController
{
public function __construct()
{
// Ensure we're logged in at this point.
$user = Registry::get('user');
if (!$user->isLoggedIn())
throw new NotAllowedException();
$photo = Asset::fromSlug($_GET['slug']);
if (empty($photo))
throw new NotFoundException();
$author = $photo->getAuthor();
if (!($user->isAdmin() || $user->getUserId() === $author->getUserId()))
throw new NotAllowedException();
if (isset($_REQUEST['confirmed']))
$this->handleDelete($photo);
parent::__construct('Confirm deletion' . ' - ' . SITE_TITLE);
$page = new ConfirmDeletePage($photo->getImage());
$this->page->adopt($page);
}
private function handleDelete(Asset $photo) {
$album_url = $photo->getSubdir();
$photo->delete();
header('Location: ' . BASEURL . '/' . $album_url);
exit;
}
}

View File

@ -11,17 +11,53 @@ class ViewPhoto extends HTMLController
public function __construct()
{
// Ensure we're logged in at this point.
if (!Registry::get('user')->isLoggedIn())
$user = Registry::get('user');
if (!$user->isLoggedIn())
throw new NotAllowedException();
$photo = Asset::fromSlug($_GET['slug']);
if (empty($photo))
throw new NotFoundException();
parent::__construct($photo->getTitle() . ' - ' . SITE_TITLE);
$author = $photo->getAuthor();
if (isset($_REQUEST['confirm_delete']) || isset($_REQUEST['delete_confirmed']))
$this->handleConfirmDelete($user, $author, $photo);
else
$this->handleViewPhoto($user, $author, $photo);
// Add an edit button to the admin bar.
if ($user->isAdmin())
$this->admin_bar->appendItem(BASEURL . '/editasset/?id=' . $photo->getId(), 'Edit this photo');
}
private function handleConfirmDelete(User $user, User $author, Asset $photo)
{
if (!($user->isAdmin() || $user->getUserId() === $author->getUserId()))
throw new NotAllowedException();
if (isset($_REQUEST['confirm_delete']))
{
$page = new ConfirmDeletePage($photo->getImage());
$this->page->adopt($page);
}
else if (isset($_REQUEST['delete_confirmed']))
{
$album_url = $photo->getSubdir();
$photo->delete();
header('Location: ' . BASEURL . '/' . $album_url);
exit;
}
}
private function handleViewPhoto(User $user, User $author, Asset $photo)
{
if (!empty($_POST))
$this->handleTagging($photo->getImage());
parent::__construct($photo->getTitle() . ' - ' . SITE_TITLE);
$page = new PhotoPage($photo->getImage());
// Exif data?
@ -43,17 +79,11 @@ class ViewPhoto extends HTMLController
if ($next_url)
$page->setNextPhotoUrl($next_url);
$user = Registry::get('user');
$author = $photo->getAuthor();
if ($user->isAdmin() || $user->getUserId() === $author->getUserId())
$page->setIsAssetOwner(true);
$this->page->adopt($page);
$this->page->setCanonicalUrl($photo->getPageUrl());
// Add an edit button to the admin bar.
if (Registry::get('user')->isAdmin())
$this->admin_bar->appendItem(BASEURL . '/editasset/?id=' . $photo->getId(), 'Edit this photo');
}
private function handleTagging(Image $photo)

View File

@ -485,14 +485,6 @@ class Asset
if (!unlink(ASSETSDIR . '/' . $this->subdir . '/' . $this->filename))
return false;
$db->query('
UPDATE tags
SET id_asset_thumb = 0
WHERE id_asset_thumb = {int:id_asset} AND kind = "Album"',
[
'id_asset' => $this->id_asset,
]);
$db->query('
DELETE FROM assets_meta
WHERE id_asset = {int:id_asset}',
@ -500,12 +492,53 @@ class Asset
'id_asset' => $this->id_asset,
]);
return $db->query('
$rows = $db->query('
SELECT id_tag
FROM assets_tags
WHERE id_asset = {int:id_asset}',
[
'id_asset' => $this->id_asset,
]);
$recount_tags = [];
if(!empty($rows))
foreach($rows as $row)
$recount_tags[] = $row['id_tag'];
$db->query('
DELETE FROM assets_tags
WHERE id_asset = {int:id_asset}',
[
'id_asset' => $this->id_asset,
]);
Tag::recount($recount_tags);
$return = $db->query('
DELETE FROM assets
WHERE id_asset = {int:id_asset}',
[
'id_asset' => $this->id_asset,
]);
$rows = $db->query('
SELECT id_tag
FROM tags
WHERE id_asset_thumb = {int:id_asset} AND kind = "Album"',
[
'id_asset' => $this->id_asset,
]);
if (!empty($rows))
{
foreach ($rows as $row)
{
$tag = Tag::fromId($row['id_tag']);
$tag->resetIdAsset();
}
}
return $return;
}
public function linkTags(array $id_tags)

View File

@ -28,7 +28,6 @@ class Dispatcher
'suggest' => 'ProvideAutoSuggest',
'timeline' => 'ViewTimeline',
'uploadmedia' => 'UploadMedia',
'confirmdelete' => 'ConfirmDelete',
];
// Work around PHP's FPM not always providing PATH_INFO.

View File

@ -289,6 +289,34 @@ class Tag
]);
}
public function resetIdAsset()
{
$db = Registry::get('db');
$row = $db->query('
SELECT MAX(id_asset) as new_id
FROM assets_tags
WHERE id_tag = {int:id_tag}',
[
'id_tag' => $this->id_tag,
]);
$new_id = 0;
if(!empty($row))
{
$new_id = $row->fetch_assoc()['new_id'];
}
return $db->query('
UPDATE tags
SET id_asset_thumb = {int:new_id}
WHERE id_tag = {int:id_tag}',
[
'new_id' => $new_id,
'id_tag' => $this->id_tag,
]);
}
public static function match($tokens)
{
if (!is_array($tokens))

View File

@ -8,10 +8,10 @@
@import url(//fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic);
@font-face {
font-family: 'Invaders';
src: url('fonts/invaders.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-family: 'Invaders';
src: url('fonts/invaders.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
body {
@ -135,7 +135,7 @@ ul#nav li a:hover {
}
.pagination .page-padding {
cursor: pointer;
cursor: pointer;
}
@ -565,7 +565,7 @@ a#previous_photo:hover, a#next_photo:hover {
content: '→';
}
#sub_photo h2, #sub_photo h3, #photo_exif_box h3 {
#sub_photo h2, #sub_photo h3, #photo_exif_box h3, #user_actions_box h3 {
font: 600 20px/30px "Open Sans", sans-serif;
margin: 0 0 10px;
}
@ -622,22 +622,13 @@ a#previous_photo:hover, a#next_photo:hover {
#user_actions_box {
background: #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
float: left;
margin: 25px 0 25px 0;
overflow: auto;
padding: 2%;
float: right;
width: 20%;
}
#confirm_box {
background: #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
padding: 2%;
margin: 25px 0 25px 0;
text-align: center;
}
/* Responsive: smartphone in portrait
---------------------------------------*/
@media only screen and (max-width: 895px) {

View File

@ -19,6 +19,13 @@ class Alert extends SubTemplate
{
echo '
<div class="alert', $this->_type != 'alert' ? ' alert-' . $this->_type : '', '">', (!empty($this->_title) ? '
<strong>' . $this->_title . '</strong><br>' : ''), $this->_message, '</div>';
<strong>' . $this->_title . '</strong><br>' : ''), '<p>', $this->_message, '</p>';
$this->additional_alert_content();
echo '</div>';
}
protected function additional_alert_content()
{}
}

27
templates/Button.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/*****************************************************************************
* Button.php
* Defines the Button template.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
class Button extends SubTemplate
{
private $content = '';
private $href = '';
private $class = '';
public function __construct($content = '', $href = '', $class = '')
{
$this->content = $content;
$this->href = $href;
$this->class = $class;
}
protected function html_content()
{
echo '
<a class="', $this->class, '" href="', $this->href, '">', $this->content, '</a>';
}
}

View File

@ -6,13 +6,11 @@
* Kabuki CMS (C) 2013-2016, Aaron van Geffen
*****************************************************************************/
class ConfirmDeletePage extends SubTemplate
class ConfirmDeletePage extends PhotoPage
{
private $photo;
public function __construct(Image $photo)
{
$this->photo = $photo;
parent::__construct($photo);
}
protected function html_content()
@ -23,30 +21,15 @@ class ConfirmDeletePage extends SubTemplate
private function confirm()
{
echo '
<div id=confirm_box>
<h1>Confirm deletion</h1>
<p>You are about to permanently delete the following photo.</p>
<a class="btn btn-red" href="', BASEURL, '/confirmdelete?slug=', $this->photo->getSlug(), '&confirmed">Delete</a>
<a class="btn" href="', $this->photo->getPageUrl(), '"> Cancel</a>
</div>';
}
$buttons = [];
$buttons[] = new Button("Delete", BASEURL . '/' . $this->photo->getSlug() . '?delete_confirmed', "btn btn-red");
$buttons[] = new Button("Cancel", $this->photo->getPageUrl(), "btn");
private function photo()
{
echo '
<div id="photo_frame">
<a href="', $this->photo->getUrl(), '">';
if ($this->photo->isPortrait())
echo '
<img src="', $this->photo->getThumbnailUrl(null, 960), '" alt="">';
else
echo '
<img src="', $this->photo->getThumbnailUrl(1280, null), '" alt="">';
echo '
</a>
</div>';
$alert = new WarningDialog(
"Confirm deletion.",
"You are about to permanently delete the following photo.",
$buttons
);
$alert->html_content();
}
}

View File

@ -23,7 +23,7 @@ class EditAssetForm extends SubTemplate
<form id="asset_form" action="" method="post" enctype="multipart/form-data">
<div class="boxed_content" style="margin-bottom: 2%">
<div style="float: right">
<a class="btn btn-red" href="', BASEURL, '/confirmdelete?slug=', $this->asset->getSlug(), '>Delete asset</a>
<a class="btn btn-red" href="', BASEURL, '/', $this->asset->getSlug(), '?delete_confirmed">Delete asset</a>
<input type="submit" value="Save asset data">
</div>
<h2>Edit asset \'', $this->asset->getTitle(), '\' (', $this->asset->getFilename(), ')</h2>

View File

@ -8,7 +8,7 @@
class PhotoPage extends SubTemplate
{
private $photo;
protected $photo;
private $exif;
private $previous_photo_url = '';
private $next_photo_url = '';
@ -29,7 +29,8 @@ class PhotoPage extends SubTemplate
$this->next_photo_url = $url;
}
public function setIsAssetOwner($flag) {
public function setIsAssetOwner($flag)
{
$this->is_asset_owner = $flag;
}
@ -50,15 +51,14 @@ class PhotoPage extends SubTemplate
$this->photoMeta();
if($this->is_asset_owner) {
if($this->is_asset_owner)
$this->addUserActions();
}
echo '
<script type="text/javascript" src="', BASEURL, '/js/photonav.js"></script>';
}
private function photo()
protected function photo()
{
echo '
<div id="photo_frame">
@ -198,7 +198,7 @@ class PhotoPage extends SubTemplate
echo '
<div id=user_actions_box>
<h3>Actions</h3>
<a class="btn btn-red" href="', BASEURL, '/confirmdelete?slug=', $this->photo->getSlug(), '">Delete</a>
<a class="btn btn-red" href="', BASEURL, '/', $this->photo->getSlug(), '?confirm_delete">Delete</a>
</div>';
}
}

View File

@ -0,0 +1,29 @@
<?php
/*****************************************************************************
* WarningDialog.php
* Defines the WarningDialog template.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
class WarningDialog extends Alert
{
protected $buttons;
public function __construct($title = '', $message = '', $buttons = [])
{
parent::__construct($title, $message);
$this->buttons = $buttons;
}
protected function additional_alert_content()
{
$this->addButtons();
}
private function addButtons()
{
foreach ($this->buttons as $button)
$button->html_content();
}
}