How to get GUID of a subfolder in a document library programmatically - sharepoint

Okay, here is the scenario...
I have created a subfolder in a document library, and when an item is added to the document library, i want to do some processing on the document and then move the item to the subfolder, say MySubFolder. For that purpose, i will be using this statement
SPListItem folder = this.workflowProperties.List.Folders[];
but the Folders[] collection will take either an int index or a guid. SInce i am doing it in a workflow, I dont know how to get the guid of the folder here. Please note that I cannot use the url to get the GUID here because the same workflow is applied to a number of document libraries and I have the MySubFolder subfolder in all of them, so giving the url seems a bit tacky here i think.

I don't have Sharepoint here right now, but you should be able to do:
Guid folderId = Guid.Empty;
foreach (SPFolderCollection folder in YourList.Folders)
{
if (folder.Name == "MySubFolder")
{
folderId = folder.UniqueId;
break;
}
}
Or, into your event handler, build your folder URL:
public override void ItemDeleting(SPItemEventProperties properties)
{
Uri folderAddress = new Uri(properties.BeforeUrl, "MySubFolder");
SPFolder folder = yourWeb.GetFolder(folderAddress.ToString());
}

I solved it by doing the following:
Guid folderId = Guid.Empty;
SPFolder spFolder = web.Folders[this.workflowProperties.List.Title].SubFolders["MySubFolder"];
folderId=spFolder.UniqueId;

Related

Liferay: How to get relative paths to web contents's documents and media

Under Web content I set my structure to have an application field: "Documents an media".
Through this field user can add various files which are then displayed in my .xhtml.
User can make this "Documents and media" field repeatable to add more files.
How could I iterate through all added files and get their relative paths.
If my Documents and media field is not repeatable I can get relative path like this:
public String getWebContentTitle(String title, String nodeName) throws PortalException, SystemException {
FacesContext context = FacesContext.getCurrentInstance();
ThemeDisplay themeDisplay = (ThemeDisplay) context.getExternalContext().getRequestMap().get(WebKeys.THEME_DISPLAY);
long groupId = themeDisplay.getScopeGroupId();
JournalArticle article = JournalArticleLocalServiceUtil.getArticleByUrlTitle(groupId, formatUrlTitle(title));
String languageKey = context.getExternalContext().getRequestLocale().toString();
JournalArticleDisplay articleDisplay = JournalContentUtil.getDisplay(groupId, article.getArticleId(), article.getTemplateId(), languageKey, themeDisplay);
JournalArticle journalArticle = JournalArticleLocalServiceUtil.getArticle(groupId, article.getArticleId());
String myContent = journalArticle.getContentByLocale(languageKey);
if (nodeName != null) {
String nodeText=getParseValue(nodeName, journalArticle, myContent);
return nodeText;
} else
{
String ret=articleDisplay.getContent();
return ret;
}
}
private String getParseValue(String fieldname, JournalArticle article, String locale) {
String nodeText = "";
try {
Document document = SAXReaderUtil.read(article.getContentByLocale(locale));
Node node = document.selectSingleNode("/root/dynamic-element[#name='" + fieldname +"']/dynamic-content");
nodeText = node.getText();
} catch(Exception e){
}
return nodeText;
}
This method return relative path to my added document (say horses.pdf).
How could I get relative paths to more documents added through "Documents and media field", which is repeatable and has defined specific Variable name (say HorsesPdfs?)
Any help would be greatly appreciated!
You could try
DLAppLocalServiceUtil.getFileEntries(REPOSITORY_ID, FOLDER_ID), probably better than DLFileEntry as its the new approach that takes workflows in consideration.
Where
REPOSITORY_ID = parent group, which is by default LR´s one GroupLocalServiceUtil.getGroup(COMPANY_ID, GroupConstants.GUEST).getGroupId()
COMPANY_ID = PortalUtil.getDefaultCompanyId(); //If just one instance, if not, better to play with CompanyLocalServiceUtil to match your Id
For FOLDER ID, you can use root older of LR´s Doc & Media which is
FOLDER_ID = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID; //or find it e.g DLAppLocalServiceUtil.getFolder( repositoryId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, FOLDER_NAME).getFolderId(); if you programtically used addFolder(long userId, long repositoryId, long parentFolderId, String name, String description, ServiceContext serviceContext)

How to add tag to document in doc library through programming in liferay?

