11 Commits

19 changed files with 554 additions and 64 deletions

10
TODO.md
View File

@@ -1,11 +1,11 @@
TODO: TODO:
* Gebruikers *persoons*tags laten verwijderen * Alleen persoonstags tonen bij foto's.
* Gebruikers persoonstags laten verwijderen vanaf fotopagina.
* 'Return to album' knop toevoegen die naar juiste pagina leidt.
* Bij taggen van user: thumbnail setten * Bij taggen van user: thumbnail setten
* Grid herberekenen; captions weglaten. * Grid herberekenen; captions weglaten.
* Sortering: alleen *albums* ASC, personen DESC!
* Album/tag management

165
controllers/EditAlbum.php Normal file
View File

@@ -0,0 +1,165 @@
<?php
/*****************************************************************************
* EditAlbum.php
* Contains the album edit controller.
*
* Kabuki CMS (C) 2013-2017, Aaron van Geffen
*****************************************************************************/
class EditAlbum extends HTMLController
{
public function __construct()
{
// Ensure it's just admins at this point.
if (!Registry::get('user')->isAdmin())
throw new NotAllowedException();
$id_tag = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (empty($id_tag) && !isset($_GET['add']) && $_GET['action'] !== 'addalbum')
throw new UnexpectedValueException('Requested album not found or not requesting a new album.');
// Adding an album?
if (isset($_GET['add']) || $_GET['action'] === 'addalbum')
{
parent::__construct('Add a new album');
$form_title = 'Add a new album';
$this->page->addClass('editalbum');
}
// Deleting one?
elseif (isset($_GET['delete']))
{
// So far so good?
$album = Tag::fromId($id_tag);
if (Session::validateSession('get') && $album->kind === 'Album' && $album->delete())
{
header('Location: ' . BASEURL . '/managealbums/');
exit;
}
else
trigger_error('Cannot delete album: an error occured while processing the request.', E_USER_ERROR);
}
// Editing one, then, surely.
else
{
$album = Tag::fromId($id_tag);
if ($album->kind !== 'Album')
trigger_error('Cannot edit album: not an album.', E_USER_ERROR);
parent::__construct('Edit album \'' . $album->tag . '\'');
$form_title = 'Edit album \'' . $album->tag . '\'';
$this->page->addClass('editalbum');
}
// Session checking!
if (empty($_POST))
Session::resetSessionToken();
else
Session::validateSession();
if ($id_tag)
$after_form = '<a href="' . BASEURL . '/editalbum/?id=' . $id_tag . '&delete&' . Session::getSessionTokenKey() . '=' . Session::getSessionToken() . '" class="btn btn-danger" onclick="return confirm(\'Are you sure you want to delete this album? You cannot undo this!\');">Delete album</a>';
elseif (!$id_tag)
$after_form = '<button name="submit_and_new" class="btn">Save and add another</button>';
$form = new Form([
'request_url' => BASEURL . '/editalbum/?' . ($id_tag ? 'id=' . $id_tag : 'add'),
'content_below' => $after_form,
'fields' => [
'id_parent' => [
'type' => 'numeric',
'label' => 'Parent album ID',
],
'id_asset_thumb' => [
'type' => 'numeric',
'label' => 'Thumbnail asset ID',
'is_optional' => true,
],
'tag' => [
'type' => 'text',
'label' => 'Album title',
'size' => 50,
'maxlength' => 255,
],
'slug' => [
'type' => 'text',
'label' => 'URL slug',
'size' => 50,
'maxlength' => 255,
],
'description' => [
'type' => 'textbox',
'label' => 'Description',
'size' => 50,
'maxlength' => 255,
'is_optional' => true,
],
],
]);
if (empty($_POST) && isset($_GET['tag']))
{
$parentTag = Tag::fromId($_GET['tag']);
if ($parentTag->kind === 'Album')
{
$formDefaults = [
'id_parent' => $parentTag->id_tag,
'tag' => 'New Album Title Here',
'slug' => ($parentTag->slug ? $parentTag->slug . '/' : '') . 'NEW_ALBUM_SLUG_HERE',
];
}
}
if (!isset($formDefaults))
$formDefaults = isset($album) ? get_object_vars($album) : $_POST;
// Create the form, add in default values.
$form->setData($formDefaults);
$formview = new FormView($form, $form_title ?? '');
$this->page->adopt($formview);
if (!empty($_POST))
{
$form->verify($_POST);
// Anything missing?
if (!empty($form->getMissing()))
return $formview->adopt(new Alert('Some data missing', 'Please fill out the following fields: ' . implode(', ', $form->getMissing()), 'error'));
$data = $form->getData();
// Quick stripping.
$data['tag'] = htmlentities($data['tag']);
$data['description'] = htmlentities($data['description']);
$data['slug'] = strtr(strtolower($data['slug']), [' ' => '-', '--' => '-', '&' => 'and', '=>' => '', "'" => "", ":"=> "", '/' => '-', '\\' => '-']);
// TODO: when updating slug, update slug for all photos in this album.
// Creating a new album?
if (!$id_tag)
{
$data['kind'] = 'Album';
$newTag = Tag::createNew($data);
if ($newTag === false)
return $formview->adopt(new Alert('Cannot create this album', 'Something went wrong while creating the album...', 'error'));
if (isset($_POST['submit_and_new']))
{
header('Location: ' . BASEURL . '/editalbum/?add&tag=' . $data['id_parent']);
exit;
}
}
// Just updating?
else
{
foreach ($data as $key => $value)
$album->$key = $value;
$album->save();
}
// Redirect to the album management page.
header('Location: ' . BASEURL . '/managealbums/');
exit;
}
}
}

