Changes to privilege system

This commit is contained in:
Marcin Kurczewski 2014-05-04 16:27:15 +02:00
parent 47f7ff3490
commit 67e4272f3e
60 changed files with 286 additions and 266 deletions

View file

@ -32,7 +32,7 @@ class Access
} }
} }
public static function check($privilege, $subPrivilege = null) public static function check(Privilege $privilege)
{ {
if (php_sapi_name() == 'cli') if (php_sapi_name() == 'cli')
return true; return true;
@ -40,7 +40,7 @@ class Access
$user = Auth::getCurrentUser(); $user = Auth::getCurrentUser();
$minAccessRank = AccessRank::Nobody; $minAccessRank = AccessRank::Nobody;
$key = TextCaseConverter::convert(Privilege::toString($privilege), $key = TextCaseConverter::convert(Privilege::toString($privilege->primary),
TextCaseConverter::CAMEL_CASE, TextCaseConverter::CAMEL_CASE,
TextCaseConverter::SPINAL_CASE); TextCaseConverter::SPINAL_CASE);
@ -48,9 +48,9 @@ class Access
{ {
$minAccessRank = self::$privileges[$key]; $minAccessRank = self::$privileges[$key];
} }
if ($subPrivilege != null) if ($privilege->secondary != null)
{ {
$key2 = $key . '.' . strtolower($subPrivilege); $key2 = $key . '.' . strtolower($privilege->secondary);
if (isset(self::$privileges[$key2])) if (isset(self::$privileges[$key2]))
{ {
$minAccessRank = self::$privileges[$key2]; $minAccessRank = self::$privileges[$key2];
@ -63,20 +63,25 @@ class Access
public static function assertAuthentication() public static function assertAuthentication()
{ {
if (!Auth::isLoggedIn()) if (!Auth::isLoggedIn())
throw new SimpleException('Not logged in'); self::fail('Not logged in');
} }
public static function assert($privilege, $subPrivilege = null) public static function assert(Privilege $privilege)
{ {
if (!self::check($privilege, $subPrivilege)) if (!self::check($privilege))
throw new SimpleException('Insufficient privileges'); self::fail();
} }
public static function assertEmailConfirmation() public static function assertEmailConfirmation()
{ {
$user = Auth::getCurrentUser(); $user = Auth::getCurrentUser();
if (!$user->emailConfirmed) if (!$user->emailConfirmed)
throw new SimpleException('Need e-mail address confirmation to continue'); self::fail('Need e-mail address confirmation to continue');
}
public static function fail($message = 'Insufficient privileges')
{
throw new SimpleException($message);
} }
public static function getIdentity($user) public static function getIdentity($user)
@ -93,7 +98,7 @@ class Access
return array_filter(PostSafety::getAll(), function($safety) return array_filter(PostSafety::getAll(), function($safety)
{ {
return Access::check(Privilege::ListPosts, PostSafety::toString($safety)) return Access::check(new Privilege(Privilege::ListPosts, PostSafety::toString($safety)))
and Auth::getCurrentUser()->hasEnabledSafety($safety); and Auth::getCurrentUser()->hasEnabledSafety($safety);
}); });
} }

View file

@ -1,7 +1,7 @@
<?php <?php
final class Api final class Api
{ {
protected static $checkPrivileges; protected static $checkPrivileges = true;
public static function run($job, $jobArgs) public static function run($job, $jobArgs)
{ {
@ -12,24 +12,32 @@ final class Api
$job->setArguments($jobArgs); $job->setArguments($jobArgs);
$job->prepare(); $job->prepare();
if (self::$checkPrivileges) self::checkPrivileges($job);
return $job->execute();
});
}
public static function checkPrivileges(AbstractJob $job)
{ {
if (!self::$checkPrivileges)
return;
if ($job->requiresAuthentication()) if ($job->requiresAuthentication())
Access::assertAuthentication(); Access::assertAuthentication();
if ($job->requiresConfirmedEmail()) if ($job->requiresConfirmedEmail())
Access::assertEmailConfirmation(); Access::assertEmailConfirmation();
$p = $job->requiresPrivilege(); $privileges = $job->requiresPrivilege();
list ($privilege, $subPrivilege) = is_array($p) if ($privileges !== false)
? $p {
: [$p, false]; if (!is_array($privileges))
if ($privilege !== false) $privileges = [$privileges];
Access::assert($privilege, $subPrivilege);
}
return $job->execute(); foreach ($privileges as $privilege)
}); Access::assert($privilege);
}
} }
public static function runMultiple($jobs) public static function runMultiple($jobs)

View file

@ -15,6 +15,6 @@ class AcceptUserRegistrationJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::AcceptUserRegistration; return new Privilege(Privilege::AcceptUserRegistration);
} }
} }

View file

@ -23,7 +23,7 @@ class AddCommentJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::AddComment; return new Privilege(Privilege::AddComment);
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -55,7 +55,7 @@ class AddPostJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::UploadPost; return new Privilege(Privilege::UploadPost);
} }
public function requiresConfirmedEmail() public function requiresConfirmedEmail()

