From 80d2d2d346126bc130c922b4b833aee6fd8c538e Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Mon, 27 Jun 2016 15:53:41 +0200
Subject: [PATCH] OO-2057: publish pages, import v 1.0 artefacts in media
 center

---
 .../EfficiencyStatementMediaHandler.java      | 13 ++++++
 .../PortfolioResultDetailsController.java     |  2 +-
 .../fo/portfolio/ForumMediaHandler.java       | 33 +++++++++++++-
 .../portfolio/BinderSecurityCallback.java     |  2 +
 .../BinderSecurityCallbackFactory.java        | 30 +++++++------
 .../olat/modules/portfolio/MediaHandler.java  |  3 ++
 .../modules/portfolio/MediaInformations.java  | 19 ++++++++
 .../modules/portfolio/PortfolioService.java   |  7 +++
 .../portfolio/handler/FileHandler.java        | 34 ++++++++++++++
 .../portfolio/handler/ImageHandler.java       |  6 +++
 .../portfolio/handler/TextHandler.java        | 13 ++++++
 .../manager/PortfolioServiceImpl.java         |  7 +++
 .../ui/AbstractPageListController.java        | 12 ++---
 .../portfolio/ui/MediaCenterController.java   | 45 ++++++++++++++++++-
 .../modules/portfolio/ui/PageController.java  | 25 ++++++++++-
 .../portfolio/ui/SharedItemsController.java   |  2 +-
 .../portfolio/ui/_content/page_content.html   | 10 ++++-
 .../ui/_i18n/LocalStrings_de.properties       |  4 ++
 .../ui/_i18n/LocalStrings_en.properties       |  4 ++
 .../portfolio/BlogEntryMediaHandler.java      | 28 ++++++++++++
 .../wiki/portfolio/WikiMediaHandler.java      | 13 ++++++
 21 files changed, 286 insertions(+), 26 deletions(-)

diff --git a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
index 0b5f66309b5..41db03b92d1 100644
--- a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
+++ b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
@@ -36,6 +36,7 @@ import org.olat.modules.portfolio.MediaInformations;
 import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.handler.AbstractMediaHandler;
 import org.olat.modules.portfolio.manager.MediaDAO;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -92,6 +93,18 @@ public class EfficiencyStatementMediaHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		String title = artefact.getTitle();
