[SalesForce] How to Upload a File to a specific Library Folder using Apex

I am trying to save a Visualforce page as a PDF file to a Library folder in our Salesforce org. I have been unable to figure out how to save this new PDF file to a specific Library folder.

I tried following the answer here but it does not appear to work for me.

Any help would be appreciated, thanks.

public static void createFile (String filename, Blob content)
{
    ContentVersion cv = new ContentVersion();
    cv.ContentLocation = 'S';
    cv.VersionData = content;
    cv.Title = filename;
    cv.PathOnClient = filename;
    insert cv;

    cv = [SELECT Id, ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id LIMIT 1];
    ContentWorkspace ws = [SELECT Id, RootContentFolderId FROM ContentWorkspace WHERE Name = 'Custom Folder Name' LIMIT 1];

    ContentDocumentLink cdl = new ContentDocumentLink();
    cdl.ContentDocumentId = cv.ContentDocumentId;
    cdl.ShareType = 'V';
    cdl.Visibility = 'InternalUsers';
    insert cdl;

    ContentFolderMember cfm = [SELECT Id, ChildRecordId, ParentContentFolderId
                              FROM ContentFolderMember
                              WHERE ChildRecordId = :cv.ContentDocumentId
                              LIMIT 1];

    ContentFolderMember updatedCfm = new ContentFolderMember(Id = cfm.Id,
                                                             ChildRecordId = cdl.ContentDocumentId,
                                                             ParentContentFolderId = ws.RootContentFolderId);
    update updatedCfm;
}

Best Answer

As I can see from Your code while creating a ContentDocumentLink you are not specifying a LinkedEntityId. Linked entity ID tells in which folder it exists.

So Minimum code needed to store file in a LibraryFolder named as "MyLibraryFolder"

ContentVersion cv = new ContentVersion();
cv.VersionData = Blob.valueOf('Pika');
cv.Title = 'filename';
cv.PathOnClient = 'myfile.xml';
insert cv;

cv = [SELECT Id, ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id LIMIT 1];
ContentWorkspace ws = [SELECT Id, RootContentFolderId FROM ContentWorkspace WHERE Name = 'MyLibraryFolder' LIMIT 1];

ContentDocumentLink cdl = new ContentDocumentLink();
cdl.ContentDocumentId = cv.ContentDocumentId;
cdl.ShareType = 'I';
cdl.Visibility = 'AllUsers';
cdl.LinkedEntityId = ws.Id; //Magic happens here
insert cdl;
Related Topic