View file

@ -43,6 +43,6 @@ class AddUserJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::RegisterAccount; return new Privilege(Privilege::RegisterAccount);
} }
} }

View file

@ -21,11 +21,9 @@ class DeleteCommentJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::DeleteComment, Privilege::DeleteComment,
Access::getIdentity($this->comment->getCommenter()) Access::getIdentity($this->comment->getCommenter()));
];
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -14,11 +14,9 @@ class DeletePostJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::DeletePost, Privilege::DeletePost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -15,10 +15,8 @@ class DeleteUserJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::DeleteUser, Privilege::DeleteUser,
Access::getIdentity($this->user) Access::getIdentity($this->user));
];
} }
} }

View file

@ -25,11 +25,9 @@ class EditCommentJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditComment, Privilege::EditComment,
Access::getIdentity($this->comment->getCommenter()) Access::getIdentity($this->comment->getCommenter()));
];
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -20,10 +20,8 @@ class EditPostContentJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostFile, Privilege::EditPostFile,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -35,10 +35,8 @@ class EditPostRelationsJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostRelations, Privilege::EditPostRelations,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -26,10 +26,8 @@ class EditPostSafetyJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostSafety, Privilege::EditPostSafety,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -26,10 +26,8 @@ class EditPostSourceJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostSource, Privilege::EditPostSource,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -34,10 +34,8 @@ class EditPostTagsJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostTags, Privilege::EditPostTags,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -21,10 +21,8 @@ class EditPostThumbJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostThumb, Privilege::EditPostThumb,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -21,10 +21,8 @@ class EditPostUrlJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostFile, Privilege::EditPostFile,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -26,10 +26,8 @@ class EditUserAccessRankJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ChangeUserEmail, Privilege::ChangeUserEmail,
Access::getIdentity($this->user), Access::getIdentity($this->user));
];
} }
} }

View file

@ -41,10 +41,8 @@ class EditUserEmailJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ChangeUserAccessRank, Privilege::ChangeUserAccessRank,
Access::getIdentity($this->user), Access::getIdentity($this->user));
];
} }
} }

View file

@ -1,19 +1,42 @@
<?php <?php
class EditUserJob extends AbstractUserJob class EditUserJob extends AbstractUserJob
{ {
public function execute() protected $subJobs;
public function __construct()
{ {
$user = $this->user; $this->subJobs =
LogHelper::bufferChanges();
$subJobs =
[ [
new EditUserAccessRankJob(), new EditUserAccessRankJob(),
new EditUserNameJob(), new EditUserNameJob(),
new EditUserPasswordJob(), new EditUserPasswordJob(),
new EditUserEmailJob(), new EditUserEmailJob(),
]; ];
}
public function canEditAnything($user)
{
$this->privileges = [];
foreach ($this->subJobs as $subJob)
{
try
{
$subJob->user = $user;
Api::checkPrivileges($subJob);
return true;
}
catch (SimpleException $e)
{
}
}
return false;
}
public function execute()
{
$user = $this->user;
LogHelper::bufferChanges();
foreach ($subJobs as $subJob) foreach ($subJobs as $subJob)
{ {
@ -31,4 +54,9 @@ class EditUserJob extends AbstractUserJob
LogHelper::flush(); LogHelper::flush();
return $user; return $user;
} }
public function requiresPrivilege()
{
return false;
}
} }

View file

@ -27,10 +27,8 @@ class EditUserNameJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ChangeUserName, Privilege::ChangeUserName,
Access::getIdentity($this->user), Access::getIdentity($this->user));
];
} }
} }

View file

@ -26,10 +26,8 @@ class EditUserPasswordJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ChangeUserPassword, Privilege::ChangeUserPassword,
Access::getIdentity($this->user), Access::getIdentity($this->user));
];
} }
} }

View file

@ -18,11 +18,9 @@ class FeaturePostJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::FeaturePost, Privilege::FeaturePost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -21,10 +21,8 @@ class FlagPostJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::FlagPost, Privilege::FlagPost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -21,10 +21,8 @@ class FlagUserJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::FlagUser, Privilege::FlagUser,
Access::getIdentity($this->user) Access::getIdentity($this->user));
];
} }
} }

View file

@ -41,6 +41,6 @@ class GetLogJob extends AbstractPageJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ViewLog; return new Privilege(Privilege::ViewLog);
} }
} }

View file