+		String description = artefact.getDescription();
+		String xml = artefact.getFulltextContent();
+		String businessPath = artefact.getBusinessPath();
+		if(businessPath == null) {
+			businessPath = "[PortfolioV2:0][MediaCenter:0]";
+		}
+		return mediaDao.createMedia(title, description, xml, EFF_MEDIA, businessPath, artefact.getSignature(), artefact.getAuthor());
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		String statementXml = media.getContent();
diff --git a/src/main/java/org/olat/course/nodes/portfolio/PortfolioResultDetailsController.java b/src/main/java/org/olat/course/nodes/portfolio/PortfolioResultDetailsController.java
index 224f993c498..fdac55cff0b 100644
--- a/src/main/java/org/olat/course/nodes/portfolio/PortfolioResultDetailsController.java
+++ b/src/main/java/org/olat/course/nodes/portfolio/PortfolioResultDetailsController.java
@@ -292,7 +292,7 @@ public class PortfolioResultDetailsController extends FormBasicController {
 	private void doOpenMap(UserRequest ureq, Binder binder) {
 		if(stackPanel instanceof TooledStackedPanel) {
 			List<AccessRights> rights = portfolioService.getAccessRights(binder, getIdentity());
-			BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForCoach(binder, rights);
+			BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForCoach(rights);
 			BinderConfiguration config = BinderConfiguration.createConfig(binder);
 			BinderController binderCtrl = new BinderController(ureq, getWindowControl(), (TooledStackedPanel)stackPanel, secCallback, binder, config);
 			String displayName = StringHelper.escapeHtml(binder.getTitle());
diff --git a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
index 544ca727d59..1d69c5af0ac 100644
--- a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
+++ b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
@@ -20,6 +20,7 @@
 package org.olat.modules.fo.portfolio;
 
 import java.io.File;
+import java.util.List;
 
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
@@ -28,7 +29,11 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.resource.OresHelper;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.core.util.vfs.VFSManager;
+import org.olat.core.util.vfs.restapi.SystemItemFilter;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.Message;
 import org.olat.modules.fo.MessageLight;
@@ -39,6 +44,8 @@ import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.handler.AbstractMediaHandler;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.manager.PortfolioFileStorage;
+import org.olat.portfolio.manager.EPFrontendManager;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -59,6 +66,8 @@ public class ForumMediaHandler extends AbstractMediaHandler {
 	private ForumManager forumManager;
 	@Autowired
 	private PortfolioFileStorage fileStorage;
+	@Autowired
+	private EPFrontendManager oldPortfolioManager;
 	
 	public ForumMediaHandler() {
 		super(FORUM_HANDLER);
@@ -113,10 +122,32 @@ public class ForumMediaHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		VFSContainer artefactFolder = oldPortfolioManager.getArtefactContainer(artefact);
+
+		String businessPath = artefact.getBusinessPath();
+		if(businessPath == null) {
+			businessPath = "[PortfolioV2:0][MediaCenter:0]";
+		}
+		Media media = mediaDao.createMedia(artefact.getTitle(), artefact.getDescription(), null, FORUM_HANDLER,
+				businessPath, artefact.getSignature(), artefact.getAuthor());
+		
+		List<VFSItem> items = artefactFolder.getItems(new SystemItemFilter());
+		if(items.size() > 0) {
+			File mediaDir = fileStorage.generateMediaSubDirectory(media);
+			String storagePath = fileStorage.getRelativePath(mediaDir);
+			mediaDao.updateStoragePath(media, storagePath, null);
+			VFSContainer mediaContainer = fileStorage.getMediaContainer(media);
+			VFSManager.copyContent(artefactFolder, mediaContainer);
+		}
+		
+		return media;
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new ForumMessageMediaController(ureq, wControl, media);
 	}
 	
-	
 }
diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
index f584616ebd3..d19e61012b5 100644
--- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
+++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
@@ -49,6 +49,8 @@ public interface BinderSecurityCallback {
 	
 	public boolean canEditPage(Page page);
 	
+	public boolean canPublish(Page page);
+	
 	public boolean canEditAccessRights(PortfolioElement element);
 	
 	public boolean canViewElement(PortfolioElement element);
diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
index d941e5cdd6f..ce634545d5e 100644
--- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
+++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
@@ -34,23 +34,23 @@ import org.olat.repository.model.RepositoryEntrySecurity;
 public class BinderSecurityCallbackFactory {
 	
 	public static final BinderSecurityCallback getCallbackForOwnedBinder(Binder binder) {
-		return new BinderSecurityCallbackImpl(true, binder.getTemplate() != null, binder.getEntry() != null);
+		return new BinderSecurityCallbackImpl(true, binder.getTemplate() != null);
 	}
 	
 	public static final BinderSecurityCallback getCallbackForMyPageList() {
-		return new BinderSecurityCallbackImpl(true, false, false);
+		return new BinderSecurityCallbackImpl(true, false);
 	}
 	
 	public static final BinderSecurityCallback getReadOnlyCallback() {
-		return new BinderSecurityCallbackImpl(false, false, false);
+		return new BinderSecurityCallbackImpl(false, false);
 	}
 	
 	public static final BinderSecurityCallback getCallbackForTemplate(RepositoryEntrySecurity security) {
 		return new BinderSecurityCallbackForTemplate(security.isEntryAdmin());
 	}
 	
-	public static final BinderSecurityCallback getCallbackForCoach(Binder binder, List<AccessRights> rights) {
-		return new BinderSecurityCallbackImpl(rights, binder.getTemplate() != null, binder.getEntry() != null);
+	public static final BinderSecurityCallback getCallbackForCoach(List<AccessRights> rights) {
+		return new BinderSecurityCallbackImpl(rights);
 	}
 	
 	private static class BinderSecurityCallbackForTemplate implements BinderSecurityCallback {
@@ -91,6 +91,11 @@ public class BinderSecurityCallbackFactory {
 			return false;
 		}
 
+		@Override
+		public boolean canPublish(Page page) {
+			return false;
+		}
+
 		@Override
 		public boolean canEditAccessRights(PortfolioElement element) {
 			return false;
@@ -120,23 +125,17 @@ public class BinderSecurityCallbackFactory {
 	private static class BinderSecurityCallbackImpl implements BinderSecurityCallback {
 		
 		private final boolean owner;
-		private final boolean hasEntry;
-		private final boolean hasTemplate;
 		private final boolean newSectionAllowed;
 		private final List<AccessRights> rights;
 		
-		public BinderSecurityCallbackImpl(boolean owner, boolean hasTemplate, boolean hasEntry) {
+		public BinderSecurityCallbackImpl(boolean owner, boolean hasTemplate) {
 			this.owner = owner;
-			this.hasEntry = hasEntry;
-			this.hasTemplate = hasTemplate;
 			this.newSectionAllowed = !hasTemplate;
 			this.rights = Collections.emptyList();
 		}
 		
-		public BinderSecurityCallbackImpl(List<AccessRights> rights, boolean hasTemplate, boolean hasEntry) {
+		public BinderSecurityCallbackImpl(List<AccessRights> rights) {
 			this.owner = false;
-			this.hasEntry = hasEntry;
-			this.hasTemplate = hasTemplate;
 			this.newSectionAllowed = false;
 			this.rights = rights;
 		}
@@ -171,6 +170,11 @@ public class BinderSecurityCallbackFactory {
 			return owner && (page.getPageStatus() == null || page.getPageStatus() != PageStatus.closed);
 		}
 
+		@Override
+		public boolean canPublish(Page page) {
+			return owner && (page.getPageStatus() == null || page.getPageStatus() == PageStatus.draft || page.getPageStatus() == PageStatus.inRevision);
+		}
+
 		@Override
 		public boolean canEditAccessRights(PortfolioElement element) {
 			return owner;
diff --git a/src/main/java/org/olat/modules/portfolio/MediaHandler.java b/src/main/java/org/olat/modules/portfolio/MediaHandler.java
index 116dabc1bf5..9de85df329d 100644
--- a/src/main/java/org/olat/modules/portfolio/MediaHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/MediaHandler.java
@@ -25,6 +25,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 
 /**
  * 
@@ -48,6 +49,8 @@ public interface MediaHandler {
 	
 	public Media createMedia(String title, String description, Object mediaObject, String businessPath, Identity author);
 	
+	public Media createMedia(AbstractArtefact artefact);
+	
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media);
 
 }
diff --git a/src/main/java/org/olat/modules/portfolio/MediaInformations.java b/src/main/java/org/olat/modules/portfolio/MediaInformations.java
index 0f596d51c21..b21bca91f5b 100644
--- a/src/main/java/org/olat/modules/portfolio/MediaInformations.java
+++ b/src/main/java/org/olat/modules/portfolio/MediaInformations.java
@@ -1,3 +1,22 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
 package org.olat.modules.portfolio;
 
 /**
diff --git a/src/main/java/org/olat/modules/portfolio/PortfolioService.java b/src/main/java/org/olat/modules/portfolio/PortfolioService.java
index b68dff0c41f..ce7c79262ec 100644
--- a/src/main/java/org/olat/modules/portfolio/PortfolioService.java
+++ b/src/main/java/org/olat/modules/portfolio/PortfolioService.java
@@ -239,6 +239,13 @@ public interface PortfolioService {
 	
 	public void updateCategories(Media media, List<String> categories);
 	
+	/**
+	 * Change the status of the page.
+	 * @param page
+	 * @param status
+	 * @return
+	 */
+	public Page changePageStatus(Page page, PageStatus status);
 	
 	/**
 	 * Close the section
diff --git a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
index f8941925930..d18f36315fa 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
@@ -34,12 +34,16 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.core.util.vfs.VFSManager;
 import org.olat.modules.portfolio.Media;
 import org.olat.modules.portfolio.MediaInformations;
 import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.manager.PortfolioFileStorage;
 import org.olat.modules.portfolio.ui.media.FileMediaController;
+import org.olat.portfolio.manager.EPFrontendManager;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.portfolio.model.artefacts.FileArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -58,6 +62,8 @@ public class FileHandler extends AbstractMediaHandler {
 	private MediaDAO mediaDao;
 	@Autowired
 	private PortfolioFileStorage fileStorage;
+	@Autowired
+	private EPFrontendManager oldPortfolioManager;
 	
 	public FileHandler() {
 		super(FILE_TYPE);
@@ -119,6 +125,34 @@ public class FileHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		Media media = null;
+		if(artefact instanceof FileArtefact) {
+			VFSContainer artefactFolder = oldPortfolioManager.getArtefactContainer(artefact);
+			String filename = ((FileArtefact)artefact).getFilename();
+			String extension = FileUtils.getFileSuffix(filename);
+			String type = FILE_TYPE;
+			if("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)
+					|| "png".equalsIgnoreCase(extension) || "gif".equalsIgnoreCase(extension)) {
+				type = ImageHandler.IMAGE_TYPE;
+			}
+			String businessPath = artefact.getBusinessPath();
+			if(businessPath == null) {
+				businessPath = "[PortfolioV2:0][MediaCenter:0]";
+			}
+			media = mediaDao.createMedia(artefact.getTitle(), artefact.getDescription(), filename, type,
+					businessPath, artefact.getSignature(), artefact.getAuthor());
+		
+			File mediaDir = fileStorage.generateMediaSubDirectory(media);
+			String storagePath = fileStorage.getRelativePath(mediaDir);
+			mediaDao.updateStoragePath(media, storagePath, filename);
+			VFSContainer mediaContainer = fileStorage.getMediaContainer(media);
+			VFSManager.copyContent(artefactFolder, mediaContainer);
+		}
+		return media;
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new FileMediaController(ureq, wControl, media);
diff --git a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
index f2af6cbca82..758e8c9ec15 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
@@ -40,6 +40,7 @@ import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.manager.PortfolioFileStorage;
 import org.olat.modules.portfolio.ui.media.ImageMediaController;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -119,6 +120,11 @@ public class ImageHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		return null;//no specific image document in old portfolio
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new ImageMediaController(ureq, wControl, media);
diff --git a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
index 197916f35ac..96c3dd41c16 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
@@ -30,6 +30,7 @@ import org.olat.modules.portfolio.MediaInformations;
 import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.ui.media.TextMediaController;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -72,6 +73,18 @@ public class TextHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		String title = artefact.getTitle();
+		String description = artefact.getDescription();
+		String content = artefact.getFulltextContent();
+		String businessPath = artefact.getBusinessPath();
+		if(businessPath == null) {
+			businessPath = "[PortfolioV2:0][MediaCenter:0]";
+		}
+		return mediaDao.createMedia(title, description, content, TEXT_MEDIA, businessPath, artefact.getSignature(), artefact.getAuthor());
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new TextMediaController(ureq, wControl, media);
diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
index 178b2df0a48..335385bc8e4 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
@@ -527,6 +527,13 @@ public class PortfolioServiceImpl implements PortfolioService {
 		return mediaDao.loadByKey(key);
 	}
 
+	@Override
+	public Page changePageStatus(Page page, PageStatus status) {
+		Page reloadedPage = pageDao.loadByKey(page.getKey());
+		((PageImpl)reloadedPage).setPageStatus(status);
+		return pageDao.updatePage(reloadedPage);
+	}
+
 	@Override
 	public Section changeSectionStatus(Section section, SectionStatus status, Identity coach) {
 		PageStatus newPageStatus;
diff --git a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java
index a3e84b8c73a..7eed82582d9 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java
@@ -160,14 +160,14 @@ implements Activateable2, TooledController, FlexiTableComponentDelegate {
 		//
 	}
 	
-	@Override
-	public void event(UserRequest ureq, Component source, Event event) {
-		super.event(ureq, source, event);
-	}
-	
 	@Override
 	public void event(UserRequest ureq, Controller source, Event event) {
-		if(newPageCtrl == source) {
+		if(pageCtrl == source) {
+			if(event == Event.CHANGED_EVENT) {
+				loadModel();
+				fireEvent(ureq, Event.CHANGED_EVENT);
+			}
+		} else if(newPageCtrl == source) {
 			if(event == Event.DONE_EVENT) {
 				loadModel();
 				fireEvent(ureq, Event.CHANGED_EVENT);
diff --git a/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java b/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java
index 0b9db577814..a0cb60c82a3 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java
@@ -70,6 +70,9 @@ import org.olat.modules.portfolio.ui.event.MediaSelectionEvent;
 import org.olat.modules.portfolio.ui.media.CollectFileMediaController;
 import org.olat.modules.portfolio.ui.media.CollectImageMediaController;
 import org.olat.modules.portfolio.ui.media.CollectTextMediaController;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.portfolio.ui.EPArtefactPoolRunController;
+import org.olat.portfolio.ui.artefacts.view.EPArtefactChoosenEvent;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -86,7 +89,7 @@ public class MediaCenterController extends FormBasicController
 	private MediaDataModel model;
 	private FlexiTableElement tableEl;
 	private String mapperThumbnailUrl;
-	private Link addFileLink, addImageLink, addTextLink;
+	private Link addFileLink, addImageLink, addTextLink, importArtefactV1Link;
 	
 	private int counter = 0;
 	private final boolean select;
@@ -97,6 +100,7 @@ public class MediaCenterController extends FormBasicController
 	private CollectFileMediaController fileUploadCtrl;
 	private CollectTextMediaController textUploadCtrl;
 	private CollectImageMediaController imageUploadCtrl;
+	private EPArtefactPoolRunController importArtefactv1Ctrl;
 	
 	@Autowired
 	private PortfolioService portfolioService;
@@ -131,7 +135,11 @@ public class MediaCenterController extends FormBasicController
 		
 		addTextLink = LinkFactory.createToolLink("add.text", translate("add.text"), this);
 		addTextLink.setIconLeftCSS("o_icon o_icon-lg o_icon_new_portfolio");
-		stackPanel.addTool(addTextLink, Align.left);	
+		stackPanel.addTool(addTextLink, Align.left);
+		
+		importArtefactV1Link = LinkFactory.createToolLink("import.artefactV1", translate("import.artefactV1"), this);
+		importArtefactV1Link.setIconLeftCSS("o_icon o_icon-lg o_icon_new_portfolio");
+		stackPanel.addTool(importArtefactV1Link, Align.left);
 	}
 
 	@Override
@@ -257,17 +265,29 @@ public class MediaCenterController extends FormBasicController
 			}
 			cmc.deactivate();
 			cleanUp();
+		} else if(importArtefactv1Ctrl == source) {
+			if(event instanceof EPArtefactChoosenEvent) {
+				EPArtefactChoosenEvent cEvent = (EPArtefactChoosenEvent)event;
+				doImportArtefactV1(cEvent.getArtefact());
+				loadModel();
+				tableEl.reloadData();
+			}
+			cmc.deactivate();
+			cleanUp();
 		} else if(cmc == source) {
+
 			cleanUp();
 		}
 		super.event(ureq, source, event);
 	}
 	
 	private void cleanUp() {
+		removeAsListenerAndDispose(importArtefactv1Ctrl);
 		removeAsListenerAndDispose(imageUploadCtrl);
 		removeAsListenerAndDispose(fileUploadCtrl);
 		removeAsListenerAndDispose(textUploadCtrl);
 		removeAsListenerAndDispose(cmc);
+		importArtefactv1Ctrl = null;
 		imageUploadCtrl = null;
 		fileUploadCtrl = null;
 		textUploadCtrl = null;
@@ -282,6 +302,8 @@ public class MediaCenterController extends FormBasicController
 			doAddFileMedia(ureq);
 		} else if(addTextLink == source) {
 			doAddTextMedia(ureq);
+		} else if(importArtefactV1Link == source) {
+			doChooseArtefactV1(ureq);
 		} else if(source == mainForm.getInitialComponent()) {
 			if("ONCLICK".equals(event.getCommand())) {
 				String rowKeyStr = ureq.getParameter("img_select");
@@ -343,6 +365,25 @@ public class MediaCenterController extends FormBasicController
 		listenTo(cmc);
 		cmc.activate();
 	}
+	
+	private void doChooseArtefactV1(UserRequest ureq) {
+		if(importArtefactv1Ctrl != null) return;
+		
+		importArtefactv1Ctrl = new EPArtefactPoolRunController(ureq, this.getWindowControl(), true);
+		listenTo(importArtefactv1Ctrl);
+		
+		String title = translate("import.artefactV1");
+		cmc = new CloseableModalController(getWindowControl(), null, importArtefactv1Ctrl.getInitialComponent(), true, title, true);
+		listenTo(cmc);
+		cmc.activate();
+	}
+	
+	private void doImportArtefactV1(AbstractArtefact oldArtefact) {
+		MediaHandler handler = portfolioService.getMediaHandler(oldArtefact.getResourceableTypeName());
+		if(handler != null) {
+			handler.createMedia(oldArtefact);
+		}
+	}
 
 	private void doSelect(UserRequest ureq, Long mediaKey) {
 		Media media = portfolioService.getMediaByKey(mediaKey);
diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageController.java b/src/main/java/org/olat/modules/portfolio/ui/PageController.java
index 00fe0559d81..432b20df6cc 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/PageController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/PageController.java
@@ -40,6 +40,7 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.CodeHelper;
 import org.olat.core.util.resource.OresHelper;
@@ -48,6 +49,7 @@ import org.olat.modules.portfolio.BinderSecurityCallback;
 import org.olat.modules.portfolio.MediaHandler;
 import org.olat.modules.portfolio.Page;
 import org.olat.modules.portfolio.PagePart;
+import org.olat.modules.portfolio.PageStatus;
 import org.olat.modules.portfolio.PortfolioService;
 import org.olat.modules.portfolio.Section;
 import org.olat.modules.portfolio.model.HTMLPart;
@@ -64,12 +66,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 public class PageController extends BasicController implements TooledController {
 
 	private VelocityContainer mainVC;
-	private Link editLink, editMetadataLink;
+	private Link editLink, editMetadataLink, publishButton;
 	protected final TooledStackedPanel stackPanel;
 	private List<FragmentWrapper> fragments = new ArrayList<>();
 	
 	private CloseableModalController cmc;
 	private PageEditorController editCtrl;
+	private DialogBoxController confirmPublishCtrl;
 	private PageMetadataEditController editMetadataCtrl;
 	private UserCommentsAndRatingsController commentsCtrl;
 	
@@ -92,6 +95,10 @@ public class PageController extends BasicController implements TooledController
 
 		loadModel(ureq);
 		
+		if(secCallback.canPublish(page)) {
+			publishButton = LinkFactory.createButton("publish", mainVC, this);
+		}
+		
 		if(secCallback.canComment(page)) {
 			CommentAndRatingSecurityCallback commentSecCallback = new CommentAndRatingDefaultSecurityCallback(getIdentity(), false, false);
 			OLATResourceable ores = OresHelper.createOLATResourceableInstance(Page.class, page.getKey());
@@ -150,6 +157,8 @@ public class PageController extends BasicController implements TooledController
 			}
 			cmc.deactivate();
 			cleanUp();
+		} else if(confirmPublishCtrl == source) {
+			doPublish(ureq);
 		} else if(cmc == source) {
 			cleanUp();
 		}
@@ -169,9 +178,23 @@ public class PageController extends BasicController implements TooledController
 			doEditPage(ureq);
 		} else if(editMetadataLink == source) {
 			doEditMetadata(ureq);
+		} else if(publishButton == source) {
+			doConfirmPublish(ureq);
 		}
 	}
 	
+	private void doConfirmPublish(UserRequest ureq) {
+		String title = translate("publish.confirm.title");
+		String text = translate("publish.confirm.descr", new String[]{ page.getTitle() });
+		confirmPublishCtrl = activateYesNoDialog(ureq, title, text, confirmPublishCtrl);
+	}
+	
+	private void doPublish(UserRequest ureq) {
+		page = portfolioService.changePageStatus(page, PageStatus.published);
+		publishButton.setVisible(false);
+		fireEvent(ureq, Event.CHANGED_EVENT);
+	}
+	
 	private void doEditMetadata(UserRequest ureq) {
 		if(editMetadataCtrl != null) return;
 		
diff --git a/src/main/java/org/olat/modules/portfolio/ui/SharedItemsController.java b/src/main/java/org/olat/modules/portfolio/ui/SharedItemsController.java
index b81a2b40fa8..bd7521c465d 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/SharedItemsController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/SharedItemsController.java
@@ -195,7 +195,7 @@ public class SharedItemsController extends FormBasicController implements Activa
 			OLATResourceable binderOres = OresHelper.createOLATResourceableInstance("Binder", binder.getKey());
 			WindowControl swControl = addToHistory(ureq, binderOres, null);
 			List<AccessRights> rights = portfolioService.getAccessRights(binder, getIdentity());
-			BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForCoach(binder, rights);
+			BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForCoach(rights);
 			BinderConfiguration config = BinderConfiguration.createConfig(binder);
 			binderCtrl = new BinderController(ureq, swControl, stackPanel, secCallback, binder, config);
 			String displayName = StringHelper.escapeHtml(binder.getTitle());
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_content/page_content.html b/src/main/java/org/olat/modules/portfolio/ui/_content/page_content.html
index c7270757200..0accc2a15c2 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_content/page_content.html
+++ b/src/main/java/org/olat/modules/portfolio/ui/_content/page_content.html
@@ -1,4 +1,12 @@
-<h1>$r.escapeHtml($pageTitle)</h1>
+<div class="o_header_with_buttons">
+	<h1>$r.escapeHtml($pageTitle)</h1>
+	#if($r.available("publish"))
+	<div class="o_button_group o_button_group_right">
+		$r.render("publish")
+	</div>
+	#end
+</div>
+
 #foreach($fragment in $fragments)
 	<div class="">$r.render($fragment.componentName)</div>
 #end
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
index 36124c301bc..c0d2a02ad9c 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
@@ -55,6 +55,7 @@ goto.my.binders=zu meinen Mappen
 goto.my.pages=zeige meine Eintr\u00E4ge
 goto.my.shared.items=zu meinen freigegebenen Mappen
 goto.shared.with.me=zeige an mich freigegebene Mappen
+import.artefactV1=Artefakte importieren
 media.center=Mediencenter
 media.center.text=Hier k\u00F6nnen Sie Mediendateien, Dokumente oder andere Artefakte hinzuf\u00FCgen. Verwenden Sie die Medien um Ihre Eintr\u00E4ge zu illustrieren und zu erg\u00E4nzen.
 meta.last.modified=zuletzt bearbeitet am {0}
@@ -85,6 +86,9 @@ portfolio.publish=Freigabe
 portfolio.root.breadcrump=Portfolio
 portfoliotask=Portfolioaufgabe
 portfoliotask.none=Keine
+publish=Eintrag publizieren
+publish.confirm.title=Publizieren
+publish.confirm.descr=Wollen Sie diesen Eintrag "{0}" publizieren?
 publish.status.title=Freigabe Status der Mappe "{0}"
 reopen=Neu \u00F6ffnen
 section.delete=Bereich l\u00F6schen
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
index fdc04111b37..bc22437af3a 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
@@ -56,6 +56,7 @@ goto.my.binders=go to my binders
 goto.my.pages=show my entries
 goto.my.shared.items=go to my shares
 goto.shared.with.me=go to shared items
+import.artefactV1=Import artefacts
 media.center=Media center
 media.center.text=Search, create, add media files or other artefacts that you want to use within your entries for illustration purpose.
 meta.last.modified=last modified {0}
@@ -86,6 +87,9 @@ portfolio.publish=Publish
 portfolio.root.breadcrump=Portfolio
 portfoliotask=Portfolio Task
 portfoliotask.none=None
+publish=Publish entry
+publish.confirm.title=Publish
+publish.confirm.descr=Do you want to publish this entry "{0}"?
 publish.status.title=Publish status of binder "{0}"
 reopen=Reopen
 section.delete=Delete section
diff --git a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
index c303caf80e3..851f14ec1b8 100644
--- a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
+++ b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
@@ -39,6 +39,8 @@ import org.olat.modules.portfolio.manager.PortfolioFileStorage;
 import org.olat.modules.webFeed.managers.FeedManager;
 import org.olat.modules.webFeed.models.Feed;
 import org.olat.modules.webFeed.models.Item;
+import org.olat.portfolio.manager.EPFrontendManager;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -59,6 +61,8 @@ public class BlogEntryMediaHandler extends AbstractMediaHandler {
 	private FeedManager feedManager;
 	@Autowired
 	private PortfolioFileStorage fileStorage;
+	@Autowired
+	private EPFrontendManager oldPortfolioManager;
 	
 	public BlogEntryMediaHandler() {
 		super(BLOG_ENTRY_HANDLER);
@@ -98,6 +102,30 @@ public class BlogEntryMediaHandler extends AbstractMediaHandler {
 		return media;
 	}
 
+	/**
+	 * Copy the item.xml and eventuel some attached medias.
+	 */
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		VFSContainer artefactFolder = oldPortfolioManager.getArtefactContainer(artefact);
+		String businessPath = artefact.getBusinessPath();
+		if(businessPath == null) {
+			businessPath = "[PortfolioV2:0][MediaCenter:0]";
+		}
+
+		String filename = null;
+		Media media = mediaDao.createMedia(artefact.getTitle(), artefact.getDescription(), filename, BLOG_ENTRY_HANDLER,
+				businessPath, artefact.getSignature(), artefact.getAuthor());
+		
+		File mediaDir = fileStorage.generateMediaSubDirectory(media);
+		String storagePath = fileStorage.getRelativePath(mediaDir);
+		mediaDao.updateStoragePath(media, storagePath, BlogArtefact.BLOG_FILE_NAME);
+		VFSContainer mediaContainer = fileStorage.getMediaContainer(media);
+		VFSManager.copyContent(artefactFolder, mediaContainer);
+
+		return media;
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new BlogEntryMediaController(ureq, wControl, media, true);
diff --git a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
index 181b6a7e055..fb297af3baf 100644
--- a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
+++ b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
@@ -32,6 +32,7 @@ import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.handler.AbstractMediaHandler;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.wiki.WikiPage;
+import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -83,6 +84,18 @@ public class WikiMediaHandler extends AbstractMediaHandler {
 		return mediaDao.createMedia(title, description, content, WIKI_HANDLER, businessPath, 70, author);
 	}
 
+	@Override
+	public Media createMedia(AbstractArtefact artefact) {
+		String title = artefact.getTitle();
+		String description = artefact.getDescription();
+		String content = artefact.getFulltextContent();
+		String businessPath = artefact.getBusinessPath();
+		if(businessPath == null) {
+			businessPath = "[PortfolioV2:0][MediaCenter:0]";
+		}
+		return mediaDao.createMedia(title, description, content, WIKI_HANDLER, businessPath, artefact.getSignature(), artefact.getAuthor());
+	}
+
 	@Override
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new WikiPageMediaController(ureq, wControl, media);
-- 
GitLab