diff --git a/browse.php b/browse.php index 2a93344..0acd99e 100755 --- a/browse.php +++ b/browse.php @@ -48,6 +48,8 @@ require_once(KT_LIB_DIR . "/permissions/permission.inc.php"); require_once(KT_LIB_DIR . '/users/userhistory.inc.php'); +require_once(KT_LIB_DIR . '/browse/columnregistry.inc.php'); + /******* NBM's FAMOUS MOVECOLUMN HACK * * Also in /plugins/ktcore/KTDocumentActions.php @@ -218,43 +220,18 @@ class BrowseDispatcher extends KTStandardDispatcher { } function do_main() { - $collection = new DocumentCollection; - - - $collection->addColumn(new SelectionColumn("Browse Selection","selection")); - $collection->addColumn(new TitleColumn("Test 1 (title)","title")); - $collection->addColumn(new DownloadColumn('','download')); - $collection->addColumn(new DateColumn(_kt("Created"),"created", "getCreatedDateTime")); - $collection->addColumn(new DateColumn(_kt("Last Modified"),"modified", "getLastModifiedDate")); - $collection->addColumn(new UserColumn(_kt('Creator'),'creator_id','getCreatorID')); - $collection->addColumn(new WorkflowColumn(_kt('Workflow State'),'workflow_state')); - - - // setup the folderside add actions - // FIXME do we want to use folder actions? - - $batchPage = (int) KTUtil::arrayGet($_REQUEST, "page", 0); - $batchSize = 20; + $collection = new AdvancedCollection; + $oColumnRegistry = KTColumnRegistry::getSingleton(); + $aColumns = $oColumnRegistry->getColumnsForView('ktcore.views.browse'); + $collection->addColumns($aColumns); + $aOptions = $collection->getEnvironOptions(); // extract data from the environment - $collection->setBatching($this->resultURL, $batchPage, $batchSize); + $aOptions['result_url'] = $this->resultURL; - - // ordering. (direction and column) - $displayOrder = KTUtil::arrayGet($_REQUEST, 'sort_order', "asc"); - if ($displayOrder !== "asc") { $displayOrder = "desc"; } - $displayControl = KTUtil::arrayGet($_REQUEST, 'sort_on', "title"); - - - $collection->setSorting($displayControl, $displayOrder); - - // add in the query object. - $qObj = $this->oQuery; - $collection->setQueryObject($qObj); - - // breadcrumbs - // FIXME handle breadcrumbs - $collection->getResults(); + $collection->setOptions($aOptions); + $collection->setQueryObject(new BrowseQuery("1", $this->oUser, array('ignorepermissions' => false))); + $oTemplating =& KTTemplating::getSingleton(); $oTemplate = $oTemplating->loadTemplate("kt3/browse"); diff --git a/docs/VERSION.txt b/docs/VERSION.txt index 5f5f468..a3951bb 100644 --- a/docs/VERSION.txt +++ b/docs/VERSION.txt @@ -1 +1 @@ -3.0.3.3 +3.0.3.4 diff --git a/lib/browse/BrowseColumns.inc.php b/lib/browse/BrowseColumns.inc.php index bef5ac8..97cf9f7 100644 --- a/lib/browse/BrowseColumns.inc.php +++ b/lib/browse/BrowseColumns.inc.php @@ -65,9 +65,9 @@ class BrowseColumn { $href .= $this->sort_direction = "asc"; } - return ''.$text.''; - + return ''.$text.''; } + function renderData($aDataRow) { if ($aDataRow["type"] == "folder") { return $this->name . ": ". print_r($aDataRow["folder"]->getName(), true); diff --git a/lib/browse/DocumentCollection.inc.php b/lib/browse/DocumentCollection.inc.php index b1894b0..84e11a4 100644 --- a/lib/browse/DocumentCollection.inc.php +++ b/lib/browse/DocumentCollection.inc.php @@ -59,7 +59,7 @@ class DocumentCollection { var $sort_column; var $sort_order; - + /* initialisation */ // columns should be added in the "correct" order (e.g. display order) @@ -240,4 +240,319 @@ class DocumentCollection { } } +/* + * Secondary class: AdvancedCollection + * + * Handles slightly more details of how the collections should work. Ultimately, this should + * replace DocumentCollection everywhere + */ + + +class AdvancedCollection { + + // handle the sorting, etc. + var $_sFolderJoinClause = null; + var $_aFolderJoinParams = null; + var $_sFolderSortField = null; + var $_sDocumentJoinClause = null; + var $_aDocumentJoinParams = null; + var $_sDocumentSortField = null; + var $_queryObj = null; + var $sort_column; + var $sort_order; + + // current documents (in _this_ batch.) + var $activeset = null; + + var $_documentData = array(); // [docid] => array(); + var $_folderData = array(); // [folderid] => array(); + var $columns = array(); // the columns in use + + var $returnURL = null; + + var $folderCount = 0; + var $documentCount = 0; + var $itemCount = 0; + var $batchStart = 0; // if batch specified a "start". + var $batchPage = 0; + var $batchSize = 20; // size of the batch // FIXME make this configurable. + + var $aOptions = array(); + var $bShowFolders = true; + var $bShowDocuments = true; + + var $_gotData = false; + var $_sorted = false; + + + /* initialisation */ + function setOptions($aOptions) { + $this->aOptions = $aOptions; + + // batching + $this->batchPage = KTUtil::arrayGet($aOptions, 'batch_page', 0); + $this->batchSize = KTUtil::arrayGet($aOptions, 'batch_size', 25); + $this->batchStart = $this->batchPage * $this->batchSize; + + // visibility + $this->bShowFolders = KTUtil::arrayGet($aOptions, 'show_folders', true); + $this->bShowDocuments = KTUtil::arrayGet($aOptions, 'show_documents', true); + + // sorting + $this->sort_column = KTUtil::arrayGet($aOptions, 'sort_on', "ktcore.columns.title"); + $this->sort_order = KTUtil::arrayGet($aOptions, 'sort_order', 'asc'); + + // url options + $this->returnURL = KTUtil::arrayGet($aOptions, 'return_url', $_SERVER['PHP_SELF']); + } + + + // we use a lot of standard variable names for these (esp. in columns.) + // no need to replicate the code everywhere. + function getEnvironOptions() { + $aNewOptions = array(); + + // batching + $aNewOptions['batch_page'] = (int) KTUtil::arrayGet($_REQUEST, "page", 0); + $aNewOptions['batch_size'] = KTUtil::arrayGet($_REQUEST, "page_size", 25); + + // ordering. (direction and column) + $aNewOptions['sort_on'] = KTUtil::arrayGet($_REQUEST, 'sort_on', "ktcore.columns.title"); + $displayOrder = KTUtil::arrayGet($_REQUEST, 'sort_order', "asc"); + if ($displayOrder !== "asc") { $displayOrder = "desc"; } + $aNewOptions['sort_order'] = $displayOrder; + + // probably URL + $aNewOptions['result_url'] = $_SERVER['PHP_SELF']; + + // return the environ options + return $aNewOptions; + } + + function setColumnOptions($sColumnNamespace, $aOptions) { + foreach ($this->columns as $key => $oColumn) { + if ($oColumn->namespace == $sColumnNamespace) { + $this->columns[$key]->setOptions($aOptions); + } + } + } + + // columns should be added in the "correct" order (e.g. display order) + function addColumn($oBrowseColumn) { array_push($this->columns, $oBrowseColumn); } + function addColumns($aColumns) { $this->columns = kt_array_merge($this->columns, $aColumns); } + function setQueryObject($oQueryObj) { $this->_queryObj = $oQueryObj; } + + /* fetch cycle */ + function setSorting() { + + $this->_sorted = true; + + // defaults + $this->_sDocumentSortField = "DM.name"; + $this->_sFolderSortField = "F.name"; + + foreach ($this->columns as $key => $oColumn) { + if ($oColumn->namespace == $this->sort_column) { + $this->columns[$key]->setSortedOn(true); + $this->columns[$key]->setSortDirection($this->sort_order); + + // get the join params from the object. + $aFQ = $this->columns[$key]->addToFolderQuery(); + $aDQ = $this->columns[$key]->addToDocumentQuery(); + + $this->_sFolderJoinClause = $aFQ[0]; + $this->_aFolderJoinParams = $aFQ[1]; + + if ($aFQ[2]) { $this->_sFolderSortField = $aFQ[2]; } + $this->_sDocumentJoinClause = $aDQ[0]; + $this->_aDocumentJoinParams = $aDQ[1]; + + if ($aDQ[2]) { + $this->_sDocumentSortField = $aDQ[2]; } + } else { + $oColumn->setSortedOn(false); + } + } + } + + + // finally, generate the results. either (documents or folders) could be null/empty + // FIXME handle column-for-sorting (esp. md?) + function getResults() { + + if ($this->_gotInfo == true) { + return; + } + + // this impacts the query used. + if (!$this->_sorted) { + $this->setSorting(); + } + + // work out how many of each item type we're going to expect. + if ($this->bShowFolders) { + $this->folderCount = $this->_queryObj->getFolderCount(); + if (PEAR::isError($this->folderCount)) { + $_SESSION['KTErrorMessage'][] = $this->folderCount->toString(); + $this->folderCount = 0; + } + } else { + $this->folderCount = 0; + } + + if ($this->bShowDocuments) { + $this->documentCount = $this->_queryObj->getDocumentCount(); + if (PEAR::isError($this->documentCount)) { + $_SESSION['KTErrorMessage'][] = $this->documentCount->toString(); + $this->documentCount = 0; + } + } else { + $this->documentCount = 0; + } + + $this->itemCount = $this->documentCount + $this->folderCount; + + // now we need the active set: this is based on the batchsize, + // batchstart. this is divided into folders/documents. (_no_ intermingling). + $folderSet = null; + $documentSet = null; + + // assume we have not documents. This impacts "where" our documents start. + // + $no_folders = true; + $documents_to_get = $this->batchSize; + $folders_to_get = 0; + + if ($this->batchStart < $this->folderCount) { + $no_folders = false; + $folders_to_get = $this->folderCount - $this->batchStart; + if ($folders_to_get > $this->batchSize) { + $folders_to_get = $this->batchSize; + $documents_to_get = 0; + } else { + $documents_to_get -= $folders_to_get; // batch-size less the folders. + } + } + + if ($no_folders) { + $this->batchStart -= $this->folderCount; + $documentSet = $this->_queryObj->getDocuments($documents_to_get, + $this->batchStart, + $this->_sDocumentSortField, + $this->sort_order, + $this->_sDocumentJoinClause, + $this->_aDocumentJoinParams); + } else { + $folderSet = $this->_queryObj->getFolders($folders_to_get, + $this->batchStart, + $this->_sFolderSortField, + $this->sort_order, + $this->_sFolderJoinQuery, + $this->_aFolderJoinParams); + + // if we're getting -any- documents this round, then get some. + if ($documents_to_get > 0) { + $documentSet = $this->_queryObj->getDocuments($documents_to_get, + 0, + $this->_sDocumentSortField, + $this->sort_order, + $this->_sDocumentJoinClause, + $this->_aDocumentJoinParams); + } + } + + if (PEAR::isError($folderSet)) { + $_SESSION['KTErrorMessage'][] = sprintf(_kt("Failed to retrieve folders: %s"), $folderSet->getMessage()); + $folderSet = array(); + $this->folderCount = 0; + } + + if (PEAR::isError($documentSet)) { + $_SESSION['KTErrorMessage'][] = sprintf(_kt("Failed to retrieve documents: %s"), $documentSet->getMessage()); + //var_dump($documentSet); exit(0); + $documentSet = array(); + $this->documentCount = 0; + + } + + $this->itemCount = $this->documentCount + $this->folderCount; + + $this->activeset = array( + "folders" => $folderSet, + "documents" => $documentSet, + ); + + $this->_gotInfo = true; // don't do this twice ... + } + + // stub: fetch all relevant information about a document (that will reasonably be fetched). + function getDocumentInfo($iDocumentId) { + if (array_key_exists($iDocumentId, $this->_documentData)) { + return $this->_documentData[$iDocumentId]; + } else { + $this->_documentData[$iDocumentId] = $this->_retrieveDocumentInfo($iDocumentId); + return $this->_documentData[$iDocumentId]; + } + } + + function _retrieveDocumentInfo($iDocumentId) { + $row_info = array("docid" => $iDocumentId); + $row_info["type"] = "document"; + $row_info["document"] =& Document::get($iDocumentId); + return $row_info; + } + + // FIXME get more document info. + function getFolderInfo($iFolderId) { + if (array_key_exists($iFolderId, $this->_folderData)) { + return $this->_folderData[$iFolderId]; + } else { + $this->_folderData[$iFolderId] = $this->_retrieveFolderInfo($iFolderId); + return $this->_folderData[$iFolderId]; + } + } + + // FIXME get more folder info. + function _retrieveFolderInfo($iFolderId) { + $row_info = array("folderid" => $iFolderId); + $row_info["type"] = "folder"; + $row_info["folder"] =& Folder::get($iFolderId); + + return $row_info; + } + + // render a particular row. + function renderRow($iDocumentId) { ; } + + // link url for a particular page. + function pageLink($iPageNumber) { + $qs = sprintf("page=%s&sort_on=%s&sort_order=%s", $iPageNumber, $this->sort_column, $this->sort_order); + return KTUtil::addQueryString($this->returnURL, $qs); + } + + function render() { + $this->setSorting(); + $this->getResults(); + + // sort out the batch + $pagecount = (int) floor($this->itemCount / $this->batchSize); + if (($this->itemCount % $this->batchSize) != 0) { + $pagecount += 1; + } + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate("kt3/document_collection"); + $aTemplateData = array( + "context" => $this, + "pagecount" => $pagecount, + "currentpage" => $this->batchPage, + "returnURL" => $this->returnURL, + "columncount" => count($this->columns), + ); + + // in order to allow OTHER things than batch to move us around, we do: + return $oTemplate->render($aTemplateData); + } +} + ?> diff --git a/lib/browse/advancedcolumns.inc.php b/lib/browse/advancedcolumns.inc.php new file mode 100644 index 0000000..fa73f20 --- /dev/null +++ b/lib/browse/advancedcolumns.inc.php @@ -0,0 +1,93 @@ +label = _kt('Base Column'); + } + + // meld the internal vars with those from the options. + function setOptions($aOptions = null) { + $this->aOptions = kt_array_merge($this->aOptions, $aOptions); + $this->sortable = KTUtil::arrayGet($this->aOptions, 'sortable', $this->sortable); + $this->return_url = KTUtil::arrayGet($this->aOptions, 'return_url', $this->return_url); + $this->sort_on = KTUtil::arrayGet($this->aOptions, 'sort_on', $this->sort_on); + $this->sort_direction = KTUtil::arrayGet($this->aOptions, 'sort_on', $this->sort_direction); + } + + /* + return the html for the header. + + "return url" : URL to return to (or null to use addQueryStringSelf) + */ + function renderHeader() { + // short-circuit + if (empty($this->label)) { return ''; } + // for safety + $label = htmlentities($this->label, ENT_NOQUOTES, 'UTF-8'); + + // without sorthing to sort on, don't bother. + if (empty($this->namespace)) { + $this->sortable = false; // if we haven't set which column we're sorted by, do nothing. + } + + // no sorting, no link + if (!$this->sortable) { + return $label; + } + + // merge the sorting options into the header. + $sort_order = $this->sort_direction == "asc" ? "desc" : "asc"; + $qs = sprintf("sort_on=%s&sort_order=%s", $this->namespace, $sort_order); + if (is_null($this->return_url)) { + $url = KTUtil::addQueryStringSelf($qs); + } else { + $url = KTUtil::addQueryString($this->return_url, $qs); + } + + return sprintf('%s', $url, $label); + } + + function renderData($aDataRow) { + if ($aDataRow["type"] == "folder") { + return $this->name . ": ". $aDataRow["folder"]->getName(); + } else { + return $this->name . ": ". $aDataRow["document"]->getName(); + } + } + + function setSortedOn($bIsSortedOn) { $this->sort_on = $bIsSortedOn; } + function getSortedOn() { return $this->sort_on; } + function setSortDirection($sSortDirection) { $this->sort_direction = $sSortDirection; } + function getSortDirection() { return $this->sort_direction; } + + function addToFolderQuery() { return array(null, null, null); } + function addToDocumentQuery() { return array(null, null, null); } + + function getName() { + return $this->label; + } + + function getEntryId() { + return KTUtil::arrayGet($this->aOptions, 'column_id', null); + } + + function getRequiredInView() { + return KTUtil::arrayGet($this->aOptions, 'required_in_view', null); + } + +} + +?> \ No newline at end of file diff --git a/lib/browse/columnentry.inc.php b/lib/browse/columnentry.inc.php new file mode 100644 index 0000000..5414c2b --- /dev/null +++ b/lib/browse/columnentry.inc.php @@ -0,0 +1,92 @@ + 'id', + 'sColumnNamespace' => 'column_namespace', + 'sViewNamespace' => 'view_namespace', + 'iPosition' => 'position', + 'sConfigArray' => 'config_array', + 'bRequired' => 'required' + ); + + var $_bUsePearError = true; + + function getColumnNamespace() { return $this->sColumnNamespace; } + function setColumnNamespace($sNewValue) { $this->sColumnNamespace = $sNewValue; } + function getViewNamespace() { return $this->sViewNamespace; } + function setViewNamespace($sNewValue) { $this->sViewNamespace = $sNewValue; } + function getPosition() { return $this->iPosition; } + function setPosition($iNewValue) { $this->iPosition = $iNewValue; } + function getConfigArray() { return unserialize($this->sConfigArray); } + function setConfigArray($aNewValue) { $this->sConfigArray = serialize($aNewValue); } + function getRequired() { return $this->bRequired; } + function setRequired($bNewValue) { $this->bRequired = $bNewValue; } + + + function _fieldValues () { return array( + 'column_namespace' => $this->sColumnNamespace, + 'view_namespace' => $this->sViewNamespace, + 'config_array' => $this->sConfigArray, + 'position' => $this->iPosition, + 'required' => $this->bRequired, + ); + } + + function _table () { return KTUtil::getTableName('column_entries'); } + function get($iEntryId) { return KTEntityUtil::get('KTColumnEntry', $iEntryId); } + function & getList($sWhereClause = null) { return KTEntityUtil::getList2('KTColumnEntry', $sWhereClause); } + function & createFromArray($aOptions) { + // transparently convert the options. + + $aOptions['configarray'] = serialize(KTUtil::arrayGet($aOptions, 'config', array())); + unset($aOptions['config']); + + return KTEntityUtil::createFromArray('KTColumnEntry', $aOptions); + } + + function & getByView($sViewNamespace, $aOptions = null) { + if (is_null($aOptions)) { $aOptions = array(); } + $aOptions['multi'] = true; + $aSelect = array('view_namespace' => $sViewNamespace); + + return KTEntityUtil::getByDict('KTColumnEntry', $aSelect, $aOptions); + } + +} +?> \ No newline at end of file diff --git a/lib/browse/columnregistry.inc.php b/lib/browse/columnregistry.inc.php new file mode 100644 index 0000000..818a809 --- /dev/null +++ b/lib/browse/columnregistry.inc.php @@ -0,0 +1,100 @@ +columns[$sNamespace] = array( + 'name' => $sName, + 'namespace' => $sNamespace, + 'class' => $sClass, + 'file' => $sFile + ); + } + + function getViewName($sNamespace) { return KTUtil::arrayGet($this->views, $sNamespace); } + function getViews() { return $this->views; } + function getColumns() { return $this->columns; } + function registerView($sName, $sNamespace) { $this->views[$sNamespace] = $sName; } + + function getColumnInfo($sNamespace) { + return KTUtil::arrayGet($this->columns, $sNamespace, null); + } + + function getColumn($sNamespace) { + $aInfo = KTUtil::arrayGet($this->columns, $sNamespace, null); + if (empty($aInfo)) { + return PEAR::raiseError(sprintf(_kt("No such column: %s"), $sNamespace)); + } + + require_once($aInfo['file']); + + return new $aInfo['class']; + } + + function getColumnsForView($sViewNamespace) { + $view_entry = KTUtil::arrayGet($this->views, $sViewNamespace); + if (is_null($view_entry)) { + return PEAR::raiseError(sprintf(_kt("No such view: %s"), $sViewNamespace)); + } + + $view_column_entries = KTColumnEntry::getByView($sViewNamespace); + if (PEAR::isError($view_column_entries)) { + return $view_column_entries; + } + + $view_columns = array(); + foreach ($view_column_entries as $oEntry) { + $res = $this->getColumn($oEntry->getColumnNamespace()); + if (PEAR::isError($res)) { return $res; } + + $aOptions = $oEntry->getConfigArray(); + $aOptions['column_id'] = $oEntry->getId(); + $aOptions['required_in_view'] = $oEntry->getRequired(); + $res->setOptions($aOptions); + + $view_columns[] = $res; + } + + return $view_columns; + } +} + +?> diff --git a/lib/plugins/plugin.inc.php b/lib/plugins/plugin.inc.php index 0f95342..e49bcac 100644 --- a/lib/plugins/plugin.inc.php +++ b/lib/plugins/plugin.inc.php @@ -52,6 +52,8 @@ class KTPlugin { var $_aLanguage = array(); var $_aHelpLanguage = array(); var $_aWFTriggers = array(); + var $_aColumns = array(); + var $_aViews = array(); function KTPlugin($sFilename = null) { $this->sFilename = $sFilename; @@ -140,6 +142,15 @@ class KTPlugin { function registerHelpLanguage($sPlugin, $sLanguage, $sBasedir) { $this->_aHelpLanguage[$sLanguage] = array($sPlugin, $sLanguage, $sBasedir); } + + function registerColumn($sName, $sNamespace, $sClassName, $sFile) { + $sFile = $this->_fixFilename($sFile); + $this->_aColumns[$sNamespace] = array($sName, $sNamespace, $sClassName, $sFile); + } + + function registerView($sName, $sNamespace) { + $this->_aViews[$sNamespace] = array($sName, $sNamespace); + } function _fixFilename($sFilename) { if (empty($sFilename)) { @@ -198,6 +209,7 @@ class KTPlugin { require_once(KT_LIB_DIR . "/i18n/i18nregistry.inc.php"); require_once(KT_LIB_DIR . "/help/help.inc.php"); require_once(KT_LIB_DIR . "/workflow/workflowutil.inc.php"); + require_once(KT_LIB_DIR . "/browse/columnregistry.inc.php"); $oPRegistry =& KTPortletRegistry::getSingleton(); $oTRegistry =& KTTriggerRegistry::getSingleton(); @@ -209,6 +221,7 @@ class KTPlugin { $oi18nRegistry =& KTi18nRegistry::getSingleton(); $oKTHelpRegistry =& KTHelpRegistry::getSingleton(); $oWFTriggerRegistry =& KTWorkflowTriggerRegistry::getSingleton(); + $oColumnRegistry =& KTColumnRegistry::getSingleton(); foreach ($this->_aPortlets as $k => $v) { call_user_func_array(array(&$oPRegistry, 'registerPortlet'), $v); @@ -261,6 +274,14 @@ class KTPlugin { foreach ($this->_aWFTriggers as $k => $v) { call_user_func_array(array(&$oWFTriggerRegistry, 'registerWorkflowTrigger'), $v); } + + foreach ($this->_aColumns as $k => $v) { + call_user_func_array(array(&$oColumnRegistry, 'registerColumn'), $v); + } + + foreach ($this->_aViews as $k => $v) { + call_user_func_array(array(&$oColumnRegistry, 'registerView'), $v); + } } function setup() { diff --git a/plugins/ktcore/KTColumns.inc.php b/plugins/ktcore/KTColumns.inc.php new file mode 100644 index 0000000..ce685c1 --- /dev/null +++ b/plugins/ktcore/KTColumns.inc.php @@ -0,0 +1,378 @@ +label = _kt("Title"); + } + + // what is used for sorting + // query addition is: + // [0] => join claus + // [1] => join params + // [2] => ORDER + + function addToFolderQuery() { + return array(null, + null, + "F.name", + ); + } + function addToDocumentQuery() { + return array(null, + null, + "DM.name" + ); + } + + + function renderFolderLink($aDataRow) { + $outStr = ''; + $outStr .= htmlentities($aDataRow["folder"]->getName(), ENT_NOQUOTES, 'UTF-8'); + $outStr .= ' '; + return $outStr; + } + + function renderDocumentLink($aDataRow) { + $outStr = 'getFilename().'">'; + $outStr .= htmlentities($aDataRow["document"]->getName(), ENT_NOQUOTES, 'UTF-8'); + $outStr .= ''; + return $outStr; + } + + function buildDocumentLink($aDataRow) { + return KTBrowseUtil::getUrlForDocument($aDataRow["document"]->getId()); + } + + function buildFolderLink($aDataRow) { + if (is_null(KTUtil::arrayGet($this->aOptions, 'direct_folder'))) { + return KTUtil::addQueryStringSelf('fFolderId='.$aDataRow["folder"]->getId()); + } else { + return KTBrowseUtil::getUrlForFolder($aDataRow['folder']); + } + } + + // use inline, since its just too heavy to even _think_ about using smarty. + function renderData($aDataRow) { + if ($aDataRow["type"] == "folder") { + $contenttype = 'folder'; + $link = $this->renderFolderLink($aDataRow); + return sprintf('%s', $contenttype, $link); + } else { + $contenttype = $this->_mimeHelper($aDataRow["document"]->getMimeTypeId()); + $link = $this->renderDocumentLink($aDataRow); + $size = $this->prettySize($aDataRow["document"]->getSize()); + return sprintf('%s (%s)', $contenttype, $link, $size); + } + } + + function prettySize($size) { + $finalSize = $size; + $label = 'b'; + + if ($finalSize > 1000) { $label='Kb'; $finalSize = floor($finalSize/1000); } + if ($finalSize > 1000) { $label='Mb'; $finalSize = floor($finalSize/1000); } + return $finalSize . $label; + } + + function _mimeHelper($iMimeTypeId) { + require_once(KT_LIB_DIR . '/mime.inc.php'); + return KTMime::getIconPath($iMimeTypeId); + } +} + +/* + * Column to handle dates + */ + +class AdvancedDateColumn extends AdvancedColumn { + var $document_field_function; + var $folder_field_function; + var $sortable = true; + var $document_sort_column; + var $folder_sort_column; + var $namespace = 'ktcore.columns.genericdate'; + + function AdvancedDateColumn() { + $this->label = _kt('Generic Date Function'); + } + + // use inline, since its just too heavy to even _think_ about using smarty. + function renderData($aDataRow) { + $outStr = ''; + if (($aDataRow["type"] == "folder") && (!is_null($this->folder_field_function))) { + $res = call_user_func(array($aDataRow["folder"], $this->folder_field_function)); + $dColumnDate = strtotime($res); + + // now reformat this into something "pretty" + return date("Y-m-d H:i", $dColumnDate); + + } else if (($aDataRow["type"] == "document") && (!is_null($this->document_field_function))) { + $res = call_user_func(array($aDataRow["document"], $this->document_field_function)); + $dColumnDate = strtotime($res); + + // now reformat this into something "pretty" + return date("Y-m-d H:i", $dColumnDate); + } else { + return '—'; + } + return $outStr; + } + + function addToFolderQuery() { + return array(null, null, null); + } + function addToDocumentQuery() { + return array(null, null, $this->name); + } +} + +class CreationDateColumn extends AdvancedDateColumn { + var $document_field_function = 'getCreatedDateTime'; + var $folder_field_function = null; + + var $document_sort_column = "D.created"; + var $folder_sort_column = null; + var $namespace = 'ktcore.columns.creationdate'; + + function CreationDateColumn() { + $this->label = _kt('Created'); + } +} + +class ModificationDateColumn extends AdvancedDateColumn { + var $document_field_function = 'getLastModifiedDate'; + var $folder_field_function = null; + + var $document_sort_column = "D.modified"; + var $folder_sort_column = null; + var $namespace = 'ktcore.columns.modificationdate'; + + function ModificationDateColumn() { + $this->label = _kt('Modified'); + } +} + +class AdvancedUserColumn extends AdvancedColumn { + var $document_field_function; + var $folder_field_function; + var $sortable = false; // by default + var $document_sort_column; + var $folder_sort_column; + var $namespace = 'ktcore.columns.genericuser'; + + function AdvancedUserColumn() { + $this->label = null; // abstract. + } + + // use inline, since its just too heavy to even _think_ about using smarty. + function renderData($aDataRow) { + $iUserId = null; + if (($aDataRow["type"] == "folder") && (!is_null($this->folder_field_function))) { + if (method_exists($aDataRow['folder'], $this->folder_field_function)) { + $iUserId = call_user_func(array($aDataRow['folder'], $this->folder_field_function)); + } + } else if (($aDataRow["type"] == "document") && (!is_null($this->document_field_function))) { + if (method_exists($aDataRow['document'], $this->document_field_function)) { + $iUserId = call_user_func(array($aDataRow['document'], $this->document_field_function)); + } + } + if (is_null($iUserId)) { + return '—'; + } + $oUser = User::get($iUserId); + if (PEAR::isError($oUser) || $oUser == false) { + return '—'; + } else { + return htmlentities($oUser->getName(), ENT_NOQUOTES, 'UTF-8'); + } + } + + function addToFolderQuery() { + return array(null, null, null); + } + + function addToDocumentQuery() { + return array(null, null, null); + } +} + +class CreatorColumn extends AdvancedUserColumn { + var $document_field_function = "getCreatorID"; + var $folder_field_function = null; + var $sortable = true; // by default + var $namespace = 'ktcore.columns.creator'; + + function CreatorColumn() { + $this->label = _kt("Creator"); // abstract. + } + + function addToFolderQuery() { + return array(null, null, null); + } + function addToDocumentQuery() { + $sUsersTable = KTUtil::getTableName('users'); + $sJoinSQL = "LEFT JOIN $sUsersTable AS users_order_join ON (D.creator_id = users_order_join.id)"; + return array($sJoinSQL, null, "users_order_join.name"); + } +} + +class AdvancedSelectionColumn extends AdvancedColumn { + var $rangename = null; + var $show_folders = true; + var $show_documents = true; + + var $namespace = "ktcore.columns.selection"; + + function AdvancedSelectionColumn() { + $this->label = ''; + } + + function setOptions($aOptions) { + AdvancedColumn::setOptions($aOptions); + $this->rangename = KTUtil::arrayGet($this->aOptions, 'rangename', $this->rangename); + $this->show_folders = KTUtil::arrayGet($this->aOptions, 'show_folders', $this->show_folders); + $this->show_documents = KTUtil::arrayGet($this->aOptions, 'show_documents', $this->show_documents); + } + + function renderHeader($sReturnURL) { + global $main; + $main->requireJSResource("resources/js/toggleselect.js"); + + return sprintf('', $this->rangename); + + } + + // only include the _f or _d IF WE HAVE THE OTHER TYPE. + function renderData($aDataRow) { + $localname = $this->rangename; + + if (($aDataRow["type"] === "folder") && ($this->show_folders)) { + if ($this->show_documents) { + $localname .= "_f[]"; + } + $v = $aDataRow["folderid"]; + } else if (($aDataRow["type"] === "document") && $this->show_documents) { + if ($this->show_folders) { + $localname .= "_d[]"; + } + $v = $aDataRow["docid"]; + } else { + return ' '; + } + + return sprintf('', $localname, $v); + } + + + // no label, but we do have a title + function getName() { + return _kt("Multiple Selection"); + } +} + + +class AdvancedSingleSelectionColumn extends AdvancedSelectionColumn { + var $namespace = 'ktcore.columns.singleselection'; + + function AdvancedSingleSelectionColumn() { + parent::AdvancedSelectionColumn(); + $this->label = null; + } + + function renderHeader() { + return ' '; + } + + // only include the _f or _d IF WE HAVE THE OTHER TYPE. + function renderData($aDataRow) { + $localname = $this->name; + + if (($aDataRow["type"] === "folder") && ($this->show_folders)) { + if ($this->show_documents) { + $localname .= "_f"; + } + $v = $aDataRow["folderid"]; + } else if (($aDataRow["type"] === "document") && $this->show_documents) { + if ($this->show_folders) { + $localname .= "_d"; + } + $v = $aDataRow["docid"]; + } else { + return ' '; + } + + return ''; + } + + // no label, but we do have a title + function getName() { + return _kt("Single Selection"); + } +} + + +class AdvancedWorkflowColumn extends AdvancedColumn { + var $namespace = 'ktcore.columns.workflow_state'; + var $sortable = false; + + function AdvancedWorkflowColumn() { + $this->label = _kt("Workflow State"); + $this->sortable = false; + } + + // use inline, since its just too heavy to even _think_ about using smarty. + function renderData($aDataRow) { + // only _ever_ show this for documents. + if ($aDataRow["type"] === "folder") { + return ' '; + } + + $oWorkflow = KTWorkflowUtil::getWorkflowForDocument($aDataRow['document']); + $oState = KTWorkflowUtil::getWorkflowStateForDocument($aDataRow['document']); + if (($oState == null) || ($oWorkflow == null)) { + return '—'; + } else { + return sprintf('%s %s', + htmlentities($oState->getName(), ENT_NOQUOTES, 'UTF-8'), + htmlentities($oWorkflow->getName(), ENT_NOQUOTES, 'UTF-8') + ); + } + } +} + +class AdvancedDownloadColumn extends AdvancedColumn { + + var $namespace = 'ktcore.columns.download'; + + function AdvancedDownloadColumn() { + $this->label = null; + } + + function renderData($aDataRow) { + // only _ever_ show this for documents. + if ($aDataRow["type"] === "folder") { + return ' '; + } + + $link = KTUtil::ktLink('action.php','ktcore.actions.document.view', 'fDocumentId=' . $aDataRow['document']->getId()); + return sprintf('%s', $link, _kt('Download Document'), _kt('Download Document')); + } + + function getName() { return _kt('Download'); } +} + +?> \ No newline at end of file diff --git a/plugins/ktcore/KTCorePlugin.php b/plugins/ktcore/KTCorePlugin.php index f47c362..60628ba 100644 --- a/plugins/ktcore/KTCorePlugin.php +++ b/plugins/ktcore/KTCorePlugin.php @@ -91,6 +91,18 @@ class KTCorePlugin extends KTPlugin { $this->registerPortlet(array('administration'), 'KTAdminSectionNavigation', 'ktcore.portlets.adminnavigation', 'KTPortlets.php'); + + $this->registerColumn(_kt("Title"), 'ktcore.columns.title', 'AdvancedTitleColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Selection"), 'ktcore.columns.selection', 'AdvancedSelectionColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Single Selection"), 'ktcore.columns.singleselection', 'AdvancedSingleSelectionColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Workflow State"), 'ktcore.columns.workflow_state', 'AdvancedWorkflowColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Creation Date"), 'ktcore.columns.creationdate', 'CreationDateColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Modification Date"), 'ktcore.columns.modificationdate', 'ModificationDateColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Creator"), 'ktcore.columns.creator', 'CreatorColumn', 'KTColumns.inc.php'); + $this->registerColumn(_kt("Download File"), 'ktcore.columns.download', 'AdvancedDownloadColumn', 'KTColumns.inc.php'); + + $this->registerView(_kt("Browse Documents"), 'ktcore.views.browse'); + $this->registerView(_kt("Search"), 'ktcore.views.search'); // workflow triggers $this->registerWorkflowTrigger('ktcore.workflowtriggers.permissionguard', 'PermissionGuardTrigger', 'KTWorkflowTriggers.inc.php'); @@ -185,6 +197,10 @@ class KTCorePlugin extends KTPlugin { $this->registerAdminPage("cleanup", 'ManageCleanupDispatcher', 'misc', _kt('Verify document storage'), _kt('Performs a check to see if the documents in your repositories all are stored on the back-end storage (usually on disk).'), 'admin/manageCleanup.php', null); + $this->registerAdminPage("views", 'ManageViewDispatcher', 'misc', + _kt('Manage views'), _kt('Allows you to specify the columns that are to be used by a particular view (e.g. Browse documents, Search)'), + 'admin/manageViews.php', null); + // plugins } diff --git a/plugins/ktcore/admin/manageViews.php b/plugins/ktcore/admin/manageViews.php new file mode 100644 index 0000000..baa3ade --- /dev/null +++ b/plugins/ktcore/admin/manageViews.php @@ -0,0 +1,109 @@ +aBreadcrumbs[] = array('url' => $_SERVER['PHP_SELF'], 'name' => _kt('Manage Views')); + return parent::check(); + } + + function do_main() { + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('ktcore/misc/columns/select_view'); + + $oColumnRegistry =& KTColumnRegistry::getSingleton(); + + $aViews = $oColumnRegistry->getViews(); + + $aTemplateData = array( + 'context' => $this, + 'views' => $aViews, + ); + return $oTemplate->render($aTemplateData); + } + + function do_editView() { + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('ktcore/misc/columns/edit_view'); + + $oColumnRegistry =& KTColumnRegistry::getSingleton(); + $aColumns = $oColumnRegistry->getColumnsForView($_REQUEST['viewNS']); + //var_dump($aColumns); exit(0); + $aAllColumns = $oColumnRegistry->getColumns(); + + $view_name = $oColumnRegistry->getViewName($_REQUEST['viewNS']); + $this->oPage->setTitle($view_name); + $this->oPage->setBreadcrumbDetails($view_name); + + $aOptions = array(); + $vocab = array(); + foreach ($aAllColumns as $aInfo) { + $vocab[$aInfo['namespace']] = $aInfo['name']; + } + $aOptions['vocab'] = $vocab; + $add_field = new KTLookupWidget(_kt("Columns"), _kt("Select a column to add to the view. Please note that while you can add multiple copies of a column, they will all behave as a single column"), 'column_ns', null, $this->oPage, true, null, $aErrors = null, $aOptions); + + $aTemplateData = array( + 'context' => $this, + 'current_columns' => $aColumns, + 'all_columns' => $aAllColumns, + 'view' => $_REQUEST['viewNS'], + 'add_field' => $add_field, + ); + return $oTemplate->render($aTemplateData); + } + + function do_deleteEntry() { + $entry_id = KTUtil::arrayGet($_REQUEST, 'entry_id'); + $view = KTUtil::arrayGet($_REQUEST, 'viewNS'); + + // none of these conditions can be reached "normally". + + $oEntry = KTColumnEntry::get($entry_id); + if (PEAR::isError($oEntry)) { + $this->errorRedirectToMain(_kt("Unable to locate the entry")); + } + + if ($oEntry->getRequired()) { + $this->errorRedirectToMain(_kt("That column is required")); + } + + if ($oEntry->getViewNamespace() != $view) { + $this->errorRedirectToMain(_kt("That column is not for the specified view")); + } + + $res = $oEntry->delete(); + + if (PEAR::isError($res)) { + $this->errorRedirectToMain(sprintf(_kt("Failed to remove that column: %s"), $res->getMessage())); + } + + $this->successRedirectTo("editView", _kt("Deleted Entry"), sprintf("viewNS=%s", $view)); + } + + function do_addEntry() { + $column_ns = KTUtil::arrayGet($_REQUEST, 'column_ns'); + $view = KTUtil::arrayGet($_REQUEST, 'viewNS'); + + $this->startTransaction(); + + $oEntry = KTColumnEntry::createFromArray(array( + 'ColumnNamespace' => $column_ns, + 'ViewNamespace' => $view, + 'Position' => 1000, // start it at the bottom + 'config' => array(), // stub, for now. + 'Required' => 0 + )); + + $this->successRedirectTo("editView", _kt("Added Entry"), sprintf("viewNS=%s", $view)); + } + +} + +?> \ No newline at end of file diff --git a/search/booleanSearch.php b/search/booleanSearch.php index 7c397d3..21c456d 100755 --- a/search/booleanSearch.php +++ b/search/booleanSearch.php @@ -97,91 +97,91 @@ class BooleanSearchDispatcher extends KTStandardDispatcher { } function do_saveSearch() { - $this->startTransaction(); - - $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSearchId', false); - $sName = KTUtil::arrayGet($_REQUEST, 'name', false); - $sSearch = KTUtil::arrayGet($_REQUEST, 'boolean_search'); - - if($iSearchId === false && $sName === false) { - $this->errorRedirectTo('performSearch', _kt('Please either enter a name, or select a search to save over'), sprintf('boolean_search_id=%s', $sSearch)); - exit(0); - } - - $datavars = $_SESSION['boolean_search'][$sSearch]; - if (!is_array($datavars)) { - $datavars = unserialize($datavars); + $this->startTransaction(); + + $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSearchId', false); + $sName = KTUtil::arrayGet($_REQUEST, 'name', false); + $sSearch = KTUtil::arrayGet($_REQUEST, 'boolean_search'); + + if($iSearchId === false && $sName === false) { + $this->errorRedirectTo('performSearch', _kt('Please either enter a name, or select a search to save over'), sprintf('boolean_search_id=%s', $sSearch)); + exit(0); } - - if (empty($datavars)) { - $this->errorRedirectToMain(_kt('You need to have at least 1 condition.')); + + $datavars = $_SESSION['boolean_search'][$sSearch]; + if (!is_array($datavars)) { + $datavars = unserialize($datavars); + } + + if (empty($datavars)) { + $this->errorRedirectToMain(_kt('You need to have at least 1 condition.')); + } + + if($iSearchId) { + $oSearch = KTSavedSearch::get($iSearchId); + if(PEAR::isError($oSearch) || $oSearch == false) { + $this->errorRedirectToMain(_kt('No such search')); + exit(0); + } + $oSearch->setSearch($datavars); + $oSearch = $oSearch->update(); + + } else { + $sName = $this->oValidator->validateEntityName('KTSavedSearch', + KTUtil::arrayGet($_REQUEST, 'name'), + array('extra_condition' => 'not is_condition', 'redirect_to' => array('new'))); + + $sNamespace = KTUtil::nameToLocalNamespace('Saved searches', $sName); + + $oSearch = KTSavedSearch::createFromArray(array('name' => $sName, + 'namespace' => $sNamespace, + 'iscondition' => false, + 'iscomplete' => true, + 'userid' => $this->oUser->getId(), + 'search' => $datavars,)); } - - if($iSearchId) { - $oSearch = KTSavedSearch::get($iSearchId); - if(PEAR::isError($oSearch) || $oSearch == false) { - $this->errorRedirectToMain(_kt('No such search')); - exit(0); - } - $oSearch->setSearch($datavars); - $oSearch = $oSearch->update(); - - } else { - $sName = $this->oValidator->validateEntityName('KTSavedSearch', - KTUtil::arrayGet($_REQUEST, 'name'), - array('extra_condition' => 'not is_condition', 'redirect_to' => array('new'))); - - $sNamespace = KTUtil::nameToLocalNamespace('Saved searches', $sName); - - $oSearch = KTSavedSearch::createFromArray(array('name' => $sName, - 'namespace' => $sNamespace, - 'iscondition' => false, - 'iscomplete' => true, - 'userid' => $this->oUser->getId(), - 'search' => $datavars,)); - } - - $this->oValidator->notError($oSearch, array( - 'redirect_to' => 'main', - 'message' => _kt('Search not saved'), - )); - - $this->commitTransaction(); + + $this->oValidator->notError($oSearch, array( + 'redirect_to' => 'main', + 'message' => _kt('Search not saved'), + )); + + $this->commitTransaction(); $this->successRedirectTo('performSearch', _kt('Search saved'), sprintf('boolean_search_id=%s', $sSearch)); } function do_deleteSearch() { - $this->startTransaction(); - - $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSavedSearchId', false); - $oSearch = KTSavedSearch::get($iSearchId); - if(PEAR::isError($oSearch) || $oSearch == false) { - $this->errorRedirectToMain(_kt('No such search')); - exit(0); - } - - $res = $oSearch->delete(); - $this->oValidator->notError($res, array( - 'redirect_to' => 'main', - 'message' => _kt('Error deleting search'), - )); - - $this->commitTransaction(); - - $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false); - $iDocumentId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false); - - if($iFolderId) { - controllerRedirect('browse', 'fFolderId=' . $iFolderId); - } else { - controllerRedirect('viewDocument', 'fDocumentId=' . $iDocumentId); - } + $this->startTransaction(); + + $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSavedSearchId', false); + $oSearch = KTSavedSearch::get($iSearchId); + if(PEAR::isError($oSearch) || $oSearch == false) { + $this->errorRedirectToMain(_kt('No such search')); + exit(0); + } + + $res = $oSearch->delete(); + $this->oValidator->notError($res, array( + 'redirect_to' => 'main', + 'message' => _kt('Error deleting search'), + )); + + $this->commitTransaction(); + + $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false); + $iDocumentId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false); + + if($iFolderId) { + controllerRedirect('browse', 'fFolderId=' . $iFolderId); + } else { + controllerRedirect('viewDocument', 'fDocumentId=' . $iDocumentId); + } } function do_editSearch() { $sSearch = KTUtil::arrayGet($_REQUEST, 'boolean_search'); - $aSearch = $_SESSION['boolean_search'][$sSearch]; + $aSearch = $_SESSION['boolean_search'][$sSearch]; if (!is_array($aSearch)) { $aSearch = unserialize($aSearch); } @@ -233,66 +233,58 @@ class BooleanSearchDispatcher extends KTStandardDispatcher { } $this->oPage->setBreadcrumbDetails($sTitle); - $collection = new DocumentCollection; - $this->browseType = "Folder"; - - //$collection->addColumn(new SelectionColumn("Browse Selection","selection")); - $t =& new TitleColumn("Test 1 (title)","title"); - $t->setOptions(array('documenturl' => $GLOBALS['KTRootUrl'] . '/view.php')); - $collection->addColumn($t); - $collection->addColumn(new DownloadColumn('','download')); - $collection->addColumn(new DateColumn(_kt("Created"),"created", "getCreatedDateTime")); - $collection->addColumn(new DateColumn(_kt("Last Modified"),"modified", "getLastModifiedDate")); - $collection->addColumn(new UserColumn(_kt('Creator'),'creator_id','getCreatorID')); - $collection->addColumn(new WorkflowColumn(_kt('Workflow State'),'workflow_state')); + $this->browseType = "Folder"; $searchable_text = KTUtil::arrayGet($_REQUEST, "fSearchableText"); - - $batchPage = (int) KTUtil::arrayGet($_REQUEST, "page", 0); - $batchSize = 20; - $sSearch = md5(serialize($aCriteriaSet)); $_SESSION['boolean_search'][$sSearch] = $aCriteriaSet; - $resultURL = KTUtil::addQueryStringSelf("action=performSearch&boolean_search_id=" . urlencode($sSearch)); - $collection->setBatching($resultURL, $batchPage, $batchSize); - // ordering. (direction and column) - $displayOrder = KTUtil::arrayGet($_REQUEST, 'sort_order', "asc"); - if ($displayOrder !== "asc") { $displayOrder = "desc"; } - $displayControl = KTUtil::arrayGet($_REQUEST, 'sort_on', "title"); - - $collection->setSorting($displayControl, $displayOrder); + $collection = new AdvancedCollection; + $oColumnRegistry = KTColumnRegistry::getSingleton(); + $aColumns = $oColumnRegistry->getColumnsForView('ktcore.views.search'); + $collection->addColumns($aColumns); + + // set a view option + $aTitleOptions = array( + 'documenturl' => $GLOBALS['KTRootUrl'] . '/view.php', + ); + $collection->setColumnOptions('ktcore.columns.title', $aTitleOptions); + + $aOptions = $collection->getEnvironOptions(); // extract data from the environment + + $aOptions['result_url'] = KTUtil::addQueryStringSelf("action=performSearch&boolean_search_id=" . urlencode($sSearch)); + + $collection->setOptions($aOptions); + $collection->setQueryObject(new BooleanSearchQuery($aCriteriaSet)); - // add in the query object. - $qObj = new BooleanSearchQuery($aCriteriaSet); - $collection->setQueryObject($qObj); + //$a = new BooleanSearchQuery($aCriteriaSet); + //var_dump($a->getDocumentCount()); exit(0); - // form fields for saving the search + // form fields for saving the search $save_fields = array(); $save_fields[] = new KTStringWidget(_kt('New search'), _kt('The name to save this search as'), 'name', null, $this->oPage, true); - $aUserSearches = KTSavedSearch::getUserSearches($this->oUser->getId(), true); - if(count($aUserSearches)) { - $aVocab = array('' => ' ---- '); - foreach($aUserSearches as $oSearch) { - $aVocab[$oSearch->getId()] = $oSearch->getName(); - } - - $aSelectOptions = array('vocab' => $aVocab); - $save_fields[] = new KTLookupWidget(_kt('Existing search'), _kt('To save over one of your existing searches, select it here.'), 'fSearchId', null, $this->oPage, true, null, null, $aSelectOptions); - } - - $collection->getResults(); + $aUserSearches = KTSavedSearch::getUserSearches($this->oUser->getId(), true); + if(count($aUserSearches)) { + $aVocab = array('' => ' ---- '); + foreach($aUserSearches as $oSearch) { + $aVocab[$oSearch->getId()] = $oSearch->getName(); + } + + $aSelectOptions = array('vocab' => $aVocab); + $save_fields[] = new KTLookupWidget(_kt('Existing search'), _kt('To save over one of your existing searches, select it here.'), 'fSearchId', null, $this->oPage, true, null, null, $aSelectOptions); + } + $oTemplating =& KTTemplating::getSingleton(); $oTemplate = $oTemplating->loadTemplate("kt3/browse"); $aTemplateData = array( - "context" => $this, - "collection" => $collection, - "custom_title" => $sTitle, - "save_fields" => $save_fields, - "boolean_search" => $sSearch, + "context" => $this, + "collection" => $collection, + "custom_title" => $sTitle, + "save_fields" => $save_fields, + "boolean_search" => $sSearch, ); return $oTemplate->render($aTemplateData); } diff --git a/search/simpleSearch.php b/search/simpleSearch.php index b3f6e5c..18e87de 100644 --- a/search/simpleSearch.php +++ b/search/simpleSearch.php @@ -34,9 +34,10 @@ require_once(KT_LIB_DIR . "/browse/DocumentCollection.inc.php"); require_once(KT_LIB_DIR . "/browse/BrowseColumns.inc.php"); require_once(KT_LIB_DIR . "/browse/PartialQuery.inc.php"); - require_once(KT_LIB_DIR . "/foldermanagement/Folder.inc"); +require_once(KT_LIB_DIR . '/browse/columnregistry.inc.php'); + class SimpleSearchTitleColumn extends TitleColumn { function setSearch($sSearch) { $this->sSearch = $sSearch; @@ -137,58 +138,40 @@ class SimpleSearchDispatcher extends KTStandardDispatcher { $aErrorOptions = array( "message" => _kt("Please provide a search term"), ); - $searchable_text = KTUtil::arrayGet($_REQUEST, "fSearchableText"); + $searchable_text = KTUtil::arrayGet($_REQUEST, "fSearchableText"); $this->oValidator->notEmpty($searchable_text, $aErrorOptions); - $collection = new DocumentCollection; - $this->browseType = "Folder"; - - //$collection->addColumn(new SelectionColumn("Browse Selection","selection")); - /* - $t = new SimpleSearchTitleColumn("Test 1 (title)","title"); - $t->setOptions(array('documenturl' => $GLOBALS['KTRootUrl'] . '/view.php')); - $t->setSearch($searchable_text); - */ - - $t =& new TitleColumn("Test 1 (title)","title"); - $t->setOptions(array('documenturl' => $GLOBALS['KTRootUrl'] . '/view.php', 'direct_folder' => true)); - $collection->addColumn($t); - $collection->addColumn(new DownloadColumn('','download')); - $collection->addColumn(new DateColumn(_kt("Created"),"created", "getCreatedDateTime")); - $collection->addColumn(new DateColumn(_kt("Last Modified"),"modified", "getLastModifiedDate")); - $collection->addColumn(new UserColumn(_kt('Creator'),'creator_id','getCreatorID')); - $collection->addColumn(new WorkflowColumn(_kt('Workflow State'),'workflow_state')); - - $batchPage = (int) KTUtil::arrayGet($_REQUEST, "page", 0); - $batchSize = 20; - - $resultURL = KTUtil::addQueryStringSelf("fSearchableText=" . $searchable_text); - $collection->setBatching($resultURL, $batchPage, $batchSize); - - - // ordering. (direction and column) - $displayOrder = KTUtil::arrayGet($_REQUEST, 'sort_order', "asc"); - if ($displayOrder !== "asc") { $displayOrder = "desc"; } - $displayControl = KTUtil::arrayGet($_REQUEST, 'sort_on', "title"); - - $collection->setSorting($displayControl, $displayOrder); - - // add in the query object. - $qObj = new SimpleSearchQuery($searchable_text); - $collection->setQueryObject($qObj); - - // breadcrumbs - // FIXME handle breadcrumbs - $collection->getResults(); - - $oTemplating =& KTTemplating::getSingleton(); - $oTemplate = $oTemplating->loadTemplate("kt3/browse"); - $aTemplateData = array( - "context" => $this, - "collection" => $collection, - ); - return $oTemplate->render($aTemplateData); - } + + $this->browseType = "Folder"; + + + $collection = new AdvancedCollection; + $oColumnRegistry = KTColumnRegistry::getSingleton(); + $aColumns = $oColumnRegistry->getColumnsForView('ktcore.views.search'); + $collection->addColumns($aColumns); + + // set a view option + $aTitleOptions = array( + 'documenturl' => $GLOBALS['KTRootUrl'] . '/view.php', + 'direct_folder' => true, + ); + $collection->setColumnOptions('ktcore.columns.title', $aTitleOptions); + + $aOptions = $collection->getEnvironOptions(); // extract data from the environment + + $aOptions['result_url'] = KTUtil::addQueryStringSelf("fSearchableText=" . $searchable_text); + + $collection->setOptions($aOptions); + $collection->setQueryObject(new SimpleSearchQuery($searchable_text)); + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate("kt3/browse"); + $aTemplateData = array( + "context" => $this, + "collection" => $collection, + ); + return $oTemplate->render($aTemplateData); + } } $oDispatcher = new SimpleSearchDispatcher(); diff --git a/templates/ktcore/misc/columns/edit_view.smarty b/templates/ktcore/misc/columns/edit_view.smarty new file mode 100644 index 0000000..fdde0a7 --- /dev/null +++ b/templates/ktcore/misc/columns/edit_view.smarty @@ -0,0 +1,46 @@ +
{i18n}The columns included in this view are displayed below. To add additional columns into the +view, use the form below the list. To remove items, click on the "delete" icon next to the column name. Note that some columns may be required +in a given view. Also, while you can +have multiple copies of a given column in a specific view this is not recommended.{/i18n}
+ +{if (!empty($current_columns))} +| {i18n}Column{/i18n} | +{i18n}Delete{/i18n} | +|
|---|---|---|
| {$oColumn->getName()} | + + {if $oColumn->getRequiredInView()} +— | + {else} +{i18n}Delete{/i18n} | + {/if} +
{i18n}No columns have been added to this view{/i18n}
{i18n}Views are the selections of documents and folders you will find throughout KnowledgeTree. Some of those +can be configured to use different kinds of columns (e.g. workflow state, the creator's name, etc.){/i18n}
+ +