152
controllers/EditTag.php Normal file
View File

@@ -0,0 +1,152 @@
<?php
/*****************************************************************************
* EditTag.php
* Contains the tag edit controller.
*
* Kabuki CMS (C) 2013-2017, Aaron van Geffen
*****************************************************************************/
class EditTag extends HTMLController
{
public function __construct()
{
// Ensure it's just admins at this point.
if (!Registry::get('user')->isAdmin())
throw new NotAllowedException();
$id_tag = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (empty($id_tag) && !isset($_GET['add']))
throw new UnexpectedValueException('Requested tag not found or not requesting a new tag.');
// Adding an tag?
if (isset($_GET['add']))
{
parent::__construct('Add a new tag');
$form_title = 'Add a new tag';
$this->page->addClass('edittag');
}
// Deleting one?
elseif (isset($_GET['delete']))
{
// So far so good?
$tag = Tag::fromId($id_tag);
if (Session::validateSession('get') && $tag->kind !== 'Album' && $tag->delete())
{
header('Location: ' . BASEURL . '/managetags/');
exit;
}
else
trigger_error('Cannot delete tag: an error occured while processing the request.', E_USER_ERROR);
}
// Editing one, then, surely.
else
{
$tag = Tag::fromId($id_tag);
if ($tag->kind === 'Album')
trigger_error('Cannot edit tag: is actually an album.', E_USER_ERROR);
parent::__construct('Edit tag \'' . $tag->tag . '\'');
$form_title = 'Edit tag \'' . $tag->tag . '\'';
$this->page->addClass('edittag');
}
// Session checking!
if (empty($_POST))
Session::resetSessionToken();
else
Session::validateSession();
if ($id_tag)
$after_form = '<a href="' . BASEURL . '/edittag/?id=' . $id_tag . '&delete&' . Session::getSessionTokenKey() . '=' . Session::getSessionToken() . '" class="btn btn-danger" onclick="return confirm(\'Are you sure you want to delete this tag? You cannot undo this!\');">Delete tag</a>';
elseif (!$id_tag)
$after_form = '<button name="submit_and_new" class="btn">Save and add another</button>';
$form = new Form([
'request_url' => BASEURL . '/edittag/?' . ($id_tag ? 'id=' . $id_tag : 'add'),
'content_below' => $after_form,
'fields' => [
'id_parent' => [
'type' => 'numeric',
'label' => 'Parent tag ID',
],
'id_asset_thumb' => [
'type' => 'numeric',
'label' => 'Thumbnail asset ID',
'is_optional' => true,
],
'kind' => [
'type' => 'select',
'label' => 'Kind of tag',
'options' => [
'Location' => 'Location',
'Person' => 'Person',
],
],
'tag' => [
'type' => 'text',
'label' => 'Tag title',
'size' => 50,
'maxlength' => 255,
],
'slug' => [
'type' => 'text',
'label' => 'URL slug',
'size' => 50,
'maxlength' => 255,
],
'description' => [
'type' => 'textbox',
'label' => 'Description',
'size' => 50,
'maxlength' => 255,
'is_optional' => true,
],
],
]);
// Create the form, add in default values.
$form->setData($id_tag ? get_object_vars($tag) : $_POST);
$formview = new FormView($form, $form_title ?? '');
$this->page->adopt($formview);
if (!empty($_POST))
{
$form->verify($_POST);
// Anything missing?
if (!empty($form->getMissing()))
return $formview->adopt(new Alert('Some data missing', 'Please fill out the following fields: ' . implode(', ', $form->getMissing()), 'error'));
$data = $form->getData();
// Quick stripping.
$data['slug'] = strtr(strtolower($data['slug']), [' ' => '-', '--' => '-', '&' => 'and', '=>' => '', "'" => "", ":"=> "", '/' => '-', '\\' => '-']);
// Creating a new tag?
if (!$id_tag)
{
$return = Tag::createNew($data);
if ($return === false)
return $formview->adopt(new Alert('Cannot create this tag', 'Something went wrong while creating the tag...', 'error'));
if (isset($_POST['submit_and_new']))
{
header('Location: ' . BASEURL . '/edittag/?add');
exit;
}
}
// Just updating?
else
{
foreach ($data as $key => $value)
$tag->$key = $value;
$tag->save();
}
// Redirect to the tag management page.
header('Location: ' . BASEURL . '/managetags/');
exit;
}
}
}

