forked from Public/pics
Merge pull request 'Introduce edit menu for admins' (#49) from edit-menu into master
Reviewed-on: Public/pics#49
This commit is contained in:
commit
2bfbe67d91
@ -30,6 +30,40 @@ class EditAsset extends HTMLController
|
|||||||
header('Location: ' . $redirectUrl);
|
header('Location: ' . $redirectUrl);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$isPrioChange = isset($_REQUEST['inc_prio']) || isset($_REQUEST['dec_prio']);
|
||||||
|
$isCoverChange = isset($_REQUEST['album_cover'], $_REQUEST['in']);
|
||||||
|
$madeChanges = false;
|
||||||
|
|
||||||
|
if ($user->isAdmin() && $isPrioChange && Session::validateSession('get'))
|
||||||
|
{
|
||||||
|
if (isset($_REQUEST['inc_prio']))
|
||||||
|
$priority = $asset->priority + 1;
|
||||||
|
else
|
||||||
|
$priority = $asset->priority - 1;
|
||||||
|
|
||||||
|
$asset->priority = max(0, min(100, $priority));
|
||||||
|
$asset->save();
|
||||||
|
$madeChanges = true;
|
||||||
|
}
|
||||||
|
elseif ($user->isAdmin() && $isCoverChange && Session::validateSession('get'))
|
||||||
|
{
|
||||||
|
$tag = Tag::fromId($_REQUEST['in']);
|
||||||
|
$tag->id_asset_thumb = $asset->getId();
|
||||||
|
$tag->save();
|
||||||
|
$madeChanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($madeChanges)
|
||||||
|
{
|
||||||
|
if (isset($_SERVER['HTTP_REFERER']))
|
||||||
|
header('Location: ' . $_SERVER['HTTP_REFERER']);
|
||||||
|
else
|
||||||
|
header('Location: ' . BASEURL . '/' . $asset->getSubdir());
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get a list of available photo albums
|
// Get a list of available photo albums
|
||||||
$allAlbums = [];
|
$allAlbums = [];
|
||||||
@ -61,10 +95,12 @@ class EditAsset extends HTMLController
|
|||||||
// Key info
|
// Key info
|
||||||
if (isset($_POST['title'], $_POST['slug'], $_POST['date_captured'], $_POST['priority']))
|
if (isset($_POST['title'], $_POST['slug'], $_POST['date_captured'], $_POST['priority']))
|
||||||
{
|
{
|
||||||
$date_captured = !empty($_POST['date_captured']) ?
|
$asset->date_captured = !empty($_POST['date_captured']) ?
|
||||||
new DateTime(str_replace('T', ' ', $_POST['date_captured'])) : null;
|
new DateTime(str_replace('T', ' ', $_POST['date_captured'])) : null;
|
||||||
$slug = Asset::cleanSlug($_POST['slug']);
|
$asset->slug = Asset::cleanSlug($_POST['slug']);
|
||||||
$asset->setKeyData(htmlspecialchars($_POST['title']), $slug, $date_captured, intval($_POST['priority']));
|
$asset->title = htmlspecialchars($_POST['title']);
|
||||||
|
$asset->priority = intval($_POST['priority']);
|
||||||
|
$asset->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changing parent album?
|
// Changing parent album?
|
||||||
|
@ -107,8 +107,11 @@ class ViewPhotoAlbum extends HTMLController
|
|||||||
if (!empty($active_filter))
|
if (!empty($active_filter))
|
||||||
$url_params['by'] = $active_filter;
|
$url_params['by'] = $active_filter;
|
||||||
|
|
||||||
if (!empty($url_params))
|
$url_suffix = http_build_query($url_params);
|
||||||
$index->setUrlSuffix('?' . http_build_query($url_params));
|
$index->setUrlSuffix('?' . $url_suffix);
|
||||||
|
|
||||||
|
$menu_items = $this->getEditMenuItems('&' . $url_suffix);
|
||||||
|
$index->setEditMenuItems($menu_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a page index as needed, while we're at it.
|
// Make a page index as needed, while we're at it.
|
||||||
@ -228,6 +231,46 @@ class ViewPhotoAlbum extends HTMLController
|
|||||||
return $buttons;
|
return $buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getEditMenuItems($url_suffix)
|
||||||
|
{
|
||||||
|
$items = [];
|
||||||
|
$sess = '&' . Session::getSessionTokenKey() . '=' . Session::getSessionToken();
|
||||||
|
|
||||||
|
if (Registry::get('user')->isLoggedIn())
|
||||||
|
{
|
||||||
|
$items[] = [
|
||||||
|
'label' => 'Edit image',
|
||||||
|
'uri' => fn($image) => $image->getEditUrl() . $url_suffix,
|
||||||
|
];
|
||||||
|
|
||||||
|
$items[] = [
|
||||||
|
'label' => 'Delete image',
|
||||||
|
'uri' => fn($image) => $image->getDeleteUrl() . $url_suffix . $sess,
|
||||||
|
'onclick' => 'return confirm(\'Are you sure you want to delete this image?\');',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Registry::get('user')->isAdmin())
|
||||||
|
{
|
||||||
|
$items[] = [
|
||||||
|
'label' => 'Make album cover',
|
||||||
|
'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&album_cover' . $sess,
|
||||||
|
];
|
||||||
|
|
||||||
|
$items[] = [
|
||||||
|
'label' => 'Increase priority',
|
||||||
|
'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&inc_prio' . $sess,
|
||||||
|
];
|
||||||
|
|
||||||
|
$items[] = [
|
||||||
|
'label' => 'Decrease priority',
|
||||||
|
'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&dec_prio' . $sess,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
private function getHeaderBox(Tag $tag)
|
private function getHeaderBox(Tag $tag)
|
||||||
{
|
{
|
||||||
// Can we go up a level?
|
// Can we go up a level?
|
||||||
|
@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
class Asset
|
class Asset
|
||||||
{
|
{
|
||||||
protected $id_asset;
|
public $id_asset;
|
||||||
protected $id_user_uploaded;
|
public $id_user_uploaded;
|
||||||
protected $subdir;
|
public $subdir;
|
||||||
protected $filename;
|
public $filename;
|
||||||
protected $title;
|
public $title;
|
||||||
protected $slug;
|
public $slug;
|
||||||
protected $mimetype;
|
public $mimetype;
|
||||||
protected $image_width;
|
public $image_width;
|
||||||
protected $image_height;
|
public $image_height;
|
||||||
protected $date_captured;
|
public $date_captured;
|
||||||
protected $priority;
|
public $priority;
|
||||||
|
|
||||||
protected $meta;
|
protected $meta;
|
||||||
protected $tags;
|
protected $tags;
|
||||||
@ -36,6 +36,11 @@ class Asset
|
|||||||
$this->date_captured = new DateTime($data['date_captured']);
|
$this->date_captured = new DateTime($data['date_captured']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canBeEditedBy(User $user)
|
||||||
|
{
|
||||||
|
return $this->isOwnedBy($user) || $user->isAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
public static function cleanSlug($slug)
|
public static function cleanSlug($slug)
|
||||||
{
|
{
|
||||||
// Only alphanumerical chars, underscores and forward slashes are allowed
|
// Only alphanumerical chars, underscores and forward slashes are allowed
|
||||||
@ -675,26 +680,26 @@ class Asset
|
|||||||
FROM assets');
|
FROM assets');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setKeyData($title, $slug, DateTime $date_captured = null, $priority)
|
public function save()
|
||||||
{
|
{
|
||||||
$params = [
|
if (empty($this->id_asset))
|
||||||
'id_asset' => $this->id_asset,
|
throw new UnexpectedValueException();
|
||||||
'title' => $title,
|
|
||||||
'slug' => $slug,
|
|
||||||
'priority' => $priority,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isset($date_captured))
|
|
||||||
$params['date_captured'] = $date_captured->format('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
return Registry::get('db')->query('
|
return Registry::get('db')->query('
|
||||||
UPDATE assets
|
UPDATE assets
|
||||||
SET title = {string:title},
|
SET id_asset = {int:id_asset},
|
||||||
slug = {string:slug},' . (isset($date_captured) ? '
|
id_user_uploaded = {int:id_user_uploaded},
|
||||||
date_captured = {datetime:date_captured},' : '') . '
|
subdir = {string:subdir},
|
||||||
|
filename = {string:filename},
|
||||||
|
title = {string:title},
|
||||||
|
slug = {string:slug},
|
||||||
|
mimetype = {string:mimetype},
|
||||||
|
image_width = {int:image_width},
|
||||||
|
image_height = {int:image_height},
|
||||||
|
date_captured = {datetime:date_captured},
|
||||||
priority = {int:priority}
|
priority = {int:priority}
|
||||||
WHERE id_asset = {int:id_asset}',
|
WHERE id_asset = {int:id_asset}',
|
||||||
$params);
|
get_object_vars($this));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUrlForAdjacentInSet($prevNext, ?Tag $tag, $activeFilter)
|
protected function getUrlForAdjacentInSet($prevNext, ?Tag $tag, $activeFilter)
|
||||||
|
@ -1,27 +1,3 @@
|
|||||||
/* Edit icon on tiled grids
|
|
||||||
-----------------------------*/
|
|
||||||
.polaroid {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.polaroid a.edit {
|
|
||||||
background: var(--bs-body-bg);
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 1px 1px 2px rgba(0,0,0,0.3);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
opacity: 0;
|
|
||||||
left: 20px;
|
|
||||||
line-height: 1.5;
|
|
||||||
padding: 5px 10px;
|
|
||||||
position: absolute;
|
|
||||||
transition: 0.25s;
|
|
||||||
top: 20px;
|
|
||||||
z-index: 50;
|
|
||||||
}
|
|
||||||
.polaroid:hover > a.edit {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Crop editor
|
/* Crop editor
|
||||||
----------------*/
|
----------------*/
|
||||||
#crop_editor {
|
#crop_editor {
|
||||||
|
@ -296,6 +296,34 @@ div.polaroid a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Edit icon on tiled grids
|
||||||
|
-----------------------------*/
|
||||||
|
.polaroid {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.polaroid div.edit {
|
||||||
|
box-shadow: 1px 1px 2px rgba(0,0,0,0.3);
|
||||||
|
opacity: 0;
|
||||||
|
left: 20px;
|
||||||
|
position: absolute;
|
||||||
|
transition: 0.25s;
|
||||||
|
top: 20px;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
.polaroid div.edit .dropdown-item {
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.polaroid div.edit .dropdown-toggle {
|
||||||
|
line-height: 1.4;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
}
|
||||||
|
.polaroid div.edit .dropdown-toggle::after {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.polaroid:hover > div.edit {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Album title boxes
|
/* Album title boxes
|
||||||
----------------------*/
|
----------------------*/
|
||||||
|
@ -25,7 +25,15 @@ class PhotoPage extends Template
|
|||||||
|
|
||||||
echo '
|
echo '
|
||||||
<div class="row mt-5">
|
<div class="row mt-5">
|
||||||
<div class="col-lg-9">
|
<div class="col-lg">';
|
||||||
|
|
||||||
|
$this->photoMeta();
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-lg">
|
||||||
<div id="sub_photo" class="content-box">';
|
<div id="sub_photo" class="content-box">';
|
||||||
|
|
||||||
$this->userActions();
|
$this->userActions();
|
||||||
@ -39,12 +47,6 @@ class PhotoPage extends Template
|
|||||||
echo '
|
echo '
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3">';
|
|
||||||
|
|
||||||
$this->photoMeta();
|
|
||||||
|
|
||||||
echo '
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="', BASEURL, '/js/photonav.js"></script>';
|
<script type="text/javascript" src="', BASEURL, '/js/photonav.js"></script>';
|
||||||
}
|
}
|
||||||
@ -109,12 +111,12 @@ class PhotoPage extends Template
|
|||||||
private function photoMeta()
|
private function photoMeta()
|
||||||
{
|
{
|
||||||
echo '
|
echo '
|
||||||
<ul class="list-group photo_meta">';
|
<ul class="list-group list-group-horizontal photo_meta">';
|
||||||
|
|
||||||
foreach ($this->metaData as $header => $body)
|
foreach ($this->metaData as $header => $body)
|
||||||
{
|
{
|
||||||
echo '
|
echo '
|
||||||
<li class="list-group-item">
|
<li class="list-group-item flex-fill">
|
||||||
<h4>', $header, '</h4>
|
<h4>', $header, '</h4>
|
||||||
', $body, '
|
', $body, '
|
||||||
</li>';
|
</li>';
|
||||||
|
@ -13,7 +13,9 @@ class PhotosIndex extends Template
|
|||||||
protected $show_headers;
|
protected $show_headers;
|
||||||
protected $show_labels;
|
protected $show_labels;
|
||||||
protected $previous_header = '';
|
protected $previous_header = '';
|
||||||
protected $url_suffix;
|
|
||||||
|
protected $edit_menu_items = [];
|
||||||
|
protected $photo_url_suffix;
|
||||||
|
|
||||||
const PANORAMA_WIDTH = 1256;
|
const PANORAMA_WIDTH = 1256;
|
||||||
const PANORAMA_HEIGHT = null;
|
const PANORAMA_HEIGHT = null;
|
||||||
@ -81,6 +83,30 @@ class PhotosIndex extends Template
|
|||||||
$this->previous_header = $header;
|
$this->previous_header = $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function editMenu(Image $image)
|
||||||
|
{
|
||||||
|
if (empty($this->edit_menu_items))
|
||||||
|
return;
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="edit dropdown">
|
||||||
|
<button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">';
|
||||||
|
|
||||||
|
foreach ($this->edit_menu_items as $item)
|
||||||
|
{
|
||||||
|
echo '
|
||||||
|
<li><a class="dropdown-item" href="', $item['uri']($image), '"',
|
||||||
|
isset($item['onclick']) ? ' onclick="' . $item['onclick'] . '"' : '',
|
||||||
|
'>', $item['label'], '</a></li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</ul>
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
|
||||||
protected function photo(Image $image, $className, $width, $height, $crop = true, $fit = true)
|
protected function photo(Image $image, $className, $width, $height, $crop = true, $fit = true)
|
||||||
{
|
{
|
||||||
// Prefer thumbnail aspect ratio if available, otherwise use image aspect ratio.
|
// Prefer thumbnail aspect ratio if available, otherwise use image aspect ratio.
|
||||||
@ -89,12 +115,11 @@ class PhotosIndex extends Template
|
|||||||
echo '
|
echo '
|
||||||
<div class="polaroid ', $className, '" style="aspect-ratio: ', $aspectRatio, '">';
|
<div class="polaroid ', $className, '" style="aspect-ratio: ', $aspectRatio, '">';
|
||||||
|
|
||||||
if ($this->show_edit_buttons)
|
if ($this->show_edit_buttons && $image->canBeEditedBy(Registry::get('user')))
|
||||||
echo '
|
$this->editMenu($image);
|
||||||
<a class="edit" href="', BASEURL, '/editasset/?id=', $image->getId(), '">Edit</a>';
|
|
||||||
|
|
||||||
echo '
|
echo '
|
||||||
<a href="', $image->getPageUrl(), $this->url_suffix, '#photo_frame">';
|
<a href="', $image->getPageUrl(), $this->photo_url_suffix, '#photo_frame">';
|
||||||
|
|
||||||
|
|
||||||
foreach (['normal-photo', 'blur-photo'] as $className)
|
foreach (['normal-photo', 'blur-photo'] as $className)
|
||||||
@ -319,8 +344,13 @@ class PhotosIndex extends Template
|
|||||||
$this->threePortraits($photos, $altLayout);
|
$this->threePortraits($photos, $altLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setEditMenuItems(array $items)
|
||||||
|
{
|
||||||
|
$this->edit_menu_items = $items;
|
||||||
|
}
|
||||||
|
|
||||||
public function setUrlSuffix($suffix)
|
public function setUrlSuffix($suffix)
|
||||||
{
|
{
|
||||||
$this->url_suffix = $suffix;
|
$this->photo_url_suffix = $suffix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user