dmFile delete protections not working


#1

Hello,

On our FarCry install it appears that when I delete files from the Content > Media & Categories > Document Library that there is nothing in the way of deleting files already associated with content. I did see Justin state elsewhere that this is suppose to be default behavior.

Is there anything obvious that could be getting in the way? I’ve tried looking through our custom side of things and have come up empty so far. Digging through the core side of things it appears that images go through a block of code blocking images in use, dmFile.cfc doesn’t include it’s own delete and appears to go through a more generic function

Anyway, I assume there’s something wacky in our install or configuration. I haven’t been able to find anything custom either, so I’m unsure where to look right now.

Thanks


#2

Hi,
It doesn’t look like dmFile does this by default. I had noticed this not working in the past but put it down to something I’d changed. But I’ve just had a look at the core and it’s missing the delete function in dmFile.cfc. To get this functionality back, you should pretty much copy the dmImage delete function into dmFile.cfc (making the appropriate changes so it refers to dmfile instead of dmimage etc).

Perhaps this should also be updated in core?

Phil


#3

I did quick and dirty invoke to the dmImage delete code as an extension to dmFile and it blocked the delete, but didn’t allow me to delete files. I can try again but go a little deeper and point it to dmFile properly, but I won’t have time to dig in until Moday.

Thanks for the second opinion Phillip, nice to know I’m not alone.


#4

Adding this to the dmFile.cfc worked for me. It blocked the document deletion until I removed it from any rules.

<cffunction name="delete" access="public" hint="Specific delete method for dmFile." returntype="struct">
<cfargument name="objectid" required="yes" type="UUID" hint="Object ID of the object being deleted">

<cfset var stLocal = StructNew()>
<!--- get object details --->
<cfset var stObj = getData(arguments.objectid)>
<cfset var stReturn = StructNew()>
<cfset var relatedTable = "">
<cfset var type	= '' />
<cfset var prop	= '' />

<cfset stReturn.bSuccess = true>
<cfset stReturn.message = "">
	
<cfset stLocal.errormessage = "">

<cfset stLocal.relatedQty = 0 />

<cfloop collection="#application.stcoapi#" item="type">
	<cfif NOT reFindNoCase("^config", type)>
		<cfloop collection="#application.stcoapi[type].stProps#" item="prop">
			<cfif application.stcoapi[type].stProps[prop].metadata.type EQ "array" AND structKeyExists(application.stcoapi[type].stProps[prop].metadata,"ftJoin") and listFindNoCase(application.stcoapi[type].stProps[prop].metadata.ftJoin, "dmFile")>
				<cfquery name="stLocal.qCheck" datasource="#application.dsn#">
				SELECT	parentId
				FROM	#type#_#prop#
				WHERE	data = '#arguments.objectid#'
				</cfquery>
				
				<cfif stLocal.qCheck.recordCount>
					<cfset stLocal.relatedQty = stLocal.relatedQty + stLocal.qCheck.recordCount />
				</cfif>
			<cfelseif application.stcoapi[type].stProps[prop].metadata.type EQ "uuid" AND structKeyExists(application.stcoapi[type].stProps[prop].metadata,"ftJoin") and listFindNoCase(application.stcoapi[type].stProps[prop].metadata.ftJoin, "dmFile")>
				<cfquery name="stLocal.qCheck" datasource="#application.dsn#">
				SELECT	objectid
				FROM	#type#
				WHERE	#prop# = '#arguments.objectid#'
				</cfquery>
				
				<cfif stLocal.qCheck.recordCount>
					<cfset stLocal.relatedQty = stLocal.relatedQty + stLocal.qCheck.recordCount />
				</cfif>			
			</cfif>
		</cfloop>
	</cfif>
</cfloop>

<cfif stLocal.relatedQty GTE 1>
	<cfset stReturn.bSuccess = false>
	<cfset stReturn.message = stReturn.message & "Sorry file [#stObj.label#] cannot be delete because it is associated to <strong>#stLocal.relatedQty#</strong> other item(s).<br />">
	<cfreturn stReturn>
<cfelse>
	<cfreturn super.delete(argumentCollection=arguments) />
</cfif>

#5

Thanks Phillip,

I setup your code on my test server as an extension to the dmFile type from core and it works perfectly. Thanks for the code.

I second the idea that this should be rolled up into core if it isn’t doing it by default after all, I was kind of surprised when I tried a mass clean out on a test server, and glad it was only a test. Wiped out a lot of files that were connected to content.


#6

Phil’s code for overriding delete in dmFile.cfc is the way to go for now, nice work :thumbsup: I thought it was in place for both dmImage and dmFile but it seems that’s not the case.

As you can see from the previous thread ([closed] Associated Content Cannot be Deleted) we have users who want it to work both ways. Ideally, we need to make this more easily configurable globally or per content type, either with a config and/or a component or formtool attribute. This same concept of configuration also applies to archival of related assets, so perhaps we can address both at the same time in a similar manner.