Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions config/vanilla/bootstrap.before.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,185 @@ function updateRolePermissions($roleType, $roles) {
}
}
}

if (!function_exists('sortsDropDown')) {
/**
* Returns a sorting drop-down menu.
*
* @param string $baseUrl Target URL with no query string applied.
* @param array $filters A multidimensional array of rows with the following properties:
* ** 'name': Friendly name for the filter.
* ** 'param': URL parameter associated with the filter.
* ** 'value': A value for the URL parameter.
* @param string $extraClasses any extra classes you add to the drop down
* @param string|null $default The default label for when no filter is active. If `null`, the default label is "All".
* @param string|null $defaultURL URL override to return to the default, unfiltered state.
* @param string $label Text for the label to attach to the cont
* @return string
*/
function sortsDropDown($baseUrl, array $filters = [], $extraClasses = '', $default = null, $defaultUrl = null, $label = 'Sort') {
if ($default === null) {
$default = t('All');
}

$links = [];
$active = paramPreference(
'sort',
'CategorySort',
null,//'Vanilla.SaveCategorySortPreference',
null,
false
);
// Translate filters into links.
foreach ($filters as $filter) {
// Make sure we have the bare minimum: a label and a URL parameter.
if (!array_key_exists('name', $filter)) {
throw new InvalidArgumentException('Sort does not have a name field.');
}
if (!array_key_exists('param', $filter)) {
throw new InvalidArgumentException('Sort does not have a param field.');
}

// Prepare for consumption by linkDropDown.
$query = [$filter['param'] => $filter['value']];
if (array_key_exists('extra', $filter) && is_array($filter['extra'])) {
$query += $filter['extra'];
}
$url = url($baseUrl . '?' . http_build_query($query));
$link = [
'name' => $filter['name'],
'url' => $url
];

// If we don't already have an active link, and this parameter and value match, this is the active link.
if ($active === null && Gdn::request()->get($filter['param']) == $filter['value']) {
$active = $filter['value'];
$link['active'] = true;
} else if ($active == $filter['value']){
$link['active'] = true;
$active = $filter['value'];
}

// Queue up another filter link.
$links[] = $link;
}

// Add the default link to the top of the list.
array_unshift($links, [
'active' => $active === null,
'name' => $default,
'url' => $defaultUrl ?: $baseUrl
]);

// Generate the markup for the drop down menu.
$output = linkDropDown($links, 'selectBox-following ' . trim($extraClasses), t($label) . ': ');
return $output;
}
}

if (!function_exists('categorySorts')) {
/**
* Returns category sorting.
*
* @param string $extraClasses any extra classes you add to the drop down
* @return string
*/
function categorySorts($extraClasses = '') {
if (!Gdn::session()->isValid()) {
return;
}

$baseUrl = Gdn::request()->path();
$transientKey = Gdn::session()->transientKey();
$filters = [
[
'name' => t('New'),
'param' => 'sort',
'value' => 'new',
'extra' => ['TransientKey' => $transientKey, 'save' => 1]
],

[
'name' => t('Old'),
'param' => 'sort',
'value' => 'old',
'extra' => ['TransientKey' => $transientKey, 'save' => 1]
]
];

$defaultParams = ['TransientKey' => $transientKey];
if (Gdn::request()->get('sort')) {
$defaultParams['sort'] = Gdn::request()->get('sort');
}

if (!empty($defaultParams)) {
$defaultUrl = $baseUrl.'?'.http_build_query($defaultParams);
} else {
$defaultUrl = $baseUrl;
}

return sortsDropDown(
$baseUrl,
$filters,
$extraClasses,
t('All'),
$defaultUrl,
'Sort'
);
}
}