View File

@@ -0,0 +1,147 @@
<?php
/*****************************************************************************
* ManageAlbums.php
* Contains the controller for admin album management.
*
* Kabuki CMS (C) 2013-2017, Aaron van Geffen
*****************************************************************************/
class ManageAlbums extends HTMLController
{
public function __construct()
{
// Ensure it's just admins at this point.
if (!Registry::get('user')->isAdmin())
throw new NotAllowedException();
$options = [
'form' => [
'action' => BASEURL . '/editalbum/',
'method' => 'get',
'class' => 'floatright',
'buttons' => [
'add' => [
'type' => 'submit',
'caption' => 'Add new album',
],
],
],
'columns' => [
'id_album' => [
'value' => 'id_tag',
'header' => 'ID',
'is_sortable' => true,
],
'tag' => [
'header' => 'Album',
'is_sortable' => true,
'parse' => [
'link' => BASEURL . '/editalbum/?id={ID_TAG}',
'data' => 'tag',
],
],
'slug' => [
'header' => 'Slug',
'is_sortable' => true,
'parse' => [
'link' => BASEURL . '/editalbum/?id={ID_TAG}',
'data' => 'slug',
],
],
'count' => [
'header' => '# Photos',
'is_sortable' => true,
'value' => 'count',
],
],
'start' => !empty($_GET['start']) ? (int) $_GET['start'] : 0,
'sort_order' => !empty($_GET['order']) ? $_GET['order'] : null,
'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : null,
'title' => 'Manage albums',
'no_items_label' => 'No albums meet the requirements of the current filter.',
'items_per_page' => 9999,
'index_class' => 'floatleft',
'base_url' => BASEURL . '/managealbums/',
'get_data' => function($offset = 0, $limit = 9999, $order = '', $direction = 'up') {
if (!in_array($order, ['id_tag', 'tag', 'slug', 'count']))
$order = 'tag';
if (!in_array($direction, ['up', 'down']))
$direction = 'up';
$db = Registry::get('db');
$res = $db->query('
SELECT *
FROM tags
WHERE kind = {string:album}
ORDER BY id_parent, {raw:order}',
[
'order' => $order . ($direction == 'up' ? ' ASC' : ' DESC'),
'album' => 'Album',
]);
$albums_by_parent = [];
while ($row = $db->fetch_assoc($res))
{
if (!isset($albums_by_parent[$row['id_parent']]))
$albums_by_parent[$row['id_parent']] = [];
$albums_by_parent[$row['id_parent']][] = $row + ['children' => []];
}
$albums = self::getChildrenRecursively(0, 0, $albums_by_parent);
$rows = self::flattenChildrenRecursively($albums);
return [
'rows' => $rows,
'order' => $order,
'direction' => ($direction == 'up' ? 'up' : 'down'),
];
},
'get_count' => function() {
return 9999;
}
];
$table = new GenericTable($options);
parent::__construct('Album management - Page ' . $table->getCurrentPage() .' - ' . SITE_TITLE);
$this->page->adopt(new TabularData($table));
}
private static function getChildrenRecursively($id_parent, $level, &$albums_by_parent)
{
$children = [];
if (!isset($albums_by_parent[$id_parent]))
return $children;
foreach ($albums_by_parent[$id_parent] as $child)
{
if (isset($albums_by_parent[$child['id_tag']]))
$child['children'] = self::getChildrenRecursively($child['id_tag'], $level + 1, $albums_by_parent);
$child['tag'] = ($level ? str_repeat('—', $level * 2) . ' ' : '') . $child['tag'];
$children[] = $child;
}
return $children;
}
private static function flattenChildrenRecursively($albums)
{
if (empty($albums))
return [];
$rows = [];
foreach ($albums as $album)
{
$rows[] = array_intersect_key($album, array_flip(['id_tag', 'tag', 'slug', 'count']));
if (!empty($album['children']))
{
$children = self::flattenChildrenRecursively($album['children']);
foreach ($children as $child)
$rows[] = array_intersect_key($child, array_flip(['id_tag', 'tag', 'slug', 'count']));
}
}
return $rows;
}
}

