From 7adb49837e3644e7f278638f994792c819ab5809 Mon Sep 17 00:00:00 2001 From: Rasmus Fuhse <fuhse@data-quest.de> Date: Mon, 15 Sep 2014 18:05:43 +0200 Subject: [PATCH] add images --- classes/MarketImage.class.php | 39 ++++++++++++++ classes/MarketPlugin.class.php | 20 +++++++ classes/MarketRelease.class.php | 5 ++ controllers/myplugins.php | 89 ++++++++++++++++++++++++++------ controllers/presenting.php | 6 +++ install.sql | 8 +++ views/myplugins/_edit_images.php | 37 +++++++++++++ views/myplugins/edit.php | 4 ++ views/myplugins/edit_images.php | 8 +++ views/myplugins/overview.php | 6 ++- views/presenting/details.php | 24 +++++++-- views/presenting/overview.php | 4 +- 12 files changed, 229 insertions(+), 21 deletions(-) create mode 100644 views/myplugins/_edit_images.php create mode 100644 views/myplugins/edit_images.php diff --git a/classes/MarketImage.class.php b/classes/MarketImage.class.php index a288955..e2ae574 100644 --- a/classes/MarketImage.class.php +++ b/classes/MarketImage.class.php @@ -1,6 +1,15 @@ <?php class MarketImage extends SimpleORMap { + + static public function findByPlugin_id($plugin_id) { + return self::findBySQL("plugin_id = ? ORDER BY position ASC, mkdate ASC", array($plugin_id)); + } + + static public function getImageDataPath() { + return $GLOBALS['STUDIP_BASE_PATH'] . "/data/pluginmarket_images"; + } + protected static function configure($config = array()) { $config['db_table'] = 'pluginmarket_images'; @@ -10,4 +19,34 @@ class MarketImage extends SimpleORMap { ); parent::configure($config); } + + public function getURL() { + return URLHelper::getURL("plugins.php/pluginmarket/presenting/image/".$this->getId(), array(), true); + } + + public function delete() { + parent::delete(); + unlink($this->getFilePath()); + } + + public function installFromPath($path) { + copy($path, $this->getFilePath()); + } + + protected function getFilePath() { + if (!file_exists(self::getImageDataPath())) { + mkdir(self::getImageDataPath()); + } + if (!$this->getId()) { + $this->setId($this->getNewId()); + } + return self::getImageDataPath()."/".$this->getId(); + } + + public function outputImage() { + $path = self::getImageDataPath()."/".$this->getId(); + header("Content-Type: ".$this['mimetype']); + header("Content-Disposition: inline; filename=".$this['filename']); + echo file_get_contents($path); + } } \ No newline at end of file diff --git a/classes/MarketPlugin.class.php b/classes/MarketPlugin.class.php index addb205..41e6d42 100644 --- a/classes/MarketPlugin.class.php +++ b/classes/MarketPlugin.class.php @@ -9,10 +9,30 @@ class MarketPlugin extends SimpleORMap { 'on_delete' => 'delete', 'on_store' => 'store', ); + $config['has_many']['images'] = array( + 'class_name' => 'MarketImage', + 'on_delete' => 'delete', + 'on_store' => 'store', + ); $config['belongs_to']['user'] = array( 'class_name' => 'User', 'foreign_key' => 'user_id', ); parent::configure($config); } + + public function isWritable($user_id = null) { + $user_id || $user_id = $GLOBALS['user']->id; + return $this['user_id'] === $user_id; + } + + public function isRootable($user_id = null) { + $user_id || $user_id = $GLOBALS['user']->id; + return $GLOBALS['perm']->have_perm("root", $user_id); + } + + public function getLogoURL() { + $firstimage = $this->images->first(); + return $firstimage ? $firstimage->getURL() : null; + } } \ No newline at end of file diff --git a/classes/MarketRelease.class.php b/classes/MarketRelease.class.php index 2468442..917499f 100644 --- a/classes/MarketRelease.class.php +++ b/classes/MarketRelease.class.php @@ -22,6 +22,11 @@ class MarketRelease extends SimpleORMap { parent::configure($config); } + public function delete() { + parent::delete(); + unlink($this->getFilePath()); + } + public function installFile() { $hash = md5(uniqid()); $tmp_folder = $GLOBALS['TMP_PATH']."/temp_plugin_".$hash; diff --git a/controllers/myplugins.php b/controllers/myplugins.php index 1ced4c3..503088c 100644 --- a/controllers/myplugins.php +++ b/controllers/myplugins.php @@ -32,6 +32,16 @@ class MypluginsController extends PluginController { } } + public function add_release_action($plugin_id) { + $this->marketplugin = new MarketPlugin($plugin_id); + $this->release = new MarketRelease(); + if (Request::isXhr()) { + $this->response->add_header('X-Title', _("Release hinzuf�gen")); + $this->set_layout(null); + } + $this->render_action("edit_release"); + } + public function edit_release_action($release_id) { $this->release = new MarketRelease($release_id); if (Request::isXhr()) { @@ -40,28 +50,77 @@ class MypluginsController extends PluginController { } } + public function edit_images_action($plugin_id) { + $this->marketplugin = new MarketPlugin($plugin_id); + if (Request::isXhr()) { + $this->response->add_header('X-Title', _("Galerie bearbeiten")); + $this->set_layout(null); + } + } + public function save_action() { if (!Request::isPost()) { throw new Exception("Method not allowed. Try a POST request."); } - $data = Request::getArray("data"); - if (!isset($data["publiclyvisible"])) { - $data['publiclyvisible'] = 0; - } $this->marketplugin = new MarketPlugin(Request::option("id") ?: null); - $this->marketplugin->setData($data); - if ($this->marketplugin->isNew()) { - $this->marketplugin['user_id'] = $GLOBALS['user']->id; + if (!$this->marketplugin->isNew() && !$this->marketplugin->isWritable()) { + throw new AccessDeniedException("Kein Zugriff"); + } + + if (Request::submitted("data")) { + $data = Request::getArray("data"); + if (!isset($data["publiclyvisible"])) { + $data['publiclyvisible'] = 0; + } + $this->marketplugin->setData($data); + if ($this->marketplugin->isNew()) { + $this->marketplugin['user_id'] = $GLOBALS['user']->id; + } } + $this->marketplugin->store(); - $release_data = Request::getArray("release"); - if ($release_data['type'] !== "zipfile" || $_FILES['release_file']['tmp_path']) { - $release = new MarketRelease(); - $release->setData($release_data); - $release['plugin_id'] = $this->marketplugin->getId(); - $release['user_id'] = $GLOBALS['user']->id; - $release->installFile(); - $release->store(); + + if (Request::submitted("image_order")) { + $order = array_flip(Request::getArray("image_order")); + foreach ($this->marketplugin->images as $image) { + $image['position'] = $order[$image->getId()] + 1; + $image->store(); + } + } + + if (Request::submitted("delete_image")) { + foreach (Request::getArray("delete_image") as $image_id) { + MarketImage::find($image_id)->delete(); + } + } + + if (Request::submitted("edit_images")) { + $files = $_FILES['new_images']; + $position = count($this->marketplugin->images); + foreach ($files['name'] as $index => $name) { + if ($files['size'][$index]) { + $position++; + $file = new MarketImage(); + $file['plugin_id'] = $this->marketplugin->getId(); + $file['filename'] = $name; + $file['mimetype'] = $files['type'][$index]; + $file['position'] = $position; + $file->installFromPath($files['tmp_name'][$index]); + $file->store(); + } + } + } + + if (Request::submitted("release")) { + $release_data = Request::getArray("release"); + if ($release_data['type'] !== "zipfile" || $_FILES['release_file']['tmp_path']) { + $release = new MarketRelease(); + $release->setData($release_data); + $release['plugin_id'] = $this->marketplugin->getId(); + $release['user_id'] = $GLOBALS['user']->id; + $release->installFile(); + $release->store(); + } } PageLayout::postMessage(MessageBox::success(_("Plugin wurde gespeichert."))); $this->redirect("pluginmarket/presenting/details/".$this->marketplugin->getId()); diff --git a/controllers/presenting.php b/controllers/presenting.php index 4740373..3b15256 100644 --- a/controllers/presenting.php +++ b/controllers/presenting.php @@ -37,4 +37,10 @@ class PresentingController extends PluginController { $this->render_nothing(); } + public function image_action($image_id) { + $this->image = new MarketImage($image_id); + $this->image->outputImage(); + $this->render_nothing(); + } + } \ No newline at end of file diff --git a/install.sql b/install.sql index f706c11..eafc817 100644 --- a/install.sql +++ b/install.sql @@ -61,3 +61,11 @@ CREATE TABLE IF NOT EXISTS `pluginmarket_tags` ( KEY `plugin_id` (`plugin_id`) ) ENGINE=MyISAM; +CREATE TABLE IF NOT EXISTS `pluginmarket_rezension` ( + `rezension_id` varchar(32) NOT NULL, + `rezension_txt` text NOT NULL, + `user_id` varchar(32) NOT NULL, + `mkdate` int(20) NOT NULL, + `plugin_id` varchar(32) NOT NULL, + KEY `plugin_id` (`plugin_id`) +) ENGINE=MyISAM; \ No newline at end of file diff --git a/views/myplugins/_edit_images.php b/views/myplugins/_edit_images.php new file mode 100644 index 0000000..3e4d88f --- /dev/null +++ b/views/myplugins/_edit_images.php @@ -0,0 +1,37 @@ +<fieldset> + <input type="hidden" name="edit_images" value="1"> + <legend> + <?= _("Galerie") ?> + </legend> + + <ol id="galery_edit"> + <? foreach ($marketplugin->images as $image) : ?> + <li> + <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: 200px;"> + <input type="hidden" name="image_order[]" value="<?= htmlReady($image->getId()) ?>"> + <label for="delete_image_<?= htmlReady($image->getId()) ?>"> + <?= Assets::img("icons/20/blue/delete") ?> + </label> + </div> + </li> + <? endforeach ?> + </ol> + <script> + jQuery(function() { + jQuery("#galery_edit").sortable(); + }); + </script> + + <div id="new_image_container"> + <div> + <label> + <?= Assets::img("icons/20/blue/upload", array('class' => "text-bottom", 'style' => "cursor: pointer;")) ?> + <input type="file" name="new_images[]"> + </label> + <a href="#" onClick="if (jQuery('#new_image_container > div').length > 1) jQuery(this).closest('div').remove(); else jQuery(this).closest('div').find('input[type=file]').val(''); return false;"><?= Assets::img("icons/20/blue/trash") ?></a> + </div> + </div> + <?= \Studip\LinkButton::create(_("Weiteres Bild"), "#", array('onClick' => "jQuery('#new_image_container > div').first().clone().appendTo('#new_image_container').find('input[type=file]').val(''); return false;")) ?> +</fieldset> \ No newline at end of file diff --git a/views/myplugins/edit.php b/views/myplugins/edit.php index b9ad3de..f50f05b 100644 --- a/views/myplugins/edit.php +++ b/views/myplugins/edit.php @@ -42,7 +42,11 @@ </div> </fieldset> + <?= $this->render_partial("myplugins/_edit_images.php", compact("marketplugin")) ?> + + <? if ($marketplugin->isNew()) : ?> <?= $this->render_partial("myplugins/_edit_release.php", array('release' => new MarketRelease())) ?> + <? endif ?> <div data-dialog-button> <?= \Studip\Button::create(_("speichern")) ?> diff --git a/views/myplugins/edit_images.php b/views/myplugins/edit_images.php new file mode 100644 index 0000000..bad18cd --- /dev/null +++ b/views/myplugins/edit_images.php @@ -0,0 +1,8 @@ +<form action="<?= PluginEngine::getLink($plugin, array(), "myplugins/save") ?>" method="post" enctype="multipart/form-data" class="studip_form"> + <input type="hidden" name="id" value="<?= $marketplugin->getId() ?>"> + <?= $this->render_partial("myplugins/_edit_images.php", compact("marketplugin")) ?> + + <div data-dialog-button> + <?= \Studip\Button::create(_("speichern")) ?> + </div> +</form> \ No newline at end of file diff --git a/views/myplugins/overview.php b/views/myplugins/overview.php index ce4c8b4..b45dc4d 100644 --- a/views/myplugins/overview.php +++ b/views/myplugins/overview.php @@ -13,6 +13,9 @@ <? foreach ($plugins as $marketplugin) : ?> <tr> <td> + <? if ($marketplugin['publiclyvisible'] && !$marketplugin['approved']) : ?> + <?= Assets::img("icons/20/red/exclaim-circle", array('title' => _("Plugin wurde noch nicht von einem Administrator freigeschaltet."), 'class' => "text-bottom")) ?> + <? endif ?> <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/".$marketplugin->getId()) ?>"> <?= htmlReady($marketplugin['name']) ?> </a> @@ -32,7 +35,8 @@ <? endif ?> </td> <td> - <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit/".$marketplugin->getId()) ?>" data-dialog><?= Assets::img("icons/20/blue/edit") ?></a> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit/".$marketplugin->getId()) ?>" data-dialog title="<?= _("Plugin-Info bearbeiten") ?>"><?= Assets::img("icons/20/blue/edit") ?></a> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/add_release/".$marketplugin->getId()) ?>" data-dialog title="<?= _("Neues Release hinzuf�gen") ?>"><?= Assets::img("icons/20/blue/add") ?></a> </td> </tr> <? endforeach ?> diff --git a/views/presenting/details.php b/views/presenting/details.php index ae365ab..47e8888 100644 --- a/views/presenting/details.php +++ b/views/presenting/details.php @@ -1,3 +1,15 @@ +<? +//OpenGraph attributes +PageLayout::addHeadElement("meta", array('property' => "og:site_name", 'content' => _("Stud.IP Plugin-Marktplatz"))); +PageLayout::addHeadElement("meta", array('property' => "og:type", 'content' => "article")); +PageLayout::addHeadElement("meta", array('property' => "og:title", 'content' => $marketplugin['name'])); +PageLayout::addHeadElement("meta", array('property' => "og:description", 'content' => $marketplugin['short_description'])); +$icon = $marketplugin->images->first(); +if ($icon) { + PageLayout::addHeadElement("meta", array('property' => "og:image", 'content' => $icon->getURL())); +} +?> + <? if (!$marketplugin['publiclyvisible']) : ?> <?= PageLayout::postMessage(MessageBox::info(_("Dieses Plugin ist nicht �ffentlich."))) ?> <? endif ?> @@ -10,8 +22,13 @@ <h2><?= _("Galerie") ?></h2> <div> - <? if ($marketplugin['user_id'] === $GLOBALS['user']->id) : ?> - <div><a href=""><?= Assets::img("icons/20/blue/add") ?></a></div> + <? foreach ($marketplugin->images as $image) : ?> + <div> + <img src="<?= htmlReady($image->getURL()) ?>" style="max-height: 150px;"> + </div> + <? endforeach ?> + <? if ($marketplugin->isWritable()) : ?> + <div><a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit_images/".$marketplugin->getId()) ?>" data-dialog><?= Assets::img("icons/20/blue/add") ?></a></div> <? endif ?> </div> @@ -97,8 +114,9 @@ $bitcoin_datafield = $author['datafields']->findBy("name", "Bitcoin-Wallet")->va -<? if ($marketplugin['user_id'] === $GLOBALS['user']->id) : ?> +<? if ($marketplugin->isWritable()) : ?> <div style="text-align: center"> <?= \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)) ?> </div> <? endif ?> \ No newline at end of file diff --git a/views/presenting/overview.php b/views/presenting/overview.php index 6cb20e0..4cd6523 100644 --- a/views/presenting/overview.php +++ b/views/presenting/overview.php @@ -99,7 +99,7 @@ <? foreach ($new_plugins as $marketplugin) : ?> <article> <h1><a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/".$marketplugin->getId()) ?>"><?= htmlReady($marketplugin['name']) ?></a></h1> - <div class="image" style="background-image: url(http://plugins.studip.de/content/screenshots/a1d85f695cfe506241d398d272ae43f0_thumb);"></div> + <div class="image" style="background-image: url(<?= $marketplugin->getLogoURL() ?>);"></div> <p class="shortdescription"> <?= htmlReady($marketplugin['short_description']) ?> </p> @@ -113,7 +113,7 @@ <? foreach ($plugins as $marketplugin) : ?> <article> <h1><a href="<?= PluginEngine::getLink($plugin, array(), "presenting/details/".$marketplugin->getId()) ?>"><?= htmlReady($marketplugin['name']) ?></a></h1> - <div class="image" style="background-image: url(http://plugins.studip.de/content/screenshots/a1d85f695cfe506241d398d272ae43f0_thumb);"></div> + <div class="image" style="background-image: url(<?= $marketplugin->getLogoURL() ?>);"></div> <p class="shortdescription"> <?= htmlReady($marketplugin['short_description']) ?> </p> -- GitLab