Implementing document in multiple categories for DOCman

I have a requirement to put the same document in two categories, however the standard install of DOCman does not have this functionality. While a document can be copied and the copy put in a different category, this approach would be difficult to maintain when a new version of the document is uploaded. I've seen lots of people asking for this functionality, so I thought I'd document how I've implemented it. If you have a better suggestion or improvements, please leave a comment at the bottom.

I'm using DOCman v1.5.8, so all code references will be applicable to this version only. I have included lots of screen shots, so if your version is different you should at least be able to find the surrounding code even when the line numbers don't match.

WARNING: The below changes modify DOCman core files, and any changes would need to be reapplied if you upgrade the DOCman version on your site. Making these changes is at your own risk, I am not offering any support and will take no responsibility for any consequences of these changes.

First thing you should do is take a full site backup, I recommend using Akeeba Backup. Now that you have a rollback plan, you can start doing some damage :)

I'm going to start by adding a second category field to jos_docman, using phpMyAdmin

ALTER TABLE 'jos_docman' ADD 'catid2' int( 11 )

image001

image003

Now in the back end I'm going to add a second category drop down which uses this catid2 field

image005

 

I've added a variable for this field into the table class

/administrator/components/com_docman/docman.class.php

//line 359 in mosDMDocument() add this line

var $catid2 = null;

image007

 

And in the check function we want to force it to be an integer

//line 470 in check() add this line

$this->catid2 = (int) $this->catid2;

image009

 

/administrator/components/com_docman/includes/documents.php

//line 85, add the following

$catid2 = $mainframe->getUserStateFromRequest("catidarc{option}{$section}", 'catid2', 0);

image011

 

 

//line 98, add the following code

if ($catid2 > 0) {

$where[] = "a.catid2=$catid2";

}

image013

 

//line 129

$query = "SELECT a.*, cc.name AS category, u.name AS editor"

 

//change to

$query = "SELECT a.*, cc.name AS category, dd.name AS category2, u.name AS editor"

 

//line 133, add

. "\n LEFT JOIN #__categories AS dd ON dd.id = a.catid2"

image015

 

 

//160, add

$options2 = array();

$options2[] = JHTML::_('select.option', '0', _DML_SELECT_CAT);

$options2[] = JHTML::_('select.option', '-1', _DML_ALL_CATS);

$lists['catid2'] = dmHTML::categoryList2($catid2, "document.adminForm.submit();", $options2);

image017

 

 

//line 231, add the following

$options2 = array(JHTML::_('select.option','0', _DML_SELECT_CAT));

$lists['catid2'] = dmHTML::categoryList2($doc->catid2, "", $options2);

image019

 

 

/administrator/components/com_docman/includes/documents.html.php

 

//line 294 add

image021

 

 

/administrator/components/com_docman/classes/DOCMAN_html.class.php

//in the dmHTML class around line 138 add the following

function categoryList2($id, $action, $options = array())

{

global $_DOCMAN;

require_once($_DOCMAN->getPath('classes', 'utils'));

$list = DOCMAN_utils::categoryArray();

// assemble menu items to the array

foreach ($list as $item) {

$options[] = JHTML::_('select.option', $item->id, $item->treename);

}

$parent = JHTML::_('select.genericlist',$options, 'catid2', 'id="catid2" class="inputbox" size="1" onchange="' . $action . '"', 'value', 'text', $id);

return $parent;

}

image023

 

 

/administrator/components/com_docman/language/english.common.php

 

//line 59, add

define('_DML_CAT2', "Secondary Category");

image025

 

 

That's about it for the back end. You should now see a second category drop down like this.

image027

 

 

Now for the front end

Now I know this next file is still in the back end, but it effects how the front end categories are looked up.

/administrator/components/com_docman/classes/DOCMAN_utils.class.php

//line 844 (I think it's line 937 in v1.5.9)

$query .= $catid ? "\n AND d.catid IN ($catid) " : "";

 

//change to

$query .= $catid ? "\n AND ((d.catid IN ($catid)) OR (d.catid2 IN ($catid))) " : "";

image029

 

//line 871

$query .= $catid ? "\n AND d.catid IN ($catid) " : "";

//change to

$query .= $catid ? "\n AND ((d.catid IN ($catid)) OR (d.catid2 IN ($catid))) " : "";

image031

 

 

//line 850

$query .= $catid ? "\n WHERE d.catid IN ($catid) " : "";

//change to

$query .= $catid ? "\n WHERE ((d.catid IN ($catid)) OR (d.catid2 IN ($catid))) " : "";

image033

 

 

//line 852

$query .= $catid ? "\n WHERE d.catid IN ($catid) " : "";