@ -1,16 +1,16 @@
<?php <?php
class GetPostContentJob extends AbstractJob class GetPostContentJob extends AbstractJob
{ {
protected $post;
public function prepare()
{
$this->post = PostModel::findByName($this->getArgument(self::POST_NAME));
}
public function execute() public function execute()
{ {
$post = PostModel::findByName($this->getArgument(self::POST_NAME)); $post = $this->post;
//todo: refactor this so that requiresPrivilege can accept multiple privileges
if ($post->hidden)
Access::assert(Privilege::RetrievePost, 'hidden');
Access::assert(Privilege::RetrievePost);
Access::assert(Privilege::RetrievePost, PostSafety::toString($post->safety));
$config = getConfig(); $config = getConfig();
$path = $config->main->filesPath . DS . $post->name; $path = $config->main->filesPath . DS . $post->name;
@ -32,7 +32,14 @@ class GetPostContentJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
//temporarily enforced in execute $post = $this->post;
return false; $privileges = [];
if ($post->hidden)
$privileges []= new Privilege(Privilege::ViewPost, 'hidden');
$privileges []= new Privilege(Privilege::ViewPost, PostSafety::toString($post->safety));
return $privileges;
} }
} }

View file

@ -5,12 +5,6 @@ class GetPostJob extends AbstractPostJob
{ {
$post = $this->post; $post = $this->post;
//todo: refactor this so that requiresPrivilege can accept multiple privileges
if ($post->hidden)
Access::assert(Privilege::ViewPost, 'hidden');
Access::assert(Privilege::ViewPost);
Access::assert(Privilege::ViewPost, PostSafety::toString($post->safety));
CommentModel::preloadCommenters($post->getComments()); CommentModel::preloadCommenters($post->getComments());
return $post; return $post;
@ -18,7 +12,14 @@ class GetPostJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
//temporarily enforced in execute $post = $this->post;
return false; $privileges = [];
if ($post->hidden)
$privileges []= new Privilege(Privilege::ViewPost, 'hidden');
$privileges []= new Privilege(Privilege::ViewPost, PostSafety::toString($post->safety));
return $privileges;
} }
} }

View file

@ -19,9 +19,8 @@ class GetPostThumbJob extends AbstractJob
$post = PostModel::findByIdOrName($name); $post = PostModel::findByIdOrName($name);
if ($post->hidden) if ($post->hidden)
Access::assert(Privilege::ListPosts, 'hidden'); Access::assert(new Privilege(Privilege::ListPosts, 'hidden'));
Access::assert(Privilege::ListPosts); Access::assert(new Privilege(Privilege::ListPosts, PostSafety::toString($post->safety)));
Access::assert(Privilege::ListPosts, PostSafety::toString($post->safety));
$post->generateThumb($width, $height); $post->generateThumb($width, $height);

View file

@ -8,10 +8,8 @@ class GetUserJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ViewUser, Privilege::ViewUser,
Access::getIdentity($this->user) Access::getIdentity($this->user));
];
} }
} }

View file

@ -27,6 +27,6 @@ class ListCommentsJob extends AbstractPageJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ListComments; return new Privilege(Privilege::ListComments);
} }
} }

View file

@ -19,6 +19,6 @@ class ListLogsJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ListLogs; return new Privilege(Privilege::ListLogs);
} }
} }

View file

@ -22,6 +22,6 @@ class ListPostsJob extends AbstractPageJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ListPosts; return new Privilege(Privilege::ListPosts);
} }
} }

View file

@ -20,6 +20,6 @@ class ListTagsJob extends AbstractPageJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ListTags; return new Privilege(Privilege::ListTags);
} }
} }

View file

@ -20,6 +20,6 @@ class ListUsersJob extends AbstractPageJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::ListUsers; return new Privilege(Privilege::ListUsers);
} }
} }

View file

@ -20,6 +20,6 @@ class MergeTagsJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::MergeTags; return new Privilege(Privilege::MergeTags);
} }
} }

View file

@ -15,7 +15,7 @@ class PreviewCommentJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::AddComment; return new Privilege(Privilege::AddComment);
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -20,6 +20,6 @@ class RenameTagsJob extends AbstractJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return Privilege::RenameTags; return new Privilege(Privilege::RenameTags);
} }
} }

View file

@ -13,10 +13,8 @@ class ScorePostJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::ScorePost, Privilege::ScorePost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -21,11 +21,9 @@ class TogglePostFavoriteJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::FavoritePost, Privilege::FavoritePost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
public function requiresAuthentication() public function requiresAuthentication()

View file

@ -52,10 +52,8 @@ class TogglePostTagJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::EditPostTags, Privilege::EditPostTags,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -21,10 +21,8 @@ class TogglePostVisibilityJob extends AbstractPostJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::HidePost, Privilege::HidePost,
Access::getIdentity($this->post->getUploader()) Access::getIdentity($this->post->getUploader()));
];
} }
} }

View file

@ -19,10 +19,8 @@ class ToggleUserBanJob extends AbstractUserJob
public function requiresPrivilege() public function requiresPrivilege()
{ {
return return new Privilege(
[
Privilege::BanUser, Privilege::BanUser,
Access::getIdentity($this->user) Access::getIdentity($this->user));
];
} }
} }

View file

