forked from Public/pics
Aaron van Geffen
e28fcd8b03
Removes the intermediate confirmation page, instead using JavaScript for confirmation. Fixes an XSS issue, in that the previous method was not passing or checking the session (!)
182 lines
5.7 KiB
PHP
182 lines
5.7 KiB
PHP
<?php
|
|
/*****************************************************************************
|
|
* EditAsset.php
|
|
* Contains the asset management controller
|
|
*
|
|
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
|
|
*****************************************************************************/
|
|
|
|
class EditAsset extends HTMLController
|
|
{
|
|
public function __construct()
|
|
{
|
|
if (empty($_GET['id']))
|
|
throw new Exception('Invalid request.');
|
|
|
|
$asset = Asset::fromId($_GET['id']);
|
|
if (empty($asset))
|
|
throw new NotFoundException('Asset not found');
|
|
|
|
// Can we edit this asset?
|
|
$user = Registry::get('user');
|
|
if (!($user->isAdmin() || $asset->isOwnedBy($user)))
|
|
throw new NotAllowedException();
|
|
|
|
if (isset($_REQUEST['delete']) && Session::validateSession('get'))
|
|
{
|
|
$redirectUrl = BASEURL . '/' . $asset->getSubdir();
|
|
$asset->delete();
|
|
|
|
header('Location: ' . $redirectUrl);
|
|
exit;
|
|
}
|
|
|
|
if (!empty($_POST))
|
|
{
|
|
if (isset($_GET['updatethumb']))
|
|
{
|
|
$image = $asset->getImage();
|
|
return $this->updateThumb($image);
|
|
}
|
|
|
|
// Key info
|
|
if (isset($_POST['title'], $_POST['slug'], $_POST['date_captured'], $_POST['priority']))
|
|
{
|
|
$date_captured = !empty($_POST['date_captured']) ? new DateTime($_POST['date_captured']) : null;
|
|
$slug = strtr($_POST['slug'], [' ' => '-', '--' => '-', '&' => 'and', '=>' => '', "'" => "", ":"=> "", '\\' => '-']);
|
|
$asset->setKeyData(htmlspecialchars($_POST['title']), $slug, $date_captured, intval($_POST['priority']));
|
|
}
|
|
|
|
// Handle tags
|
|
$new_tags = [];
|
|
if (isset($_POST['tag']) && is_array($_POST['tag']))
|
|
foreach ($_POST['tag'] as $id_tag => $bool)
|
|
if (is_numeric($id_tag))
|
|
$new_tags[] = $id_tag;
|
|
|
|
$current_tags = array_keys($asset->getTags());
|
|
|
|
$tags_to_unlink = array_diff($current_tags, $new_tags);
|
|
$asset->unlinkTags($tags_to_unlink);
|
|
|
|
$tags_to_link = array_diff($new_tags, $current_tags);
|
|
$asset->linkTags($tags_to_link);
|
|
|
|
// Meta data
|
|
if (isset($_POST['meta_key'], $_POST['meta_value']))
|
|
{
|
|
$new_meta = array_filter(array_combine($_POST['meta_key'], $_POST['meta_value']), function($e) {
|
|
return !empty($e);
|
|
});
|
|
|
|
$asset->setMetaData($new_meta);
|
|
}
|
|
|
|
// A replacement file?
|
|
if (isset($_FILES['replacement'], $_POST['replacement_target']) && !empty($_FILES['replacement']['tmp_name']))
|
|
{
|
|
if ($_POST['replacement_target'] === 'full')
|
|
{
|
|
$asset->replaceFile($_FILES['replacement']['tmp_name']);
|
|
if ($asset->isImage())
|
|
{
|
|
$image = $asset->getImage();
|
|
$image->removeAllThumbnails();
|
|
}
|
|
}
|
|
elseif (preg_match('~^thumb_(\d+x\d+(?:_c[best]?)?)$~', $_POST['replacement_target'], $match))
|
|
{
|
|
$image = $asset->getImage();
|
|
if (($replace_result = $image->replaceThumbnail($match[1], $_FILES['replacement']['tmp_name'])) !== 0)
|
|
throw new Exception('Could not replace thumbnail \'' . $match[1] . '\' with the uploaded file. Error code: ' . $replace_result);
|
|
}
|
|
}
|
|
|
|
header('Location: ' . BASEURL . '/editasset/?id=' . $asset->getId());
|
|
}
|
|
|
|
// Get list of thumbnails
|
|
$thumbs = $this->getThumbs($asset);
|
|
|
|
$page = new EditAssetForm($asset, $thumbs);
|
|
parent::__construct('Edit asset \'' . $asset->getTitle() . '\' (' . $asset->getFilename() . ') - ' . SITE_TITLE);
|
|
$this->page->adopt($page);
|
|
}
|
|
|
|
private function getThumbs(Asset $asset)
|
|
{
|
|
if (!$asset->isImage())
|
|
return [];
|
|
|
|
$image = $asset->getImage();
|
|
$subdir = $image->getSubdir();
|
|
$metadata = $image->getMeta();
|
|
$thumb_selectors = $image->getThumbnails();
|
|
|
|
$thumbs = [];
|
|
foreach ($thumb_selectors as $selector => $filename)
|
|
{
|
|
if (!preg_match('~^(?<width>\d+)x(?<height>\d+)(?<suffix>_c(?<method>[best]?))?$~', $selector, $thumb))
|
|
continue;
|
|
|
|
$dimensions = $thumb['width'] . 'x' . $thumb['height'];
|
|
|
|
// Does the thumbnail exist on disk? If not, use an url to generate it.
|
|
if (!$filename || !file_exists(THUMBSDIR . '/' . $subdir . '/' . $filename))
|
|
$thumb_url = BASEURL . '/thumbnail/' . $image->getId() . '/' . $dimensions . ($thumb['suffix'] ?? '') . '/';
|
|
else
|
|
$thumb_url = THUMBSURL . '/' . $subdir . '/' . $filename;
|
|
|
|
$has_crop_boundary = isset($metadata['crop_' . $dimensions]);
|
|
$has_custom_image = isset($metadata['custom_' . $dimensions]);
|
|
|
|
$thumbs[] = [
|
|
'dimensions' => [(int) $thumb['width'], (int) $thumb['height']],
|
|
'cropped' => !$has_custom_image && (!empty($thumb['suffix']) || $has_crop_boundary),
|
|
'crop_method' => !$has_custom_image && !empty($thumb['method']) ? $thumb['method'] : (!empty($thumb['suffix']) ? 'c' : null),
|
|
'crop_region' => $has_crop_boundary ? $metadata['crop_' . $dimensions] : null,
|
|
'custom_image' => $has_custom_image,
|
|
'filename' => $filename,
|
|
'url' => $thumb_url,
|
|
];
|
|
}
|
|
|
|
return $thumbs;
|
|
}
|
|
|
|
private function updateThumb(Image $image)
|
|
{
|
|
$data = json_decode($_POST['data']);
|
|
$meta = $image->getMeta();
|
|
|
|
// Set new crop boundary.
|
|
$crop_key = 'crop_' . $data->thumb_width . 'x' . $data->thumb_height;
|
|
$crop_value = $data->crop_width . ',' . $data->crop_height . ',' . $data->source_x . ',' . $data->source_y;
|
|
$meta[$crop_key] = $crop_value;
|
|
|
|
// If we previously uploaded a custom thumbnail, stop considering it such.
|
|
$custom_key = 'custom_' . $data->thumb_width . 'x' . $data->thumb_height;
|
|
if (isset($meta[$custom_key]))
|
|
{
|
|
// TODO: delete from disk
|
|
unset($meta[$custom_key]);
|
|
}
|
|
|
|
// Save meta changes so far.
|
|
$image->setMetaData($meta);
|
|
|
|
// Force a rebuild of related thumbnails.
|
|
$image->removeThumbnailsOfSize($data->thumb_width, $data->thumb_height);
|
|
|
|
$payload = [
|
|
'key' => $crop_key,
|
|
'value' => $crop_value,
|
|
'url' => $image->getThumbnailUrl($data->thumb_width, $data->thumb_height, 'exact'),
|
|
];
|
|
|
|
header('Content-Type: text/json; charset=utf-8');
|
|
echo json_encode($payload);
|
|
exit;
|
|
}
|
|
}
|