View File

@@ -19,6 +19,7 @@ class ManageErrors extends HTMLController
{ {
ErrorLog::flush(); ErrorLog::flush();
header('Location: ' . BASEURL . '/manageerrors/'); header('Location: ' . BASEURL . '/manageerrors/');
exit;
} }
Session::resetSessionToken(); Session::resetSessionToken();

View File

@@ -15,6 +15,17 @@ class ManageTags extends HTMLController
throw new NotAllowedException(); throw new NotAllowedException();
$options = [ $options = [
'form' => [
'action' => BASEURL . '/edittag/',
'method' => 'get',
'class' => 'floatright',
'buttons' => [
'add' => [
'type' => 'submit',
'caption' => 'Add new tag',
],
],
],
'columns' => [ 'columns' => [
'id_post' => [ 'id_post' => [
'value' => 'id_tag', 'value' => 'id_tag',
@@ -25,7 +36,7 @@ class ManageTags extends HTMLController
'header' => 'Tag', 'header' => 'Tag',
'is_sortable' => true, 'is_sortable' => true,
'parse' => [ 'parse' => [
'link' => BASEURL . '/managetag/?id={ID_TAG}', 'link' => BASEURL . '/edittag/?id={ID_TAG}',
'data' => 'tag', 'data' => 'tag',
], ],
], ],
@@ -33,7 +44,7 @@ class ManageTags extends HTMLController
'header' => 'Slug', 'header' => 'Slug',
'is_sortable' => true, 'is_sortable' => true,
'parse' => [ 'parse' => [
'link' => BASEURL . '/managetag/?id={ID_TAG}', 'link' => BASEURL . '/edittag/?id={ID_TAG}',
'data' => 'slug', 'data' => 'slug',
], ],
], ],
@@ -53,9 +64,10 @@ class ManageTags extends HTMLController
'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : null, 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : null,
'title' => 'Manage tags', 'title' => 'Manage tags',
'no_items_label' => 'No tags meet the requirements of the current filter.', 'no_items_label' => 'No tags meet the requirements of the current filter.',
'items_per_page' => 25, 'items_per_page' => 30,
'index_class' => 'floatleft',
'base_url' => BASEURL . '/managetags/', 'base_url' => BASEURL . '/managetags/',
'get_data' => function($offset = 0, $limit = 15, $order = '', $direction = 'up') { 'get_data' => function($offset = 0, $limit = 30, $order = '', $direction = 'up') {
if (!in_array($order, ['id_post', 'tag', 'slug', 'kind', 'count'])) if (!in_array($order, ['id_post', 'tag', 'slug', 'kind', 'count']))
$order = 'tag'; $order = 'tag';
if (!in_array($direction, ['up', 'down'])) if (!in_array($direction, ['up', 'down']))
@@ -64,12 +76,14 @@ class ManageTags extends HTMLController
$data = Registry::get('db')->queryAssocs(' $data = Registry::get('db')->queryAssocs('
SELECT * SELECT *
FROM tags FROM tags
WHERE kind != {string:album}
ORDER BY {raw:order} ORDER BY {raw:order}
LIMIT {int:offset}, {int:limit}', LIMIT {int:offset}, {int:limit}',
[ [
'order' => $order . ($direction == 'up' ? ' ASC' : ' DESC'), 'order' => $order . ($direction == 'up' ? ' ASC' : ' DESC'),
'offset' => $offset, 'offset' => $offset,
'limit' => $limit, 'limit' => $limit,
'album' => 'Album',
]); ]);
return [ return [
@@ -81,7 +95,9 @@ class ManageTags extends HTMLController
'get_count' => function() { 'get_count' => function() {
return Registry::get('db')->queryValue(' return Registry::get('db')->queryValue('
SELECT COUNT(*) SELECT COUNT(*)
FROM tags'); FROM tags
WHERE kind != {string:album}',
['album' => 'Album']);
} }
]; ];

View File

@@ -93,10 +93,10 @@ class ManageUsers extends HTMLController
'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : '', 'sort_direction' => !empty($_GET['dir']) ? $_GET['dir'] : '',
'title' => 'Manage users', 'title' => 'Manage users',
'no_items_label' => 'No users meet the requirements of the current filter.', 'no_items_label' => 'No users meet the requirements of the current filter.',
'items_per_page' => 15, 'items_per_page' => 30,
'index_class' => 'floatleft', 'index_class' => 'floatleft',
'base_url' => BASEURL . '/manageusers/', 'base_url' => BASEURL . '/manageusers/',
'get_data' => function($offset = 0, $limit = 15, $order = '', $direction = 'down') { 'get_data' => function($offset = 0, $limit = 30, $order = '', $direction = 'down') {
if (!in_array($order, ['id_user', 'surname', 'first_name', 'slug', 'emailaddress', 'last_action_time', 'ip_address', 'is_admin'])) if (!in_array($order, ['id_user', 'surname', 'first_name', 'slug', 'emailaddress', 'last_action_time', 'ip_address', 'is_admin']))
$order = 'id_user'; $order = 'id_user';

View File

@@ -116,13 +116,6 @@ class Asset
} }
} }
public static function byPostId($id_post, $return_format = 'object')
{
$db = Registry::get('db');
// !!! TODO
}
public static function createNew(array $data, $return_format = 'object') public static function createNew(array $data, $return_format = 'object')
{ {
// Extract the data array. // Extract the data array.
@@ -438,7 +431,19 @@ class Asset
public function delete() public function delete()
{ {
return Registry::get('db')->query(' $db = Registry::get('db');
if (!unlink(ASSETSDIR . '/' . $this->subdir . '/' . $this->filename))
return false;
$db->query('
DELETE FROM assets_meta
WHERE id_asset = {int:id_asset}',
[
'id_asset' => $this->id_asset,
]);
return $db->query('
DELETE FROM assets DELETE FROM assets
WHERE id_asset = {int:id_asset}', WHERE id_asset = {int:id_asset}',
[ [
@@ -481,7 +486,7 @@ class Asset
public static function getCount() public static function getCount()
{ {
return $db->queryValue(' return Registry::get('db')->queryValue('
SELECT COUNT(*) SELECT COUNT(*)
FROM assets'); FROM assets');
} }

View File

@@ -11,12 +11,15 @@ class Dispatcher
public static function route() public static function route()
{ {
$possibleActions = [ $possibleActions = [
'addalbum' => 'EditAlbum',
'albums' => 'ViewPhotoAlbums', 'albums' => 'ViewPhotoAlbums',
'editalbum' => 'EditAlbum',
'editasset' => 'EditAsset', 'editasset' => 'EditAsset',
'edittag' => 'EditTag',
'edituser' => 'EditUser', 'edituser' => 'EditUser',
'login' => 'Login', 'login' => 'Login',
'logout' => 'Logout', 'logout' => 'Logout',
'managecomments' => 'ManageComments', 'managealbums' => 'ManageAlbums',
'manageerrors' => 'ManageErrors', 'manageerrors' => 'ManageErrors',
'managetags' => 'ManageTags', 'managetags' => 'ManageTags',
'manageusers' => 'ManageUsers', 'manageusers' => 'ManageUsers',

View File

@@ -114,15 +114,16 @@ class GenericTable extends PageIndex
private function parseAllRows($rows, $options) private function parseAllRows($rows, $options)
{ {
// Parse all rows... foreach ($rows as $i => $row)
$i = 0;
foreach ($rows as $row)
{ {
$i ++; $className = $i & 1 ? 'even' : 'odd';
$newRow = array( if (isset($options['row_classifier']))
'class' => $i %2 == 1 ? 'odd' : 'even', $className .= $options['row_classifier']($row);
'cells' => array(),
); $newRow = [
'class' => $className,
'cells' => [],
];
foreach ($options['columns'] as $column) foreach ($options['columns'] as $column)
{ {
@@ -154,7 +155,12 @@ class GenericTable extends PageIndex
// timestamps: let's make them readable! // timestamps: let's make them readable!
case 'timestamp': case 'timestamp':
$pattern = !empty($column['parse']['data']['pattern']) && $column['parse']['data']['pattern'] == 'long' ? '%F %H:%M' : '%H:%M'; if (empty($column['parse']['data']['pattern']) || $column['parse']['data']['pattern'] === 'long')
$pattern = '%F %H:%M';
elseif ($column['parse']['data']['pattern'] === 'short')
$pattern = '%F';
else
$pattern = $column['parse']['data']['pattern'];
if (!is_numeric($row[$column['parse']['data']['timestamp']])) if (!is_numeric($row[$column['parse']['data']['timestamp']]))
$timestamp = strtotime($row[$column['parse']['data']['timestamp']]); $timestamp = strtotime($row[$column['parse']['data']['timestamp']]);

View File

@@ -9,10 +9,10 @@
class PageIndex class PageIndex
{ {
protected $page_index = []; protected $page_index = [];
protected $current_page = 0; protected $current_page = 1;
protected $items_per_page = 0; protected $items_per_page = 0;
protected $needsPageIndex = false; protected $needsPageIndex = false;
protected $num_pages = 0; protected $num_pages = 1;
protected $recordCount = 0; protected $recordCount = 0;
protected $start = 0; protected $start = 0;
protected $sort_order = null; protected $sort_order = null;

View File

@@ -260,6 +260,8 @@ class Tag
id_parent = {int:id_parent}, id_parent = {int:id_parent},
id_asset_thumb = {int:id_asset_thumb}, id_asset_thumb = {int:id_asset_thumb},
tag = {string:tag}, tag = {string:tag},
slug = {string:slug},
description = {string:description},
count = {int:count} count = {int:count}
WHERE id_tag = {int:id_tag}', WHERE id_tag = {int:id_tag}',
get_object_vars($this)); get_object_vars($this));
@@ -270,7 +272,7 @@ class Tag
$db = Registry::get('db'); $db = Registry::get('db');
$res = $db->query(' $res = $db->query('
DELETE FROM posts_tags DELETE FROM assets_tags
WHERE id_tag = {int:id_tag}', WHERE id_tag = {int:id_tag}',
[ [
'id_tag' => $this->id_tag, 'id_tag' => $this->id_tag,

View File

@@ -18,8 +18,8 @@ body {
font: 13px/1.7 "Open Sans", sans-serif; font: 13px/1.7 "Open Sans", sans-serif;
padding: 0 0 3em; padding: 0 0 3em;
margin: 0; margin: 0;
background: #99BFCE 0 -50% fixed; background: #aaa 0 -50% fixed;
background-image: radial-gradient(ellipse at top, #c3dee5 0%,#92b9ca 55%,#365e77 100%); /* W3C */ background-image: radial-gradient(ellipse at top, #ccc 0%, #aaa 55%, #333 100%);
} }
#wrapper, header { #wrapper, header {
@@ -34,11 +34,11 @@ header {
} }
a { a {
color: #487C96; color: #963626;
text-decoration: none; text-decoration: none;
} }
a:hover { a:hover {
color: #222; color: #262626;
} }
/* Logo /* Logo
@@ -163,14 +163,12 @@ ul#nav li a:hover {
.tiled_grid div.landscape, .tiled_grid div.portrait, .tiled_grid div.panorama, .tiled_grid div.landscape, .tiled_grid div.portrait, .tiled_grid div.panorama,
.tiled_grid div.duo, .tiled_grid div.single { .tiled_grid div.duo, .tiled_grid div.single {
background: #fff; background: #fff;
border-bottom-style: none !important;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
float: left; float: left;
line-height: 0; line-height: 0;
margin: 0 3.5% 3.5% 0; margin: 0 3.5% 3.5% 0;
overflow: none; overflow: none;
position: relative; position: relative;
padding-bottom: 5px;
width: 31%; width: 31%;
} }
.tiled_grid div img { .tiled_grid div img {
@@ -181,7 +179,7 @@ ul#nav li a:hover {
color: #000; color: #000;
margin: 0; margin: 0;
font: 400 18px "Open Sans", sans-serif; font: 400 18px "Open Sans", sans-serif;
padding: 20px 5px 15px; padding: 15px 5px;
text-overflow: ellipsis; text-overflow: ellipsis;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
@@ -192,9 +190,7 @@ ul#nav li a:hover {
} }
.tiled_grid div.landscape:hover, .tiled_grid div.portrait:hover, .tiled_grid div.panorama:hover, .tiled_grid div.landscape:hover, .tiled_grid div.portrait:hover, .tiled_grid div.panorama:hover,
.tiled_grid div.duo:hover, .tiled_grid div.single:hover { .tiled_grid div.duo:hover, .tiled_grid div.single:hover {
padding-bottom: 0; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
border-bottom-width: 5px;
border-bottom-style: solid !important;
} }
/* Panoramas */ /* Panoramas */
@@ -305,7 +301,7 @@ ul#nav li a:hover {
margin: 0 0 1.5% 0; margin: 0 0 1.5% 0;
} }
.album_title_box h2 { .album_title_box h2 {
color: #487C96; color: #262626;
font: 400 18px/2 "Open Sans", sans-serif !important; font: 400 18px/2 "Open Sans", sans-serif !important;
margin: 0; margin: 0;
} }
@@ -385,16 +381,16 @@ input, select, .btn {
padding: 3px; padding: 3px;
} }
input[type=submit], button, .btn { input[type=submit], button, .btn {
background: #C5E2EA; background: #ddd;
border-radius: 3px; border-radius: 3px;
border: 1px solid #8BBFCE; border: 1px solid #aaa;
display: inline-block; display: inline-block;
font: inherit; font: inherit;
padding: 4px 5px; padding: 4px 5px;
} }
input[type=submit]:hover, button:hover, .btn:hover { input[type=submit]:hover, button:hover, .btn:hover {
background-color: #bddce5; background-color: #d0d0d0;
border-color: #88b7c6; border-color: #a0a0a0;
} }
textarea { textarea {
border: 1px solid #ccc; border: 1px solid #ccc;
@@ -519,12 +515,9 @@ textarea {
/* Styling for the photo pages /* Styling for the photo pages
--------------------------------*/ --------------------------------*/
#photo_frame { #photo_frame {
overflow: hidden;
text-align: center; text-align: center;
} }
#photo_frame a { #photo_frame a {
background: #fff;
border: 0.9em solid #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
cursor: -moz-zoom-in; cursor: -moz-zoom-in;
display: inline-block; display: inline-block;
@@ -539,7 +532,7 @@ textarea {
#previous_photo, #next_photo { #previous_photo, #next_photo {
background: #fff; background: #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
color: #678FA4; color: #262626;
font-size: 3em; font-size: 3em;
line-height: 0.5; line-height: 0.5;
padding: 32px 8px; padding: 32px 8px;
@@ -674,7 +667,7 @@ a#previous_photo:hover, a#next_photo:hover {
} }
.tiled_grid div h4 { .tiled_grid div h4 {
font-size: 14px; font-size: 14px;
padding: 15px 5px 10px; padding: 15px 5px;
} }
.tiled_row > div, .tiled_row .single, .tiled_row .duo { .tiled_row > div, .tiled_row .single, .tiled_row .duo {

View File

@@ -146,7 +146,7 @@ CropEditor.prototype.save = function() {
source_x: this.source_x.value, source_x: this.source_x.value,
source_y: this.source_y.value source_y: this.source_y.value
}; };
var req = HttpRequest("post", this.parent.action + "?id=" + this.opt.asset_id + "&updatethumb", var req = HttpRequest("post", this.opt.submitUrl + "?id=" + this.opt.asset_id + "&updatethumb",
"data=" + encodeURIComponent(JSON.stringify(payload)), function(response) { "data=" + encodeURIComponent(JSON.stringify(payload)), function(response) {
this.opt.after_save(response); this.opt.after_save(response);
this.hide(); this.hide();

View File

@@ -15,6 +15,7 @@ class AdminBar extends SubTemplate
echo ' echo '
<div id="admin_bar"> <div id="admin_bar">
<ul> <ul>
<li><a href="', BASEURL, '/managealbums/">Albums</a></li>
<li><a href="', BASEURL, '/managetags/">Tags</a></li> <li><a href="', BASEURL, '/managetags/">Tags</a></li>
<li><a href="', BASEURL, '/manageusers/">Users</a></li> <li><a href="', BASEURL, '/manageusers/">Users</a></li>
<li><a href="', BASEURL, '/manageerrors/">Errors [', ErrorLog::getCount(), ']</a></li>'; <li><a href="', BASEURL, '/manageerrors/">Errors [', ErrorLog::getCount(), ']</a></li>';

View File

@@ -14,7 +14,7 @@ class AlbumIndex extends SubTemplate
protected $row_limit = 1000; protected $row_limit = 1000;
const TILE_WIDTH = 400; const TILE_WIDTH = 400;
const TILE_HEIGHT = 267; const TILE_HEIGHT = 300;
public function __construct(array $albums, $show_edit_buttons = false, $show_labels = true) public function __construct(array $albums, $show_edit_buttons = false, $show_labels = true)
{ {

View File

@@ -193,6 +193,7 @@ class EditAssetForm extends SubTemplate
<script type="text/javascript"> <script type="text/javascript">
setTimeout(function() { setTimeout(function() {
var editor = new CropEditor({ var editor = new CropEditor({
submit_url: "', BASEURL, '/editasset/",
original_image_src: "', $this->asset->getUrl(), '", original_image_src: "', $this->asset->getUrl(), '",
editor_container_parent_id: "asset_form", editor_container_parent_id: "asset_form",
thumbnail_select_id: "thumbnail_src", thumbnail_select_id: "thumbnail_src",

View File

@@ -24,10 +24,8 @@ class FormView extends SubTemplate
{ {
if (!empty($this->title)) if (!empty($this->title))
echo ' echo '
<div id="journal_title"> <div class="admin_box">
<h3>', $this->title, '</h3> <h2>', $this->title, '</h2>';
</div>
<div id="inner">';
foreach ($this->_subtemplates as $template) foreach ($this->_subtemplates as $template)
$template->html_main(); $template->html_main();
@@ -134,7 +132,7 @@ class FormView extends SubTemplate
case 'numeric': case 'numeric':
echo ' echo '
<input type="number"', isset($field['step']) ? ' step="' . $field['step'] . '"' : '', '" min="', isset($field['min_value']) ? $field['min_value'] : '0', '" max="', isset($field['max_value']) ? $field['max_value'] : '9999', '" name="', $field_id, '" id="', $field_id, '"', isset($field['size']) ? ' size="' . $field['size'] . '"' : '', isset($field['maxlength']) ? ' maxlength="' . $field['maxlength'] . '"' : '', ' value="', htmlentities($this->data[$field_id]), '"', !empty($field['disabled']) ? ' disabled' : '', '>'; <input type="number"', isset($field['step']) ? ' step="' . $field['step'] . '"' : '', ' min="', isset($field['min_value']) ? $field['min_value'] : '0', '" max="', isset($field['max_value']) ? $field['max_value'] : '9999', '" name="', $field_id, '" id="', $field_id, '"', isset($field['size']) ? ' size="' . $field['size'] . '"' : '', isset($field['maxlength']) ? ' maxlength="' . $field['maxlength'] . '"' : '', ' value="', htmlentities($this->data[$field_id]), '"', !empty($field['disabled']) ? ' disabled' : '', '>';
break; break;
case 'file': case 'file':

View File

@@ -19,7 +19,7 @@ class PhotosIndex extends SubTemplate
const PANORAMA_HEIGHT = null; const PANORAMA_HEIGHT = null;
const PORTRAIT_WIDTH = 400; const PORTRAIT_WIDTH = 400;
const PORTRAIT_HEIGHT = 640; const PORTRAIT_HEIGHT = 645;
const LANDSCAPE_WIDTH = 850; const LANDSCAPE_WIDTH = 850;
const LANDSCAPE_HEIGHT = 640; const LANDSCAPE_HEIGHT = 640;
@@ -31,9 +31,9 @@ class PhotosIndex extends SubTemplate
const SINGLE_HEIGHT = 412; const SINGLE_HEIGHT = 412;
const TILE_WIDTH = 400; const TILE_WIDTH = 400;
const TILE_HEIGHT = 267; const TILE_HEIGHT = 300;
public function __construct(PhotoMosaic $mosaic, $show_edit_buttons = false, $show_labels = true, $show_headers = true) public function __construct(PhotoMosaic $mosaic, $show_edit_buttons = false, $show_labels = false, $show_headers = true)
{ {
$this->mosaic = $mosaic; $this->mosaic = $mosaic;
$this->show_edit_buttons = $show_edit_buttons; $this->show_edit_buttons = $show_edit_buttons;