4

I've been trying to have this code done with and finished for ages, and everytime I think I'm done, the person who wanted the code always adds an extra feature he'd like added in last minute. :T

In any case, I've gotten this far in my code for a custom controller and VisualForce page to display ContentVersion objects:

ContentVersionFiles.vfp:

<apex:page docType="html-5.0" readOnly="true" recordSetVar="{!content}" controller="ContentVersionController" showChat="false" showHeader="false" showQuickActionVfHeader="false" sidebar="false">
  <apex:includeScript id="console-js" value="/support/console/35.0/integration.js" />
  <apex:variable var="count" value="{!0}" />
  <apex:pageBlock title="Registration Scans" id="pageBlock">
    <apex:form id="topForm">
      <div align="center" style="display:{!IF(NOT(ISNULL(content)), 'block', 'none')}">
        <div id="pgNum1"><font size="1pt">Page #:&nbsp;<apex:outputLabel value="{!PageNumber}"/>&nbsp;out of&nbsp;<apex:outputLabel value="{!totalPageNumber}"/>&nbsp;&nbsp;&nbsp;&nbsp;</font></div>
        <apex:commandButton value="Previous" action="{!previousBtnClick}" reRender="pageBlock" disabled="{!previousButtonEnabled}" />
        <apex:commandButton value="Next" action="{!nextBtnClick}" reRender="pageBlock" disabled="{!nextButtonDisabled}" />
      </div>
    </apex:form>
    <apex:panelBar id="scans">
      <apex:repeat var="cv" value="{!pageContent}">
        <apex:variable var="count" value="{!count + 1}" />
        <apex:panelBarItem id="barItem" label="{!cv.Title} - #{!count} of {!content.size}" onenter="autoResize(this.id)"><a href="/{!cv.Id}"><img id="image" src="/sfc/servlet.shepherd/version/download/{!cv.Id}" title="{!cv.Title}" /></a></apex:panelBarItem>
      </apex:repeat>
    </apex:panelBar>
    <apex:form id="bottomForm">
      <div align="center" style="display:{!IF(NOT(ISNULL(content)), 'block', 'none')}">
        <div id="pgNum2"><font size="1pt">Page #:&nbsp;<apex:outputLabel value="{!PageNumber}"/>&nbsp;out of&nbsp;<apex:outputLabel value="{!totalPageNumber}"/>&nbsp;&nbsp;&nbsp;&nbsp;</font></div>
        <apex:commandButton value="Previous" action="{!previousBtnClick}" reRender="pageBlock" disabled="{!previousButtonEnabled}" />
        <apex:commandButton value="Next" action="{!nextBtnClick}" reRender="pageBlock" disabled="{!nextButtonDisabled}" />
      </div>
    </apex:form>
  </apex:pageBlock>
</apex:page>

ContentVersionController.apxc:

public with sharing class ContentVersionController {
    public List<ContentVersion> pageContent { get; set; }    
    public List<ContentVersion> content { get; set; }
    public String selectedContentId { get; set; }
    private ApexPages.StandardSetController controller;
    private Integer pageNumber;
    private Integer pageSize;
    private Integer totalPageNumber;

    public ContentVersionController() {
        //controller = new ApexPages.StandardSetController();
        pageNumber = 0;
        totalPageNumber = 0;
        pageSize = 20;
        ViewData();
    }

    public ContentVersionController(ApexPages.StandardSetController con) {
        controller = con;
        pageNumber = 0;
        totalPageNumber = 0;
        pageSize = 20;
        ViewData();
    }

    public List<ContentVersion> getContentVersions() {
        return [SELECT Id, Title, ContentDocumentId FROM ContentVersion
                WHERE IsLatest = true AND OwnerId = '005A0000003mkyk'];
    }

    public Integer getPageNumber() {
        return pageNumber;
    }

    public List<ContentVersion> getContent() {
        //return pageContent;
        return [SELECT Id, Title, ContentDocumentId FROM ContentVersion
                WHERE IsLatest = true AND OwnerId = '005A0000003mkyk'];
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public Boolean getPreviousButtonEnabled() {
        return !(pageNumber > 1);
    }

    public Boolean getNextButtonDisabled() {
        if (content == null) {
            return true;
        } else {
            return ((pageNumber * pageSize) >= content.size());
        }
    }

    public Integer getTotalPageNumber() {
        if(totalPageNumber == 0 && content !=null) {
            totalPageNumber = content.size() / pageSize;
            Integer mod = content.size() - (totalPageNumber * pageSize);
            if(mod > 0) {
                totalPageNumber++;
            }
        }
        return totalPageNumber;
    }

    public PageReference ViewData() {
        content = null;
        totalPageNumber = 0;
        BindData(1);
        return null;
    }

    public void BindData(Integer newPageIndex) {
        try {
            if(content == null){
               content = [SELECT Id, Title, ContentDocumentId FROM ContentVersion
                          WHERE IsLatest = true AND OwnerId = '005A0000003mkyk'];
            }
            pageContent = new List<ContentVersion>();
            transient Integer counter = 0;
            transient Integer min = 0;
            transient Integer max = 0;
            if (newPageIndex > pageNumber) {
                min = pageNumber * pageSize;
                max = newPageIndex * pageSize;
            } else {
                max = newPageIndex * pageSize;
                min = max - pageSize;
                //min = min <>
            }
            for(ContentVersion c : content) {
                counter++;
                if (counter > min && counter <= max){
                    pageContent.add(c);
                }
            }
            pageNumber = newPageIndex;
            if (pageContent == null || pageContent.size() <= 0) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, 'Data not available for this view.'));
            }
        } catch(Exception ex) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.FATAL, ex.getMessage()));
        }
    }

    public PageReference nextBtnClick() {
        BindData(pageNumber + 1);
        pageNumber += 1;
        return null;
    }

    public PageReference previousBtnClick() {
        BindData(pageNumber - 1);
        pageNumber -= 1;
        return null;
    }

    public PageReference deleteBtnClick() {
        /* TODO: get current ContentDocumentId of a clicked-on(selected) ContentVersion record, and delete the ContentDocument associated with it,
           since you can't delete a ContentVersion via API calls. */
        return null;
    }
}

