Simplified view management

This commit is contained in:
Marcin Kurczewski 2014-05-16 21:38:33 +02:00
parent 0aa75704a2
commit e95b8d93d8
45 changed files with 803 additions and 556 deletions

@ -1 +1 @@
Subproject commit 19bb5ee3901cf6402d7507c30b8fc183c3fc0bcc
Subproject commit 78597486abb1bd6344a64a70c87d9deca14b7ff7

View file

@ -1,95 +1,5 @@
<?php
require_once '../src/core.php';
if (isset($_SERVER['REDIRECT_URL']))
$query = rtrim($_SERVER['REDIRECT_URL'], '/');
else
$query = rtrim($_SERVER['REQUEST_URI'], '/');
$context = Core::getContext();
$context->query = $query;
function renderView()
{
$context = Core::getContext();
\Chibi\View::render($context->layoutName, $context);
}
$context->simpleControllerName = null;
$context->simpleActionName = null;
\Chibi\Router::setObserver(function($route, $args)
{
$context = Core::getContext();
$context->route = $route;
list ($className, $methodName) = $route->destination;
$context->simpleControllerName = TextCaseConverter::convert(
str_replace('Controller', '', $className),
TextCaseConverter::CAMEL_CASE,
TextCaseConverter::SPINAL_CASE);
$context->simpleActionName = TextCaseConverter::convert(
preg_replace('/Action|View/', '', $methodName),
TextCaseConverter::CAMEL_CASE,
TextCaseConverter::SPINAL_CASE);
$context->viewName = sprintf(
'%s-%s',
$context->simpleControllerName,
$context->simpleActionName);
});
Assets::setTitle(Core::getConfig()->main->title);
$context->handleExceptions = false;
$context->layoutName
= isset($_SERVER['HTTP_X_AJAX'])
? 'layout-json'
: 'layout-normal';
$context->viewName = '';
$context->transport = new StdClass;
SessionHelper::init();
if (!Auth::isLoggedIn())
Auth::tryAutoLogin();
register_shutdown_function(function()
{
$error = error_get_last();
if ($error !== null)
\Chibi\Util\Headers::setCode(400);
});
try
{
try
{
\Chibi\Router::run($query);
renderView();
AuthController::observeWorkFinish();
}
catch (\Chibi\UnhandledRouteException $e)
{
throw new SimpleNotFoundException($query . ' not found.');
}
}
catch (SimpleException $e)
{
if ($e instanceof SimpleNotFoundException)
\Chibi\Util\Headers::setCode(404);
else
\Chibi\Util\Headers::setCode(400);
Messenger::message($e->getMessage(), false);
if (!$context->handleExceptions)
$context->viewName = 'message';
renderView();
}
catch (Exception $e)
{
\Chibi\Util\Headers::setCode(400);
Messenger::message($e->getMessage(), false);
$context->transport->exception = $e;
$context->transport->queries = \Chibi\Database::getLogs();
$context->viewName = 'error-exception';
renderView();
}
$dispatcher = new Dispatcher();
$dispatcher->run();

View file

@ -0,0 +1,82 @@
<?php
class AbstractController
{
protected $assets;
private $layoutName;
private static $isRendered;
public function isAjax()
{
return isset($_SERVER['HTTP_X_AJAX']);
}
public function __construct()
{
$this->switchLayout('layout-normal');
$this->assets = new Assets();
$this->assets->setTitle(Core::getConfig()->main->title);
}
public function __destruct()
{
if ($this->isAjax())
$this->renderAjax();
}
public function renderAjax()
{
$this->switchLayout('layout-json');
$this->renderView(null);
}
public function renderFile()
{
$this->switchLayout('layout-file');
$this->renderView(null);
}
public function renderView($viewName)
{
//no matter which controller runs it (including ErrorController), render only once
if (self::isRendered())
return;
self::markAsRendered();
$context = Core::getContext();
if ($viewName !== null)
$context->viewName = $viewName;
View::renderTopLevel($this->layoutName, $this->assets);
}
protected function redirectToLastVisitedUrl($filter = null)
{
$targetUrl = SessionHelper::getLastVisitedUrl($filter);
if (!$targetUrl)
$targetUrl = \Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']);
$this->redirect($targetUrl);
}
protected function redirect($url)
{
if (!$this->isAjax())
\Chibi\Util\Url::forward($url);
}
private static function isRendered()
{
return self::$isRendered;
}
private static function markAsRendered()
{
self::$isRendered = true;
}
private function switchLayout($layoutName)
{
$this->layoutName = $layoutName;
}
}

View file

@ -1,53 +1,35 @@
<?php
class AuthController
class AuthController extends AbstractController
{
public function loginView()
{
//check if already logged in
if (Auth::isLoggedIn())
self::redirect();
$this->redirectToLastVisitedUrl('auth');
else
$this->renderView('auth-login');
}
public function loginAction()
{
$context = Core::getContext();
$context->viewName = 'auth-login';
$context->handleExceptions = true;
try
{
$suppliedName = InputHelper::get('name');
$suppliedPassword = InputHelper::get('password');
$remember = boolval(InputHelper::get('remember'));
Auth::login($suppliedName, $suppliedPassword, $remember);
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
$this->renderView('auth-login');
}
$suppliedName = InputHelper::get('name');
$suppliedPassword = InputHelper::get('password');
$remember = boolval(InputHelper::get('remember'));
Auth::login($suppliedName, $suppliedPassword, $remember);
self::redirect();
$this->redirectToLastVisitedUrl('auth');
}
public function logoutAction()
{
Auth::logout();
self::redirect();
}
public static function observeWorkFinish()
{
if (strpos(\Chibi\Util\Headers::get('Content-Type'), 'text/html') === false)
return;
if (\Chibi\Util\Headers::getCode() != 200)
return;
$context = Core::getContext();
if ($context->simpleControllerName == 'auth')
return;
$_SESSION['login-redirect-url'] = $context->query;
}
private static function redirect()
{
if (isset($_SESSION['login-redirect-url']))
{
\Chibi\Util\Url::forward(\Chibi\Util\Url::makeAbsolute($_SESSION['login-redirect-url']));
unset($_SESSION['login-redirect-url']);
exit;
}
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']));
exit;
$this->redirectToLastVisitedUrl('auth');
}
}

View file

@ -1,5 +1,5 @@
<?php
class CommentController
class CommentController extends AbstractController
{
public function listView($page = 1)
{
@ -12,6 +12,7 @@ class CommentController
$context = Core::getContext();
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
$this->renderView('comment-list');
}
public function addAction()
@ -26,6 +27,7 @@ class CommentController
]);
Core::getContext()->transport->textPreview = $comment->getTextMarkdown();
$this->renderAjax();
}
else
{
@ -35,13 +37,18 @@ class CommentController
JobArgs::ARG_POST_ID => InputHelper::get('post-id'),
JobArgs::ARG_NEW_TEXT => InputHelper::get('text')
]);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToLastVisitedUrl();
}
$this->redirectToLastVisitedUrl();
}
public function editView($id)
{
Core::getContext()->transport->comment = CommentModel::getById($id);
$this->renderView('comment-edit');
}
public function editAction($id)
@ -56,6 +63,7 @@ class CommentController
]);
Core::getContext()->transport->textPreview = $comment->getTextMarkdown();
$this->renderAjax();
}
else
{
@ -65,8 +73,12 @@ class CommentController
JobArgs::ARG_COMMENT_ID => $id,
JobArgs::ARG_NEW_TEXT => InputHelper::get('text')
]);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToLastVisitedUrl('comment/');
}
$this->redirectToLastVisitedUrl();
}
public function deleteAction($id)
@ -76,14 +88,10 @@ class CommentController
[
JobArgs::ARG_COMMENT_ID => $id,
]);
$this->redirectToLastVisitedUrl();
}
private function redirectToLastVisitedUrl()
{
$lastUrl = SessionHelper::getLastVisitedUrl();
if ($lastUrl)
\Chibi\Util\Url::forward($lastUrl);
exit;
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToLastVisitedUrl('comment/');
}
}

