Commit ea511ccdc0dac9f7d38c3714dbab5c7e7d16eeff

Authored by kevin_fourie
1 parent f2698927

Merged in from DEV trunk...

KTC-263
"Internal RSS feed does not work on FF but partially works on IE"
Fixed. Added a check on whether an external feed is pointing to an internal document.

Committed by: Megan Watson
Reviewed by: Conrad Vermeulen

KTC-266
"The 'Dashboard' External RSS feed dashlet does not support password authenticated feeds"

Fixed. Added a better error message for authenticated rss feeds.

Committed By: Jonathan Byrne
Reviewed By: Kevin Fourie

KTS-2750
"Allow/enable multiple documents to be selected when attempting to link documents"
Fixed. Changed the collection to use the advanced selection. Removed the collection widget and added breadcrumbs. The collection widget wasn't using the mochikit correctly.

KEP-121
"Links to or from external world"
Fixed. Added a link to the Links action to add an external url as a link.

Committed by: Megan Watson
Reviewed by: Conrad Vermeulen


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/STABLE/trunk@7849 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/documentmanagement/DocumentLink.inc
... ... @@ -8,32 +8,32 @@
8 8 * KnowledgeTree Open Source Edition
9 9 * Document Management Made Simple
10 10 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
11   - *
  11 + *
12 12 * This program is free software; you can redistribute it and/or modify it under
13 13 * the terms of the GNU General Public License version 3 as published by the
14 14 * Free Software Foundation.
15   - *
  15 + *
16 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 19 * details.
20   - *
  20 + *
21 21 * You should have received a copy of the GNU General Public License
22 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23   - *
  23 + *
24 24 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
25 25 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
26   - *
  26 + *
27 27 * The interactive user interfaces in modified source and object code versions
28 28 * of this program must display Appropriate Legal Notices, as required under
29 29 * Section 5 of the GNU General Public License version 3.
30   - *
  30 + *
31 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 32 * these Appropriate Legal Notices must retain the display of the "Powered by
33   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
34 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
35   - * must display the words "Powered by KnowledgeTree" and retain the original
36   - * copyright notice.
  35 + * must display the words "Powered by KnowledgeTree" and retain the original
  36 + * copyright notice.
