diff --git a/PluginMarket.class.php b/PluginMarket.class.php index fa1354a89425b8f9fcc9ead06357c3e687d81556..d027cd244de8800d7697440172ac155b9edf2b29 100755 --- a/PluginMarket.class.php +++ b/PluginMarket.class.php @@ -55,6 +55,7 @@ class PluginMarket extends StudIPPlugin implements SystemPlugin, HomepagePlugin public function initialize() { + PageLayout::addSqueezePackage('lightbox'); $this->addStylesheet('assets/pluginmarket.less'); PageLayout::addHeadElement('link', array( 'rel' => 'alternate', diff --git a/assets/pluginmarket.less b/assets/pluginmarket.less index d19d21d942bd691d2f869f4784fbaaa575831299..6316dc4ff8dba789a991bd40d394fb1b581585a0 100755 --- a/assets/pluginmarket.less +++ b/assets/pluginmarket.less @@ -10,7 +10,7 @@ .flex-justify-content(center); .flex-align-items(stretch); - > .image { + .image { padding: 5px; border: 5px solid #eeeeee; margin: 5px; diff --git a/assets/studiptable.js b/assets/studiptable.js index cb8c480286411351888c0bcb61320734c99d612b..51b5e2d88d7ffc9056889b0ce27ce6d7b5e249f5 100755 --- a/assets/studiptable.js +++ b/assets/studiptable.js @@ -82,6 +82,9 @@ STUDIP.table = function (element, opt) { } else if (sortType === 'int') { sort1 = parseFloat('0' + $(a).find('td:nth-child(' + headerIndex + ')').text().trim()); sort2 = parseFloat('0' + $(b).find('td:nth-child(' + headerIndex + ')').text().trim()); + } else if (sortType === 'sorter') { + sort1 = parseFloat('0' + $(a).find('td:nth-child(' + headerIndex + ')').data('sorter')); + sort2 = parseFloat('0' + $(b).find('td:nth-child(' + headerIndex + ')').data('sorter')); } else { sort1 = $(a).find('td:nth-child(' + headerIndex + ')').text().trim().toLowerCase(); sort2 = $(b).find('td:nth-child(' + headerIndex + ')').text().trim().toLowerCase(); diff --git a/classes/MarketPlugin.class.php b/classes/MarketPlugin.class.php index ac0fdfc0acdb0f06e2ea382bba366057534ce9f5..9a6960ae61d25d1ab6d9ca8f005edcf9826e1093 100755 --- a/classes/MarketPlugin.class.php +++ b/classes/MarketPlugin.class.php @@ -146,33 +146,20 @@ class MarketPlugin extends SimpleORMap { } public function calculateRating() { - $cache = StudipCacheFactory::getCache(); - $cache_key = 'pluginmarket_rating/'.$this->getId(); - $rating = $cache->read($cache_key); - - if ($rating === false) { - $latest_release_date = $this->releases[0]->mkdate; - $rating = 0; - $factors = 0; - foreach ($this->reviews as $review) { - $factor = (120 * 86400) / ($latest_release_date - $review['chdate']); - if ($factor < 0) { - $factor = 1; - } - if ($factor > 1) { - $factor = 1; - } - $rating += $review['rating'] * $factor * 2; - $factors += $factor; - } - if ($factors > 0) { - $rating /= $factors; - } else { - return $rating = null; - } - - $cache->write($cache_key, $rating, 60 * 5); + $rating = 0; + $factors = 0; + foreach ($this->reviews as $review) { + $age = time() - $review['chdate']; + $factor = (pi() - 2 * atan($age / (86400 * 180))) / pi(); + $rating += $review['rating'] * $factor * 2; + $factors += $factor; + } + if ($factors > 0) { + $rating /= $factors; + } else { + return $rating = null; } + return $rating; } } \ No newline at end of file diff --git a/controllers/presenting.php b/controllers/presenting.php index aeeb5bfe1a14f8d2e7f0adbe0c81b1b74f4cab22..6c8121df042d6eb038ac5fd2c8caa00983fb407a 100755 --- a/controllers/presenting.php +++ b/controllers/presenting.php @@ -88,8 +88,24 @@ class PresentingController extends MarketController } $this->plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY RAND() LIMIT 3"); - - $this->best_plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY rating DESC LIMIT 6"); + + $this->latest_plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY mkdate DESC LIMIT 5"); + + $best = DBManager::get()->prepare(" + SELECT pluginmarket_plugins.* + FROM pluginmarket_plugins + LEFT JOIN pluginmarket_reviews ON (pluginmarket_plugins.plugin_id = pluginmarket_reviews.plugin_id) + WHERE publiclyvisible = 1 + AND approved = 1 + GROUP BY pluginmarket_plugins.plugin_id + ORDER BY pluginmarket_plugins.rating DESC, MAX(pluginmarket_reviews.chdate) DESC + LIMIT 6 + "); + $best->execute(); + $this->best_plugins = array(); + foreach ($best->fetchAll(PDO::FETCH_ASSOC) as $data) { + $this->best_plugins[] = MarketPlugin::buildExisting($data); + } $this->render_action('overview_'.$_SESSION['pluginmarket']['view']); } @@ -102,6 +118,7 @@ class PresentingController extends MarketController OR (SELECT CONCAT(Vorname, ' ', Nachname) FROM auth_user_md5 WHERE user_id = pluginmarket_plugins.user_id LIMIT 1) LIKE :likesearch OR MATCH (short_description, description) AGAINST (:search IN BOOLEAN MODE) OR (SELECT GROUP_CONCAT(' ', tag) FROM pluginmarket_tags WHERE pluginmarket_tags.plugin_id = plugin_id GROUP BY pluginmarket_tags.plugin_id LIMIT 1) LIKE :likesearch + OR (SELECT 1 FROM pluginmarket_plugin_usages WHERE pluginmarket_plugins.plugin_id = pluginmarket_plugin_usages.plugin_id AND name LIKE :likesearch LIMIT 1) ) AND publiclyvisible = 1 AND approved = 1 diff --git a/plugin.manifest b/plugin.manifest index 5a73a83a0d1c756ac47864e7b1c691680041d3b8..01a4c73e6edfd25fda740945f5eb3a537aae179e 100755 --- a/plugin.manifest +++ b/plugin.manifest @@ -1,4 +1,4 @@ pluginname=PluginMarktplatz pluginclassname=PluginMarket origin=studip -version=1.0.12 +version=1.0.15 diff --git a/views/myplugins/_edit_images.php b/views/myplugins/_edit_images.php index 0394c8a211ea3c201efd9ff5965af3c1f903e032..1920a0a380607bb88dc58b86f99fb14a99f164fb 100755 --- a/views/myplugins/_edit_images.php +++ b/views/myplugins/_edit_images.php @@ -9,7 +9,9 @@ <li class="image"> <input type="checkbox" name="delete_image[]" value="<?= htmlReady($image->getId()) ?>" id="delete_image_<?= htmlReady($image->getId()) ?>"> <div> - <img src="<?= htmlReady($image->getURL()) ?>" style="max-height: 150px;"> + <a href="<?= htmlReady($image->getURL()) ?>" data-lightbox="plugin_gallery"> + <img src="<?= htmlReady($image->getURL()) ?>" style="max-height: 150px;"> + </a> <input type="hidden" name="image_order[]" value="<?= htmlReady($image->getId()) ?>"> <label for="delete_image_<?= htmlReady($image->getId()) ?>"> <?= Assets::img("icons/20/blue/trash", array('style' => "cursor: pointer;")) ?> diff --git a/views/presenting/details.php b/views/presenting/details.php index 2dbd3d6ff87f9ba57b92e55739c8ffcac3df8d7f..b5f5408f158749f93095532588a3159a624fdffe 100755 --- a/views/presenting/details.php +++ b/views/presenting/details.php @@ -16,20 +16,31 @@ if ($icon) { <h1><?= htmlReady($marketplugin['name']) ?></h1> <div> - <?= formatReady($marketplugin['description']) ?> + <?= htmlReady($marketplugin['short_description']) ?> </div> - +<?if ($marketplugin['description']) : ?> + <div> + <br> + <?= formatReady($marketplugin['description']) ?> + </div> +<? endif ?> <? if (count($marketplugin->images) > 0 || $marketplugin->isWritable()) : ?> <h2><?= _("Galerie") ?></h2> <ol id="pluginmarket_galery_view" class="pluginmarket_galery"> <? foreach ($marketplugin->images as $image) : ?> <div class="image"> - <img src="<?= htmlReady($image->getURL()) ?>"> + <a href="<?= htmlReady($image->getURL()) ?>" data-lightbox="plugin_gallery"> + <img src="<?= htmlReady($image->getURL()) ?>"> + </a> </div> <? endforeach ?> <? if ($marketplugin->isWritable()) : ?> - <div><a href="<?= $controller->url_for('myplugins/edit_images/' . $marketplugin->getId()) ?>" data-dialog title="<?= _("Galerie bearbeiten / neue Bilder hinzuf�gen") ?>"><?= Assets::img("icons/20/blue/add") ?></a></div> + <div> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit_images/". $marketplugin->getId()) ?>" data-dialog title="<?= _("Galerie bearbeiten / neue Bilder hinzuf�gen") ?>"> + <?= Assets::img("icons/20/blue/add") ?> + </a> + </div> <? endif ?> </ol> <? endif ?> @@ -38,12 +49,14 @@ if ($icon) { <ul class="plugin-usages"> <? foreach ($marketplugin['uses'] as $use): ?> <li> - <?= htmlReady($use->name) ?> + <a href="<?= PluginEngine::getLink($plugin, array('search' => htmlReady($use->name)), "presenting/all") ?>"> + <?= htmlReady($use->name) ?> + </a> <? if ($use->plugin->isWritable(User::findCurrent()->id)): ?> (<?= ObjectdisplayHelper::link($use->user) ?>) <? endif; ?> <? if ($use->isEditable()): ?> - <a href="<?= $controller->url_for('presenting/delete_usage/' . $use->id) ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/delete_usage/" . $use->id) ?>"> <?= Assets::img('icons/blue/trash.svg'); ?> </a> <? endif; ?> @@ -114,7 +127,7 @@ if ($icon) { <? foreach ($marketplugin->releases as $release) : ?> <tr> <td> - <a href="<?= $controller->url_for('presenting/download/' . $release->getId()) ?>" title="<?= _("Dieses Release runterladen") ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/download/". $release->getId()) ?>" title="<?= _("Dieses Release runterladen") ?>"> <?= Assets::img("icons/20/blue/download", array('class' => "text-bottom")) ?> <?= htmlReady($release['version']) ?> </a> @@ -126,15 +139,15 @@ if ($icon) { <td><?= htmlReady($release['downloads']) ?></td> <td class="actions"> <? if ($marketplugin->isWritable()) : ?> - <a href="<?= $controller->url_for('myplugins/edit_release/' . $release->getId()) ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit_release/" . $release->getId()) ?>" data-dialog> <?= Assets::img("icons/20/blue/edit", array('class' => "text-bottom")) ?> </a> - <a href="<?= $controller->url_for('presenting/delete_release/' . $release->getId()) ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/delete_release/" . $release->getId()) ?>"> <?= Assets::img("icons/20/blue/trash", array('class' => "text-bottom", 'onclick' => "return window.confirm('"._("Pluginrelease wirklich unwiderrufbar l�schen?")."');")) ?> </a> <? endif ?> <? if ($GLOBALS['perm']->have_perm("autor")) : ?> - <a href="<?= $controller->url_for('presenting/follow_release/' . $release->getId()) ?>" title="<?= _("F�r automatische Updates registrieren.") ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/follow_release/" . $release->getId()) ?>" title="<?= _("F�r automatische Updates registrieren.") ?>" data-dialog> <?= Assets::img("icons/20/blue/rss", array('class' => "text-bottom")) ?> </a> <? endif ?> @@ -146,7 +159,7 @@ if ($icon) { <tfoot> <tr> <td colspan="7"> - <a href="<?= $controller->url_for('myplugins/add_release/' . $marketplugin->getId()) ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/add_release/" . $marketplugin->getId()) ?>" data-dialog> <?= Assets::img("icons/20/blue/add") ?> </a> </td> @@ -234,15 +247,15 @@ if ($icon) { <a <?= ($GLOBALS['perm']->have_perm("autor") && !$marketplugin->isWritable()) ? 'href="' . $controller->url_for('presenting/review/' . $marketplugin->getId()) . '" data-dialog' : "" ?> title="<?= sprintf(_("%s von 5 Sternen"), round($marketplugin['rating'] / 2, 1)) ?>"> <? endif ?> <? $marketplugin['rating'] = round($marketplugin['rating'], 1) / 2 ?> - <? $v = $marketplugin['rating'] >= 1 ? 3 : ($marketplugin['rating'] >= 0.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 0.75 ? 3 : ($marketplugin['rating'] >= 0.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 2 ? 3 : ($marketplugin['rating'] >= 1.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 1.75 ? 3 : ($marketplugin['rating'] >= 1.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 3 ? 3 : ($marketplugin['rating'] >= 2.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 2.75 ? 3 : ($marketplugin['rating'] >= 2.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 4 ? 3 : ($marketplugin['rating'] >= 3.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 3.75 ? 3 : ($marketplugin['rating'] >= 3.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] > 4.5 ? 3 : ($marketplugin['rating'] >= 4.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 4.75 ? 3 : ($marketplugin['rating'] >= 4.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> <? if (!$marketplugin->isWritable()) : ?> </a> @@ -282,11 +295,11 @@ if ($icon) { <div style="text-align: center"> <? if ($marketplugin->isWritable()) : ?> - <?= \Studip\LinkButton::create(_("bearbeiten"), $controller->url_for('myplugins/edit/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> - <?= \Studip\LinkButton::create(_("Release hinzuf�gen"), $controller->url_for('myplugins/add_release/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> + <?= \Studip\LinkButton::create(_("bearbeiten"), PluginEngine::getURL($plugin, array(), "myplugins/edit/" . $marketplugin->getId()), array('data-dialog' => 1)) ?> + <?= \Studip\LinkButton::create(_("Release hinzuf�gen"), PluginEngine::getURL($plugin, array(), "myplugins/add_release/" . $marketplugin->getId()), array('data-dialog' => 1)) ?> <? endif ?> <? if ($marketplugin['user_id'] !== $GLOBALS['user']->id) : ?> - <?= \Studip\LinkButton::create(_("Plugin abonnieren"), $controller->url_for('presenting/register_for_pluginnews/' . $marketplugin->getId()), array('title' => _("Neuigkeiten des Plugins per Nachricht bekommen."), 'data-dialog' => "1")) ?> + <?= \Studip\LinkButton::create(_("Plugin abonnieren"), PluginEngine::getURL($plugin, array(), "presenting/register_for_pluginnews/" . $marketplugin->getId()), array('title' => _("Neuigkeiten des Plugins per Nachricht bekommen."), 'data-dialog' => "1")) ?> <? endif ?> <? if ($marketplugin->isRootable()) : ?> <form action="?" method="post" style="display: inline-block; margin: 0px;"> diff --git a/views/presenting/overview_list.php b/views/presenting/overview_list.php index 7f9b69f6d98229e0fb29fe26d7953e7d4aa43445..6287307741be273b81bf4a1976ed41d0a26e828c 100755 --- a/views/presenting/overview_list.php +++ b/views/presenting/overview_list.php @@ -10,6 +10,9 @@ <th data-sort-type="int"> <?= _('Standorte') ?> </th> + <th data-sort-type="sorter"> + <?= _('Letzte �nderung') ?> + </th> <th data-sort-type="int"> <?= _('Downloads') ?> </th> @@ -29,6 +32,9 @@ <td> <?= htmlReady($marketplugin->uses->count()) ?> </td> + <td data-sorter="<?= $marketplugin->releases->orderBy('chdate DESC')->val('mkdate') ?>"> + <?= strftime('%x', $marketplugin->releases->orderBy('chdate DESC')->val('mkdate')) ?> + </td> <td> <?= htmlReady($marketplugin->getDownloads()) ?> </td> diff --git a/views/presenting/overview_tiles.php b/views/presenting/overview_tiles.php index 5fec0875bdee6ab8baf5db7f26984b763500c65d..175e15e94bbd8cf69819143de0dca1f4a3681eef 100755 --- a/views/presenting/overview_tiles.php +++ b/views/presenting/overview_tiles.php @@ -1,5 +1,5 @@ <? if ($show_all) : ?> - <h2><?=count($plugins)?> <?= _('Plugins') ?></h2> + <h2><?= count($plugins) ?> <?= _('Plugins') ?></h2> <div class="plugins_shortview"> <? foreach ($plugins as $marketplugin) : ?> <?= $this->render_partial("presenting/_plugin_short.php", compact("marketplugin", "plugin")) ?> @@ -15,6 +15,13 @@ </div> <? endif ?> + <h2><?= _("Neueste Plugins") ?></h2> + <div class="plugins_shortview"> + <? foreach ($latest_plugins as $marketplugin) : ?> + <?= $this->render_partial("presenting/_plugin_short.php", compact("marketplugin", "plugin")) ?> + <? endforeach ?> + </div> + <h2><?= _("Zuf�llige Plugins") ?></h2> <div class="plugins_shortview"> <? foreach ($plugins as $marketplugin) : ?> diff --git a/views/tools/sidebar_graphics_generator.php b/views/tools/sidebar_graphics_generator.php index 48093cdc339c929e9e205c6c24f4a58ab415e579..b9514828af773704b5f8560d557d2488f5d53a98 100755 --- a/views/tools/sidebar_graphics_generator.php +++ b/views/tools/sidebar_graphics_generator.php @@ -1,4 +1,4 @@ -<h2><?= _("Erstellen von Siderbar-Grafiken") ?></h2> +<h2><?= _("Erstellen von Sidebar-Grafiken") ?></h2> <table> <tbody> @@ -7,7 +7,7 @@ <td><input type="color" id="color" value="#24437c" onChange="STUDIP.SidebarGraphicsGenerator.drawImage();"></td> </tr> <tr> - <td><label for="localicon"><?= _("Bilddatei (SVG, quadratisch, wei�)") ?></label></td> + <td><label for="localicon"><?= _("Bilddatei (SVG, quadratisch, weiß)") ?></label></td> <td><input type="file" id="localicon" onChange="STUDIP.SidebarGraphicsGenerator.setFile(this); return false;"></td> </tr> <tr style="display: none;"> @@ -31,4 +31,4 @@ <?= Assets::img("icons/16/blue/download") ?> <?= _("Speichern unter ...") ?> </a> -</div> \ No newline at end of file +</div>