View file

@ -0,0 +1,30 @@
<?php
class ErrorController extends AbstractController
{
public function simpleExceptionView(Exception $exception)
{
if ($exception instanceof SimpleNotFoundException)
\Chibi\Util\Headers::setCode(404);
else
\Chibi\Util\Headers::setCode(400);
Messenger::fail($exception->getMessage());
if ($this->isAjax())
$this->renderAjax();
else
$this->renderView('message');
}
public function seriousExceptionView(Exception $exception)
{
\Chibi\Util\Headers::setCode(400);
Messenger::fail($exception->getMessage());
$context->transport->exception = $exception;
$context->transport->queries = \Chibi\Database::getLogs();
if ($this->isAjax())
$this->renderAjax();
else
$this->renderView('error-exception');
}
}

View file

@ -1,30 +1,27 @@
<?php
class LogController
class LogController extends AbstractController
{
public function listView()
{
$ret = Api::run(new ListLogsJob(), []);
Core::getContext()->transport->logs = $ret;
$this->renderView('log-list');
}
public function logView($name, $page = 1, $filter = '')
{
$context = Core::getContext();
$context->viewName = 'log-view';
//redirect requests in form of ?query=... to canonical address
$formQuery = InputHelper::get('query');
if ($formQuery !== null)
{
\Chibi\Util\Url::forward(
\Chibi\Router::linkTo(
['LogController', 'logView'],
[
'name' => $name,
'filter' => $formQuery,
'page' => 1
]));
exit;
$this->redirect(\Chibi\Router::linkTo(
['LogController', 'logView'],
[
'name' => $name,
'filter' => $formQuery,
'page' => 1
]));
return;
}
$ret = Api::run(
@ -46,9 +43,11 @@ class LogController
$lines = TextHelper::parseMarkdown($lines, true);
$lines = trim($lines);
$context = Core::getContext();
$context->transport->paginator = $ret;
$context->transport->lines = $lines;
$context->transport->filter = $filter;
$context->transport->name = $name;
$this->renderView('log-view');
}
}

View file

@ -1,68 +1,75 @@
<?php
class PostController
class PostController extends AbstractController
{
public function listView($query = null, $page = 1, $source = 'posts', $additionalInfo = null)
{
$context = Core::getContext();
$context->viewName = 'post-list-wrapper';
$context->source = $source;
$context->additionalInfo = $additionalInfo;
$context->handleExceptions = true;
//redirect requests in form of /posts/?query=... to canonical address
$formQuery = InputHelper::get('query');
if ($formQuery !== null)
try
{
$context->transport->searchQuery = $formQuery;
$context->transport->lastSearchQuery = $formQuery;
if (strpos($formQuery, '/') !== false)
throw new SimpleException('Search query contains invalid characters');
//redirect requests in form of /posts/?query=... to canonical address
$formQuery = InputHelper::get('query');
if ($formQuery !== null)
{
$context->transport->searchQuery = $formQuery;
$context->transport->lastSearchQuery = $formQuery;
if (strpos($formQuery, '/') !== false)
throw new SimpleException('Search query contains invalid characters');
$url = \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => $source,
'additionalInfo' => $additionalInfo,
'query' => $formQuery]);
\Chibi\Util\Url::forward($url);
exit;
$url = \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => $source,
'additionalInfo' => $additionalInfo,
'query' => $formQuery]);
$this->redirect($url);
return;
}
$query = trim($query);
$context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query;
if ($source == 'mass-tag')
{
Access::assert(new Privilege(Privilege::MassTag));
$context->massTagTag = $additionalInfo;
$context->massTagQuery = $query;
if (!Access::check(new Privilege(Privilege::MassTag, 'all')))
$query = trim($query . ' submit:' . Auth::getCurrentUser()->getName());
}
$ret = Api::run(
new ListPostsJob(),
[
JobArgs::ARG_PAGE_NUMBER => $page,
JobArgs::ARG_QUERY => $query
]);
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
$query = trim($query);
$context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query;
if ($source == 'mass-tag')
{
Access::assert(new Privilege(Privilege::MassTag));
$context->massTagTag = $additionalInfo;
$context->massTagQuery = $query;
if (!Access::check(new Privilege(Privilege::MassTag, 'all')))
$query = trim($query . ' submit:' . Auth::getCurrentUser()->getName());
}
$ret = Api::run(
new ListPostsJob(),
[
JobArgs::ARG_PAGE_NUMBER => $page,
JobArgs::ARG_QUERY => $query
]);
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
$this->renderView('post-list-wrapper');
}
public function favoritesView($page = 1)
{
$this->listView('favmin:1', $page);
$this->listView('favmin:1', $page, 'favorites');
}
public function upvotedView($page = 1)
{
$this->listView('scoremin:1', $page);
$this->listView('scoremin:1', $page, 'upvoted');
}
public function randomView($page = 1)
{
$this->listView('order:random', $page);
$this->listView('order:random', $page, 'random');
}
public function toggleTagAction($id, $tag, $enable)
@ -79,11 +86,15 @@ class PostController
JobArgs::ARG_NEW_STATE => $enable,
]);
$this->redirectToLastVisitedUrl();
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToLastVisitedUrl();
}
public function uploadView()
{
$this->renderView('post-upload');
}
public function uploadAction()
@ -111,6 +122,11 @@ class PostController
}
Api::run(new AddPostJob(), $jobArgs);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToPostList();
}
public function editView($id)
@ -119,6 +135,7 @@ class PostController
JobArgs::ARG_POST_ID => $id]);
$context = Core::getContext()->transport->post = $post;
$this->renderView('post-edit');
}
public function editAction($id)
@ -163,13 +180,21 @@ class PostController
}
Api::run(new EditPostJob(), $jobArgs);
$this->redirectToGenericView($id);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToGenericView($id);
}
public function flagAction($id)
{
Api::run(new FlagPostJob(), [JobArgs::ARG_POST_ID => $id]);
$this->redirectToGenericView($id);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToGenericView($id);
}
public function hideAction($id)
@ -192,7 +217,7 @@ class PostController
{
Api::run(new DeletePostJob(), [
JobArgs::ARG_POST_ID => $id]);
$this->redirectToGenericView($id);
$this->redirectToPostList();
}
public function addFavoriteAction($id)
@ -229,7 +254,6 @@ class PostController
public function genericView($id)
{
$context = Core::getContext();
$context->viewName = 'post-view';
$post = Api::run(new GetPostJob(), [
JobArgs::ARG_POST_ID => $id]);
@ -262,6 +286,8 @@ class PostController
$context->transport->post = $post;
$context->transport->prevPostId = $prevPostId ? $prevPostId : null;
$context->transport->nextPostId = $nextPostId ? $nextPostId : null;
$this->renderView('post-view');
}
public function fileView($name)
@ -275,7 +301,7 @@ class PostController
$context->transport->fileHash = 'post' . md5(substr($ret->fileContent, 0, 4096));
$context->transport->fileContent = $ret->fileContent;
$context->transport->lastModified = $ret->lastModified;
$context->layoutName = 'layout-file';
$this->renderFile();
}
public function thumbView($name)
@ -289,9 +315,10 @@ class PostController
$context->transport->fileHash = 'thumb' . md5(substr($ret->fileContent, 0, 4096));
$context->transport->fileContent = $ret->fileContent;
$context->transport->lastModified = $ret->lastModified;
$context->layoutName = 'layout-file';
$this->renderFile();
}
private function splitPostIds($string)
{
$ids = preg_split('/\D/', trim($string));
@ -309,19 +336,15 @@ class PostController
return $tags;
}
private function redirectToLastVisitedUrl()
private function redirectToPostList()
{
$lastUrl = SessionHelper::getLastVisitedUrl();
if ($lastUrl)
\Chibi\Util\Url::forward($lastUrl);
exit;
$this->redirect(\Chibi\Router::linkTo(['PostController', 'listView']));
}
private function redirectToGenericView($id)
{
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(
$this->redirect(\Chibi\Router::linkTo(
['PostController', 'genericView'],
['id' => $id]));
exit;
}
}