@ -31,11 +31,11 @@ class PostController
$context->transport->lastSearchQuery = $query; $context->transport->lastSearchQuery = $query;
if ($source == 'mass-tag') if ($source == 'mass-tag')
{ {
Access::assert(Privilege::MassTag); Access::assert(new Privilege(Privilege::MassTag));
$context->massTagTag = $additionalInfo; $context->massTagTag = $additionalInfo;
$context->massTagQuery = $query; $context->massTagQuery = $query;
if (!Access::check(Privilege::MassTag, 'all')) if (!Access::check(new Privilege(Privilege::MassTag, 'all')))
$query = trim($query . ' submit:' . Auth::getCurrentUser()->name); $query = trim($query . ' submit:' . Auth::getCurrentUser()->name);
} }
@ -67,9 +67,9 @@ class PostController
public function toggleTagAction($id, $tag, $enable) public function toggleTagAction($id, $tag, $enable)
{ {
Access::assert( Access::assert(new Privilege(
Privilege::MassTag, Privilege::MassTag,
Access::getIdentity(PostModel::findById($id)->getUploader())); Access::getIdentity(PostModel::findById($id)->getUploader())));
Api::run( Api::run(
new TogglePostTagJob(), new TogglePostTagJob(),
@ -113,7 +113,9 @@ class PostController
public function editView($id) public function editView($id)
{ {
$post = PostModel::findByIdOrName($id); $post = Api::run(new GetPostJob(), [
GetPostJob::POST_ID => $id]);
$context = getContext()->transport->post = $post; $context = getContext()->transport->post = $post;
} }

View file

@ -79,8 +79,6 @@ class TagController
$context->viewName = 'tag-list-wrapper'; $context->viewName = 'tag-list-wrapper';
$context->handleExceptions = true; $context->handleExceptions = true;
Access::assert(Privilege::MergeTags);
Api::run( Api::run(
new MergeTagsJob(), new MergeTagsJob(),
[ [
@ -103,8 +101,6 @@ class TagController
$context->viewName = 'tag-list-wrapper'; $context->viewName = 'tag-list-wrapper';
$context->handleExceptions = true; $context->handleExceptions = true;
Access::assert(Privilege::MergeTags);
Api::run( Api::run(
new RenameTagsJob(), new RenameTagsJob(),
[ [
@ -120,7 +116,7 @@ class TagController
$context = getContext(); $context = getContext();
$context->viewName = 'tag-list-wrapper'; $context->viewName = 'tag-list-wrapper';
Access::assert(Privilege::MassTag); Access::assert(new Privilege(Privilege::MassTag));
if (!InputHelper::get('submit')) if (!InputHelper::get('submit'))
return; return;

View file

@ -27,6 +27,18 @@ class UserController
$flagged = in_array(TextHelper::reprUser($user), SessionHelper::get('flagged', [])); $flagged = in_array(TextHelper::reprUser($user), SessionHelper::get('flagged', []));
if ($tab == 'uploads')
$query = 'submit:' . $user->name;
elseif ($tab == 'favs')
$query = 'fav:' . $user->name;
elseif ($tab == 'delete')
Access::assert(new Privilege(Privilege::DeleteUser));
elseif ($tab == 'settings')
Access::assert(new Privilege(Privilege::ChangeUserSettings));
elseif ($tab == 'edit' and !(new EditUserJob)->canEditAnything(Auth::getCurrentUser()))
Access::fail();
$context = getContext(); $context = getContext();
$context->flagged = $flagged; $context->flagged = $flagged;
$context->transport->tab = $tab; $context->transport->tab = $tab;
@ -34,11 +46,6 @@ class UserController
$context->handleExceptions = true; $context->handleExceptions = true;
$context->viewName = 'user-view'; $context->viewName = 'user-view';
if ($tab == 'uploads')
$query = 'submit:' . $user->name;
elseif ($tab == 'favs')
$query = 'fav:' . $user->name;
if (isset($query)) if (isset($query))
{ {
$ret = Api::run( $ret = Api::run(
@ -60,9 +67,9 @@ class UserController
$user = getContext()->transport->user; $user = getContext()->transport->user;
Access::assert( Access::assert(new Privilege(
Privilege::ChangeUserSettings, Privilege::ChangeUserSettings,
Access::getIdentity($user)); Access::getIdentity($user)));
$suppliedSafety = InputHelper::get('safety'); $suppliedSafety = InputHelper::get('safety');
if (!is_array($suppliedSafety)) if (!is_array($suppliedSafety))
@ -157,9 +164,9 @@ class UserController
{ {
$user = Auth::getCurrentUser(); $user = Auth::getCurrentUser();
Access::assert( Access::assert(new Privilege(
Privilege::ChangeUserSettings, Privilege::ChangeUserSettings,
Access::getIdentity($user)); Access::getIdentity($user)));
if (!in_array($safety, PostSafety::getAll())) if (!in_array($safety, PostSafety::getAll()))
throw new SimpleExcetpion('Invalid safety'); throw new SimpleExcetpion('Invalid safety');

View file

@ -44,4 +44,13 @@ class Privilege extends Enum
const ListLogs = 32; const ListLogs = 32;
const ViewLog = 33; const ViewLog = 33;
public $primary;
public $secondary;
public function __construct($primary, $secondary = null)
{
$this->primary = $primary;
$this->secondary = $secondary;
}
} }

View file

@ -11,7 +11,7 @@ class CommentSearchParser extends AbstractSearchParser
$allowedSafety = Access::getAllowedSafety(); $allowedSafety = Access::getAllowedSafety();
$crit->add(Sql\InFunctor::fromArray('post.safety', Sql\Binding::fromArray($allowedSafety))); $crit->add(Sql\InFunctor::fromArray('post.safety', Sql\Binding::fromArray($allowedSafety)));
if (!Access::check(Privilege::ListPosts, 'hidden')) if (!Access::check(new Privilege(Privilege::ListPosts, 'hidden')))
$crit->add(new Sql\NegationFunctor(new Sql\StringExpression('hidden'))); $crit->add(new Sql\NegationFunctor(new Sql\StringExpression('hidden')));
$this->statement->setCriterion($crit); $this->statement->setCriterion($crit);

View file

@ -27,7 +27,7 @@ class PostSearchParser extends AbstractSearchParser
if (Auth::getCurrentUser()->hasEnabledHidingDislikedPosts() and !$this->showDisliked) if (Auth::getCurrentUser()->hasEnabledHidingDislikedPosts() and !$this->showDisliked)
$this->processComplexToken('special', 'disliked', true); $this->processComplexToken('special', 'disliked', true);
if (!Access::check(Privilege::ListPosts, 'hidden') or !$this->showHidden) if (!Access::check(new Privilege(Privilege::ListPosts, 'hidden')) or !$this->showHidden)
$this->processComplexToken('special', 'hidden', true); $this->processComplexToken('special', 'hidden', true);
foreach ($this->tags as $item) foreach ($this->tags as $item)

View file

@ -36,9 +36,9 @@ Assets::addScript('comment-edit.js');
<?= TextHelper::formatDate($this->context->comment->commentDate, false) ?> <?= TextHelper::formatDate($this->context->comment->commentDate, false) ?>
</span> </span>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::EditComment, Privilege::EditComment,
Access::getIdentity($commenter))): ?> Access::getIdentity($commenter)))): ?>
<span class="edit"> <span class="edit">
<a href="<?= \Chibi\Router::linkTo( <a href="<?= \Chibi\Router::linkTo(
['CommentController', 'editView'], ['CommentController', 'editView'],
@ -48,9 +48,9 @@ Assets::addScript('comment-edit.js');
</span> </span>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::DeleteComment, Privilege::DeleteComment,
Access::getIdentity($commenter))): ?> Access::getIdentity($commenter)))): ?>
<span class="delete"> <span class="delete">
<a class="simple-action confirmable" <a class="simple-action confirmable"
data-confirm-text="Are you sure you want to delete this comment?" data-confirm-text="Are you sure you want to delete this comment?"

View file

@ -42,7 +42,7 @@ Assets::addScript('core.js');
<span>Load:&nbsp;<?= sprintf('%.05f', microtime(true) - $this->context->startTime) ?>s</span> <span>Load:&nbsp;<?= sprintf('%.05f', microtime(true) - $this->context->startTime) ?>s</span>
<span>Queries:&nbsp;<?= count(\Chibi\Database::getLogs()) ?></span> <span>Queries:&nbsp;<?= count(\Chibi\Database::getLogs()) ?></span>
<span><a href="<?= SZURU_LINK ?>">szurubooru&nbsp;v<?= SZURU_VERSION ?></a></span> <span><a href="<?= SZURU_LINK ?>">szurubooru&nbsp;v<?= SZURU_VERSION ?></a></span>
<?php if (Access::check(Privilege::ListLogs)): ?> <?php if (Access::check(new Privilege(Privilege::ListLogs))): ?>
<span><a href="<?= \Chibi\Router::linkTo(['LogController', 'listView']) ?>">Logs</a></span> <span><a href="<?= \Chibi\Router::linkTo(['LogController', 'listView']) ?>">Logs</a></span>
<?php endif ?> <?php endif ?>
<hr> <hr>

View file

@ -12,9 +12,9 @@
id="edit-token" id="edit-token"
value="<?= htmlspecialchars($this->context->transport->post->getEditToken()) ?>"/> value="<?= htmlspecialchars($this->context->transport->post->getEditToken()) ?>"/>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::EditPostSafety, Privilege::EditPostSafety,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row safety"> <div class="form-row safety">
<label>Safety:</label> <label>Safety:</label>
@ -34,9 +34,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::EditPostTags, Privilege::EditPostTags,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row tags"> <div class="form-row tags">
<label for="tags">Tags:</label> <label for="tags">Tags:</label>
@ -52,9 +52,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if ( <?php if (Access::check(new Privilege(
Access::check(Privilege::EditPostSource, Privilege::EditPostSource,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row source"> <div class="form-row source">
<label for="source">Source:</label> <label for="source">Source:</label>
@ -67,9 +67,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if ( <?php if (Access::check(new Privilege(
Access::check(Privilege::EditPostRelations, Privilege::EditPostRelations,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row thumb"> <div class="form-row thumb">
<label for="relations">Relations:</label> <label for="relations">Relations:</label>
@ -85,9 +85,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if ( <?php if (Access::check(new Privilege(
Access::check(Privilege::EditPostFile, Privilege::EditPostFile,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row url"> <div class="form-row url">
<label for="url">File:</label> <label for="url">File:</label>
@ -104,9 +104,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if ( <?php if (Access::check(new Privilege(
Access::check(Privilege::EditPostThumb, Privilege::EditPostThumb,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="form-row thumb"> <div class="form-row thumb">
<label for="thumb">Thumb:</label> <label for="thumb">Thumb:</label>

View file

@ -3,31 +3,25 @@ Assets::setSubTitle('posts');
$tabs = []; $tabs = [];
$activeTab = 0; $activeTab = 0;
if (Access::check(Privilege::ListPosts)) if (Access::check(new Privilege(Privilege::ListPosts)))
$tabs []= ['All posts', \Chibi\Router::linkTo(['PostController', 'listView'])]; $tabs []= ['All posts', \Chibi\Router::linkTo(['PostController', 'listView'])];
if (Access::check(Privilege::ListPosts)) if (Access::check(new Privilege(Privilege::ListPosts)))
{ {
$tabs []= ['Random', \Chibi\Router::linkTo(['PostController', 'randomView'])]; $tabs []= ['Random', \Chibi\Router::linkTo(['PostController', 'randomView'])];
if ($this->context->simpleActionName == 'random') if ($this->context->simpleActionName == 'random')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
}
if (Access::check(Privilege::ListPosts))
{
$tabs []= ['Favorites', \Chibi\Router::linkTo(['PostController', 'favoritesView'])]; $tabs []= ['Favorites', \Chibi\Router::linkTo(['PostController', 'favoritesView'])];
if ($this->context->simpleActionName == 'favorites') if ($this->context->simpleActionName == 'favorites')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
}
if (Access::check(Privilege::ListPosts))
{
$tabs []= ['Upvoted', \Chibi\Router::linkTo(['PostController', 'upvotedView'])]; $tabs []= ['Upvoted', \Chibi\Router::linkTo(['PostController', 'upvotedView'])];
if ($this->context->simpleActionName == 'upvoted') if ($this->context->simpleActionName == 'upvoted')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
} }
if (Access::check(Privilege::MassTag)) if (Access::check(new Privilege(Privilege::MassTag)))
{ {
$tabs []= ['Mass tag', \Chibi\Router::linkTo(['PostController', 'listView'], [ $tabs []= ['Mass tag', \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => 'mass-tag', 'source' => 'mass-tag',

View file

@ -5,7 +5,7 @@ Assets::addScript('post-list.js');
<?php if (isset($this->context->source) <?php if (isset($this->context->source)
and $this->context->source == 'mass-tag' and $this->context->source == 'mass-tag'
and Access::check(Privilege::MassTag)): ?> and Access::check(new Privilege(Privilege::MassTag))): ?>
<?php \Chibi\View::render('tag-mass-tag', $this->context) ?> <?php \Chibi\View::render('tag-mass-tag', $this->context) ?>

View file

@ -17,9 +17,9 @@ $editPostPrivileges = [
$editPostPrivileges = array_fill_keys($editPostPrivileges, false); $editPostPrivileges = array_fill_keys($editPostPrivileges, false);
foreach (array_keys($editPostPrivileges) as $privilege) foreach (array_keys($editPostPrivileges) as $privilege)
{ {
if (Access::check( if (Access::check(new Privilege(
$privilege, $privilege,
Access::getIdentity($this->context->transport->post->getUploader()))) Access::getIdentity($this->context->transport->post->getUploader()))))
$editPostPrivileges[$privilege] = true; $editPostPrivileges[$privilege] = true;
} }
@ -158,9 +158,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
['id' => $this->context->transport->post->id, 'score' => $score]); ['id' => $this->context->transport->post->id, 'score' => $score]);
} }
?> ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ScorePost, Privilege::ScorePost,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<?php if ($this->context->score === 1): ?> <?php if ($this->context->score === 1): ?>
<a class="simple-action selected" href="<?= $scoreLink(0) ?>"> <a class="simple-action selected" href="<?= $scoreLink(0) ?>">
<?php else: ?> <?php else: ?>
@ -202,9 +202,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
</div> </div>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::FavoritePost, Privilege::FavoritePost,
Access::getIdentity($this->context->transport->post->getUploader()))): ?> Access::getIdentity($this->context->transport->post->getUploader())))): ?>
<div class="hl-option"> <div class="hl-option">
<?php if (!$this->context->favorite): ?> <?php if (!$this->context->favorite): ?>
<a class="add-fav icon simple-action" <a class="add-fav icon simple-action"
@ -271,9 +271,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<?php <?php
$options = []; $options = [];
if (Access::check( if (Access::check(new Privilege(
Privilege::FeaturePost, Privilege::FeaturePost,
Access::getIdentity($this->context->transport->post->getUploader()))) Access::getIdentity($this->context->transport->post->getUploader()))))
{ {
$options []= $options []=
[ [
@ -287,9 +287,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
]; ];
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::FlagPost, Privilege::FlagPost,
Access::getIdentity($this->context->transport->post->getUploader()))) Access::getIdentity($this->context->transport->post->getUploader()))))
{ {
if ($this->context->flagged) if ($this->context->flagged)
{ {
@ -314,9 +314,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
} }
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::HidePost, Privilege::HidePost,
Access::getIdentity($this->context->transport->post->getUploader()))) Access::getIdentity($this->context->transport->post->getUploader()))))
{ {
if ($this->context->transport->post->hidden) if ($this->context->transport->post->hidden)
{ {
@ -342,9 +342,9 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
} }
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::DeletePost, Privilege::DeletePost,
Access::getIdentity($this->context->transport->post->getUploader()))) Access::getIdentity($this->context->transport->post->getUploader()))))
{ {
$options []= $options []=
[ [
@ -392,7 +392,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<?php endif ?> <?php endif ?>
</div> </div>
<?php if (Access::check(Privilege::AddComment)): ?> <?php if (Access::check(new Privilege(Privilege::AddComment))): ?>
<div class="unit comment-add"> <div class="unit comment-add">
<?php \Chibi\View::render('comment-add', $this->context) ?> <?php \Chibi\View::render('comment-add', $this->context) ?>
</div> </div>

View file

@ -3,10 +3,18 @@ Assets::setSubTitle('tags');
Assets::addStylesheet('tag-list.css'); Assets::addStylesheet('tag-list.css');
$tabs = []; $tabs = [];
if (Access::check(Privilege::ListTags)) $tabs['list'] = ['List', 'listView']; if (Access::check(new Privilege(Privilege::ListTags)))
if (Access::check(Privilege::RenameTags)) $tabs['rename'] = ['Rename', 'renameView']; $tabs['list'] = ['List', 'listView'];
if (Access::check(Privilege::MergeTags)) $tabs['merge'] = ['Merge', 'mergeView'];
if (Access::check(Privilege::MassTag)) $tabs['mass-tag-redirect'] = ['Mass tag', 'massTagRedirectAction']; if (Access::check(new Privilege(Privilege::RenameTags)))
$tabs['rename'] = ['Rename', 'renameView'];
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'];
$showTabs = count($tabs) > 1; $showTabs = count($tabs) > 1;
?> ?>

View file

@ -18,7 +18,7 @@
\Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']), \Chibi\Router::linkTo(['StaticPagesController', 'mainPageView']),
$activeController == 'static-pages' and $activeAction == 'main-page'); $activeController == 'static-pages' and $activeAction == 'main-page');
if (Access::check(Privilege::ListPosts)) if (Access::check(new Privilege(Privilege::ListPosts)))
{ {
$registerNavItem( $registerNavItem(
'Browse', 'Browse',
@ -26,7 +26,7 @@
$activeController == 'post' and $activeAction != 'upload'); $activeController == 'post' and $activeAction != 'upload');
} }
if (Access::check(Privilege::UploadPost)) if (Access::check(new Privilege(Privilege::UploadPost)))
{ {
$registerNavItem( $registerNavItem(
'Upload', 'Upload',
@ -34,7 +34,7 @@
$activeController == 'post' and $activeAction == 'upload'); $activeController == 'post' and $activeAction == 'upload');
} }
if (Access::check(Privilege::ListComments)) if (Access::check(new Privilege(Privilege::ListComments)))
{ {
$registerNavItem( $registerNavItem(
'Comments', 'Comments',
@ -42,7 +42,7 @@
$activeController == 'comment'); $activeController == 'comment');
} }
if (Access::check(Privilege::ListTags)) if (Access::check(new Privilege(Privilege::ListTags)))
{ {
$registerNavItem( $registerNavItem(
'Tags', 'Tags',
@ -50,7 +50,7 @@
$activeController == 'tag'); $activeController == 'tag');
} }
if (Access::check(Privilege::ListUsers)) if (Access::check(new Privilege(Privilege::ListUsers)))
{ {
$registerNavItem( $registerNavItem(
'Users', 'Users',
@ -104,13 +104,15 @@
} }
?> ?>
<?php if (Access::check(Privilege::ChangeUserSettings, Access::getIdentity(Auth::getCurrentUser()))): ?> <?php if (Access::check(new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity(Auth::getCurrentUser())))): ?>
<li class="safety"> <li class="safety">
<ul> <ul>
<?php foreach (PostSafety::getAll() as $safety): ?> <?php foreach (PostSafety::getAll() as $safety): ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ListPosts, Privilege::ListPosts,
PostSafety::toString($safety))): ?> PostSafety::toString($safety)))): ?>
<li class="safety-<?= TextCaseConverter::convert( <li class="safety-<?= TextCaseConverter::convert(
PostSafety::toString($safety), PostSafety::toString($safety),

View file

@ -20,9 +20,9 @@
<hr> <hr>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ChangeUserName, Privilege::ChangeUserName,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<div class="form-row nickname"> <div class="form-row nickname">
<label for="name">Name:</label> <label for="name">Name:</label>
@ -37,9 +37,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ChangeUserEmail, Privilege::ChangeUserEmail,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<div class="form-row email"> <div class="form-row email">
<label for="name">E-mail:</label> <label for="name">E-mail:</label>
@ -54,9 +54,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if ( <?php if (Access::check(new Privilege(
Access::check(Privilege::ChangeUserPassword, Privilege::ChangeUserPassword,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<div class="form-row password1"> <div class="form-row password1">
<label for="password1">New password:</label> <label for="password1">New password:</label>
@ -82,9 +82,9 @@
</div> </div>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ChangeUserAccessRank, Privilege::ChangeUserAccessRank,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<div class="form-row access-rank"> <div class="form-row access-rank">
<label for="access-rank">Access rank:</label> <label for="access-rank">Access rank:</label>

View file

@ -9,7 +9,9 @@
<label>Safety:</label> <label>Safety:</label>
<div class="input-wrapper"> <div class="input-wrapper">
<?php foreach (PostSafety::getAll() as $safety): ?> <?php foreach (PostSafety::getAll() as $safety): ?>
<?php if (Access::check(Privilege::ListPosts, PostSafety::toString($safety))): ?> <?php if (Access::check(new Privilege(
Privilege::ListPosts,
PostSafety::toString($safety)))): ?>
<label> <label>
<?php <?php
$attrs = []; $attrs = [];

View file

@ -52,9 +52,9 @@ Assets::addStylesheet('user-view.css');
</span> </span>
</div> </div>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ViewUserEmail, Privilege::ViewUserEmail,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<div class="key-value email"> <div class="key-value email">
<span class="key">E-mail:</span> <span class="key">E-mail:</span>
@ -79,9 +79,9 @@ Assets::addStylesheet('user-view.css');
foreach (array_keys($userModificationPrivileges) as $privilege) foreach (array_keys($userModificationPrivileges) as $privilege)
{ {
if (Access::check( if (Access::check(new Privilege(
$privilege, $privilege,
Access::getIdentity($this->context->transport->user))) Access::getIdentity($this->context->transport->user))))
{ {
$userModificationPrivileges[$privilege] = true; $userModificationPrivileges[$privilege] = true;
} }
@ -102,7 +102,7 @@ Assets::addStylesheet('user-view.css');
]; ];
} }
if (Access::check(Privilege::AcceptUserRegistration) if (Access::check(new Privilege(Privilege::AcceptUserRegistration))
and !$this->context->transport->user->staffConfirmed and !$this->context->transport->user->staffConfirmed
and getConfig()->registration->staffActivation) and getConfig()->registration->staffActivation)
{ {
@ -116,9 +116,9 @@ Assets::addStylesheet('user-view.css');
]; ];
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::FlagUser, Privilege::FlagUser,
Access::getIdentity($this->context->transport->user))) Access::getIdentity($this->context->transport->user))))
{ {
if ($this->context->flagged) if ($this->context->flagged)
{ {
@ -143,9 +143,9 @@ Assets::addStylesheet('user-view.css');
} }
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::BanUser, Privilege::BanUser,
Access::getIdentity($this->context->transport->user))) Access::getIdentity($this->context->transport->user))))
{ {
if (!$this->context->transport->user->banned) if (!$this->context->transport->user->banned)
{ {
@ -173,9 +173,9 @@ Assets::addStylesheet('user-view.css');
} }
} }
if (Access::check( if (Access::check(new Privilege(
Privilege::DeleteUser, Privilege::DeleteUser,
Access::getIdentity($this->context->transport->user))) Access::getIdentity($this->context->transport->user))))
{ {
$options []= $options []=
[ [
@ -223,9 +223,9 @@ Assets::addStylesheet('user-view.css');
</a> </a>
</li> </li>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::ChangeUserSettings, Privilege::ChangeUserSettings,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<?php if ($this->context->transport->tab == 'settings'): ?> <?php if ($this->context->transport->tab == 'settings'): ?>
<li class="selected settings"> <li class="selected settings">
@ -256,9 +256,9 @@ Assets::addStylesheet('user-view.css');
</li> </li>
<?php endif ?> <?php endif ?>
<?php if (Access::check( <?php if (Access::check(new Privilege(
Privilege::DeleteUser, Privilege::DeleteUser,
Access::getIdentity($this->context->transport->user))): ?> Access::getIdentity($this->context->transport->user)))): ?>
<?php if ($this->context->transport->tab == 'delete'): ?> <?php if ($this->context->transport->tab == 'delete'): ?>
<li class="selected delete"> <li class="selected delete">
<?php else: ?> <?php else: ?>