37 37 * Contributor( s): ______________________________________
38 38 *
39 39 *
... ... @@ -50,6 +50,10 @@ class DocumentLink extends KTEntity {
50 50 var $iChildDocumentId;
51 51 /** type of link */
52 52 var $iLinkTypeId;
  53 + /** external url */
  54 + var $sTargetUrl;
  55 + /** external name */
  56 + var $sTargetName;
53 57  
54 58  
55 59 var $_aFieldToSelect = array(
... ... @@ -57,6 +61,8 @@ class DocumentLink extends KTEntity {
57 61 'iParentDocumentId' => 'parent_document_id',
58 62 'iChildDocumentId' => 'child_document_id',
59 63 'iLinkTypeId' => 'link_type_id',
  64 + 'sTargetUrl' => 'external_url',
  65 + 'sTargetName' => 'external_name',
60 66 );
61 67  
62 68  
... ... @@ -68,13 +74,15 @@ class DocumentLink extends KTEntity {
68 74 * @param Link type primary key
69 75 *
70 76 */
71   - function DocumentLink($iNewParentDocumentID = null, $iNewChildDocumentID = null, $iLinkTypeId = null) {
  77 + function DocumentLink($iNewParentDocumentID = null, $iNewChildDocumentID = null, $iLinkTypeId = null, $sTargetUrl = null, $sTargetName = null) {
72 78 //object not created yet
73 79 global $default;
74 80 $this->iId = -1;
75 81 $this->iParentDocumentId = $iNewParentDocumentID;
76 82 $this->iChildDocumentId = $iNewChildDocumentID;
77 83 $this->iLinkTypeId = $iLinkTypeId;
  84 + $this->sTargetUrl = $sTargetUrl;
  85 + $this->sTargetName = $sTargetName;
78 86 }
79 87  
80 88 function getID() { return $this->iId; }
... ... @@ -84,6 +92,10 @@ class DocumentLink extends KTEntity {
84 92 function setChildDocumentID($iNewValue) { $this->iChildDocumentId = $iNewValue; }
85 93 function getLinkTypeID() { return $this->iLinkTypeId; }
86 94 function setLinkTypeID($iNewValue) { $this->iLinkTypeId = $iNewValue; }
  95 + function getTargetUrl() { return $this->sTargetUrl; }
  96 + function setTargetUrl($iNewValue) { $this->sTargetUrl = $iNewValue; }
  97 + function getTargetName() { return $this->sTargetName; }
  98 + function setTargetName($iNewValue) { $this->sTargetName = $iNewValue; }
87 99  
88 100 /**
89 101 * Helper getters
... ... @@ -118,6 +130,8 @@ class DocumentLink extends KTEntity {
118 130 'parent_document_id' => $this->iParentDocumentId,
119 131 'child_document_id' => $this->iChildDocumentId,
120 132 'link_type_id' => $this->iLinkTypeId,
  133 + 'external_url' => $this->sTargetUrl,
  134 + 'external_name' => $this->sTargetName,
121 135 );
122 136 }
123 137  
... ... @@ -126,29 +140,33 @@ class DocumentLink extends KTEntity {
126 140 return $default->document_link_table;
127 141 }
128 142  
129   -
130 143 // static boilerplate
131 144 function & get($iDocumentLinkID) {
132   - global $default;
133   -
134   - $sql = $default->db;
135   - $result = $sql->query(array("SELECT * FROM $default->document_link_table WHERE id = ?", $iDocumentLinkID));/*ok*/
136   - if ($result) {
137   - if ($sql->next_record()) {
138   - $oDocumentLink = new DocumentLink($sql->f("parent_document_id"), $sql->f("child_document_id"), $sql->f("link_type_id"));
139   - $oDocumentLink->iId = $sql->f("id");
140   - return $oDocumentLink;
141   - }
142   - $_SESSION["errorMessage"] = $lang_err_object_not_exist."id = ".$iDocumentLinkID." table = $default->document_link_table";
143   - return false;
144   - }
145   - $_SESSION["errorMessage"] = $lang_err_database;
146   - return false;
  145 + $table = DocumentLink::_table();
  146 + $query = "SELECT * FROM $table WHERE id = '$iDocumentLinkID'";
  147 + $result = DBUtil::getOneResult($query);
  148 +
  149 + if(PEAR::isError($result)) {
  150 + $_SESSION['errorMessage'] = $result->getMessage();
  151 + return false;
  152 + }
  153 +
  154 + if(!empty($result)){
  155 + $oDocumentLink = new DocumentLink($result['parent_document_id'], $result['child_document_id'], $result['link_type_id'], $result['external_url'], $result['external_name']);
  156 + $oDocumentLink->iId = $result['id'];
  157 + return $oDocumentLink;
  158 + }
  159 + $_SESSION['errorMessage'] = _kt('The object does not exist. id = '.$iDocumentLinkID.' table = '.$table);
  160 + return false;
147 161 }
  162 +
148 163 function getList($sWhereClause = null) {
149 164 return KTEntityUtil::getList2('DocumentLink', $sWhereClause);
150 165 }
151   - function &createFromArray($aArray) { return KTEntityUtil::createFromArray('DocumentLink', $aArray); }
  166 +
  167 + function &createFromArray($aArray) {
  168 + return KTEntityUtil::createFromArray('DocumentLink', $aArray);
  169 + }
152 170  
153 171 /**
154 172 * Static function
... ... @@ -159,7 +177,8 @@ class DocumentLink extends KTEntity {
159 177 * @return Array array of DocumentLink objects, false otherwise.
160 178 */
161 179 function getLinksFromDocument($iDocumentId) {
162   - return KTEntityUtil::getList2('DocumentLink', sprintf("parent_document_id = %d", $iDocumentId));
  180 + $sWhere = "parent_document_id = $iDocumentId AND child_document_id != $iDocumentId";
  181 + return KTEntityUtil::getList2('DocumentLink', $sWhere);
163 182 }
164 183  
165 184 /**
... ... @@ -171,8 +190,22 @@ class DocumentLink extends KTEntity {
171 190 * @return Array array of DocumentLink objects, false otherwise.
172 191 */
173 192 function getLinksToDocument($iDocumentId) {
174   - return KTEntityUtil::getList2('DocumentLink', sprintf("child_document_id = %d", $iDocumentId));
  193 + $sWhere = "child_document_id = $iDocumentId AND parent_document_id != $iDocumentId";
  194 + return KTEntityUtil::getList2('DocumentLink', $sWhere);
  195 + }
  196 +
  197 + /**
  198 + * Static function
  199 + * Get a list of external DocumentLinks where iDocumentId is the parent
  200 + *
  201 + * @param Integer Document ID of parent
  202 + *
  203 + * @return Array array of DocumentLink objects, false otherwise.
  204 + */
  205 + function getExternalLinks($iDocumentId) {
  206 + $sWhere = "child_document_id = $iDocumentId AND parent_document_id = $iDocumentId";
  207 + return KTEntityUtil::getList2('DocumentLink', $sWhere);
175 208 }
176 209 }
177 210  
178 211 -?>
  212 +?>
179 213 \ No newline at end of file
... ...
lib/validation/dispatchervalidation.inc.php
... ... @@ -5,32 +5,32 @@
5 5 * KnowledgeTree Open Source Edition
6 6 * Document Management Made Simple
7 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8   - *
  8 + *
9 9 * This program is free software; you can redistribute it and/or modify it under
10 10 * the terms of the GNU General Public License version 3 as published by the
11 11 * Free Software Foundation.
12   - *
  12 + *
13 13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 16 * details.
17   - *
  17 + *
18 18 * You should have received a copy of the GNU General Public License
19 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20   - *
  20 + *
21 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23   - *
  23 + *
24 24 * The interactive user interfaces in modified source and object code versions
25 25 * of this program must display Appropriate Legal Notices, as required under
26 26 * Section 5 of the GNU General Public License version 3.
27   - *
  27 + *
28 28 * In accordance with Section 7(b) of the GNU General Public License version 3,
29 29 * these Appropriate Legal Notices must retain the display of the "Powered by
30   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
31 31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
32   - * must display the words "Powered by KnowledgeTree" and retain the original
33   - * copyright notice.
  32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 34 * Contributor( s): ______________________________________
35 35 *
36 36 */
... ... @@ -222,10 +222,10 @@ class KTDispatcherValidation {
222 222  
223 223 $iMaxlen = (int)KTUtil::arrayGet($aOptions, 'max_str_len', false);
224 224 if($iMaxlen !== false && $iMaxlen !== 0 && strlen($sString) > $iMaxlen) {
225   - $aOptions['message'] = KTUtil::arrayGet($aOptions,
226   - 'max_str_len_message',
  225 + $aOptions['message'] = KTUtil::arrayGet($aOptions,
  226 + 'max_str_len_message',
227 227 _kt("The string is too long: the maximum length in characters is ") . $iMaxlen);
228   - $this->handleError($aOptions);
  228 + $this->handleError($aOptions);
229 229 }
230 230  
231 231 return $sString;
... ... @@ -238,8 +238,8 @@ class KTDispatcherValidation {
238 238 'message', _kt("An empty string was given"));
239 239 $this->handleError($aOptions);
240 240 }
241   -
242   - // illegal characters: /\ <>|%+':"?*
  241 +
  242 + // illegal characters: /\ <>|%+':"?*
243 243 $pattern = "[\*|\%|\\\|\/|\<|\>|\+|\:|\?|\||\'|\"]";
244 244 if(preg_match($pattern, $sString)){
245 245 $sChars = "\/<>|%+*':\"?";
... ... @@ -262,20 +262,20 @@ class KTDispatcherValidation {
262 262 if(!is_numeric($sInteger)) {
263 263 $aOptions['message'] = KTUtil::arrayGet($aOptions, 'message', _kt("A non-numeric value was given"));
264 264 $this->handleError($aOptions);
265   - }
  265 + }
266 266  
267 267 return intval($sInteger);
268 268 }
269 269  
270 270 function validateFile($aFile, $aOptions = null) {
271 271 $bError = false;
272   -
  272 +
273 273 if (strlen(trim($aFile['name'])) == 0) {
274 274 $bError = true;
275 275 } else {
276 276 $bError = KTUtil::arrayGet($aFile, 'error');
277 277 }
278   -
  278 +
279 279 if ($bError) {
280 280 $message = _kt("You did not select a valid document to upload");
281 281  
... ... @@ -388,29 +388,29 @@ class KTDispatcherValidation {
388 388 }
389 389 return $oEntity;
390 390 }
391   -
392   -
393   -
394   -
395   -
  391 +
  392 +
  393 +
  394 +
  395 +
396 396 /* unlike the KTEmail version, this only handles ONE email address */
397 397 function validateEmailAddress($sEmailAddress, $aOptions = null) {
398 398 $sEmailAddress = trim($sEmailAddress);
399   -
  399 +
400 400 if (!ereg ("^[^@ ]+@[^@ ]+\.[^@ \.]+$", $sEmailAddress )) {
401 401 $aOptions['message'] = KTUtil::arrayGet($aOptions,
402   - 'message',
  402 + 'message',
403 403 _kt("This is not a valid email address."));
404 404 $this->handleError($aOptions);
405 405 }
406 406 return $sEmailAddress;
407 407 }
408   -
409   -
  408 +
  409 +
410 410 /* just does an empty string validation with an appropriate message, and then a duplicate name validation */
411 411 function validateEntityName($sEntityTypeName, $sName, $aOptions = null) {
412 412 $aOptions['message'] = KTUtil::arrayGet($aOptions, 'empty_message', _kt("No name was given for this item"));
413   -
  413 +
414 414 $sName = $this->validateString($sName, $aOptions);
415 415 $aOptions['message'] = KTUtil::arrayGet($aOptions, 'duplicate_message', _kt("An item with this name already exists"));
416 416 return $this->validateDuplicateName($sEntityTypeName, $sName, $aOptions);
... ... @@ -446,8 +446,16 @@ class KTDispatcherValidation {
446 446 $aOptions['message'] = _kt('Password and confirmation password do not match');
447 447 $this->handleError($aOptions);
448 448 }
449   -
450 449  
  450 + function validateUrl($sUrl, $aOptions = null) {
  451 + $sUrl = trim($sUrl);
  452 +
  453 + if(!((bool) preg_match("'^[^:]+:(?:[0-9a-z\.\?&-_=\+\/]+[\.]{1})*(?:[0-9a-z\.\?&-_=\+\/]+\.)[a-z]{2,3}.*$'i", $sUrl))){
  454 + $aOptions['message'] = KTUtil::arrayGet($aOptions, 'message', _kt('This is not a valid URL.'));
  455 + $this->handleError($aOptions);
  456 + }
  457 + return $sUrl;
  458 + }
451 459 }
452 460  
453 461 ?>
... ...
plugins/ktstandard/KTDocumentLinks.php
... ... @@ -5,32 +5,32 @@
5 5 * KnowledgeTree Open Source Edition
6 6 * Document Management Made Simple
7 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8   - *
  8 + *
9 9 * This program is free software; you can redistribute it and/or modify it under
10 10 * the terms of the GNU General Public License version 3 as published by the
11 11 * Free Software Foundation.
12   - *
  12 + *
13 13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 16 * details.
17   - *
  17 + *
18 18 * You should have received a copy of the GNU General Public License
19 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20   - *
  20 + *
21 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23   - *
  23 + *
24 24 * The interactive user interfaces in modified source and object code versions
25 25 * of this program must display Appropriate Legal Notices, as required under
26 26 * Section 5 of the GNU General Public License version 3.
27   - *
  27 + *
28 28 * In accordance with Section 7(b) of the GNU General Public License version 3,
29 29 * these Appropriate Legal Notices must retain the display of the "Powered by
30   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
31 31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
32   - * must display the words "Powered by KnowledgeTree" and retain the original
33   - * copyright notice.
  32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 34 * Contributor( s): ______________________________________
35 35 *
36 36 */
... ... @@ -49,22 +49,22 @@ require_once(KT_LIB_DIR . &quot;/browse/columnregistry.inc.php&quot;);
49 49  
50 50 class KTDocumentLinks extends KTPlugin {
51 51 var $sNamespace = "ktstandard.documentlinks.plugin";
52   -
  52 +
53 53 function KTDocumentLinks($sFilename = null) {
54 54 $res = parent::KTPlugin($sFilename);
55 55 $this->sFriendlyName = _kt('Inter-document linking');
56 56 return $res;
57   - }
  57 + }
58 58  
59 59 function setup() {
60 60 $this->registerAction('documentaction', 'KTDocumentLinkAction', 'ktcore.actions.document.link');
61   - $this->registerAction('documentviewlet', 'KTDocumentLinkViewlet', 'ktcore.viewlets.document.link');
62   - $this->registerColumn(_kt('Link Title'), 'ktdocumentlinks.columns.title', 'KTDocumentLinkTitle',
  61 + $this->registerAction('documentviewlet', 'KTDocumentLinkViewlet', 'ktcore.viewlets.document.link');
  62 + $this->registerColumn(_kt('Link Title'), 'ktdocumentlinks.columns.title', 'KTDocumentLinkTitle',
63 63 dirname(__FILE__) . '/KTDocumentLinksColumns.php');
64 64 $this->registerAdminPage("linkmanagement", 'KTDocLinkAdminDispatcher', 'documents',
65 65 _kt('Link Type Management'),
66 66 _kt('Manage the different ways documents can be associated with one another.'),
67   - __FILE__, null);
  67 + __FILE__, null);
68 68 }
69 69 }
70 70  
... ... @@ -72,64 +72,87 @@ class KTDocumentLinks extends KTPlugin {
72 72  
73 73 class KTDocumentLinkViewlet extends KTDocumentViewlet {
74 74 var $sName = 'ktcore.viewlets.document.link';
75   -
  75 +
76 76 function display_viewlet() {
77 77 $oKTTemplating =& KTTemplating::getSingleton();
78 78 $oTemplate =& $oKTTemplating->loadTemplate("ktstandard/links/links_viewlet");
79   - if (is_null($oTemplate)) { return ""; }
  79 + if (is_null($oTemplate)) { return ''; }
80 80  
81   - $temp_links_from = DocumentLink::getLinksFromDocument($this->oDocument->getId());
82   - $temp_links_to = DocumentLink::getLinksToDocument($this->oDocument->getId());
  81 + $iDocId = $this->oDocument->getId();
  82 + $temp_links_from = DocumentLink::getLinksFromDocument($iDocId);
  83 + $temp_links_to = DocumentLink::getLinksToDocument($iDocId);
  84 + $temp_links_external = DocumentLink::getExternalLinks($iDocId);
83 85  
84 86 $links_to = array();
85   - $links_from = array();
86   -
87   - foreach ($temp_links_from as $link) {
88   - $oDoc = $link->getChildDocument();
89   - if (PEAR::isError($oDoc)) {
90   - continue;
91   - }
92   -
93   - if (KTPermissionUtil::userHasPermissionOnItem($this->oUser, 'ktcore.permissions.read', $oDoc)) {
94   - $type = $link->getLinkType();
95   - $aInfo = array(
96   - 'url' => KTBrowseUtil::getUrlForDocument($oDoc),
97   - 'name' => $oDoc->getName(),
98   - 'type' => $type->getName(),
99   - 'description' => $type->getDescription(),
100   - );
101   -
102   - $links_from[] = $aInfo;
  87 + $links_from = array();
  88 + $links_external = array();
  89 +
  90 + if(!empty($temp_links_from)){
  91 + foreach ($temp_links_from as $link) {
  92 + $oDoc = $link->getChildDocument();
  93 + if (PEAR::isError($oDoc)) {
  94 + continue;
  95 + }
  96 +
  97 + if (KTPermissionUtil::userHasPermissionOnItem($this->oUser, 'ktcore.permissions.read', $oDoc)) {
  98 + $type = $link->getLinkType();
  99 + $aInfo = array(
  100 + 'url' => KTBrowseUtil::getUrlForDocument($oDoc),
  101 + 'name' => $oDoc->getName(),
  102 + 'type' => $type->getName(),
  103 + 'description' => $type->getDescription(),
  104 + );
  105 +
  106 + $links_from[] = $aInfo;
  107 + }
103 108 }
104 109 }
105   -
106   - foreach ($temp_links_to as $link) {
107   - $oDoc = $link->getParentDocument();
108   - if (PEAR::isError($oDoc)) {
109   - continue;
  110 +
  111 + if(!empty($temp_links_to)){
  112 + foreach ($temp_links_to as $link) {
  113 + $oDoc = $link->getParentDocument();
  114 + if (PEAR::isError($oDoc)) {
  115 + continue;
  116 + }
  117 +
  118 + if (KTPermissionUtil::userHasPermissionOnItem($this->oUser, 'ktcore.permissions.read', $oDoc)) {
  119 + $type = $link->getLinkType();
  120 + $aInfo = array(
  121 + 'url' => KTBrowseUtil::getUrlForDocument($oDoc),
  122 + 'name' => $oDoc->getName(),
  123 + 'type' => $type->getName(),
  124 + 'description' => $type->getDescription(),
  125 + );
  126 +
  127 + $links_to[] = $aInfo;
  128 + }
110 129 }
111   -
112   - if (KTPermissionUtil::userHasPermissionOnItem($this->oUser, 'ktcore.permissions.read', $oDoc)) {
  130 + }
  131 +
  132 + if(!empty($temp_links_external)){
  133 + foreach ($temp_links_external as $link) {
113 134 $type = $link->getLinkType();
  135 +
114 136 $aInfo = array(
115   - 'url' => KTBrowseUtil::getUrlForDocument($oDoc),
116   - 'name' => $oDoc->getName(),
117   - 'type' => $type->getName(),
118   - 'description' => $type->getDescription(),
  137 + 'url' => $link->getTargetUrl(),
  138 + 'name' => $link->getTargetName(),
  139 + 'type' => $type->getName(),
  140 + 'description' => $type->getDescription(),
119 141 );
120   -
121   - $links_to[] = $aInfo;
  142 +
  143 + $links_external[] = $aInfo;
122 144 }
123   - }
  145 + }
124 146  
125   - if (empty($links_from) && empty($links_to)) {
126   - return "";
  147 + if (empty($links_from) && empty($links_to) && empty($links_external)) {
  148 + return '';
127 149 }
128   -
  150 +
129 151 $oTemplate->setData(array(
130 152 'context' => $this,
131 153 'links_from' => $links_from,
132 154 'links_to' => $links_to,
  155 + 'links_external' => $links_external,
133 156 ));
134 157 return $oTemplate->render();
135 158 }
... ... @@ -149,27 +172,24 @@ class KTDocumentLinkAction extends KTDocumentAction {
149 172 $this->oPage->setBreadcrumbDetails(_kt("Links"));
150 173 $this->oPage->setTitle(_kt("Links"));
151 174  
152   - $oDocument = Document::get(
153   - KTUtil::arrayGet($_REQUEST, 'fDocumentId', 0)
154   - );
  175 + $iDocId = $_REQUEST['fDocumentId'];
  176 + $oDocument = Document::get($iDocId);
155 177  
156 178 $oReadPermission =& KTPermission::getByName('ktcore.permissions.read');
157 179 $oWritePermission =& KTPermission::getByName('ktcore.permissions.write');
158   -
  180 +
159 181 $aTemplateData = array(
160 182 'context' => $this,
161   - 'links_from' => DocumentLink::getLinksFromDocument($oDocument->getId()),
162   - 'links_to' => DocumentLink::getLinksToDocument($oDocument->getId()),
  183 + 'iDocId' => $iDocId,
  184 + 'links_external' => DocumentLink::getExternalLinks($iDocId),
  185 + 'links_from' => DocumentLink::getLinksFromDocument($iDocId),
  186 + 'links_to' => DocumentLink::getLinksToDocument($iDocId),
163 187 'read_permission' => KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oReadPermission, $this->oDocument),
164 188 'write_permission' => KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oWritePermission, $this->oDocument),
165 189 );
166   -
167   -
168   - return $oTemplate->render($aTemplateData);
169   - }
170   -
171   -
172 190  
  191 + return $oTemplate->render($aTemplateData);
  192 + }
173 193  
174 194 // select a target for the link
175 195 function do_new() {
... ... @@ -177,176 +197,204 @@ class KTDocumentLinkAction extends KTDocumentAction {
177 197 $this->oPage->setTitle(_kt("New Link"));
178 198  
179 199 $oPermission =& KTPermission::getByName('ktcore.permissions.write');
180   - if (PEAR::isError($oPermission) ||
  200 + if (PEAR::isError($oPermission) ||
181 201 !KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $this->oDocument)) {
182 202 $this->errorRedirectToMain(_kt('You do not have sufficient permissions to add a document link'), sprintf("fDocumentId=%d", $this->oDocument->getId()));
183 203 exit(0);
184 204 }
185 205  
186 206 $oParentDocument =& $this->oDocument;
187   -
188   - if (PEAR::isError($oParentDocument)) {
  207 +
  208 + if (PEAR::isError($oParentDocument)) {
189 209 $this->errorRedirectToMain(_kt('Invalid parent document selected.'));
190 210 exit(0);
191 211 }
192 212  
193 213 $oFolder = Folder::get(KTUtil::arrayGet($_REQUEST, 'fFolderId', $oParentDocument->getFolderID()));
194   - if (PEAR::isError($oFolder) || ($oFolder == false)) {
  214 + if (PEAR::isError($oFolder) || ($oFolder == false)) {
195 215 $this->errorRedirectToMain(_kt('Invalid folder selected.'));
196 216 exit(0);
197 217 }
198 218 $iFolderId = $oFolder->getId();
199   -
  219 +
200 220 // Setup the collection for move display.
201   -
202 221 $collection = new AdvancedCollection();
203 222 $aBaseParams = array('fDocumentId'=>$oParentDocument->getId());
204 223  
205   -
206 224 $oCR =& KTColumnRegistry::getSingleton();
  225 + $col = $oCR->getColumn('ktcore.columns.selection');
  226 + $aColOptions = array();
  227 + $aColOptions['qs_params'] = kt_array_merge($aBaseParams, array('fFolderId'=>$oFolder->getId()));
  228 + $aColOptions['show_folders'] = false;
  229 + $aColOptions['show_documents'] = true;
  230 + $aColOptions['rangename'] = 'linkselection[]';
  231 + $col->setOptions($aColOptions);
  232 + $collection->addColumn($col);
207 233  
208   - $col = $oCR->getColumn('ktcore.columns.singleselection');
209   - $col->setOptions(array('qs_params'=>kt_array_merge($aBaseParams, array('fFolderId'=>$oFolder->getId()))));
210   - $collection->addColumn($col);
211   -
212 234 $col = $oCR->getColumn('ktdocumentlinks.columns.title');
213   - $col->setOptions(array('qs_params'=>kt_array_merge($aBaseParams, array('fFolderId'=>$oFolder->getId()))));
  235 + $col->setOptions(array('qs_params'=>kt_array_merge($aBaseParams, array('action' => 'new', 'fFolderId'=>$oFolder->getId()))));
214 236 $collection->addColumn($col);
215   -
  237 +
216 238 $qObj = new BrowseQuery($iFolderId);
217 239 $collection->setQueryObject($qObj);
218 240  
219 241 $aOptions = $collection->getEnvironOptions();
220   - $aOptions['result_url'] = KTUtil::addQueryString($_SERVER['PHP_SELF'],
  242 + //$aOptions['is_browse'] = true;
  243 + $aOptions['result_url'] = KTUtil::addQueryString($_SERVER['PHP_SELF'],
221 244 array(kt_array_merge($aBaseParams, array('fFolderId' => $oFolder->getId()))));
222 245  
223 246 $collection->setOptions($aOptions);
224 247  
225   - $oWF =& KTWidgetFactory::getSingleton();
226   - $oWidget = $oWF->get('ktcore.widgets.collection',
227   - array('label' => _kt('Target Document'),
228   - 'description' => _kt('Use the folder collection and path below to browse to the document you wish to link to.'),
229   - 'required' => true,
230   - 'name' => 'browse',
231   - 'folder_id' => $oFolder->getId(),
232   - 'bcurl_params' => $aBaseParams,
233   - 'collection' => $collection));
  248 + $aURLParams = $aBaseParams;
  249 + $aURLParams['action'] = 'new';
  250 + $aBreadcrumbs = $this->_generate_breadcrumbs($oFolder, $iFolderId, $aURLParams);
234 251  
235   -
236   -
237 252 $aTemplateData = array(
238 253 'context' => $this,
239 254 'folder' => $oFolder,
240 255 'parent' => $oParentDocument,
241 256 'breadcrumbs' => $aBreadcrumbs,
242   - 'collection' => $oWidget,
  257 + 'collection' => $collection,
243 258 'link_types' => LinkType::getList("id > 0"),
244 259 );
245   -
  260 +
246 261 $oTemplate =& $this->oValidator->validateTemplate('ktstandard/action/link');
247   - return $oTemplate->render($aTemplateData);
  262 + return $oTemplate->render($aTemplateData);
248 263 }
249 264  
250   - // select a type for the link
251   - function do_type_select() {
252   - $this->oPage->setBreadcrumbDetails(_kt("link"));
  265 + function do_external() {
  266 + $this->oPage->setBreadcrumbDetails(_kt("New External Link"));
  267 + $this->oPage->setTitle(_kt("New External Link"));
253 268  
254   - $oParentDocument = Document::get(KTUtil::arrayGet($_REQUEST, 'fDocumentId'));
255   - if (PEAR::isError($oParentDocument)) {
256   - $this->errorRedirectToMain(_kt('Invalid parent document selected.'));
  269 + $oPermission =& KTPermission::getByName('ktcore.permissions.write');
  270 + if (PEAR::isError($oPermission) ||
  271 + !KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $this->oDocument)) {
  272 + $this->errorRedirectToMain(_kt('You do not have sufficient permissions to add a document link'), sprintf("fDocumentId=%d", $this->oDocument->getId()));
257 273 exit(0);
258 274 }
259 275  
260   - /*
261   - print '<pre>';
262   - var_dump($_REQUEST);
263   - exit(0);
264   - */
  276 + $oParentDocument =& $this->oDocument;
  277 + $iParentId = $oParentDocument->getId();
265 278  
  279 + $aTemplateData = array(
  280 + 'context' => $this,
  281 + 'iDocId' => $iParentId,
  282 + 'link_types' => LinkType::getList("id > 0"),
  283 + );
266 284  
267   - $oTargetDocument = Document::get(KTUtil::arrayGet($_REQUEST, '_d'));
268   - if (PEAR::isError($oTargetDocument)) {
269   - $this->errorRedirectToMain(_kt('Invalid target document selected.'));
270   - exit(0);
271   - }
  285 + $oTemplate =& $this->oValidator->validateTemplate('ktstandard/action/link_external');
  286 + return $oTemplate->render($aTemplateData);
  287 + }
  288 +
  289 + // select a type for the link
  290 + function do_type_select() {
  291 + $this->oPage->setBreadcrumbDetails(_kt("link"));
  292 +
  293 + $sType = (isset($_REQUEST['linktype'])) ? $_REQUEST['linktype'] : 'internal';
  294 + $sTarget = '';
  295 + $aTarget = array();
272 296  
  297 + if($sType == 'external'){
  298 + $iParentId = $_REQUEST['fDocumentId'];
  299 + $aTarget['url'] = $_REQUEST['target_url'];
  300 + $aTarget['name'] = $_REQUEST['target_name'];
  301 + $aDocuments = array($iParentId);
  302 +
  303 + $this->oValidator->validateUrl($aTarget['url']);
  304 + if(empty($aTarget['name'])){
  305 + $aTarget['name'] = $aTarget['url'];
  306 + }
  307 + }else{
  308 + $iParentId = $_REQUEST['fDocumentId'];
  309 + $aDocuments = $_REQUEST['linkselection'];
  310 + if(empty($aDocuments)){
  311 + $this->errorRedirectToMain(_kt('No documents have been selected.'));
  312 + exit;
  313 + }
  314 + }
  315 + $sDocuments = serialize($aDocuments);
  316 + $sTarget = serialize($aTarget);
273 317  
274 318 // form fields
275 319 $aFields = array();
276   -
  320 +
277 321 $aVocab = array();
278 322 foreach(LinkType::getList("id > 0") as $oLinkType) {
279 323 $aVocab[$oLinkType->getID()] = $oLinkType->getName();
280   - }
  324 + }
281 325  
282 326 $aOptions = array('vocab' => $aVocab);
283 327 $aFields[] = new KTLookupWidget(
284   - _kt('Link Type'),
285   - _kt('The type of link you wish to use'),
286   - 'fLinkTypeId',
  328 + _kt('Link Type'),
  329 + _kt('The type of link you wish to use'),
  330 + 'fLinkTypeId',
287 331 null,
288 332 $this->oPage,
289 333 true,
290 334 null,
291 335 null,
292 336 $aOptions);
293   -
  337 +
294 338 $aTemplateData = array(
295 339 'context' => $this,
296   - 'parent_id' => $oParentDocument->getId(),
297   - 'target_id' => $oTargetDocument->getId(),
  340 + 'parent_id' => $iParentId,
  341 + 'target_id' => $sDocuments,
  342 + 'target_url' => $sTarget,
298 343 'fields' => $aFields,
299 344 );
300   -
301   - $oTemplate =& $this->oValidator->validateTemplate('ktstandard/action/link_type_select');
302   - return $oTemplate->render($aTemplateData);
303   -
304 345  
  346 + $oTemplate =& $this->oValidator->validateTemplate('ktstandard/action/link_type_select');
  347 + return $oTemplate->render($aTemplateData);
305 348 }
306 349  
307   -
308   -
309 350 // make the link
310 351 function do_make_link() {
311 352 $this->oPage->setBreadcrumbDetails(_kt("link"));
312   -
313   - // check validity of things
314   - $oParentDocument = Document::get(KTUtil::arrayGet($_REQUEST, 'fDocumentId'));
315   - if (PEAR::isError($oParentDocument)) {
316   - $this->errorRedirectToMain(_kt('Invalid parent document selected.'));
317   - exit(0);
318   - }
319   -
320   - $oTargetDocument = Document::get(KTUtil::arrayGet($_REQUEST, 'fTargetDocumentId'));
321   - if (PEAR::isError($oTargetDocument)) {
322   - $this->errorRedirectToMain(_kt('Invalid target document selected.'));
323   - exit(0);
324   - }
325   -
326   - $oLinkType = LinkType::get(KTUtil::arrayGet($_REQUEST, 'fLinkTypeId'));
327   - if (PEAR::isError($oLinkType)) {
  353 + $iParentId = $_REQUEST['fDocumentId'];
  354 + $iLinkTypeId = $_REQUEST['fLinkTypeId'];
  355 + $sDocIds = $_REQUEST['fTargetDocumentId'];
  356 + $aDocIds = unserialize($sDocIds);
  357 + $sTarget = $_REQUEST['fTargetUrl'];
  358 + $aTarget = unserialize($sTarget);
  359 +
  360 + $oLinkType = LinkType::get($iLinkTypeId);
  361 + if (PEAR::isError($oLinkType)) {
328 362 $this->errorRedirectToMain(_kt('Invalid link type selected.'));
329 363 exit(0);
330 364 }
331 365  
  366 + $sTargetUrl = '';
  367 + $sTargetName = '';
  368 + if(!empty($aTarget)){
  369 + $sTargetUrl = $aTarget['url'];
  370 + $sTargetName = $aTarget['name'];
  371 + }
332 372  
333   - // create document link
  373 + // create document links
334 374 $this->startTransaction();
335   -
336   - $oDocumentLink =& DocumentLink::createFromArray(array(
337   - 'iParentDocumentId' => $oParentDocument->getId(),
338   - 'iChildDocumentId' => $oTargetDocument->getId(),
339   - 'iLinkTypeId' => $oLinkType->getId(),
340   - ));
341 375  
342   - if (PEAR::isError($oDocumentLink)) {
343   - $this->errorRedirectToMain(_kt('Could not create document link'), sprintf('fDocumentId=%d', $oParentDocument->getId()));
344   - exit(0);
  376 + if(!empty($aDocIds)){
  377 + foreach ($aDocIds as $iDocId){
  378 +
  379 + $oDocumentLink =& DocumentLink::createFromArray(array(
  380 + 'iParentDocumentId' => $iParentId,
  381 + 'iChildDocumentId' => $iDocId,
  382 + 'iLinkTypeId' => $iLinkTypeId,
  383 + 'sTargetUrl' => $sTargetUrl,
  384 + 'sTargetName' => $sTargetName,
  385 + ));
  386 +
  387 + if (PEAR::isError($oDocumentLink)) {
  388 + $this->rollbackTransaction();
  389 + $this->errorRedirectToMain(_kt('Could not create document link'), sprintf('fDocumentId=%d', $iParentId));
  390 + exit(0);
  391 + }
  392 + }
345 393 }
346 394  
347 395 $this->commitTransaction();
348 396  
349   - $this->successRedirectToMain(_kt('Document link created'), sprintf('fDocumentId=%d', $oParentDocument->getId()));
  397 + $this->successRedirectToMain(_kt('Document link created'), sprintf('fDocumentId=%d', $iParentId));
350 398 exit(0);
351 399 }
352 400  
... ... @@ -357,30 +405,29 @@ class KTDocumentLinkAction extends KTDocumentAction {
357 405  
358 406 // check security
359 407 $oPermission =& KTPermission::getByName('ktcore.permissions.write');
360   - if (PEAR::isError($oPermission) ||
  408 + if (PEAR::isError($oPermission) ||
361 409 !KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $this->oDocument)) {
362 410 $this->errorRedirectToMain(_kt('You do not have sufficient permissions to delete a link'), sprintf("fDocumentId=%d", $this->oDocument->getId()));
363 411 exit(0);
364 412 }
365 413  
366   -
367 414 // check validity of things
368 415 $oDocumentLink = DocumentLink::get(KTUtil::arrayGet($_REQUEST, 'fDocumentLinkId'));
369   - if (PEAR::isError($oDocumentLink)) {
  416 + if (PEAR::isError($oDocumentLink)) {
370 417 $this->errorRedirectToMain(_kt('Invalid document link selected.'));
371 418 exit(0);
372 419 }
373 420 $oParentDocument = Document::get(KTUtil::arrayGet($_REQUEST, 'fDocumentId'));
374   - if (PEAR::isError($oParentDocument)) {
  421 + if (PEAR::isError($oParentDocument)) {
375 422 $this->errorRedirectToMain(_kt('Invalid document selected.'));
376 423 exit(0);
377 424 }
378   -
  425 +
379 426 // do deletion
380 427 $this->startTransaction();
381   -
  428 +
382 429 $res = $oDocumentLink->delete();
383   -
  430 +
384 431 if (PEAR::isError($res)) {
385 432 $this->errorRedirectToMain(_kt('Could not delete document link'), sprintf('fDocumentId=%d', $oParentDocument->getId()));
386 433 exit(0);
... ... @@ -391,7 +438,61 @@ class KTDocumentLinkAction extends KTDocumentAction {
391 438 $this->successRedirectToMain(_kt('Document link deleted'), sprintf('fDocumentId=%d', $oParentDocument->getId()));
392 439 exit(0);
393 440 }
  441 +
  442 + function _generate_breadcrumbs($oFolder, $iFolderId, $aURLParams) {
  443 + static $aFolders = array();
  444 + static $aBreadcrumbs = array();
  445 +
  446 + // Check if selected folder is a parent of the current folder
  447 + if(in_array($iFolderId, $aFolders)){
  448 + $temp = array_flip($aFolders);
  449 + $key = $temp[$iFolderId];
  450 + array_splice($aFolders, $key);
  451 + array_splice($aBreadcrumbs, $key);
  452 + return $aBreadcrumbs;
  453 + }
  454 +
  455 + // Check for the parent of the selected folder unless its the root folder
  456 + $iParentId = $oFolder->getParentID();
  457 + if($iFolderId != 1 && in_array($iParentId, $aFolders)){
  458 + $temp = array_flip($aFolders);
  459 + $key = $temp[$iParentId];
  460 + array_splice($aFolders, $key);
  461 + array_splice($aBreadcrumbs, $key);
  462 + array_push($aFolders, $iFolderId);
  463 +
  464 + $aParams = $aURLParams;
  465 + $aParams['fFolderId'] = $iFolderId;
  466 + $url = KTUtil::addQueryString($_SERVER['PHP_SELF'], $aParams);
  467 + $aBreadcrumbs[] = array('url' => $url, 'name' => $oFolder->getName());
  468 + return $aBreadcrumbs;
  469 + }
  470 +
  471 + // Create the breadcrumbs
  472 + $folder_path_names = $oFolder->getPathArray();
  473 + $folder_path_ids = explode(',', $oFolder->getParentFolderIds());
  474 + $folder_path_ids[] = $oFolder->getId();
  475 + if ($folder_path_ids[0] == 0) {
  476 + array_shift($folder_path_ids);
  477 + array_shift($folder_path_names);
  478 + }
  479 +
  480 + $iCount = count($folder_path_ids);
  481 + $range = range(0, $iCount - 1);
  482 + foreach ($range as $index) {
  483 + $id = $folder_path_ids[$index];
  484 + $name = $folder_path_names[$index];
  485 +
  486 + $aParams = $aURLParams;
  487 + $aParams['fFolderId'] = $id;
  488 + $url = KTUtil::addQueryString($_SERVER['PHP_SELF'], $aParams);
  489 + $aBreadcrumbs[] = array('url' => $url, 'name' => $name);
  490 + }
  491 + $aFolders = $folder_path_ids;
  492 + return $aBreadcrumbs;
  493 + }
394 494 }
  495 +
395 496 class KTDocLinkAdminDispatcher extends KTAdminDispatcher {
396 497 var $sHelpPage = 'ktcore/admin/link type management.html';
397 498  
... ... @@ -403,17 +504,17 @@ class KTDocLinkAdminDispatcher extends KTAdminDispatcher {
403 504 function do_main() {
404 505 $this->aBreadcrumbs[] = array('name' => _kt('Document Links'));
405 506 $this->oPage->setBreadcrumbDetails(_kt("view"));
406   -
  507 +
407 508 $aLinkTypes =& LinkType::getList('id > 0');
408   -
  509 +
409 510 $addLinkForm = array();
410   - // KTBaseWidget($sLabel, $sDescription, $sName, $value, $oPage, $bRequired = false, $sId = null, $aErrors = null, $aOptions = null)
  511 + // KTBaseWidget($sLabel, $sDescription, $sName, $value, $oPage, $bRequired = false, $sId = null, $aErrors = null, $aOptions = null)
411 512 $addLinkForm[] = new KTStringWidget(_kt('Name'), _kt('A short, human-readable name for the link type.'), 'fName', null, $this->oPage, true);
412 513 $addLinkForm[] = new KTStringWidget(_kt('Description'), _kt('A short brief description of the relationship implied by this link type.'), 'fDescription', null, $this->oPage, true);
413   -
414   -
  514 +
  515 +
415 516 $oTemplating =& KTTemplating::getSingleton();
416   - $oTemplate = $oTemplating->loadTemplate('ktcore/document/admin/linktypesadmin');
  517 + $oTemplate = $oTemplating->loadTemplate('ktcore/document/admin/linktypesadmin');
417 518 $oTemplate->setData(array(
418 519 "context" => $this,
419 520 "add_form" => $addLinkForm,
... ... @@ -421,28 +522,28 @@ class KTDocLinkAdminDispatcher extends KTAdminDispatcher {
421 522 ));
422 523 return $oTemplate;
423 524 }
424   -
  525 +
425 526 function do_edit() {
426 527 $link_id = KTUtil::arrayGet($_REQUEST, 'fLinkTypeId', null, false);
427 528 if ($link_id === null) {
428 529 $this->errorRedirectToMain(_kt("Please specify a link type to edit."));
429 530 }
430   -
  531 +
431 532 $oLinkType =& LinkType::get($link_id);
432   -
  533 +
433 534 $this->aBreadcrumbs[] = array('name' => _kt('Document Links'));
434 535 $this->oPage->setBreadcrumbDetails(_kt("view"));
435   -
  536 +
436 537 $aLinkTypes =& LinkType::getList('id > 0');
437   -
  538 +
438 539 $editLinkForm = array();
439   - // KTBaseWidget($sLabel, $sDescription, $sName, $value, $oPage, $bRequired = false, $sId = null, $aErrors = null, $aOptions = null)
  540 + // KTBaseWidget($sLabel, $sDescription, $sName, $value, $oPage, $bRequired = false, $sId = null, $aErrors = null, $aOptions = null)
440 541 $editLinkForm[] = new KTStringWidget(_kt('Name'), _kt('A short, human-readable name for the link type.'), 'fName', $oLinkType->getName(), $this->oPage, true);
441 542 $editLinkForm[] = new KTStringWidget(_kt('Description'), _kt('A short brief description of the relationship implied by this link type.'), 'fDescription', $oLinkType->getDescription(), $this->oPage, true);
442   -
443   -
  543 +
  544 +
444 545 $oTemplating =& KTTemplating::getSingleton();
445   - $oTemplate = $oTemplating->loadTemplate('ktcore/document/admin/linktypesadmin');
  546 + $oTemplate = $oTemplating->loadTemplate('ktcore/document/admin/linktypesadmin');
446 547 $oTemplate->setData(array(
447 548 "context" => $this,
448 549 "edit_form" => $editLinkForm,
... ... @@ -450,54 +551,54 @@ class KTDocLinkAdminDispatcher extends KTAdminDispatcher {
450 551 "links" => $aLinkTypes,
451 552 ));
452 553 return $oTemplate;
453   - }
454   -
  554 + }
  555 +
455 556  
456 557 function do_update() {
457 558 $link_id = KTUtil::arrayGet($_REQUEST, 'fLinkTypeId', null, false);
458 559 if ($link_id === null) {
459 560 $this->errorRedirectToMain(_kt("Please specify a link type to update."));
460 561 }
461   -
462   - $name = KTUtil::arrayGet($_REQUEST, 'fName');
  562 +
  563 + $name = KTUtil::arrayGet($_REQUEST, 'fName');
463 564 $description = KTUtil::arrayGet($_REQUEST, 'fDescription');
464 565  
465 566 if (empty($name) || empty($description)) { // for bonus points, make this go to edit, and edit catch it.
466 567 $this->errorRedirectToMain(_kt('Please enter information for all fields.'));
467 568 }
468   -
  569 +
469 570 $oLinkType =& LinkType::get($link_id);
470   -
  571 +
471 572 $oLinkType->setName($name);
472 573 $oLinkType->setDescription($description);
473 574 $oLinkType->update();
474   -
  575 +
475 576 $this->successRedirectToMain(_kt("Link Type updated."));
476 577 }
477   -
  578 +
478 579 function do_add() {
479   - $name = KTUtil::arrayGet($_REQUEST, 'fName');
  580 + $name = KTUtil::arrayGet($_REQUEST, 'fName');
480 581 $description = KTUtil::arrayGet($_REQUEST, 'fDescription');
481 582  
482 583 if (empty($name) || empty($description)) {
483 584 $this->errorRedirectToMain(_kt('Please enter information for all fields.'));
484 585 }
485   -
  586 +
486 587 $oLinkType = new LinkType($name, $description);
487 588 $oLinkType->create();
488   -
  589 +
489 590 //$oLinkType =& LinkType::createFromArray(array("sName" => $name, "sDescription" => $description));
490   -
  591 +
491 592 $this->successRedirectToMain(_kt("Link Type created."));
492 593 }
493   -
  594 +
494 595 function do_delete() {
495 596 $types_to_delete = KTUtil::arrayGet($_REQUEST, 'fLinksToDelete'); // is an array.
496 597  
497 598 if (empty($types_to_delete)) {
498 599 $this->errorRedirectToMain(_kt('Please select one or more link types to delete.'));
499 600 }
500   -
  601 +
501 602 $count = 0;
502 603 foreach ($types_to_delete as $link_id) {
503 604 $oLinkType = LinkType::get($link_id);
... ... @@ -505,13 +606,13 @@ class KTDocLinkAdminDispatcher extends KTAdminDispatcher {
505 606 foreach(DocumentLink::getList(sprintf("link_type_id = %d", $link_id)) as $oLink) {
506 607 $oLink->delete();
507 608 }
508   -
  609 +
509 610 $oLinkType->delete(); // technically, this is a bad thing
510   - $count += 1;
  611 + $count += 1;
511 612 }
512   -
  613 +
513 614 //$oLinkType =& LinkType::createFromArray(array("sName" => $name, "sDescription" => $description));
514   -
  615 +
515 616 $this->successRedirectToMain($count . " " . _kt("Link types deleted."));
516 617 }
517 618  
... ...
plugins/rssplugin/KTrss.inc.php
... ... @@ -84,6 +84,27 @@ class KTrss{
84 84 return $response;
85 85 }
86 86  
  87 + // Get the data for the document or folder
  88 + function getExternalInternalFeed($sFeed, $iUserId){
  89 + $aRss = array();
  90 + $pos = strpos($sFeed, 'docId');
  91 +
  92 + if($pos === false){
  93 + $pos = strpos($sFeed, 'folderId');
  94 + $folderId = substr($sFeed, $pos+9);
  95 + $aRss[] = KTrss::getOneFolder($folderId, $iUserId);
  96 + }else{
  97 + $docId = substr($sFeed, $pos+6);
  98 + $aRss[] = KTrss::getOneDocument($docId, $iUserId);
  99 + }
  100 +
  101 + if($aRss){
  102 + $internalFeed = KTrss::arrayToXML($aRss);
  103 + $response = rss2arrayBlock($internalFeed);
  104 + }
  105 + return $response;
  106 + }
  107 +
87 108 // Get list of document subscriptions
88 109 function getDocumentList($iUserId){
89 110 $sQuery = "SELECT document_id as id FROM document_subscriptions WHERE user_id = ?";
... ...
plugins/rssplugin/loadFeed.inc.php
... ... @@ -5,49 +5,69 @@
5 5 * KnowledgeTree Open Source Edition
6 6 * Document Management Made Simple
7 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8   - *
  8 + *
9 9 * This program is free software; you can redistribute it and/or modify it under
10 10 * the terms of the GNU General Public License version 3 as published by the
11 11 * Free Software Foundation.
12   - *
  12 + *
13 13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 16 * details.
17   - *
  17 + *
18 18 * You should have received a copy of the GNU General Public License
19 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20   - *
  20 + *
21 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23   - *
  23 + *
24 24 * The interactive user interfaces in modified source and object code versions
25 25 * of this program must display Appropriate Legal Notices, as required under
26 26 * Section 5 of the GNU General Public License version 3.
27   - *
  27 + *
28 28 * In accordance with Section 7(b) of the GNU General Public License version 3,
29 29 * these Appropriate Legal Notices must retain the display of the "Powered by
30   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
31 31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
32   - * must display the words "Powered by KnowledgeTree" and retain the original
33   - * copyright notice.
  32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 34 * Contributor( s): ______________________________________
35 35 *
36 36 */
37 37 require_once('../../config/dmsDefaults.php');
38 38 require_once(KT_DIR. '/plugins/rssplugin/rss2array.inc.php');
39 39 require_once(KT_DIR. '/plugins/rssplugin/KTrss.inc.php');
40   -
  40 +
41 41 $feed = $_GET["feed"];
42 42 $user = $_GET["user"];
43   -
  43 +
  44 + // URL must start with http:// - change it if it starts with feed://
  45 + if(preg_match("/^feed:\/\/([^\/]+)(.*)$/", $feed, $matches)){
  46 + $feed = preg_replace("/^feed:\/\//", "http://", $feed);
  47 + }
  48 +
44 49 // Check if the feed matches a url
45 50 if(!preg_match("/^http:\/\/([^\/]+)(.*)$/", $feed, $matches)){
46 51 // If not, it is an internal feed
47 52 $aRSSArray = KTrss::getInternalFeed($user);
48 53 }else{
49 54 // If it is a url, it is an external feed
50   - $aRSSArray = rss2array($feed);
  55 + // However, sometimes internal documents get added as external feeds
  56 + // Check that the url isn't an internal one.
  57 + global $default;
  58 + $rootUrl = $default->rootUrl;
  59 + $bSSL = $default->sslEnabled;
  60 +
  61 + $sProtocol = ($bSSL) ? 'https' : 'http';
  62 + $sBaseUrl = $sProtocol.'://'.$_SERVER['HTTP_HOST'].$rootUrl;
  63 +
  64 + $sInternal = $sBaseUrl.'/rss.php';
  65 + if(!(strpos($feed, $sInternal) === FALSE)){
  66 + // Feed is internal
  67 + $aRSSArray = KTrss::getExternalInternalFeed($feed, $user);
  68 + }else{
  69 + $aRSSArray = rss2array($feed);
  70 + }
51 71 }
52 72 if(count($aRSSArray[errors]) > 0){
53 73 for($i=0;$i<count($aRSSArray[errors]);$i++){
... ... @@ -70,6 +90,6 @@
70 90 <tr><td colspan='2'><br></td></tr>";
71 91 }
72 92 $response .= "</table></div><br>";
73   -
  93 +
74 94 echo $response;
75 95 -?>
  96 +?>
76 97 \ No newline at end of file
... ...
plugins/rssplugin/rss2array.inc.php
... ... @@ -143,7 +143,10 @@
143 143 xml_parser_free($xml_parser);
144 144  
145 145 }
146   -
  146 + else if($status == 401)
  147 + {
  148 + $rss2array_globals[errors][] = "Password authenticated feeds are not supported.";
  149 + }
147 150 else {
148 151  
149 152 $rss2array_globals[errors][] = "Can't get feed: HTTP status code $status";
... ...
sql/mysql/install/structure.sql
... ... @@ -318,6 +318,8 @@ CREATE TABLE `document_link` (
318 318 `parent_document_id` int(11) NOT NULL default '0',
319 319 `child_document_id` int(11) NOT NULL default '0',
320 320 `link_type_id` int(11) NOT NULL default '0',
  321 + `external_url` varchar(255),
  322 + `external_name` varchar(50),
321 323 PRIMARY KEY (`id`),
322 324 KEY `parent_document_id` (`parent_document_id`),
323 325 KEY `child_document_id` (`child_document_id`),
... ...
sql/mysql/upgrade/3.5.2/document_link.sql 0 → 100644
  1 +ALTER TABLE `document_link` ADD `external_url` varchar(255), ADD `external_name` varchar(50);
0 2 \ No newline at end of file
... ...
templates/ktstandard/action/document_links.smarty
... ... @@ -19,7 +19,7 @@
19 19  
20 20  
21 21  
22   -{if $links_from || $links_to}
  22 +{if $links_from || $links_to || $links_external}
23 23  
24 24 {foreach from=$links_from item=link}
25 25  
... ... @@ -35,7 +35,7 @@
35 35 {/if}
36 36 </td>
37 37  
38   - <td><a href="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main">{$target->getName()|sanitize}</a></td>
  38 + <td><a href="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main" title="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main">{$target->getName()|sanitize}</a></td>
39 39 <td>{$type->getName()}</td>
40 40 <td>{i18n}Linked <b>from</b> this document{/i18n}</td>
41 41 </tr>
... ... @@ -55,14 +55,34 @@
55 55 &nbsp;
56 56 {/if}
57 57 </td>
58   -
59   - <td><a href="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main">{$target->getName()|sanitize}</a></td>
  58 + <td><a title="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main" href="{"viewDocument"|generateControllerUrl}&qs[fDocumentId]={$target->getId()}&qs[action]=main">{$target->getName()|sanitize}</a></td>
60 59 <td>{$type->getName()}</td>
61 60 <td>{i18n}Links <b>to</b> this document{/i18n}</td>
62 61 </tr>
63 62  
64 63 {/foreach}
65 64  
  65 +{foreach from=$links_external item=link}
  66 +
  67 +{assign var="type" value=$link->getLinkType()}
  68 +{assign var="url" value=$link->getTargetUrl()}
  69 +{assign var="name" value=$link->getTargetName()}
  70 +
  71 + <tr>
  72 + <td>
  73 + {if $write_permission}
  74 + <a href="{addQS}action=delete&fDocumentId={$iDocId}&fDocumentLinkId={$link->getId()}{/addQS}" class="ktAction ktDelete">{i18n}Delete{/i18n}</a>
  75 + {else}
  76 + &nbsp;
  77 + {/if}
  78 + </td>
  79 +
  80 + <td><a href="{$url}" title='{$url}'>{$link->getTargetName()|sanitize}</a></td>
  81 + <td>{$type->getName()}</td>
  82 + <td>{i18n}External link <b>from</b> this document{/i18n}</td>
  83 + </tr>
  84 +
  85 +{/foreach}
66 86  
67 87 {else}
68 88 <tr><td colspan="4" align="center">{i18n}There are no links to or from this document.{/i18n}</td></tr>
... ... @@ -78,6 +98,10 @@
78 98 {if $write_permission}
79 99 <a class="ktAction ktAdd ktInline" href="{addQS}action=new&fDocumentId={$context->oDocument->getId()}{/addQS}">{i18n}Add a new link{/i18n}</a>
80 100 <a
81   -href="{addQS}action=new&fDocumentId={$context->oDocument->getId()}&fFolderId={$context->oDocument->getFolderId()}{/addQS}">{i18n}Add a new link{/i18n}</a>.
  101 +href="{addQS}action=new&fDocumentId={$context->oDocument->getId()}&fFolderId={$context->oDocument->getFolderId()}{/addQS}">{i18n}Add a new link{/i18n}</a>
  102 +<br /><br />
  103 +<a class="ktAction ktAdd ktInline" href="{addQS}action=external&fDocumentId={$iDocId}{/addQS}">{i18n}Add a new link{/i18n}</a>
  104 +<a
  105 +href="{addQS}action=external&fDocumentId={$iDocId}&fFolderId={$context->oDocument->getFolderId()}{/addQS}">{i18n}Add an external link{/i18n}</a>.
82 106 {/if}
83 107  
... ...
templates/ktstandard/action/link.smarty
... ... @@ -5,6 +5,14 @@
5 5 <p class="descriptiveText">{i18n}Select a target document to link to.{/i18n}
6 6 </p>
7 7  
  8 +{foreach from=$breadcrumbs item=breadcrumb name=bc}
  9 + {if !$smarty.foreach.bc.last}
  10 + <a href="{$breadcrumb.url}">{$breadcrumb.name|sanitize}</a> &raquo;
  11 + {else}
  12 + {$breadcrumb.name|sanitize}
  13 + {/if}
  14 +{/foreach}
  15 +
8 16 <form method="POST" action="{$smarty.server.PHP_SELF}">
9 17 {$collection->render()}
10 18 <div class="form_actions">
... ...
templates/ktstandard/action/link_external.smarty 0 → 100644
  1 +<h2>{i18n}Add External Link{/i18n}</h2>
  2 +
  3 +
  4 +{if $link_types}
  5 +<p class='descriptiveText'>{i18n}Enter the URL to the external document or site.{/i18n}
  6 +</p>
  7 +
  8 +<form method='POST' action="{$smarty.server.PHP_SELF}">
  9 +
  10 +<label for='target_name'>{i18n}Link Name{/i18n}: </label><br />
  11 +<input id='target_name' name='target_name' />
  12 +<br />
  13 +<label for='target_url'>{i18n}Link URL{/i18n}: </label><br />
  14 +<input id='target_url' name='target_url' value='http://' size='60' />
  15 +
  16 +<div class='form_actions'>
  17 +<input type='hidden' name='action' value='type_select' />
  18 +<input type='hidden' name='linktype' value='external' />
  19 +<input type='hidden' name='fDocumentId' value='{$iDocId}' />
  20 +<input type='submit' name='submit[move]' value='{i18n}Link{/i18n}' />
  21 +</div>
  22 +</form>
  23 +{else}
  24 +<div class='ktInfoMessage'><span>
  25 +{i18n}No link types are defined. Please ask the administrator to add them.{/i18n}</span></div>
  26 +
  27 +{/if}
0 28 \ No newline at end of file
... ...
templates/ktstandard/action/link_type_select.smarty
1 1 <h2>{i18n}Add Link{/i18n}</h2>
2 2  
3   -<form method="POST" action="{$smarty.server.PHP_SELF}">
  3 +<form method='POST' action="{$smarty.server.PHP_SELF}">
4 4  
5   -<input type="hidden" name="action" value="make_link" />
6   -<input type="hidden" name="fDocumentId" value="{$parent_id}" />
7   -<input type="hidden" name="fTargetDocumentId" value="{$target_id}" />
  5 +<input type='hidden' name='action' value='make_link' />
  6 +<input type='hidden' name='fDocumentId' value='{$parent_id}' />
  7 +<input type='hidden' name='fTargetDocumentId' value='{$target_id}' />
  8 +<input type='hidden' name='fTargetUrl' value='{$target_url}' />
8 9  
9 10 <fieldset>
10 11 <legend>{i18n}Select a link type.{/i18n}</legend>
... ... @@ -14,8 +15,8 @@
14 15 {/foreach}
15 16 </fieldset>
16 17  
17   -<div class="form_actions">
18   -<input type="submit" name="submit[move]" value="{i18n}Link{/i18n}" />
  18 +<div class='form_actions'>
  19 +<input type='submit' name='submit[move]' value="{i18n}Link{/i18n}" />
19 20 </div>
20 21 </fieldset>
21 22 </form>
... ...
templates/ktstandard/links/links_viewlet.smarty
1 1 <div class="viewlet">
2 2 {if $links_from}
3   - <h3>{i18n}Links from this document{/i18n}</h3>
4   - <ul>
5   - {foreach from=$links_from item=info}
6   - <li class="descriptiveText">{i18n}from{/i18n} <a href="{$info.url}" title="{$info.description}">{$info.name|sanitize}</a> ({$info.type})</li>
7   - {/foreach}
8   - </ul>
  3 + <h3>{i18n}Links from this document{/i18n}</h3>
  4 + <ul>
  5 + {foreach from=$links_from item=info}
  6 + <li class="descriptiveText"><a href="{$info.url}" title="{$info.description}">{$info.name|sanitize}</a> ({$info.type})</li>
  7 + {/foreach}
  8 + </ul>
9 9 {/if}
10 10  
11 11 {if $links_to}
12   - <h3>{i18n}Links to this document{/i18n}</h3>
13   - <ul>
14   - {foreach from=$links_to item=info}
15   - <li class="descriptiveText">{i18n}to{/i18n} <a href="{$info.url}" title="{$info.description}">{$info.name|sanitize}</a> ({$info.type})</li>
16   - {/foreach}
17   - </ul>
  12 + <h3>{i18n}Links to this document{/i18n}</h3>
  13 + <ul>
  14 + {foreach from=$links_to item=info}
  15 + <li class="descriptiveText"><a href="{$info.url}" title="{$info.description}">{$info.name|sanitize}</a> ({$info.type})</li>
  16 + {/foreach}
  17 + </ul>
  18 + {/if}
  19 +
  20 + {if $links_external}
  21 + <h3>{i18n}External Links from this document{/i18n}</h3>
  22 + <ul>
  23 + {foreach from=$links_external item=info}
  24 + <li class="descriptiveText"><a href="{$info.url}" title="{$info.description}: {$info.url}">{$info.name|sanitize}</a> ({$info.type})</li>
  25 + {/foreach}
  26 + </ul>
18 27 {/if}
19 28  
20 29 </div>
... ...