Compare commits
26 Commits
version-1.
...
version-1.
| Author | SHA1 | Date | |
|---|---|---|---|
| cda7f3115c | |||
| e439a074a6 | |||
| ee9bdd45c0 | |||
| 9fe8acc747 | |||
| 096cea078c | |||
| 2a25434862 | |||
| 943297900c | |||
| 95e289d82d | |||
| 1a15e347f2 | |||
| 31e1357b47 | |||
| 08cc6b1c77 | |||
| 1623a430e5 | |||
| 9f92ed6d7a | |||
| fc02c9b93a | |||
| 9dfb2649e5 | |||
| 9b2cc5caae | |||
| fa5ef75205 | |||
| f4bcb1e584 | |||
| 1f7fe35cec | |||
| 0a55730696 | |||
| 7f5ce1820d | |||
| 6c0f6b06e6 | |||
| b66088319b | |||
| 2a7b44dfb2 | |||
| a85afff188 | |||
| 01bfc66842 |
11
TODO.md
11
TODO.md
@@ -1,4 +1,11 @@
|
|||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
* Taggen door gebruikers
|
* Alleen persoonstags tonen bij foto's.
|
||||||
* Album management
|
|
||||||
|
* Gebruikers persoonstags laten verwijderen vanaf fotopagina.
|
||||||
|
|
||||||
|
* 'Return to album' knop toevoegen die naar juiste pagina leidt.
|
||||||
|
|
||||||
|
* Bij taggen van user: thumbnail setten
|
||||||
|
|
||||||
|
* Grid herberekenen; captions weglaten.
|
||||||
|
|||||||
2
app.php
2
app.php
@@ -23,7 +23,7 @@ $user->updateAccessTime();
|
|||||||
Registry::set('user', $user);
|
Registry::set('user', $user);
|
||||||
|
|
||||||
// Handle errors our own way.
|
// Handle errors our own way.
|
||||||
//set_error_handler('ErrorHandler::handleError');
|
set_error_handler('ErrorHandler::handleError');
|
||||||
ini_set("display_errors", DEBUG ? "On" : "Off");
|
ini_set("display_errors", DEBUG ? "On" : "Off");
|
||||||
|
|
||||||
// The real magic starts here!
|
// The real magic starts here!
|
||||||
|
|||||||
165
controllers/EditAlbum.php
Normal file
165
controllers/EditAlbum.php
Normal 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
152
controllers/EditTag.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,8 +30,8 @@ class Login extends HTMLController
|
|||||||
header('Location: ' . base64_decode($_POST['redirect_url']));
|
header('Location: ' . base64_decode($_POST['redirect_url']));
|
||||||
elseif (isset($_SESSION['login_url']))
|
elseif (isset($_SESSION['login_url']))
|
||||||
{
|
{
|
||||||
unset($_SESSION['redirect_url']);
|
header('Location: ' . $_SESSION['login_url']);
|
||||||
header('Location: ' . $_SESSION['redirect_url']);
|
unset($_SESSION['login_url']);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
header('Location: ' . BASEURL . '/');
|
header('Location: ' . BASEURL . '/');
|
||||||
|
|||||||
147
controllers/ManageAlbums.php
Normal file
147
controllers/ManageAlbums.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -14,10 +14,18 @@ class ManageTags extends HTMLController
|
|||||||
if (!Registry::get('user')->isAdmin())
|
if (!Registry::get('user')->isAdmin())
|
||||||
throw new NotAllowedException();
|
throw new NotAllowedException();
|
||||||
|
|
||||||
if (isset($_REQUEST['create']) && isset($_POST['tag']))
|
|
||||||
$this->handleTagCreation();
|
|
||||||
|
|
||||||
$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',
|
||||||
@@ -28,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',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -36,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',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -56,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']))
|
||||||
@@ -67,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 [
|
||||||
@@ -84,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']);
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -92,36 +105,4 @@ class ManageTags extends HTMLController
|
|||||||
parent::__construct('Tag management - Page ' . $table->getCurrentPage() .' - ' . SITE_TITLE);
|
parent::__construct('Tag management - Page ' . $table->getCurrentPage() .' - ' . SITE_TITLE);
|
||||||
$this->page->adopt(new TabularData($table));
|
$this->page->adopt(new TabularData($table));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function handleTagCreation()
|
|
||||||
{
|
|
||||||
header('Content-Type: text/json; charset=utf-8');
|
|
||||||
|
|
||||||
// It better not already exist!
|
|
||||||
if (Tag::exactMatch($_POST['tag']))
|
|
||||||
{
|
|
||||||
echo '{"error":"Tag already exists!"}';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$label = htmlentities(trim($_POST['tag']));
|
|
||||||
$slug = strtr(strtolower($label), [' ' => '-']);
|
|
||||||
$tag = Tag::createNew([
|
|
||||||
'tag' => $label,
|
|
||||||
'slug' => $slug,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Did we succeed?
|
|
||||||
if (!$tag)
|
|
||||||
{
|
|
||||||
echo '{"error":"Could not create tag."}';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'label' => $tag->tag,
|
|
||||||
'id_tag' => $tag->id_tag,
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,22 @@ class ProvideAutoSuggest extends JSONController
|
|||||||
if (!Registry::get('user')->isLoggedIn())
|
if (!Registry::get('user')->isLoggedIn())
|
||||||
throw new NotAllowedException();
|
throw new NotAllowedException();
|
||||||
|
|
||||||
if (!isset($_GET['type']))
|
if (!isset($_REQUEST['type']))
|
||||||
throw new UnexpectedValueException('Unsupported autosuggest request.');
|
throw new UnexpectedValueException('Unsupported autosuggest request.');
|
||||||
|
|
||||||
if ($_GET['type'] === 'tags' && isset($_GET['data']))
|
if ($_REQUEST['type'] === 'tags' && isset($_REQUEST['data']))
|
||||||
|
return $this->handleTagSearch();
|
||||||
|
|
||||||
|
if ($_REQUEST['type'] === 'createtag' && isset($_REQUEST['tag']))
|
||||||
|
return $this->handleTagCreation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleTagSearch()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
$data = array_unique(explode(' ', urldecode($_GET['data'])));
|
$data = array_unique(explode(' ', urldecode($_REQUEST['data'])));
|
||||||
$data = array_filter($data, function($item) {
|
$data = array_filter($data, function($item) {
|
||||||
return strlen($item) >= 3;
|
return strlen($item) >= 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->payload = ['items' => []];
|
$this->payload = ['items' => []];
|
||||||
@@ -30,7 +38,7 @@ class ProvideAutoSuggest extends JSONController
|
|||||||
if (count($data) === 0)
|
if (count($data) === 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$results = Tag::match($data);
|
$results = Tag::matchPeople($data);
|
||||||
foreach ($results as $id_tag => $tag)
|
foreach ($results as $id_tag => $tag)
|
||||||
$this->payload['items'][] = [
|
$this->payload['items'][] = [
|
||||||
'label' => $tag,
|
'label' => $tag,
|
||||||
@@ -38,4 +46,35 @@ class ProvideAutoSuggest extends JSONController
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleTagCreation()
|
||||||
|
{
|
||||||
|
// It better not already exist!
|
||||||
|
if (Tag::exactMatch($_REQUEST['tag']))
|
||||||
|
{
|
||||||
|
$this->payload = ['error' => true, 'msg' => "Tag already exists!"];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$label = htmlentities(trim($_REQUEST['tag']));
|
||||||
|
$slug = strtr($label, [' ' => '-']);
|
||||||
|
$tag = Tag::createNew([
|
||||||
|
'tag' => $label,
|
||||||
|
'kind' => 'Person',
|
||||||
|
'slug' => $slug,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Did we succeed?
|
||||||
|
if (!$tag)
|
||||||
|
{
|
||||||
|
$this->payload = ['error' => true, 'msg' => "Could not create tag."];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->payload = [
|
||||||
|
'success' => true,
|
||||||
|
'label' => $tag->tag,
|
||||||
|
'id_tag' => $tag->id_tag,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ class ViewPhoto extends HTMLController
|
|||||||
if (empty($photo))
|
if (empty($photo))
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
|
|
||||||
|
if (!empty($_POST))
|
||||||
|
$this->handleTagging($photo->getImage());
|
||||||
|
|
||||||
parent::__construct($photo->getTitle() . ' - ' . SITE_TITLE);
|
parent::__construct($photo->getTitle() . ' - ' . SITE_TITLE);
|
||||||
$page = new PhotoPage($photo->getImage());
|
$page = new PhotoPage($photo->getImage());
|
||||||
|
|
||||||
@@ -47,4 +50,21 @@ class ViewPhoto extends HTMLController
|
|||||||
if (Registry::get('user')->isAdmin())
|
if (Registry::get('user')->isAdmin())
|
||||||
$this->admin_bar->appendItem(BASEURL . '/editasset/?id=' . $photo->getId(), 'Edit this photo');
|
$this->admin_bar->appendItem(BASEURL . '/editasset/?id=' . $photo->getId(), 'Edit this photo');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleTagging(Image $photo)
|
||||||
|
{
|
||||||
|
header('Content-Type: text/json; charset=utf-8');
|
||||||
|
|
||||||
|
// Are we tagging a photo?
|
||||||
|
if (!isset($_POST['id_tag']))
|
||||||
|
{
|
||||||
|
echo json_encode(['error' => true, 'msg' => 'Invalid tag request.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are!
|
||||||
|
$photo->linkTags([(int) $_POST['id_tag']]);
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class ViewPhotoAlbum extends HTMLController
|
|||||||
{
|
{
|
||||||
$back_link = BASEURL . '/people/';
|
$back_link = BASEURL . '/people/';
|
||||||
$back_link_title = 'Back to "People"';
|
$back_link_title = 'Back to "People"';
|
||||||
|
$is_person = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$header_box = new AlbumHeaderBox($title, $description, $back_link, $back_link_title);
|
$header_box = new AlbumHeaderBox($title, $description, $back_link, $back_link_title);
|
||||||
@@ -84,7 +85,7 @@ class ViewPhotoAlbum extends HTMLController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load a photo mosaic for the current tag.
|
// Load a photo mosaic for the current tag.
|
||||||
list($mosaic, $total_count) = $this->getPhotoMosaic($id_tag, $page);
|
list($mosaic, $total_count) = $this->getPhotoMosaic($id_tag, $page, !isset($is_person));
|
||||||
if (isset($mosaic))
|
if (isset($mosaic))
|
||||||
{
|
{
|
||||||
$index = new PhotosIndex($mosaic, Registry::get('user')->isAdmin());
|
$index = new PhotosIndex($mosaic, Registry::get('user')->isAdmin());
|
||||||
@@ -111,13 +112,13 @@ class ViewPhotoAlbum extends HTMLController
|
|||||||
($page > 1 ? 'page/' . $page . '/' : ''));
|
($page > 1 ? 'page/' . $page . '/' : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPhotoMosaic($id_tag, $page)
|
public function getPhotoMosaic($id_tag, $page, $sort_linear)
|
||||||
{
|
{
|
||||||
// Create an iterator.
|
// Create an iterator.
|
||||||
list($this->iterator, $total_count) = AssetIterator::getByOptions([
|
list($this->iterator, $total_count) = AssetIterator::getByOptions([
|
||||||
'id_tag' => $id_tag,
|
'id_tag' => $id_tag,
|
||||||
'order' => 'date_captured',
|
'order' => 'date_captured',
|
||||||
'direction' => $id_tag > 0 ? 'asc' : 'desc',
|
'direction' => $sort_linear ? 'asc' : 'desc',
|
||||||
'limit' => self::PER_PAGE,
|
'limit' => self::PER_PAGE,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
], true);
|
], true);
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class Email
|
|||||||
$boundary = uniqid('sr');
|
$boundary = uniqid('sr');
|
||||||
|
|
||||||
if (empty($headers))
|
if (empty($headers))
|
||||||
$headers .= "From: HashRU Pics <no-reply@pics.hashru.nl>\r\n";
|
$headers .= "From: HashRU Pics <no-reply@aaronweb.net>\r\n";
|
||||||
|
|
||||||
// Set up headers.
|
// Set up headers.
|
||||||
$headers .= "MIME-Version: 1.0\r\n";
|
$headers .= "MIME-Version: 1.0\r\n";
|
||||||
@@ -44,7 +44,7 @@ class Email
|
|||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
return file_put_contents(BASEDIR . '/mail_dumps.txt', "To: \"$addressee\" <$address>\r\n$headers\r\nSubject: $subject\r\n" . self::wrapLines($message), FILE_APPEND);
|
return file_put_contents(BASEDIR . '/mail_dumps.txt', "To: \"$addressee\" <$address>\r\n$headers\r\nSubject: $subject\r\n" . self::wrapLines($message), FILE_APPEND);
|
||||||
else
|
else
|
||||||
return mail("\"$addressee\" <$address>", $subject, $message, $headers, '-fbounces@pics.hashru.nl');
|
return mail("\"$addressee\" <$address>", $subject, $message, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function wrapLines($body, $maxlength = 80, $break = "\r\n")
|
public static function wrapLines($body, $maxlength = 80, $break = "\r\n")
|
||||||
|
|||||||
@@ -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']]);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class Member extends User
|
|||||||
'emailaddress' => 'string-255',
|
'emailaddress' => 'string-255',
|
||||||
'password_hash' => 'string-255',
|
'password_hash' => 'string-255',
|
||||||
'creation_time' => 'int',
|
'creation_time' => 'int',
|
||||||
'ip_address' => 'string-15',
|
'ip_address' => 'string-45',
|
||||||
'is_admin' => 'int',
|
'is_admin' => 'int',
|
||||||
], $new_user, ['id_user']);
|
], $new_user, ['id_user']);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -226,6 +226,9 @@ class Tag
|
|||||||
if (!isset($data['id_parent']))
|
if (!isset($data['id_parent']))
|
||||||
$data['id_parent'] = 0;
|
$data['id_parent'] = 0;
|
||||||
|
|
||||||
|
if (!isset($data['description']))
|
||||||
|
$data['description'] = '';
|
||||||
|
|
||||||
if (!isset($data['count']))
|
if (!isset($data['count']))
|
||||||
$data['count'] = 0;
|
$data['count'] = 0;
|
||||||
|
|
||||||
@@ -257,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));
|
||||||
@@ -267,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,
|
||||||
@@ -297,6 +302,23 @@ class Tag
|
|||||||
['tokens' => '%' . strtolower(implode('%', $tokens)) . '%']);
|
['tokens' => '%' . strtolower(implode('%', $tokens)) . '%']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function matchPeople($tokens)
|
||||||
|
{
|
||||||
|
if (!is_array($tokens))
|
||||||
|
$tokens = explode(' ', $tokens);
|
||||||
|
|
||||||
|
return Registry::get('db')->queryPair('
|
||||||
|
SELECT id_tag, tag
|
||||||
|
FROM tags
|
||||||
|
WHERE LOWER(tag) LIKE {string:tokens} AND
|
||||||
|
kind = {string:person}
|
||||||
|
ORDER BY tag ASC',
|
||||||
|
[
|
||||||
|
'tokens' => '%' . strtolower(implode('%', $tokens)) . '%',
|
||||||
|
'person' => 'Person',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public static function exactMatch($tag)
|
public static function exactMatch($tag)
|
||||||
{
|
{
|
||||||
if (!is_string($tag))
|
if (!is_string($tag))
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -588,6 +581,20 @@ a#previous_photo:hover, a#next_photo:hover {
|
|||||||
margin: 25px 3.5% 25px 0;
|
margin: 25px 3.5% 25px 0;
|
||||||
width: 68.5%;
|
width: 68.5%;
|
||||||
}
|
}
|
||||||
|
#sub_photo #tag_list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 1em 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#sub_photo #tag_list li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#sub_photo #tag_list li:after {
|
||||||
|
content: ', ';
|
||||||
|
}
|
||||||
|
#sub_photo #tag_list li:last-child:after {
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
#photo_exif_box {
|
#photo_exif_box {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -660,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 {
|
||||||
|
|||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -69,7 +69,7 @@ AutoSuggest.prototype.onType = function(input, event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tokens = input.value.split(/\s+/).filter(function(token) {
|
var tokens = input.value.split(/\s+/).filter(function(token) {
|
||||||
return token.length >= 3;
|
return token.length >= 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tokens.length === 0) {
|
if (tokens.length === 0) {
|
||||||
@@ -173,6 +173,6 @@ TagAutoSuggest.prototype.fillContainer = function(response) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TagAutoSuggest.prototype.createNewTag = function(callback) {
|
TagAutoSuggest.prototype.createNewTag = function(callback) {
|
||||||
var request_uri = this.baseurl + '/managetags/?create';
|
var request_uri = this.baseurl + '/suggest/?type=createtag';
|
||||||
var request = new HttpRequest('post', request_uri, 'tag=' + encodeURIComponent(this.input.value), callback, this);
|
var request = new HttpRequest('post', request_uri, 'tag=' + encodeURIComponent(this.input.value), callback, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ function enableKeyDownNavigation() {
|
|||||||
var target = document.getElementById("previous_photo").href;
|
var target = document.getElementById("previous_photo").href;
|
||||||
if (target) {
|
if (target) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.location.href = target;
|
document.location.href = target + '#photo_frame';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.keyCode == 39) {
|
else if (event.keyCode == 39) {
|
||||||
var target = document.getElementById("next_photo").href;
|
var target = document.getElementById("next_photo").href;
|
||||||
if (target) {
|
if (target) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.location.href = target;
|
document.location.href = target + '#photo_frame';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
@@ -53,13 +53,13 @@ function enableTouchNavigation() {
|
|||||||
var target = document.getElementById("previous_photo").href;
|
var target = document.getElementById("previous_photo").href;
|
||||||
if (target) {
|
if (target) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.location.href = target;
|
document.location.href = target + '#photo_frame';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var target = document.getElementById("next_photo").href;
|
var target = document.getElementById("next_photo").href;
|
||||||
if (target) {
|
if (target) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.location.href = target;
|
document.location.href = target + '#photo_frame';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ UploadQueue.prototype.addEvents = function() {
|
|||||||
that.hideSpinner();
|
that.hideSpinner();
|
||||||
that.submit.disabled = false;
|
that.submit.disabled = false;
|
||||||
};
|
};
|
||||||
|
that.addPreviewBoxForQueueSlot(i);
|
||||||
that.addPreviewForFile(that.queue.files[i], i, callback);
|
that.addPreviewForFile(that.queue.files[i], i, callback);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -33,6 +34,12 @@ UploadQueue.prototype.clearPreviews = function() {
|
|||||||
this.current_upload_index = -1;
|
this.current_upload_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UploadQueue.prototype.addPreviewBoxForQueueSlot = function(index) {
|
||||||
|
var preview_box = document.createElement('div');
|
||||||
|
preview_box.id = 'upload_preview_' + index;
|
||||||
|
this.preview_area.appendChild(preview_box);
|
||||||
|
};
|
||||||
|
|
||||||
UploadQueue.prototype.addPreviewForFile = function(file, index, callback) {
|
UploadQueue.prototype.addPreviewForFile = function(file, index, callback) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return false;
|
return false;
|
||||||
@@ -42,30 +49,19 @@ UploadQueue.prototype.addPreviewForFile = function(file, index, callback) {
|
|||||||
preview.title = file.name;
|
preview.title = file.name;
|
||||||
preview.style.maxHeight = '150px';
|
preview.style.maxHeight = '150px';
|
||||||
|
|
||||||
var preview_box = document.createElement('div');
|
var preview_box = document.getElementById('upload_preview_' + index);
|
||||||
preview_box.id = 'upload_preview_' + index;
|
|
||||||
preview_box.appendChild(preview);
|
preview_box.appendChild(preview);
|
||||||
|
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
var that = this;
|
var that = this;
|
||||||
var appendMe = function() {
|
reader.addEventListener('load', function() {
|
||||||
preview.src = reader.result;
|
preview.src = reader.result;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
preview.addEventListener('load', function() {
|
preview.addEventListener('load', function() {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
that.preview_area.appendChild(preview_box);
|
}, false);
|
||||||
};
|
|
||||||
var waitForMe = function() {
|
|
||||||
var previews = that.preview_area.childNodes;
|
|
||||||
if (previews.length === 0 || previews[previews.length - 1].id === 'upload_preview_' + (index - 1)) {
|
|
||||||
appendMe();
|
|
||||||
} else {
|
|
||||||
setTimeout(waitForMe, 10);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
reader.addEventListener('load', waitForMe, false);
|
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(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>';
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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':
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class PhotoPage extends SubTemplate
|
|||||||
{
|
{
|
||||||
echo '
|
echo '
|
||||||
<h3>Tags</h3>
|
<h3>Tags</h3>
|
||||||
<ul>';
|
<ul id="tag_list">';
|
||||||
|
|
||||||
foreach ($this->photo->getTags() as $tag)
|
foreach ($this->photo->getTags() as $tag)
|
||||||
{
|
{
|
||||||
@@ -153,9 +153,7 @@ class PhotoPage extends SubTemplate
|
|||||||
echo '
|
echo '
|
||||||
<div>
|
<div>
|
||||||
<h3>Link tags</h3>
|
<h3>Link tags</h3>
|
||||||
<ul id="tag_list">
|
<p style="position: relative"><input type="text" id="new_tag" placeholder="Type to link a new tag"></p>
|
||||||
<li id="new_tag_container"><input type="text" id="new_tag" placeholder="Type to link a new tag"></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="', BASEURL, '/js/ajax.js"></script>
|
<script type="text/javascript" src="', BASEURL, '/js/ajax.js"></script>
|
||||||
<script type="text/javascript" src="', BASEURL, '/js/autosuggest.js"></script>
|
<script type="text/javascript" src="', BASEURL, '/js/autosuggest.js"></script>
|
||||||
@@ -166,26 +164,15 @@ class PhotoPage extends SubTemplate
|
|||||||
listElement: "tag_list",
|
listElement: "tag_list",
|
||||||
baseUrl: "', BASEURL, '",
|
baseUrl: "', BASEURL, '",
|
||||||
appendCallback: function(item) {
|
appendCallback: function(item) {
|
||||||
if (document.getElementById("linked_tag_" + item.id_tag)) {
|
var request = new HttpRequest("post", "', $this->photo->getPageUrl(), '",
|
||||||
return;
|
"id_tag=" + item.id_tag, function(response) {
|
||||||
}
|
var newNode = document.createElement("li");
|
||||||
|
var newLabel = document.createTextNode(item.label);
|
||||||
|
newNode.appendChild(newLabel);
|
||||||
|
|
||||||
var newCheck = document.createElement("input");
|
var list = document.getElementById("tag_list");
|
||||||
newCheck.type = "checkbox";
|
list.appendChild(newNode);
|
||||||
newCheck.name = "tag[" + item.id_tag + "]";
|
}, this);
|
||||||
newCheck.id = "linked_tag_" + item.id_tag;
|
|
||||||
newCheck.title = "Uncheck to delete";
|
|
||||||
newCheck.checked = "checked";
|
|
||||||
|
|
||||||
var newNode = document.createElement("li");
|
|
||||||
newNode.appendChild(newCheck);
|
|
||||||
|
|
||||||
var newLabel = document.createTextNode(item.label);
|
|
||||||
newNode.appendChild(newLabel);
|
|
||||||
|
|
||||||
var list = document.getElementById("tag_list");
|
|
||||||
var input = document.getElementById("new_tag_container");
|
|
||||||
list.insertBefore(newNode, input);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user