It took me a lot of work to get this working correctly, and I REALLY don't want to break anything, if at all possible. The way the VisualForce page works is that it will show all the ContentVersion records in a massive list of <apex:panelBar> elements, all closed by default, and only one ContentVersion is visible at a time when a user clicks on the given panel bar. Is there a way to add a delete button for each of the records? Or at least for the current record that's in view? I realize it'll need AJAX to handle reloading the content within the panel bars, but I'll handle that on my own. I just want to know if a delete functionality is possible in this setup. Can anyone help?

5
  • You want to delete the record from the database, or you want to hide that panelBarItem from the panelBar? Commented Nov 17, 2015 at 15:20
  • I'd prefer deleting them, but if it's not possible, hiding them is an option.
    – LewdLime
    Commented Nov 17, 2015 at 16:04
  • you can delete the ContentDocument (and all versions therein) but you can't delete a ContentVersion
    – cropredy
    Commented Jan 27, 2016 at 0:40
  • You can delete a ContentVersion by deleting the parent ContentDocument object.
    – LewdLime
    Commented Jan 27, 2016 at 0:41
  • I just don't know how to do that when the page has the readonly option set.
    – LewdLime
    Commented Jan 27, 2016 at 0:42

1 Answer 1

1

I've found the solution, but not in the way that I thought I would. Thankfully, either from recent updates to Salesforce, or simply due a lack of understanding on my part (the latter being more likely), the answer is to delete the parent ContentDocument record that is related to each ContentVersion:

  1. Generate a report of files that have been downloaded.

    Or, run a SOQL query on ContentVersionHistory: SELECT Id, Title, ContentVersionId FROM ContentVersionHistory WHERE Field = 'contentVersionDownloaded'

    Which ever way that lets you pull that data and insert it into a temporary relational database like MySQL or MariaDB.

  2. Run a similar query/report on all the ContentVersion records available to the library, and put this in a separate table within the temporary database.

    REMEMBER: You NEED to include the ContentDocumentId for this query or you won't have any way to know which ContentDocument records will need to be removed. For example:

    SELECT Id, ContentDocumentId, Title FROM ContentVersion WHERE FirstPublishLocationId IN (SELECT ParentId FROM ContentDocument)

  3. In the temporary database, run a INNER JOIN query to show a dataset of only the records that have been downloaded and exist in the given library. This is so you filter out any other files that you don't want deleted, or ones that exist outside of the library in question.

  4. Generate a CSV of that dataset from step 3. This is required so that you can just use the Apex Data Loader tool to mass delete the files, rather than use a delete button on each file individually. MySQL Workbench has a save functionality for SQL query results to be saved as a CSV.
  5. Be sure to run the Data Loader with enough heap space to actually function: Add -Xms1024m -Xmx1596m to either the command line batch file, or modify the shortcut that opens the tool to include these flags, or you will get Java heap space errors.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .