| 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 )
Now in the back end I'm going to add a second category drop down which uses this catid2 field
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;
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;
/administrator/components/com_docman/includes/documents.php //line 85, add the following $catid2 = $mainframe->getUserStateFromRequest("catidarc{option}{$section}", 'catid2', 0);
//line 98, add the following code if ($catid2 > 0) { $where[] = "a.catid2=$catid2"; }
//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"
//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);
//line 231, add the following $options2 = array(JHTML::_('select.option','0', _DML_SELECT_CAT)); $lists['catid2'] = dmHTML::categoryList2($doc->catid2, "", $options2);
/administrator/components/com_docman/includes/documents.html.php
//line 294 add
/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; }
/administrator/components/com_docman/language/english.common.php
//line 59, add define('_DML_CAT2', "Secondary Category");
That's about it for the back end. You should now see a second category drop down like this.
Now for the front endNow 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))) " : "";
//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))) " : "";
//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))) " : "";
//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))) " : "";
//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))) " : "";
/components/com_docman/includes/documents.php
//line 167, add $options2 = array(JHTML::_('select.option','0', _DML_SELECT_CAT));
//line 174, add $lists['catid2'] = dmHTML::categoryList2($doc->catid2, "", $options2);
Now the number of files in a category does not include those assigned via the second category drop down. Let's change that.
/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; }
Now the secondary categories are being counted too
Ok, now we need to add a second category drop down to the front end
/components/com_docman/includes/documents.html.php
//line 75, add some code for the second category drop down
All done. Now you can put the same document into two different categories. |
Comments
No I don't think you can have two files, each document is a single file.
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..
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;
}
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;
RSS feed for comments to this post