if (!function_exists('discussionSorts')) {
/**
* Returns discussions sorting.
*
* @param string $extraClasses any extra classes you add to the drop down
* @return string
*/
function discussionSorts($extraClasses = '') {
if (!Gdn::session()->isValid()) {
return;
}

$baseUrl = Gdn::request()->path();
$transientKey = Gdn::session()->transientKey();

$filters = [
[
'name' => t('New'),
'param' => 'sort',
'value' => 'new',
'extra' => ['TransientKey' => $transientKey, 'save' => 1]
],
[
'name' => t('Old'),
'param' => 'sort',
'value' => 'old',
'extra' => ['TransientKey' => $transientKey, 'save' => 1]
]
];


$defaultParams = ['save' => 1, 'TransientKey' => $transientKey];
if (Gdn::request()->get('sort')) {
$defaultParams['sort'] = Gdn::request()->get('sort');
}

if (!empty($defaultParams)) {
$defaultUrl = $baseUrl.'?'.http_build_query($defaultParams);
} else {
$defaultUrl = $baseUrl;
}

return sortsDropDown(
$baseUrl,
$filters,
$extraClasses,
t('All'),
$defaultUrl,
'Sort'
);
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class CategoriesController extends VanillaController {
/** @var bool Value indicating if the category-following filter should be displayed when rendering a view */
public $enableFollowingFilter = true;//false;

const SORT_LAST_POST = 'new';
const SORT_OLDEST_POST = 'old';

/**
* @var \Closure $categoriesCompatibilityCallback A backwards-compatible callback to get `$this->data('Categories')`.
Expand Down Expand Up @@ -273,6 +275,7 @@ public function index($categoryIdentifier = '', $page = '0') {
]);

$saveFollowing = Gdn::request()->get('save') && Gdn::session()->validateTransientKey(Gdn::request()->get('TransientKey', ''));

$followed = paramPreference(
'followed',
'FollowedCategories',
Expand All @@ -283,9 +286,23 @@ public function index($categoryIdentifier = '', $page = '0') {
} else {
$this->enableFollowingFilter = $followed = false;
}

$this->setData('EnableFollowingFilter', $this->enableFollowingFilter);
$this->setData('Followed', $followed);

$saveSorting =Gdn::request()->get('sort') && Gdn::request()->get('save') && Gdn::session()->validateTransientKey(Gdn::request()->get('TransientKey', ''));

$sort = paramPreference(
'sort',
'CategorySort',
null,//'Vanilla.SaveCategorySortPreference',
null,
$saveSorting
);

$this->log('index: sorts: after', ['$sort' => $sort, '$saveSorting'=>$saveSorting]);
$this->setData('CategorySort', $sort);

if ($categoryIdentifier == '') {
switch ($layout) {
case 'mixed':
Expand Down Expand Up @@ -585,6 +602,24 @@ public function all($Category = '', $displayAs = '') {
);
}

if($this->data('CategorySort')) {
if( $this->data('CategorySort') == self::SORT_OLDEST_POST) {
usort($categoryTree, function ($a, $b) {
return Gdn_Format::toTimestamp($a['LastDateInserted']) - Gdn_Format::toTimestamp($b['LastDateInserted']);
});

} else if( $this->data('CategorySort') == self::SORT_LAST_POST) {
usort($categoryTree, function ($a, $b) {
return Gdn_Format::toTimestamp($b['LastDateInserted']) - Gdn_Format::toTimestamp($a['LastDateInserted']);

});
}
} else {
usort($categoryTree, function ($a, $b) { // desc
return Gdn_Format::toTimestamp($b['LastDateInserted']) - Gdn_Format::toTimestamp($a['LastDateInserted']);
});
}

$this->setData('CategoryTree', $categoryTree);

// Add modules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class DiscussionModel extends Gdn_Model {
protected static $allowedSorts = [
'hot' => ['key' => 'hot', 'name' => 'Hot', 'orderBy' => ['DateLastComment' => 'desc']],
'top' => ['key' => 'top', 'name' => 'Top', 'orderBy' => ['Score' => 'desc', 'DateInserted' => 'desc']],
'new' => ['key' => 'new', 'name' => 'New', 'orderBy' => ['DateInserted' => 'desc']]
'new' => ['key' => 'new', 'name' => 'New', 'orderBy' => ['DateInserted' => 'desc']],
'old' => ['key' => 'old', 'name' => 'Old', 'orderBy' => ['DateInserted' => 'asc']]
];

/**
Expand Down
5 changes: 4 additions & 1 deletion vanilla/applications/vanilla/views/categories/all.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
echo wrap($description, 'div', ['class' => 'P PageDescription']);
}
$this->fireEvent('AfterPageTitle');
echo '<div class="PageControls Top">';
if ($this->data('EnableFollowingFilter')) {
echo '<div class="PageControls Top">'.categoryFilters().'</div>';
echo categoryFilters();
}
echo categorySorts();
echo '</div>';
$categories = $this->data('CategoryTree');
writeCategoryList($categories, 1);
49 changes: 49 additions & 0 deletions vanilla/applications/vanilla/views/categories/discussions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php if (!defined('APPLICATION')) exit();
echo '<h1 class="H HomepageTitle">'.$this->data('Title').'</h1>';
echo '<div class="PageControls Top">';
if ($this->data('EnableFollowingFilter')) {
echo categoryFilters();
}
echo categorySorts();
echo '</div>';

$ViewLocation = $this->fetchViewLocation('discussions', 'discussions');
?>
<div class="Categories">
<?php if ($this->CategoryData->numRows() > 0): ?>
<?php foreach ($this->CategoryData->result() as $Category) :
if ($Category->CategoryID <= 0)
continue;

$this->Category = $Category;
$this->DiscussionData = $this->CategoryDiscussionData[$Category->CategoryID];

if ($this->DiscussionData->numRows() > 0) : ?>

<div class="CategoryBox Category-<?php echo $Category->UrlCode; ?>">
<?php echo getOptions($Category); ?>
<h2 class="H"><?php
echo anchor(htmlspecialchars($Category->Name), categoryUrl($Category));
Gdn::controller()->EventArguments['Category'] = $Category;
Gdn::controller()->fireEvent('AfterCategoryTitle');
?></h2>

<ul class="DataList Discussions">
<?php include($this->fetchViewLocation('discussions', 'discussions')); ?>
</ul>

<?php if ($this->DiscussionData->numRows() == $this->DiscussionsPerCategory) : ?>
<div class="MorePager">
<?php echo anchor(t('More Discussions'), '/categories/'.$Category->UrlCode); ?>
</div>
<?php endif; ?>

</div>

<?php endif; ?>

<?php endforeach; ?>
<?php else: ?>
<div class="Empty"><?php echo t('No categories were found.'); ?></div>
<?php endif; ?>
</div>
5 changes: 4 additions & 1 deletion vanilla/applications/vanilla/views/categories/table.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
<?php
$this->fireEvent('AfterDescription');
$this->fireEvent('AfterPageTitle');
echo '<div class="PageControls Top">';
if ($this->data('EnableFollowingFilter')) {
echo '<div class="PageControls Top">'.categoryFilters().'</div>';
echo categoryFilters();
}
echo categorySorts();
echo '</div>';
$categories = $this->data('CategoryTree');
writeCategoryTable($categories);
?>
3 changes: 3 additions & 0 deletions vanilla/applications/vanilla/views/discussions/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
if ($this->data('EnableFollowingFilter')) {
echo discussionFilters();
}
if($this instanceof CategoriesController) {
echo discussionSorts();
}
$this->fireEvent('PageControls');
echo '</div>';

Expand Down