diff --git a/assets/pluginmarket.css b/assets/pluginmarket.css index 7860735a5aed0913af43ee669b33dbed10b084de..5489e70cc1ee823b135649b7d98a3c1f5f38712c 100644 --- a/assets/pluginmarket.css +++ b/assets/pluginmarket.css @@ -30,13 +30,10 @@ list-style-type: none; text-align: center; } + .plugins_shortview > article { display: inline-block; margin: 7px; - padding: 8px; - background-color: #3c454e; - box-shadow: 0px 0px 10px rgba(0,0,0,0.3); - color: white; width: 250px; height: 260px; max-width: 250px; @@ -44,24 +41,9 @@ overflow: hidden; } - -.plugins_shortview > article .headerimagedescription { - max-height: 250px; - overflow: hidden; -} -.plugins_shortview > article h1 { - margin: 0px; - border: none; - color: white; -} -.plugins_shortview > article h1 > a, .plugins_shortview > article > h1 > a:hover { - color: white; -} .plugins_shortview > article .image { margin: 4px; - margin-left: -4px; - margin-right: -4px; - width: calc(100% + 8px); + width: calc(100%-8px); height: 150px; background-position: center center; background-size: auto calc(100% - 6px); @@ -71,19 +53,11 @@ } .plugins_shortview > article .shortdescription { font-size: 0.9em; - color: #879199; height: 70px; /*max-height: 70px; */ overflow: hidden; margin-bottom: 0px; } -.plugins_shortview > article .tags a { - color: white; - opacity: 0.8; -} -.plugins_shortview > article .tags a:hover { - opacity: 1; -} .plugins_shortview.new > article { -webkit-animation: scaling 700ms ease-out; @@ -150,4 +124,40 @@ .starscore { white-space: nowrap; +} + +article.contentbox { + border-color: #D0D7E3; + border-style: solid; + border-width: 1px; + transition: all 300ms ease 0s; + position: relative; +} + +article.contentbox header { + width: 100%; + background-color: #E7EBF1; + color: #24437C; + font-size: 12pt; + font-weight: bold; + text-align: left; + line-height: 2em; +} + +article.contentbox h1 { + padding: 5px; + margin: 0px; + color: #28497C; + border-bottom: medium none; + font-size: medium; +} + +article.contentbox footer { + position: absolute; + bottom: 0px; + background-color: white; + width: 100%; + border-top-color: #D0D7E3; + border-top-style: solid; + border-top-width: 1px; } \ No newline at end of file diff --git a/assets/pluginmarket.js b/assets/pluginmarket.js new file mode 100644 index 0000000000000000000000000000000000000000..b7de11d3e87207b570ffcf2a3fb6b98c3c6ad218 --- /dev/null +++ b/assets/pluginmarket.js @@ -0,0 +1,3 @@ +$(document).ready(function() { + STUDIP.table($('#plugintable'), {sortable: true}); +}); \ No newline at end of file diff --git a/assets/studiptable.js b/assets/studiptable.js new file mode 100644 index 0000000000000000000000000000000000000000..eaad9e9c789b7fd14d1d868942dbace299518683 --- /dev/null +++ b/assets/studiptable.js @@ -0,0 +1,91 @@ +jQuery.fn.extend({ + studipTable: function (opt) { + return new STUDIP.table(this, opt); + } +}); + +STUDIP.table = function (element, opt) { + + this.maxSize = 25; + this.sortable = true; + + $.extend(this, opt); + this.element = element; + var self = this; + + // Find rows and cols + this.rows = element.find('tbody tr:not(:has(th))'); + this.cols = element.find('thead tr td'); + this.headers = element.find('th'); + + // Init pagination + if (false && this.rows.length > this.maxSize) { + this.pages = Math.ceil(this.rows.length / this.maxSize); + + this.pageination = $('<div>').addClass('tablepagination'); + for (var i = 0; i < this.pages; i++) { + this.pageination.append($('<a>').html(i + 1).prop('data-page', i + 1).click(function (e) { + e.preventDefault(); + self.page($(this).prop('data-page')); + })); + } + + element.append($('<tfoot>').append($('<tr>').append($('<td>').prop('colspan', this.cols.length).html(this.pageination)))); + this.page(1); + } + + // Init search fields + if (this.searchInput) { + $(this.searchInput).keyup(function (e) { + var keyword = $(self.searchInput).val(); + if (keyword.length > 1) { + self.rows.hide(); + self.rows.filter(':contains(' + keyword + ')').show(); + } else { + self.rows.show(); + } + }); + } + + // Apply sortable + if (this.sortable) { + this.headers.click(function (e) { + + var asc = true; + // Check if this is already sorted + if ($(this).attr('data-sort') === 'asc') { + asc = false; + self.headers.removeAttr('data-sort'); + $(this).attr('data-sort', 'desc'); + } else { + self.headers.removeAttr('data-sort'); + $(this).attr('data-sort', 'asc'); + } + + var sortType = $(this).attr('data-sort-type'); + + var headerIndex = $(this).index() + 1; + var body = self.rows.parent(); + self.rows.sort(function (a, b) { + var attr = $(a).find('td:nth-child(' + headerIndex + ')').attr('data-sort'); + if (typeof attr !== typeof undefined && attr !== false) { + return ($(a).find('td:nth-child(' + headerIndex + ')').attr('data-sort') > $(b).find('td:nth-child(' + headerIndex + ')').attr('data-sort')) === asc; + } + if (sortType === 'int') { + return (parseFloat('0' + $(a).find('td:nth-child(' + headerIndex + ')').html().trim()) > parseFloat('0' + $(b).find('td:nth-child(' + headerIndex + ')').html().trim())) === asc; + } + return ($(a).find('td:nth-child(' + headerIndex + ')').html() > $(b).find('td:nth-child(' + headerIndex + ')').html()) === asc; + }); + self.rows.detach().appendTo(body); + }); + } + +}; + +STUDIP.table.prototype.page = function (number) { + this.rows.show(); + var maxSize = this.maxSize; + this.rows.filter(function (index) { + return index < (number - 1) * maxSize || index >= number * maxSize; + }).hide(); +}; \ No newline at end of file diff --git a/classes/MarketPlugin.class.php b/classes/MarketPlugin.class.php index d102be4d274513cbe4ea05077eb93036e8a57d5e..5d0bd81ade36b7da3e58c48fc35cf0918126fd7b 100644 --- a/classes/MarketPlugin.class.php +++ b/classes/MarketPlugin.class.php @@ -119,6 +119,15 @@ class MarketPlugin extends SimpleORMap { $statement->execute(array($this->getId())); return $statement->fetchAll(PDO::FETCH_COLUMN, 0); } + + /** + * Returns sum of downloads + * + * @return int Number of downloads + */ + public function getDownloads() { + return DBManager::get()->fetchColumn('SELECT SUM(downloads) FROM pluginmarket_releases WHERE plugin_id = ?', array($this->id)); + } public function getRating() { $cache = StudipCacheFactory::getCache(); diff --git a/controllers/presenting.php b/controllers/presenting.php index a2b341b1ca059dcb4a990f94a2d65c3f2f7de349..b82e90694d924082689f63c69b4b1ca0d2b3b75b 100644 --- a/controllers/presenting.php +++ b/controllers/presenting.php @@ -17,6 +17,8 @@ class PresentingController extends PluginController { $config->store("last_pluginmarket_visit", $_SESSION['last_pluginmarket_visit']); } PageLayout::addStylesheet($this->plugin->getPluginURL()."/assets/pluginmarket.css"); + PageLayout::addScript($this->plugin->getPluginURL()."/assets/studiptable.js"); + PageLayout::addScript($this->plugin->getPluginURL()."/assets/pluginmarket.js"); $statement = DBManager::get()->prepare(" SELECT pluginmarket_tags.tag, COUNT(*) AS number @@ -31,7 +33,12 @@ class PresentingController extends PluginController { "); $statement->execute(); $this->tags = $statement->fetchAll(PDO::FETCH_ASSOC); - + + // Set view + $_SESSION['pluginmarket']['view'] = Request::get('view') ? : $_SESSION['pluginmarket']['view']; + if (!isset($_SESSION['pluginmarket']['view'])) { + $_SESSION['pluginmarket']['view'] = 'tiles'; + } // Sidebar $sidebar = Sidebar::Get(); @@ -49,6 +56,14 @@ class PresentingController extends PluginController { } $sidebar->addWidget($tagWidget); + // Create view widget + if ($action != 'details') { + $viewWidget = new ViewsWidget(); + $viewWidget->addLink(_('Kacheln'), URLHelper::getLink('', array('view' => 'tiles')))->setActive($_SESSION['pluginmarket']['view'] == 'tiles'); + $viewWidget->addLink(_('Liste'), URLHelper::getLink('', array('view' => 'list')))->setActive($_SESSION['pluginmarket']['view'] == 'list'); + $sidebar->addWidget($viewWidget); + } + } public function overview_action() { @@ -59,6 +74,8 @@ class PresentingController extends PluginController { } $this->plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY RAND() LIMIT 6"); + + $this->render_action('overview_'.$_SESSION['pluginmarket']['view']); } public function all_action() { @@ -98,6 +115,7 @@ class PresentingController extends PluginController { } else { $this->plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY name ASC"); } + $this->render_action('overview_'.$_SESSION['pluginmarket']['view']); } public function details_action($plugin_id) { diff --git a/views/presenting/_plugin_short.php b/views/presenting/_plugin_short.php index 1b4739de27fec9700aa08a087bf89e6c2c71db7b..ac3fa9139985a2b503113ca145b5f99376221574 100644 --- a/views/presenting/_plugin_short.php +++ b/views/presenting/_plugin_short.php @@ -1,19 +1,19 @@ -<article> - <div class="headerimagedescription"> - <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/".$marketplugin->getId()) ?>"> +<article class="contentbox"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/" . $marketplugin->getId()) ?>"> + <header> <h1><?= htmlReady($marketplugin['name']) ?></h1> - <div class="image" style="background-image: url(<?= $marketplugin->getLogoURL() ?>);"></div> - </a> - <p class="shortdescription"> - <?= htmlReady($marketplugin['short_description']) ?> - </p> - </div> + </header> + <div class="image" style="background-image: url(<?= $marketplugin->getLogoURL() ?>);"></div> + </a> + <p class="shortdescription"> + <?= htmlReady($marketplugin['short_description']) ?> + </p> <? $tags = $marketplugin->getTags() ?> <? if (count($tags)) : ?> - <div class="tags"> + <footer class="tags"> <? foreach ($tags as $tag) : ?> - <a href="<?= PluginEngine::getLink($plugin, array('tag' => $tag), "presenting/all") ?>"><?= Assets::img("icons/16/white/tag.svg", array('class' => "text-bottom")) ?> <?= htmlReady(ucwords($tag)) ?></a> + <a href="<?= PluginEngine::getLink($plugin, array('tag' => $tag), "presenting/all") ?>"><?= Assets::img("icons/16/blue/tag.svg", array('class' => "text-bottom")) ?> <?= htmlReady(ucwords($tag)) ?></a> <? endforeach ?> - </div> + </footer> <? endif ?> </article> \ No newline at end of file diff --git a/views/presenting/overview_list.php b/views/presenting/overview_list.php new file mode 100644 index 0000000000000000000000000000000000000000..733bda15d77f74445f52d6c5f61b6d20d8c6c789 --- /dev/null +++ b/views/presenting/overview_list.php @@ -0,0 +1,35 @@ +<table id="plugintable" class="default"> + <caption> + <?= _('Plugins') ?> + </caption> + <thead> + <tr> + <th> + <?= _('Name') ?> + </th> + <th data-sort-type="int"> + <?= _('Downloads') ?> + </th> + <th data-sort-type="int"> + <?= _('Bewertung') ?> + </th> + </tr> + </thead> + <tbody> + <? foreach ($plugins as $marketplugin): ?> + <tr> + <td data-sort="<?= htmlReady($marketplugin->name) ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/" . $marketplugin->getId()) ?>"> + <?= htmlReady($marketplugin->name) ?> + </a> + </td> + <td> + <?= htmlReady($marketplugin->getDownloads()) ?> + </td> + <td> + <?= htmlReady($marketplugin->getRating()) ?> + </td> + </tr> + <? endforeach; ?> + </tbody> +</table> \ No newline at end of file diff --git a/views/presenting/overview.php b/views/presenting/overview_tiles.php similarity index 100% rename from views/presenting/overview.php rename to views/presenting/overview_tiles.php