lis 202014

Salesforce – Jak pobrać listę plików z Chatter Files powiązanych z rekordem

Pliki powiązane z rekordem można przechowywać na 2 sposoby: jako załączniki (w sekcji Notes & Attachements) oraz jako Salesforce Content (wykorzystując Chatter Files)

Stanąłem ostatnio przed zadaniem stworzenia strony Visualforce, która osadzona na Page Layout jako inline Visualforce pokazywała będzie pliki dodane przez Chatter Files powiązane z przeglądanym rekordem. Samo dodawanie odbywa się przez Chattera. Przypisanie Topicu do wpisu w Chatterze traktowane jest jako kategoria pliku, co pozwala później filtrować dodane pliki.

inline-vf-chatter-files

Całość zapakowane jako komponent aby można było użyć w wielu miejscach.

Klasa Apex:

public with sharing class ChatterFiles { 

    public List<FeedItem> files { get; set; }     
    public string category { get; set; }     
    public Id recordId { get 
                            {    return recordId;    }
                        set { 
                                recordId = value; 
                                SearchFiles();
                            }
                        }

    public class entry {
        public FeedItem item { get; set; }
        public List<string> topics { get; set; }
        public string categories { get; set; }
    }
    public List<entry> items { get; set; }     
            
    public ChatterFiles() {
        items = new List<entry>();
    }
        
    public void SearchFiles () {        
        items.clear();
        List<FeedItem> feedFiles = [ SELECT Id, CreatedById, CreatedDate, Body, CommentCount, ContentFileName, ContentDescription, 
                                         InsertedById, ParentId, RelatedRecordId, Title, Type
                                          FROM FeedItem 
                                         WHERE Type = 'ContentPost' AND ParentId = :this.recordId
                                         ORDER BY CreatedDate DESC
                                    ];
        
        Set<Id> feedIds = new Set<Id> (new Map<Id,SObject>(feedFiles).keySet());
        List<TopicAssignment> topicList = [ SELECT Topic.Name, TopicId, Id, EntityId FROM TopicAssignment WHERE EntityId IN :feedIds ORDER BY Topic.Name ASC];
        
        for(FeedItem f : feedFiles){           
               List<string> topics = new List<string>();
            entry line = new entry();
            boolean validCategory = false;
            line.item = f;
            line.categories = '';
            for(TopicAssignment t : topicList){
                if (t.EntityId == f.Id) {
                    topics.add(t.Topic.Name);
                    line.categories += t.Topic.Name + ', ';
                    if (this.category == t.Topic.Name) {
                        validCategory = true;
                    }
                }
            }
            if (line.categories.length()>4) {
                line.categories = line.categories.substring(0, line.categories.length()-2);                
            }
            line.topics = topics;

            // is selected Category and Feed contains valid category OR category is not selected              
            if ((String.isNotEmpty(this.category) && (validCategory)) || String.isEmpty(this.category)) {
                items.add(line);            
            }           
        }
    }
        
    public List<Selectoption> getTopicItems(){
        List<SelectOption> options = new List<SelectOption>();  
        options.add(new SelectOption('', '-- select --'); 
        
        List<FeedItem> filesForTopics = [ SELECT Id, CreatedById, CreatedDate, Body, CommentCount, ContentFileName, ContentDescription, 
                                          InsertedById, ParentId, RelatedRecordId, Title, Type
                                           FROM FeedItem 
                                          WHERE Type = 'ContentPost' AND ParentId = :this.recordId 
                                          ORDER BY CreatedDate DESC
                                         ];        
        
        Set<Id> topicIds = new Set<Id> (new Map<Id,SObject>(filesForTopics).keySet());
                         
        List<TopicAssignment> topicList = [ SELECT Topic.Name, TopicId, Id, EntityId FROM TopicAssignment WHERE EntityId IN :topicIds ORDER BY Topic.Name ASC];

        Set<Id> myset = new Set<Id>();
        List<TopicAssignment> result = new List<TopicAssignment>();
        for (TopicAssignment t : topicList) {
            if (!myset.contains(t.TopicId)) {
                myset.add(t.TopicId);
                options.add(new SelectOption(t.Topic.Name, t.Topic.Name)); 
            }
        }

        return options;
    }
    
    public PageReference GoToNewFile() {
        PageReference pageRef = new PageReference('/apex/ChatterFilesNew');        
        pageRef.setRedirect(true);
        return pageRef;
    }    
}

Kod komponentu

<apex:component controller="ChatterFiles">
    <apex:attribute name="textId" description="This is ID of the record" type="String" required="true" assignTo="{!recordId}" />

    <apex:pageBlock id="pageBlock">
        <apex:form >
        </apex:form>

        <apex:form >
            <div style="text-align: right">            
            Category: &nbsp;
            <apex:selectList value="{!category}" multiselect="false" id="category" size="1" style="margin: 10px 0;" >
                <apex:selectOptions value="{!TopicItems}" />
                <apex:actionSupport event="onchange" action="{!SearchFiles}" rerender="pageBlock" />
            </apex:selectList>
            </div>
            
            <div align="center" draggable="false" >
                <apex:outputLink value="/apex/ChatterFilesNew?parentId={!recordId}" target="_top" styleClass="btn" style="text-decoration: none; padding: 3px 5px; margin-bottom: 10px; display: inline-block; ">Create</apex:outputLink>
            </div>        
            
        </apex:form>
         
        <apex:pageBlockTable value="{!items}" var="list" id="files">
            <apex:column headerValue="Name" >
                 <apex:outputLink value="/{!list.item.Id}" target="_top">{!list.item.ContentFileName} </apex:outputLink>
            </apex:column>
            <apex:column headerValue="Description" >
                 <apex:outputText >{!list.item.Body} {!list.item.ContentDescription} </apex:outputText>
            </apex:column>
            <apex:column headerValue="Category" >
                 <apex:outputText value="{!list.categories}"/>
            </apex:column>
            <apex:column headerValue="Created Date" >
                 <apex:outputField value="{!list.item.CreatedDate}"/>
            </apex:column>
            <apex:column headerValue="Author" >
                 <apex:outputField value="{!list.item.CreatedById}"/>
            </apex:column>
            </apex:pageBlockTable>
    </apex:pageBlock> 
</apex:component>

Kod strony VF z wywołaniem komponentu. W poniższym przykładzie Resource__c to nazwa customowego obiektu:

<apex:page standardController="Resource__c">
    <c:ChatterFiles textId="{!Resource__c.Id}" />  
</apex:page>
Tagged with , , , , , , 2 komentarze
2 Responses to Salesforce – Jak pobrać listę plików z Chatter Files powiązanych z rekordem
  1. Antonius Meliat

    Many thanks for your Salesforce ? How to „how to retrieve list of Chatter Files related to a record”. The GoToNewFiles method points to ‚/apex/ChatterFilesNew’. Can you provide the code for this as well. I’ve come this far following your how-to and I’m stuck here. Many thanks in advance for your help

  2. Grzegorz Skaruz

    @Antonius I’ve send you the code and I’ve updated the post.

Dodaj komentarz

Your email address will not be published. Please enter your name, email and a comment.