//change to

$query .= $catid ? "\n WHERE ((d.catid IN ($catid)) OR (d.catid2 IN ($catid))) " : "";

image035

 

 

//line 855

$query .= $catid ? "\n AND d.catid IN ($catid) " : "";

//change to

$query .= $catid ? "\n AND ((d.catid IN ($catid)) OR (d.catid2 IN ($catid))) " : "";

image037

 

/components/com_docman/includes/documents.php

 

//line 167, add

$options2 = array(JHTML::_('select.option','0', _DML_SELECT_CAT));

image039

 

//line 174, add

$lists['catid2'] = dmHTML::categoryList2($doc->catid2, "", $options2);

image041

 

 

Now the number of files in a category does not include those assigned via the second category drop down. Let's change that.

image043

 

 

/administrator/components/com_docman/classes/DOCMAN_utils.class.php

//line 682, add the following (around line 776 for v1.5.9)

$query = "SELECT catid2, count( d.id ) AS count "

. "\n FROM #__docman AS d";

 

if (!$user->userid/*&& !$_DOCMAN->getCfg('registered')*/) {

$query .= "\n WHERE dmowner=" . _DM_PERMIT_EVERYONE

. "\n AND d.published=1 "

. "\n AND d.approved=1";

} elseif ($user->isSpecial) {

$query .= " ";

} elseif ($user->canApprove()) {

$query .= " ";

} elseif ($user->canPublish()) {

$query .= "\n WHERE d.approved=1";

} elseif ($user->userid) {

$query .= "\n WHERE (dmowner=" . $user->userid

. "\n OR dmmantainedby=" . $user->userid

. "\n OR dmowner=" . _DM_PERMIT_EVERYONE

. "\n OR dmowner=" . _DM_PERMIT_REGISTERED;

if ($user->groupsIn != '0,0') {

$query .= "\n OR dmowner IN (" . $user->groupsIn . ")";

}

$query .= "\n)";

$query .= "\n AND d.published=1"

. "\n AND d.approved=1";

}

$query .= "\n GROUP BY d.catid2";

 

// Performance: each query should only be executed once

static $docresults = array();

if( !isset( $docresults[$query])) {

$database->setQuery($query);

$docresults[$query] = $database->loadObjectList('catid2');

}

$docs2 = & $docresults[$query];

 

 

//line 741 (around line 836 for v1.5.9)

if (isset($docs2[$catid])) {

$total += $docs2[$catid]->count;

}

image045

 

 

Now the secondary categories are being counted too

image047

 

Ok, now we need to add a second category drop down to the front end

image049

 

 

/components/com_docman/includes/documents.html.php

 

//line 75, add some code for the second category drop down

image051

 

image053

 

All done. Now you can put the same document into two different categories.

 

Comments  

 
0 #6 Tim Plummer 2013-01-26 11:22
Quoting skp:
Hi.. Thank you so much for your post..
I have a query.. Plz tell me..
can I save a document with two files??

No I don't think you can have two files, each document is a single file.
Quote
 
 
0 #5 skp 2013-01-22 19:41
Hi.. Thank you so much for your post..
I have a query.. Plz tell me..
can I save a document with two files??
and I want to download these two files separately from front end.. It should have to different download links with each file.. Please help..
Thanks in advance..
Quote
 
 
0 #4 Hammy 2013-01-08 21:52
Fantastic, thanks.
Quote
 
 
0 #3 michel_ 2012-12-18 23:47
If the user has access to the second catagory, but not the first the download button will nog show.

Fix:
In /administrator/components/com_docman/classes/DOCMAN_user.class.php in function canDownload change:

//check if user has access to the document's category
if(!$this->canAccessCatego ry($doc->catid)) {
return false;
}

to:

//check if user has access to the document's category
if(!$this->canAccessCatego ry($doc->catid) && !$this->canAccessCatego ry($doc->catid2)) {
return false;
}
Quote
 
 
0 #2 Arioch 2012-02-01 01:05
Thank you very much, it was exactly what I needed.

Just one thing: the back end does not indicate how many files are connected to each category (in the Category section of the Docman component).

So, if, like me, you prefer to know how many documents are related to each category without having to go the front end:
// In /administrator/components/com_docman/includes/categories.php
// on l. 118
// Replace
. "\n WHERE d.catid = " . $list[$i]->id;
// with
. "\n WHERE d.catid = " . $list[$i]->id
. "\n OR d.catid2 = " . $list[$i]->id;
Quote
 
 
0 #1 thpbt 2012-01-24 01:18
Excellent, this was really helpful and thorough, thanks.
Quote
 

Add comment


Security code
Refresh