I am new to liferay. I am using liferay 6.0.5
I want to add "Archive" tag to doc library document through code so latter on I can fetch the document with "Archive" tag.
how to do this?
Here is the code being worked upon :
private void addArchive(List<DLFileEntry> fileEntryList) {
try
{
long groupId=0;
long userId=0;
String className=null;
long classPK=0;
long categoryIds[]=null;
String tagNames[]=null;
String newTagNames[] = new String[20];
long entryId = 0;
List<AssetTag> TNames = new ArrayList<AssetTag>();
int i = 0;
for(DLFileEntry cur:fileEntryList)
{
groupId=cur.getGroupId();
userId=cur.getUserId();
className=cur.getClass().getName();
classPK=cur.getPrimaryKey();
AssetEntry ae=AssetEntryLocalServiceUtil.getEntry(groupId, cur.getUuid());
categoryIds=ae.getCategoryIds();
entryId = ae.getEntryId();
TNames = ae.getTags();
System.out.println(cur.getTitle());
i=0;
for(AssetTag tag : TNames)
{
System.out.println(tag.getName());
newTagNames[i]=tag.getName().toString();
i++;
}
newTagNames[i]="NameArchive";
AssetEntryLocalServiceUtil.updateEntry(userId, groupId, className, classPK, categoryIds, newTagNames);
System.out.println("------------------------------------------------");
}
System.out.println("outside for loop");
}
catch (Exception e) {
// TODO: handle exception
}
}
Firstly you need to find the "entryId" of the File in your Document Library using the DLFileEntryLocalServiceUtil class (and the other associated DL*LocalServiceUtil classes).
The "entryId" relates to the "classPK" field on the assetentry table in the database. Then you can use the following method to update the AssetEntry with the Tag "Archive":
AssetEntryLocalServiceUtil.updateEntry(userId, groupId, DLFileEntry.class.getName(), fileEntryIdYouJustGot, categoryIds, new String[] {"Archive"});
This will remove any other tags though so you may want to retrieve the current tags from the Asset Entry and then add "Archive" to them, then pass the resulting array to the method.
But this is the basis of what you need to do.
~~ EDIT ~~
Amend your getEntryLine to use the following. You're passing in the DLFileEntry UUID, but if you look at the Source Code it's asking for a classUuid which I don't believe are the same thing. Also add logging in your Exception handling to see if a Exception is being thrown.
AssetEntry ae=AssetEntryLocalServiceUtil.getEntry(groupId, classPK);

Sharepoint: Create a subweb from an item event handler

I have a "project list" (title, lead, members, site-URL) that is supposed to refer to team sites under the site that has the project list. So I added an SPItemEventReceiverto my feature in a sandbox solution to do that.
In ItemAdding(properties), I invoke the following:
string projectName = properties.AfterProperties["Title"].ToString();
SPWeb currentWeb = properties.Web;
SPWeb subweb = currentWeb.Webs.Add(projectName, projectName,
"Project site for " + projectName, (uint) currentWeb.Locale.LCID,
Microsoft.SharePoint.SPWebTemplate.WebTemplateSTS, true, false);
But when debugging, the call to Add throws an SPException wrapping a COMException for a HResult code of FAILED with the message The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request.
Is there something wrong with the parameters, or should I delegate the actual creation to a workflow instead?
Following try with this:
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
// Get the web where the event was raised
SPWeb spCurrentSite = properties.OpenWeb();
//Get the name of the list where the event was raised
String curListName = properties.ListTitle;
//If the list is our list named SubSites the create a new subsite directly below the current site
if (curListName == "SubSites")
{
//Get the SPListItem object that raised the event
SPListItem curItem = properties.ListItem;
//Get the Title field from this item. This will be the name of our new subsite
String curItemSiteName = properties.AfterProperties["Title"].ToString();
//Get the Description field from this item. This will be the description for our new subsite
string curItemDescription = properties.AfterProperties["Description"].ToString();
//Update the SiteUrl field of the item, this is the URL of our new subsite
properties.AfterProperties["SiteUrl"] = spCurrentSite.Url + "/" + curItemSiteName;
//Create the subsite based on the template from the Solution Gallery
SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, curItemDescription, Convert.ToUInt16(1033), "{8FCAD92C-EF01-4127-A0B6-23008C67BA26}#1TestProject", false, false);
//Set the new subsite to inherit it's top navigation from the parent site, Usefalse if you do not want this.
newSite.Navigation.UseShared = true;
newSite.Close();
}
}
Seems to be some deadlock situation; I solved my particular case by using the post-event ItemAdded instead (changing from setting values in AfterProperties to updating the ListItem instead). There, for some reason, the call to Webs.Add() completes normally...