View file

@ -1,11 +1,10 @@
<?php
class StaticPagesController
class StaticPagesController extends AbstractController
{
public function mainPageView()
{
$context = Core::getContext();
$context->transport->postCount = PostModel::getCount();
$context->viewName = 'static-main';
$context->transport->postSpaceUsage = PostModel::getSpaceUsage();
PostModel::featureRandomPostIfNecessary();
@ -17,6 +16,8 @@ class StaticPagesController
$context->featuredPostUser = UserModel::tryGetByName(
PropertyModel::get(PropertyModel::FeaturedPostUserName));
}
$this->renderView('static-main');
}
public function helpView($tab = null)
@ -31,9 +32,10 @@ class StaticPagesController
if (!isset($config->help->paths[$tab]))
throw new SimpleException('Invalid tab');
$context->viewName = 'static-help';
$context->path = TextHelper::absolutePath($config->help->paths[$tab]);
$context->tab = $tab;
$this->renderView('static-help');
}
public function fatalErrorView($code = null)

View file

@ -1,5 +1,5 @@
<?php
class TagController
class TagController extends AbstractController
{
public function listView($filter = 'order:alpha,asc', $page = 1)
{
@ -11,11 +11,11 @@ class TagController
]);
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
$context->highestUsage = TagSearchService::getMostUsedTag()->getPostCount();
$context->filter = $filter;
$context->transport->tags = $ret->entities;
$context->transport->paginator = $ret;
$this->renderViewWithSource('tag-list-wrapper', 'list');
}
public function autoCompleteView()
@ -42,6 +42,8 @@ class TagController
'count' => $tag->getPostCount(),
];
}, $ret->entities));
$this->renderAjax();
}
public function relatedView()
@ -67,76 +69,94 @@ class TagController
'count' => $tag->getPostCount(),
];
}, $ret->entities));
$this->renderAjax();
}
public function mergeView()
{
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
$this->renderViewWithSource('tag-list-wrapper', 'merge');
}
public function mergeAction()
{
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
$context->handleExceptions = true;
try
{
Api::run(
new MergeTagsJob(),
[
JobArgs::ARG_SOURCE_TAG_NAME => InputHelper::get('source-tag'),
JobArgs::ARG_TARGET_TAG_NAME => InputHelper::get('target-tag'),
]);
Api::run(
new MergeTagsJob(),
[
JobArgs::ARG_SOURCE_TAG_NAME => InputHelper::get('source-tag'),
JobArgs::ARG_TARGET_TAG_NAME => InputHelper::get('target-tag'),
]);
Messenger::success('Tags merged successfully.');
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
Messenger::message('Tags merged successfully.');
$this->renderViewWithSource('tag-list-wrapper', 'merge');
}
public function renameView()
{
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
$this->renderViewWithSource('tag-list-wrapper', 'rename');
}
public function renameAction()
{
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
$context->handleExceptions = true;
try
{
Api::run(
new RenameTagsJob(),
[
JobArgs::ARG_SOURCE_TAG_NAME => InputHelper::get('source-tag'),
JobArgs::ARG_TARGET_TAG_NAME => InputHelper::get('target-tag'),
]);
Api::run(
new RenameTagsJob(),
[
JobArgs::ARG_SOURCE_TAG_NAME => InputHelper::get('source-tag'),
JobArgs::ARG_TARGET_TAG_NAME => InputHelper::get('target-tag'),
]);
Messenger::success('Tag renamed successfully.');
}
catch (Exception $e)
{
Messenger::fail($e->getMessage());
}
Messenger::message('Tag renamed successfully.');
$this->renderViewWithSource('tag-list-wrapper', 'rename');
}
public function massTagRedirectView()
{
$context = Core::getContext();
$context->viewName = 'tag-list-wrapper';
Access::assert(new Privilege(Privilege::MassTag));
$this->renderViewWithSource('tag-list-wrapper', 'mass-tag');
}
public function massTagRedirectAction()
{
$this->massTagRedirectView();
Access::assert(new Privilege(Privilege::MassTag));
$suppliedOldPage = intval(InputHelper::get('old-page'));
$suppliedOldQuery = InputHelper::get('old-query');
$suppliedQuery = InputHelper::get('query');
$suppliedTag = InputHelper::get('tag');
$params = [
$params =
[
'source' => 'mass-tag',
'query' => $suppliedQuery ?: ' ',
'additionalInfo' => $suppliedTag ? $suppliedTag : '',
];
if ($suppliedOldPage != 0 and $suppliedOldQuery == $suppliedQuery)
$params['page'] = $suppliedOldPage;
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(['PostController', 'listView'], $params));
exit;
$this->redirect(\Chibi\Router::linkTo(['PostController', 'listView'], $params));
}
private function renderViewWithSource($viewName, $source)
{
$context = Core::getContext();
$context->source = $source;
$this->renderView($viewName);
}
}

View file