Add a folder to current document library

How do I add a folder to current document library (well if the folder does not exists in the current document library)?
(Current being where ever the end user is)
(I am going to add this code to itemAdded event handler)
curSPList.Items.Add("My Folder Name", SPFileSystemObjectType.Folder);
will create a new folder in any SharePoint list, including a document library. If you plan on implementing this in an event handler you can get the reference to the SPList from the "List" property of the SPItemEventProperties parameter.
Here is the final code that works. Creates a Folder "uHippo" in the current document library if "uHippo" does not exists.
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
using (SPSite currentSite = new SPSite(properties.WebUrl))
using (SPWeb currentWeb = currentSite.OpenWeb())
{ SPListItem oItem = properties.ListItem;
string doclibname = "Not a doclib";
//Gets the name of the document library
SPList doclibList = oItem.ParentList;
if (null != doclibList)
{
doclibname = doclibList.Title;
}
bool foundFolder = false; //Assume it isn't there by default
if (doclibList.Folders.Count > 0) //If the folder list is empty, then the folder definitely doesn't exist.
{
foreach (SPListItem fItem in doclibList.Folders)
{
if (fItem.Title.Equals("uHippo"))
{
foundFolder = true; //Folder does exist, break loop.
break;
}
}
}
if (foundFolder == false)
{
SPListItem folder = doclibList.Folders.Add(doclibList.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, "uHippo");
folder.Update();
}
}
}

Find out the URL for the document library of a SharePoint document

If i know the URL for a document, can I find the URL for sharepoint document library in which the document is present. The following are two sample URLs for a SharePoint site. The first document is present under the root of a document library. The second document is present under a folder "folder1" within the document library. Appreciate if there is anyway to know the URL for a document library (http:///sites/site1/DocLib/Forms/AllItems.aspx).
http:///sites/site1/DocLib/a.doc
http:///sites/site1/DocLib/folder1/a.doc
Thanks for your replies. I am looking for a solution with MOSS OOTB web service or based on the URL pattern. Can we use any of these to acheive this please?
Thanks.
The SPWeb object has a GetFile method, which takes the full file url.
SPFile file = web.GetFile(yoururl);
Now it's easy to get to the SPList's url, by using the following:
string listUrl = file.Item.ParentList.DefaultViewUrl;
So, in a method together:
public string GetListUrlFromFileUrl(string fullFileUrl)
{
using (SPSite site = new SPSite(fullFileUrl))
{
using(SPWeb myWeb = site.OpenWeb())
{
SPFile file = myWeb.GetFile(fullFileUrl);
return file.Item.ParentList.DefaultViewUrl;
}
}
}
Make sure to reference Microsoft.Sharepoint.dll in your project as well.
There are two different ways I do this, depending on the situation. Neither performs extremely well (important to note), though the second solution typically performs fairly well for our use cases.
The first is extremely simple:
private SPList GetListForFile(string fileUrl)
{
using (SPSite site = new SPSite(fileUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPFile file = web.GetFile(fileUrl);
if (file.Exists)
{
return file.Item.ParentList;
}
}
}
return null;
}
The second is a little more complex. It does require you first chopping off the file part of the URL, then passing it in to the method to get the correct SPWeb, then finding the right list in the web.
private SPList GetListForFile(string fileUrl)
{
using(SPWeb web = OpenWeb(GetFolderUrl(fileUrl)))
{
string listName = fileUrl.Replace(web.ServerRelativeUrl, "");
listName = listName.Substring(0, listName.IndexOf('/'));
return web.Lists[listName];
}
}
private string GetFolderUrl(string fileUrl)
{
return Regex.Replace(fileUrl, #"/[^/]+?\.[A-Z0-9_]{1,6}$", "",
RegexOptions.IgnoreCase | RegexOptions.Singleline);
}
private SPWeb OpenWeb(string folderUrl)
{
SPWeb web = null;
while(web == null)
{
web = Site.OpenWeb(folderUrl);
if (!web.Exists)
{
web.Dispose();
web = null;
}
folderUrl = folderUrl.Substring(0, folderUrl.LastIndexOf("/"));
if (folderUrl.Length == 0)
{
folderUrl = "/";
}
}
return web;
}

Resources