@ -1,5 +1,5 @@
<?php
class UserController
class UserController extends AbstractController
{
public function listView($filter = 'order:alpha,asc', $page = 1)
{
@ -11,117 +11,117 @@ class UserController
]);
$context = Core::getContext();
$context->filter = $filter;
$context->transport->users = $ret->entities;
$context->transport->paginator = $ret;
$this->renderView('user-list');
}
public function genericView($identifier, $tab = 'favs', $page = 1)
{
$user = Api::run(
new GetUserJob(),
$this->appendUserIdentifierArgument([], $identifier));
$flagged = in_array(TextHelper::reprUser($user), SessionHelper::get('flagged', []));
if ($tab == 'uploads')
$query = 'submit:' . $user->getName();
elseif ($tab == 'favs')
$query = 'fav:' . $user->getName();
elseif ($tab == 'delete')
{
Access::assert(new Privilege(
Privilege::DeleteUser,
Access::getIdentity($user)));
}
elseif ($tab == 'settings')
{
Access::assert(new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($user)));
}
elseif ($tab == 'edit' and !(new EditUserJob)->canEditAnything(Auth::getCurrentUser()))
Access::fail();
$context = Core::getContext();
$context->flagged = $flagged;
$context->transport->tab = $tab;
$context->transport->user = $user;
$context->handleExceptions = true;
$context->viewName = 'user-view';
if (isset($query))
{
$ret = Api::run(
new ListPostsJob(),
[
JobArgs::ARG_PAGE_NUMBER => $page,
JobArgs::ARG_QUERY => $query
]);
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
$context->transport->lastSearchQuery = $query;
}
$this->prepareGenericView($identifier, $tab, $page);
$this->renderView('user-view');
}
public function settingsAction($identifier)
{
$this->genericView($identifier, 'settings');
$this->prepareGenericView($identifier, 'settings');
$suppliedSafety = InputHelper::get('safety');
$desiredSafety = PostSafety::makeFlags($suppliedSafety);
try
{
$suppliedSafety = InputHelper::get('safety');
$desiredSafety = PostSafety::makeFlags($suppliedSafety);
$user = Api::run(
new EditUserSettingsJob(),
$this->appendUserIdentifierArgument(
[
JobArgs::ARG_NEW_SETTINGS =>
$user = Api::run(
new EditUserSettingsJob(),
$this->appendUserIdentifierArgument(
[
UserSettings::SETTING_SAFETY => $desiredSafety,
UserSettings::SETTING_ENDLESS_SCROLLING => InputHelper::get('endless-scrolling'),
UserSettings::SETTING_POST_TAG_TITLES => InputHelper::get('post-tag-titles'),
UserSettings::SETTING_HIDE_DISLIKED_POSTS => InputHelper::get('hide-disliked-posts'),
]
], $identifier));
JobArgs::ARG_NEW_SETTINGS =>
[
UserSettings::SETTING_SAFETY => $desiredSafety,
UserSettings::SETTING_ENDLESS_SCROLLING => InputHelper::get('endless-scrolling'),
UserSettings::SETTING_POST_TAG_TITLES => InputHelper::get('post-tag-titles'),
UserSettings::SETTING_HIDE_DISLIKED_POSTS => InputHelper::get('hide-disliked-posts'),
]
], $identifier));
Core::getContext()->transport->user = $user;
if ($user->getId() == Auth::getCurrentUser()->getId())
Auth::setCurrentUser($user);
Core::getContext()->transport->user = $user;
if ($user->getId() == Auth::getCurrentUser()->getId())
Auth::setCurrentUser($user);
Messenger::message('Browsing settings updated!');
Messenger::success('Browsing settings updated!');
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
$this->renderView('user-view');
}
public function editAction($identifier)
{
$this->genericView($identifier, 'edit');
$this->requirePasswordConfirmation();
$this->prepareGenericView($identifier, 'edit');
if (InputHelper::get('password1') != InputHelper::get('password2'))
throw new SimpleException('Specified passwords must be the same');
try
{
$this->requirePasswordConfirmation();
$args =
[
JobArgs::ARG_NEW_USER_NAME => InputHelper::get('name'),
JobArgs::ARG_NEW_PASSWORD => InputHelper::get('password1'),
JobArgs::ARG_NEW_EMAIL => InputHelper::get('email'),
JobArgs::ARG_NEW_ACCESS_RANK => InputHelper::get('access-rank'),
];
$args = $this->appendUserIdentifierArgument($args, $identifier);
if (InputHelper::get('password1') != InputHelper::get('password2'))
throw new SimpleException('Specified passwords must be the same');
$args = array_filter($args);
$user = Api::run(new EditUserJob(), $args);
$args =
[
JobArgs::ARG_NEW_USER_NAME => InputHelper::get('name'),
JobArgs::ARG_NEW_PASSWORD => InputHelper::get('password1'),
JobArgs::ARG_NEW_EMAIL => InputHelper::get('email'),
JobArgs::ARG_NEW_ACCESS_RANK => InputHelper::get('access-rank'),
];
$args = $this->appendUserIdentifierArgument($args, $identifier);
if (Auth::getCurrentUser()->getId() == $user->getId())
Auth::setCurrentUser($user);
$args = array_filter($args);
$user = Api::run(new EditUserJob(), $args);
$message = 'Account settings updated!';
if (Mailer::getMailCounter() > 0)
$message .= ' You will be sent an e-mail address confirmation message soon.';
if (Auth::getCurrentUser()->getId() == $user->getId())
Auth::setCurrentUser($user);
Messenger::message($message);
$message = 'Account settings updated!';
if (Mailer::getMailCounter() > 0)
$message .= ' You will be sent an e-mail address confirmation message soon.';
Messenger::success($message);
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
$this->renderView('user-view');
}
public function deleteAction($identifier)
{
$this->prepareGenericView($identifier, 'delete');
try
{
$this->requirePasswordConfirmation();
Api::run(
new DeleteUserJob(),
$this->appendUserIdentifierArgument([], $identifier));
$user = UserModel::tryGetById(Auth::getCurrentUser()->getId());
if (!$user)
Auth::logOut();
$this->redirectToMainPage();
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
$this->renderView('user-view');
}
}
public function toggleSafetyAction($safety)
@ -144,23 +144,6 @@ class UserController
$this->redirectToLastVisitedUrl();
}
public function deleteAction($identifier)
{
$this->genericView($identifier, 'delete');
$this->requirePasswordConfirmation();
Api::run(
new DeleteUserJob(),
$this->appendUserIdentifierArgument([], $identifier));
$user = UserModel::tryGetById(Auth::getCurrentUser()->getId());
if (!$user)
Auth::logOut();
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']));
exit;
}
public function flagAction($identifier)
{
Api::run(
@ -199,70 +182,70 @@ class UserController
public function registrationView()
{
$context = Core::getContext();
$context->handleExceptions = true;
//check if already logged in
if (Auth::isLoggedIn())
{
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']));
exit;
}
$this->redirectToMainPage();
$this->renderView('user-registration');
}
public function registrationAction()
{
$this->registrationView();
if (InputHelper::get('password1') != InputHelper::get('password2'))
throw new SimpleException('Specified passwords must be the same');
$user = Api::run(new AddUserJob(),
[
JobArgs::ARG_NEW_USER_NAME => InputHelper::get('name'),
JobArgs::ARG_NEW_PASSWORD => InputHelper::get('password1'),
JobArgs::ARG_NEW_EMAIL => InputHelper::get('email'),
]);
if (!Core::getConfig()->registration->needEmailForRegistering and !Core::getConfig()->registration->staffActivation)
try
{
Auth::setCurrentUser($user);
if (InputHelper::get('password1') != InputHelper::get('password2'))
throw new SimpleException('Specified passwords must be the same');
$user = Api::run(new AddUserJob(),
[
JobArgs::ARG_NEW_USER_NAME => InputHelper::get('name'),
JobArgs::ARG_NEW_PASSWORD => InputHelper::get('password1'),
JobArgs::ARG_NEW_EMAIL => InputHelper::get('email'),
]);
if (!$this->isAnyAccountActivationNeeded())
{
Auth::setCurrentUser($user);
}
$message = 'Congratulations, your account was created.';
if (Mailer::getMailCounter() > 0)
{
$message .= ' Please wait for activation e-mail.';
if (Core::getConfig()->registration->staffActivation)
$message .= ' After this, your registration must be confirmed by staff.';
}
elseif (Core::getConfig()->registration->staffActivation)
$message .= ' Your registration must be now confirmed by staff.';
Messenger::success($message);
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
$message = 'Congratulations, your account was created.';
if (Mailer::getMailCounter() > 0)
{
$message .= ' Please wait for activation e-mail.';
if (Core::getConfig()->registration->staffActivation)
$message .= ' After this, your registration must be confirmed by staff.';
}
elseif (Core::getConfig()->registration->staffActivation)
$message .= ' Your registration must be now confirmed by staff.';
Messenger::message($message);
$this->renderView('user-registration');
}
public function activationView()
{
$context = Core::getContext();
$context->viewName = 'user-select';
Assets::setSubTitle('account activation');
$this->assets->setSubTitle('account activation');
$this->renderView('user-select');
}
public function activationAction($tokenText)
{
$context = Core::getContext();
$context->viewName = 'message';
Assets::setSubTitle('account activation');
$this->assets->setSubTitle('account activation');
$identifier = InputHelper::get('identifier');
try
{
if (empty($tokenText))
{
Api::run(
new ActivateUserEmailJob(),
$this->appendUserIdentifierArgument([], $identifier));
Messenger::message('Activation e-mail resent.');
Messenger::success('Activation e-mail resent.');
}
else
{
@ -272,45 +255,115 @@ class UserController
$message = 'Activation completed successfully.';
if (Core::getConfig()->registration->staffActivation)
$message .= ' However, your account still must be confirmed by staff.';
Messenger::message($message);
Messenger::success($message);
if (!Core::getConfig()->registration->staffActivation)
Auth::setCurrentUser($user);
}
}
catch (SimpleException $e)
{
Messenger::fail($e->getMessage());
}
$this->renderView('message');
}
public function passwordResetView()
{
$context = Core::getContext();
$context->viewName = 'user-select';
Assets::setSubTitle('password reset');
$this->assets->setSubTitle('password reset');
$this->renderView('user-select');
}
public function passwordResetAction($tokenText)
{
$context = Core::getContext();
$context->viewName = 'message';
Assets::setSubTitle('password reset');
$this->assets->setSubTitle('password reset');
$identifier = InputHelper::get('identifier');
if (empty($tokenText))
try
{
Api::run(
new PasswordResetJob(),
$this->appendUserIdentifierArgument([], $identifier));
if (empty($tokenText))
{
Api::run(
new PasswordResetJob(),
$this->appendUserIdentifierArgument([], $identifier));
Messenger::message('E-mail sent. Follow instructions to reset password.');
Messenger::success('E-mail sent. Follow instructions to reset password.');
}
else
{
$ret = Api::run(new PasswordResetJob(), [ JobArgs::ARG_TOKEN => $tokenText ]);
Messenger::success(sprintf(
'Password reset successful. Your new password is **%s**.',
$ret->newPassword));
Auth::setCurrentUser($ret->user);
}
}
else
catch (SimpleException $e)
{
$ret = Api::run(new PasswordResetJob(), [ JobArgs::ARG_TOKEN => $tokenText ]);
Messenger::message(sprintf(
'Password reset successful. Your new password is **%s**.',
$ret->newPassword));
Auth::setCurrentUser($ret->user);
Messenger::fail($e->getMessage());
}
$this->renderView('message');
}
private function prepareGenericView($identifier, $tab, $page = 1)
{
$user = Api::run(
new GetUserJob(),
$this->appendUserIdentifierArgument([], $identifier));
$flagged = in_array(TextHelper::reprUser($user), SessionHelper::get('flagged', []));
if ($tab == 'uploads')
$query = 'submit:' . $user->getName();
elseif ($tab == 'favs')
$query = 'fav:' . $user->getName();
elseif ($tab == 'delete')
{
Access::assert(new Privilege(
Privilege::DeleteUser,
Access::getIdentity($user)));
}
elseif ($tab == 'settings')
{
Access::assert(new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($user)));
}
elseif ($tab == 'edit' and !(new EditUserJob)->canEditAnything(Auth::getCurrentUser()))
Access::fail();
$context = Core::getContext();
$context->flagged = $flagged;
$context->transport->tab = $tab;
$context->transport->user = $user;
if (isset($query))
{
$ret = Api::run(
new ListPostsJob(),
[
JobArgs::ARG_PAGE_NUMBER => $page,
JobArgs::ARG_QUERY => $query
]);
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
$context->transport->lastSearchQuery = $query;
}
}
private function isAnyAccountActivationNeeded()
{
$config = Core::getConfig();
return ($config->registration->needEmailForRegistering
or $config->registration->staffActivation);
}
private function requirePasswordConfirmation()
@ -334,19 +387,16 @@ class UserController
return $arguments;
}
private function redirectToLastVisitedUrl()
private function redirectToMainPage()
{
$lastUrl = SessionHelper::getLastVisitedUrl();
if ($lastUrl)
\Chibi\Util\Url::forward($lastUrl);
$this->redirect(\Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']));
exit;
}
private function redirectToGenericView($identifier)
{
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(
$this->redirect(\Chibi\Router::linkTo(
['UserController', 'genericView'],
['identifier' => $identifier]));
exit;
}
}

77
src/Dispatcher.php Normal file
View file

@ -0,0 +1,77 @@
<?php
class Dispatcher
{
public function run()
{
$query = $this->retrieveQuery();
$context = Core::getContext();
$context->query = $query;
$context->transport = new StdClass;
$this->setRouterObserver();
$this->ensureResponseCodeUponFail();
SessionHelper::init();
if (!Auth::isLoggedIn())
Auth::tryAutoLogin();
$this->routeAndHandleErrors($query);
}
private function routeAndHandleErrors($query)
{
try
{
\Chibi\Router::run($query);
}
catch (\Chibi\UnhandledRouteException $e)
{
$errorController = new ErrorController;
$errorController->simpleExceptionView(new SimpleNotFoundException($query . ' not found.'));
}
catch (SimpleException $e)
{
$errorController = new ErrorController;
$errorController->simpleExceptionView($e);
}
catch (SimpleException $e)
{
$errorController = new ErrorController;
$errorController->seriousExceptionView($e);
}
}
private function ensureResponseCodeUponFail()
{
register_shutdown_function(function()
{
$error = error_get_last();
if ($error !== null)
\Chibi\Util\Headers::setCode(400);
});
}
private function retrieveQuery()
{
if (isset($_SERVER['REDIRECT_URL']))
return $this->parseRawHttpQuery($_SERVER['REDIRECT_URL']);
else
return $this->parseRawHttpQuery($_SERVER['REQUEST_URI']);
}
private function parseRawHttpQuery($rawHttpQuery)
{
return rtrim($rawHttpQuery, '/');
}
private function setRouterObserver()
{
\Chibi\Router::setObserver(function($route, $args)
{
$context = Core::getContext();
$context->route = $route;
});
}
}

View file

@ -1,47 +1,41 @@
<?php
class Assets extends \Chibi\Util\Assets
{
private static $pageThumb = null;
private static $subTitle = null;
private $pageThumb = null;
private $subTitle = null;
public static function init()
public function setSubTitle($text)
{
\Chibi\Util\Assets::disable();
self::enable();
$this->subTitle = $text;
}
public static function setSubTitle($text)
public function setPageThumb($path)
{
self::$subTitle = $text;
$this->pageThumb = $path;
}
public static function setPageThumb($path)
{
self::$pageThumb = $path;
}
public static function addStylesheet($path)
public function addStylesheet($path)
{
return parent::addStylesheet('/media/css/' . $path);
}
public static function addScript($path)
public function addScript($path)
{
return parent::addScript('/media/js/' . $path);
}
public static function transformHtml($html)
public function transformHtml($html)
{
self::$title = isset(self::$subTitle)
? sprintf('%s&nbsp;&ndash;&nbsp;%s', self::$title, self::$subTitle)
: self::$title;
$this->title = isset($this->subTitle)
? sprintf('%s&nbsp;&ndash;&nbsp;%s', $this->title, $this->subTitle)
: $this->title;
$html = parent::transformHtml($html);
$headSnippet = '<meta property="og:title" content="' . self::$title . '"/>';
$headSnippet = '<meta property="og:title" content="' . $this->title . '"/>';
$headSnippet .= '<meta property="og:url" content="' . \Chibi\Util\Url::currentUrl() . '"/>';
if (!empty(self::$pageThumb))
$headSnippet .= '<meta property="og:image" content="' . self::$pageThumb . '"/>';
if (!empty($this->pageThumb))
$headSnippet .= '<meta property="og:image" content="' . $this->pageThumb . '"/>';
$bodySnippet = '<script type="text/javascript">';
$bodySnippet .= '$(function() {';
@ -54,5 +48,3 @@ class Assets extends \Chibi\Util\Assets
return $html;
}
}
Assets::init();

View file

@ -4,11 +4,7 @@ class SessionHelper
public static function init()
{
session_start();
register_shutdown_function(function()
{
if (\Chibi\Util\Headers::getRequestMethod() == 'GET')
$_SESSION['last-visited-url'] = Core::getContext()->query;
});
register_shutdown_function([__CLASS__, 'tryRememberVisitedUrl']);
}
public static function get($key, $default = null)
@ -23,10 +19,40 @@ class SessionHelper
$_SESSION[$key] = $value;
}
public static function getLastVisitedUrl()
public static function getLastVisitedUrl($filter = null)
{
if (isset($_SESSION['last-visited-url']))
foreach ($_SESSION['last-visited-url'] as $lastUrl)
if ($filter === null or stripos($lastUrl, $filter) === false)
return \Chibi\Util\Url::makeAbsolute($lastUrl);
return null;
}
public static function tryRememberVisitedUrl()
{
if (\Chibi\Util\Headers::getRequestMethod() != 'GET')
return;
if (\Chibi\Util\Headers::getCode() != 200)
return;
if (strpos(\Chibi\Util\Headers::get('Content-Type'), 'text/html') === false)
return;
self::rememberVisitedUrl();
self::removeExcessHistory();
}
private static function rememberVisitedUrl()
{
if (!isset($_SESSION['last-visited-url']))
return '';
return \Chibi\Util\Url::makeAbsolute($_SESSION['last-visited-url']);
$_SESSION['last-visited-url'] = [];
array_unshift($_SESSION['last-visited-url'], Core::getContext()->query);
}
private static function removeExcessHistory()
{
array_splice($_SESSION['last-visited-url'], 3);
}
}

View file

@ -1,13 +1,22 @@
<?php
class Messenger
{
public static function message($message, $success = true)
public static function success($message)
{
if (empty($message))
return;
self::message($message, true);
}
public static function fail($message)
{
self::message($message, false);
}
private static function message($message, $success = true)
{
$context = Core::getContext();
$message = $message ?: 'Empty message';
if (!preg_match('/[.?!]$/', $message))
$message .= '.';

22
src/View.php Normal file
View file

@ -0,0 +1,22 @@
<?php
class View extends \Chibi\View
{
public static function renderTopLevel($viewName, $assets)
{
$context = Core::getContext();
$view = new View($viewName);
$view->registerDecorator(new \Chibi\Util\Minify());
$view->registerDecorator($assets);
$view->context = $context;
$view->assets = $assets;
$view->render();
}
protected function renderExternal($viewName)
{
$view = new View($viewName);
$view->context = $this->context;
$view->assets = $this->assets;
$view->render();
}
}

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubTitle('authentication form');
Assets::addStylesheet('auth.css');
$this->assets->setSubTitle('authentication form');
$this->assets->addStylesheet('auth.css');
?>
<form
@ -34,7 +34,7 @@ Assets::addStylesheet('auth.css');
</div>
</div>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row help">
<label></label>

View file

@ -1,6 +1,6 @@
<?php
Assets::addStylesheet('comment-edit.css');
Assets::addScript('comment-edit.js');
$this->assets->addStylesheet('comment-edit.css');
$this->assets->addScript('comment-edit.js');
?>
<form

View file

@ -1,6 +1,6 @@
<?php
Assets::addStylesheet('comment-edit.css');
Assets::addScript('comment-edit.js');
$this->assets->addStylesheet('comment-edit.css');
$this->assets->addScript('comment-edit.js');
?>
<form

View file

@ -1,15 +1,15 @@
<?php
Assets::setSubTitle('comments');
$this->assets->setSubTitle('comments');
?>
<?php if (empty($this->context->transport->posts)): ?>
<p class="alert alert-warning">No comments to show.</p>
<?php else: ?>
<?php
Assets::addStylesheet('comment-list.css');
Assets::addStylesheet('comment-small.css');
Assets::addStylesheet('comment-edit.css');
Assets::addScript('comment-edit.js');
$this->assets->addStylesheet('comment-list.css');
$this->assets->addStylesheet('comment-small.css');
$this->assets->addStylesheet('comment-edit.css');
$this->assets->addScript('comment-edit.js');
?>
<div class="comments-wrapper">
@ -22,12 +22,12 @@ Assets::setSubTitle('comments');
$comments = array_reverse($post->getComments());
$commentsToDisplay = array_slice($comments, 0, Core::getConfig()->comments->maxCommentsInList);
?>
<?php \Chibi\View::render('post-small', $this->context) ?>
<?php $this->renderExternal('post-small') ?>
</div>
<div class="comments">
<?php foreach ($commentsToDisplay as $comment): ?>
<?php $this->context->comment = $comment ?>
<?php \Chibi\View::render('comment-small', $this->context) ?>
<?php $this->renderExternal('comment-small') ?>
<?php endforeach ?>
<?php if (count($comments) > count($commentsToDisplay)): ?>
@ -43,6 +43,6 @@ Assets::setSubTitle('comments');
<?php endforeach ?>
</div>
<?php \Chibi\View::render('paginator', $this->context) ?>
<?php $this->renderExternal('paginator') ?>
</div>
<?php endif ?>

View file

@ -1,7 +1,7 @@
<?php
Assets::addStylesheet('comment-small.css');
Assets::addStylesheet('comment-edit.css');
Assets::addScript('comment-edit.js');
$this->assets->addStylesheet('comment-small.css');
$this->assets->addStylesheet('comment-edit.css');
$this->assets->addScript('comment-edit.js');
?>
<div class="comment">

View file

@ -1,4 +1,7 @@
<?php Assets::addStylesheet('debug.css') ?>
<?php
$this->assets->addStylesheet('debug.css');
?>
<div class="main-wrapper">
<?php foreach (\Chibi\Database::getLogs() as $log): ?>
<div class="debug">

View file

@ -1,10 +1,10 @@
<?php
Assets::addStylesheet('../lib/jquery-ui/jquery-ui.css');
Assets::addStylesheet('core.css');
Assets::addScript('../lib/jquery/jquery.min.js');
Assets::addScript('../lib/jquery-ui/jquery-ui.min.js');
Assets::addScript('../lib/mousetrap/mousetrap.min.js');
Assets::addScript('core.js');
$this->assets->addStylesheet('../lib/jquery-ui/jquery-ui.css');
$this->assets->addStylesheet('core.css');
$this->assets->addScript('../lib/jquery/jquery.min.js');
$this->assets->addScript('../lib/jquery-ui/jquery-ui.min.js');
$this->assets->addScript('../lib/mousetrap/mousetrap.min.js');
$this->assets->addScript('core.js');
?>
<!DOCTYPE html>
@ -24,14 +24,14 @@ Assets::addScript('core.js');
<nav id="top-nav">
<div class="main-wrapper">
<?php \Chibi\View::render('top-navigation', $this->context) ?>
<?php $this->renderExternal('top-navigation') ?>
</div>
<div class="clear"></div>
</nav>
<section id="content">
<div class="main-wrapper">
<?= \Chibi\View::render($this->context->viewName, $this->context) ?>
<?php $this->renderExternal($this->context->viewName) ?>
</div>
<div class="clear"></div>
</section>
@ -60,7 +60,7 @@ Assets::addScript('core.js');
</footer>
<?php if (Core::getConfig()->misc->debugQueries): ?>
<?= \Chibi\View::render('debug', $this->context) ?>
<?php $this->renderExternal('debug') ?>
<?php endif ?>
<div id="small-screen"></div>

View file

@ -1,5 +1,5 @@
<?php
Assets::setSubTitle('logs (' . $this->context->transport->name . ')');
$this->assets->setSubTitle('logs (' . $this->context->transport->name . ')');
?>
<?php if (empty($this->context->transport->lines)): ?>
@ -8,8 +8,8 @@ Assets::setSubTitle('logs (' . $this->context->transport->name . ')');
</p>
<?php else: ?>
<?php
Assets::addStylesheet('logs.css');
Assets::addScript('logs.js');
$this->assets->addStylesheet('logs.css');
$this->assets->addScript('logs.js');
?>
<form method="get"
@ -29,5 +29,5 @@ Assets::setSubTitle('logs (' . $this->context->transport->name . ')');
<code><?= $this->context->transport->lines ?></code>
</div>
<?php \Chibi\View::render('paginator', $this->context) ?>
<?php $this->renderExternal('paginator') ?>
<?php endif ?>

View file

@ -41,9 +41,9 @@ if (!function_exists('pageUrl'))
<?php if (!empty($pagesVisible)): ?>
<?php
Assets::addStylesheet('paginator.css');
$this->assets->addStylesheet('paginator.css');
if (Auth::getCurrentUser()->getSettings()->hasEnabledEndlessScrolling())
Assets::addScript('paginator-endless.js');
$this->assets->addScript('paginator-endless.js');
?>
<nav class="paginator-wrapper">

View file

@ -1,5 +1,5 @@
<?php
Assets::setPageThumb(\Chibi\Router::linkTo(
$this->assets->setPageThumb(\Chibi\Router::linkTo(
['PostController', 'thumbView'],
['name' => $this->context->transport->post->getName()]));
$post = $this->context->transport->post;

View file

@ -1,5 +1,5 @@
<?php
Assets::setSubTitle('posts');
$this->assets->setSubTitle('posts');
$tabs = [];
$activeTab = 0;
@ -9,15 +9,15 @@ if (Access::check(new Privilege(Privilege::ListPosts)))
if (Access::check(new Privilege(Privilege::ListPosts)))
{
$tabs []= ['Random', \Chibi\Router::linkTo(['PostController', 'randomView'])];
if ($this->context->simpleActionName == 'random')
if ($this->context->source == 'random')
$activeTab = count($tabs) - 1;
$tabs []= ['Favorites', \Chibi\Router::linkTo(['PostController', 'favoritesView'])];
if ($this->context->simpleActionName == 'favorites')
if ($this->context->source == 'favorites')
$activeTab = count($tabs) - 1;
$tabs []= ['Upvoted', \Chibi\Router::linkTo(['PostController', 'upvotedView'])];
if ($this->context->simpleActionName == 'upvoted')
if ($this->context->source == 'upvoted')
$activeTab = count($tabs) - 1;
}
@ -61,5 +61,5 @@ if (Access::check(new Privilege(Privilege::MassTag)))
</nav>
<div class="tab-content">
<?php \Chibi\View::render('post-list', $this->context) ?>
<?php $this->renderExternal('post-list') ?>
</div>

View file

@ -1,17 +1,17 @@
<?php
Assets::addStylesheet('post-list.css');
Assets::addScript('post-list.js');
$this->assets->addStylesheet('post-list.css');
$this->assets->addScript('post-list.js');
if (isset($this->context->source)
and $this->context->source == 'mass-tag'
and Access::check(new Privilege(Privilege::MassTag)))
{
\Chibi\View::render('tag-mass-tag', $this->context);
$this->renderExternal('tag-mass-tag');
}
?>
<?php if (!empty($this->context->transport->message)): ?>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<?php elseif (empty($this->context->transport->posts)): ?>
<p class="alert alert-warning">No posts to show.</p>
<?php else: ?>
@ -19,11 +19,11 @@ if (isset($this->context->source)
<div class="posts paginator-content">
<?php foreach ($this->context->transport->posts as $post): ?>
<?php $this->context->post = $post ?>
<?php \Chibi\View::render('post-small', $this->context) ?>
<?php $this->renderExternal('post-small') ?>
<?php endforeach ?>
</div>
<div class="clear"></div>
</div>
<?php \Chibi\View::render('paginator', $this->context) ?>
<?php $this->renderExternal('paginator') ?>
<?php endif ?>

View file

@ -1,5 +1,5 @@
<?php
Assets::addStylesheet('post-small.css');
$this->assets->addStylesheet('post-small.css');
$classNames =
[

View file

@ -1,9 +1,9 @@
<?php
Assets::setSubTitle('upload');
Assets::addStylesheet('post-upload.css');
Assets::addScript('post-upload.js');
Assets::addStylesheet('../lib/tagit/jquery.tagit.css');
Assets::addScript('../lib/tagit/jquery.tagit.js');
$this->assets->setSubTitle('upload');
$this->assets->addStylesheet('post-upload.css');
$this->assets->addScript('post-upload.js');
$this->assets->addStylesheet('../lib/tagit/jquery.tagit.css');
$this->assets->addScript('../lib/tagit/jquery.tagit.js');
?>
<div id="sidebar">

View file

@ -2,11 +2,11 @@
$subTitle = sprintf('showing %s&nbsp;&ndash;%s',
TextHelper::reprPost($this->context->transport->post),
TextHelper::reprTags($this->context->transport->post->getTags()));
Assets::setSubTitle($subTitle);
Assets::addStylesheet('post-view.css');
Assets::addScript('post-view.js');
Assets::addStylesheet('../lib/tagit/jquery.tagit.css');
Assets::addScript('../lib/tagit/jquery.tagit.js');
$this->assets->setSubTitle($subTitle);
$this->assets->addStylesheet('post-view.css');
$this->assets->addScript('post-view.js');
$this->assets->addStylesheet('../lib/tagit/jquery.tagit.css');
$this->assets->addScript('../lib/tagit/jquery.tagit.js');
$editPostPrivileges = [
Privilege::EditPostSafety,
@ -364,24 +364,24 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
}
$this->context->options = $options;
\Chibi\View::render('sidebar-options', $this->context);
$this->renderExternal('sidebar-options');
?>
</div>
<div id="inner-content">
<?php if ($canEditAnything): ?>
<div class="unit edit-post">
<?php \Chibi\View::render('post-edit', $this->context) ?>
<?php $this->renderExternal('post-edit') ?>
</div>
<?php endif ?>
<div class="post-wrapper post-type-<?= $this->context->transport->post->getType()->toString() ?>">
<?= \Chibi\View::render('post-file-render', $this->context) ?>
<?php $this->renderExternal('post-file-render') ?>
</div>
<?php
Assets::addStylesheet('comment-list.css');
Assets::addStylesheet('comment-small.css');
$this->assets->addStylesheet('comment-list.css');
$this->assets->addStylesheet('comment-small.css');
?>
<div class="comments-wrapper">
@ -391,7 +391,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<div class="comments">
<?php foreach ($this->context->transport->post->getComments() as $comment): ?>
<?php $this->context->comment = $comment ?>
<?= \Chibi\View::render('comment-small', $this->context) ?>
<?php $this->renderExternal('comment-small') ?>
<?php endforeach ?>
</div>
</div>
@ -400,7 +400,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<?php if (Access::check(new Privilege(Privilege::AddComment))): ?>
<div class="unit comment-add">
<?php \Chibi\View::render('comment-add', $this->context) ?>
<?php $this->renderExternal('comment-add') ?>
</div>
<?php endif ?>
</div>

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubtitle('help');
Assets::addStylesheet('static-help.css');
$this->assets->setSubtitle('help');
$this->assets->addStylesheet('static-help.css');
$tabs = Core::getConfig()->help->subTitles;
$firstTab = !empty($tabs) ? array_keys($tabs)[0] : null;

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubtitle('home');
Assets::addStylesheet('static-main.css');
$this->assets->setSubtitle('home');
$this->assets->addStylesheet('static-main.css');
?>
<div id="welcome">
@ -22,7 +22,7 @@ Assets::addStylesheet('static-main.css');
'id' => $this->context->featuredPost->getId()]);
?>
<?php \Chibi\View::render('post-file-render', $this->context) ?>
<?php $this->renderExternal('post-file-render') ?>
</div>
<div class="footer">

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubTitle('tags');
Assets::addStylesheet('tag-list.css');
$this->assets->setSubTitle('tags');
$this->assets->addStylesheet('tag-list.css');
$tabs = [];
if (Access::check(new Privilege(Privilege::ListTags)))
@ -13,7 +13,7 @@ if (Access::check(new Privilege(Privilege::MergeTags)))
$tabs['merge'] = ['Merge', 'mergeView'];
if (Access::check(new Privilege(Privilege::MassTag)))
$tabs['mass-tag-redirect'] = ['Mass tag', 'massTagRedirectAction'];
$tabs['mass-tag'] = ['Mass tag', 'massTagRedirectAction'];
$showTabs = count($tabs) > 1;
?>
@ -21,12 +21,12 @@ $showTabs = count($tabs) > 1;
<?php if ($showTabs): ?>
<nav class="tabs">
<ul>
<?php foreach ($tabs as $tab => $item): ?>
<?php foreach ($tabs as $source => $item): ?>
<?php list ($name, $action) = $item ?>
<?php if ($this->context->simpleActionName == $tab): ?>
<li class="selected <?= $tab ?>">
<?php if ($this->context->source == $source): ?>
<li class="selected <?= $source ?>">
<?php else: ?>
<li class="<?= $tab ?>">
<li class="<?= $source ?>">
<?php endif ?>
<a href="<?= \Chibi\Router::linkTo(['TagController', $action]) ?>">
<?= $name ?>
@ -39,20 +39,20 @@ $showTabs = count($tabs) > 1;
<div class="tab-content">
<?php endif ?>
<?php if ($this->context->simpleActionName == 'merge'): ?>
<?php \Chibi\View::render('tag-merge', $this->context) ?>
<?php if ($this->context->source == 'merge'): ?>
<?php $this->renderExternal('tag-merge') ?>
<?php endif ?>
<?php if ($this->context->simpleActionName == 'rename'): ?>
<?php \Chibi\View::render('tag-rename', $this->context) ?>
<?php if ($this->context->source == 'rename'): ?>
<?php $this->renderExternal('tag-rename') ?>
<?php endif ?>
<?php if ($this->context->simpleActionName == 'list'): ?>
<?php \Chibi\View::render('tag-list', $this->context) ?>
<?php if ($this->context->source == 'list'): ?>
<?php $this->renderExternal('tag-list') ?>
<?php endif ?>
<?php if ($this->context->simpleActionName == 'mass-tag-redirect'): ?>
<?php \Chibi\View::render('tag-mass-tag', $this->context) ?>
<?php if ($this->context->source == 'mass-tag'): ?>
<?php $this->renderExternal('tag-mass-tag') ?>
<?php endif ?>
<?php if ($showTabs): ?>

View file

@ -44,5 +44,5 @@
</ul>
</div>
<?php \Chibi\View::render('paginator', $this->context) ?>
<?php $this->renderExternal('paginator') ?>
<?php endif ?>

View file

@ -16,7 +16,7 @@
</div>
</div>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -16,7 +16,7 @@
</div>
</div>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -2,8 +2,20 @@
<?php
$nav = [];
$activeController = $this->context->simpleControllerName;
$activeAction = $this->context->simpleActionName;
list ($className, $methodName)
= isset($this->context->route)
? $this->context->route->destination
: [null, null];
$activeController = TextCaseConverter::convert(
str_replace('Controller', '', $className),
TextCaseConverter::CAMEL_CASE,
TextCaseConverter::SPINAL_CASE);
$activeAction = TextCaseConverter::convert(
preg_replace('/Action|View/', '', $methodName),
TextCaseConverter::CAMEL_CASE,
TextCaseConverter::SPINAL_CASE);
$registerNavItem = function ($text, $link, $active = false) use (&$nav)
{

View file

@ -16,7 +16,7 @@
</div>
<?php endif ?>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -107,7 +107,7 @@
</div>
<?php endif ?>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubTitle('users');
Assets::addStylesheet('user-list.css');
$this->assets->setSubTitle('users');
$this->assets->addStylesheet('user-list.css');
?>
<nav class="sort-styles">
@ -71,5 +71,5 @@ Assets::addStylesheet('user-list.css');
<div class="clear"></div>
</div>
<?php \Chibi\View::render('paginator', $this->context) ?>
<?php $this->renderExternal('paginator') ?>
<?php endif ?>

View file

@ -1,12 +1,12 @@
<?php
Assets::setSubTitle('registration form');
$this->assets->setSubTitle('registration form');
?>
<?php if (isset($this->context->transport->message) and $this->context->transport->success): ?>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<?php else: ?>
<?php
Assets::addStylesheet('auth.css');
$this->assets->addStylesheet('auth.css');
?>
<form
@ -72,7 +72,7 @@ Assets::setSubTitle('registration form');
Leave blank for random Gravatar.
</p>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -1,8 +1,8 @@
<?php if (isset($this->context->transport->message)): ?>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<?php else: ?>
<?php
Assets::addStylesheet('auth.css');
$this->assets->addStylesheet('auth.css');
?>
<form
@ -17,7 +17,7 @@
</div>
</div>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -91,7 +91,7 @@ $settings = $this->context->transport->user->getSettings();
</div>
</div>
<?php \Chibi\View::render('message', $this->context) ?>
<?php $this->renderExternal('message') ?>
<div class="form-row">
<label></label>

View file

@ -1,6 +1,6 @@
<?php
Assets::setSubTitle($this->context->transport->user->getName());
Assets::addStylesheet('user-view.css');
$this->assets->setSubTitle($this->context->transport->user->getName());
$this->assets->addStylesheet('user-view.css');
?>
<div id="sidebar">
@ -188,7 +188,7 @@ Assets::addStylesheet('user-view.css');
}
$this->context->options = $options;
\Chibi\View::render('sidebar-options', $this->context);
$this->renderExternal('sidebar-options');
?>
</div>
@ -277,15 +277,15 @@ Assets::addStylesheet('user-view.css');
<div class="tab-content">
<?php if (isset($this->context->transport->posts)): ?>
<?php \Chibi\View::render('post-list', $this->context) ?>
<?php $this->renderExternal('post-list') ?>
<?php endif ?>
<?php if ($this->context->transport->tab == 'settings'): ?>
<?php \Chibi\View::render('user-settings', $this->context) ?>
<?php $this->renderExternal('user-settings') ?>
<?php elseif ($this->context->transport->tab == 'edit'): ?>
<?php \Chibi\View::render('user-edit', $this->context) ?>
<?php $this->renderExternal('user-edit') ?>
<?php elseif ($this->context->transport->tab == 'delete'): ?>
<?php \Chibi\View::render('user-delete', $this->context) ?>
<?php $this->renderExternal('user-delete') ?>
<?php endif ?>
</div>