Commit cb65c9652c15664d2966352995357c903d1ce8f5
Merge branch 'download_notification' into edge
Showing
11 changed files
with
666 additions
and
68 deletions
download_notification.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * Electronic Signatures ajax functionality | |
| 4 | + * | |
| 5 | + * The contents of this file are subject to the KnowledgeTree | |
| 6 | + * Commercial Editions On-Premise License ("License"); | |
| 7 | + * You may not use this file except in compliance with the License. | |
| 8 | + * You may obtain a copy of the License at | |
| 9 | + * http://www.knowledgetree.com/about/legal/ | |
| 10 | + * The terms of this license may change from time to time and the latest | |
| 11 | + * license will be published from time to time at the above Internet address. | |
| 12 | + * | |
| 13 | + * This edition of the KnowledgeTree software | |
| 14 | + * is NOT licensed to you under Open Source terms. | |
| 15 | + * You may not redistribute this source code. | |
| 16 | + * For more information please see the License above. | |
| 17 | + * | |
| 18 | + * (c) 2008, 2009 KnowledgeTree Inc. | |
| 19 | + * All Rights Reserved. | |
| 20 | + * | |
| 21 | + * @copyright 2008-2009, KnowledgeTree Inc. | |
| 22 | + * @license GNU General Public License version 3 | |
| 23 | + * @author KnowledgeTree Team | |
| 24 | + * @package Electronic Signatures | |
| 25 | + * @version Version 0.9 | |
| 26 | + */ | |
| 27 | + | |
| 28 | +//$full_dir = dirname(__FILE__); | |
| 29 | + | |
| 30 | +//$pos = strpos($full_dir, 'plugins'); | |
| 31 | +//$dir = substr($full_dir, 0, $pos); | |
| 32 | + | |
| 33 | +require_once('config/dmsDefaults.php'); | |
| 34 | +require_once(KT_LIB_DIR . '/foldermanagement/compressionArchiveUtil.inc.php'); | |
| 35 | +require_once(KT_LIB_DIR . '/foldermanagement/downloadNotification.inc.php'); | |
| 36 | + | |
| 37 | +$action = $_POST['action']; | |
| 38 | +$code = $_POST['code']; | |
| 39 | +if ($action == 'delete') { | |
| 40 | + DownloadQueue::deleteDownload($code); | |
| 41 | +} | |
| 42 | +else { | |
| 43 | + $head = $_POST['head']; | |
| 44 | + | |
| 45 | + // display the download notification | |
| 46 | + $notification = new KTDownloadNotification($code); | |
| 47 | + echo $notification->getNotificationForm($head); | |
| 48 | +} | |
| 49 | + | |
| 50 | +exit; | |
| 51 | +?> | |
| 0 | 52 | \ No newline at end of file | ... | ... |
lib/foldermanagement/compressionArchiveUtil.inc.php
| ... | ... | @@ -311,6 +311,12 @@ class ZipFolder { |
| 311 | 311 | |
| 312 | 312 | KTUtil::download($sZipFile, $mimeType, $fileSize, $fileName); |
| 313 | 313 | KTUtil::deleteDirectory($sTmpPath); |
| 314 | + // remove notification file if it exists | |
| 315 | + DownloadQueue::removeNotificationFile(); | |
| 316 | + | |
| 317 | + // remove zip file database entry and any stragglers | |
| 318 | + DBUtil::whereDelete('download_queue', array('code' => $exportCode)); | |
| 319 | + | |
| 314 | 320 | return true; |
| 315 | 321 | } |
| 316 | 322 | |
| ... | ... | @@ -398,6 +404,26 @@ class ZipFolder { |
| 398 | 404 | |
| 399 | 405 | return false; |
| 400 | 406 | } |
| 407 | + | |
| 408 | + /** | |
| 409 | + * Returns the zip file name with extension | |
| 410 | + * | |
| 411 | + * @return string | |
| 412 | + */ | |
| 413 | + public function getZipFileName() | |
| 414 | + { | |
| 415 | + return $this->sZipFileName . '.' . $this->extension; | |
| 416 | + } | |
| 417 | + | |
| 418 | + /** | |
| 419 | + * Returns the path to the zip file | |
| 420 | + * | |
| 421 | + * @return string | |
| 422 | + */ | |
| 423 | + public function getTmpPath() | |
| 424 | + { | |
| 425 | + return $this->sTmpPath; | |
| 426 | + } | |
| 401 | 427 | } |
| 402 | 428 | |
| 403 | 429 | /** |
| ... | ... | @@ -410,6 +436,7 @@ class DownloadQueue |
| 410 | 436 | private $bNotifications; |
| 411 | 437 | private $errors; |
| 412 | 438 | private $lockFile; |
| 439 | + static private $notificationFile = 'download_queue_notification'; | |
| 413 | 440 | |
| 414 | 441 | /** |
| 415 | 442 | * Construct download queue object |
| ... | ... | @@ -446,25 +473,25 @@ class DownloadQueue |
| 446 | 473 | |
| 447 | 474 | /** |
| 448 | 475 | * Remove an item from the download queue |
| 476 | + * Will not remove zip object types, these must be independently removed | |
| 449 | 477 | * |
| 450 | 478 | * @param string $code Identification string for the download item |
| 451 | 479 | * @return boolean | PEAR_Error |
| 452 | 480 | */ |
| 453 | 481 | public function removeItem($code) |
| 454 | 482 | { |
| 455 | - $where = array('code' => $code); | |
| 456 | - $res = DBUtil::whereDelete('download_queue', $where); | |
| 483 | + $res = DBUtil::runQuery('DELETE FROM download_queue WHERE code = "' . $code . '" AND object_type != "zip"'); | |
| 457 | 484 | return $res; |
| 458 | 485 | } |
| 459 | 486 | |
| 460 | 487 | /** |
| 461 | - * Get all download items in the queue | |
| 488 | + * Get all download items (other than zip object type) in the queue | |
| 462 | 489 | * |
| 463 | 490 | * @return Queue array | PEAR_Error |
| 464 | 491 | */ |
| 465 | 492 | public function getQueue() |
| 466 | 493 | { |
| 467 | - $sql = 'SELECT * FROM download_queue d WHERE status = 0 ORDER BY date_added, code'; | |
| 494 | + $sql = 'SELECT * FROM download_queue d WHERE status = 0 AND object_type != "zip" ORDER BY date_added, code'; | |
| 468 | 495 | $rows = DBUtil::getResultArray($sql); |
| 469 | 496 | |
| 470 | 497 | if(PEAR::isError($rows)){ |
| ... | ... | @@ -502,12 +529,15 @@ class DownloadQueue |
| 502 | 529 | * @param string $error Optional. The error's generated during the archive |
| 503 | 530 | * @return boolean |
| 504 | 531 | */ |
| 505 | - public function setItemStatus($code, $status = 1, $error = null) | |
| 532 | + public function setItemStatus($code, $status = 1, $error = null, $zip = false) | |
| 506 | 533 | { |
| 507 | 534 | $fields = array(); |
| 508 | 535 | $fields['status'] = $status; |
| 509 | 536 | $fields['errors'] = !empty($error) ? json_encode($error) : null; |
| 510 | 537 | $where = array('code' => $code); |
| 538 | + if ($zip) { | |
| 539 | + $where['object_type'] = 'zip'; | |
| 540 | + } | |
| 511 | 541 | $res = DBUtil::whereUpdate('download_queue', $fields, $where); |
| 512 | 542 | return $res; |
| 513 | 543 | } |
| ... | ... | @@ -617,6 +647,18 @@ class DownloadQueue |
| 617 | 647 | $this->errors = null; |
| 618 | 648 | $_SESSION['zipcompression'] = null; |
| 619 | 649 | } |
| 650 | + | |
| 651 | + // check for any errors and if none found then create the entry for the zip file which will be used by the notification code | |
| 652 | + if (!PEAR::isError($res) && !PEAR::isError($result)/* && !PEAR::isError() // There was a third one here originally but I cannot remember what it was // */) { | |
| 653 | + // create the db entry | |
| 654 | + self::addItem($code, self::getFolderId($code), -1, 'zip'); | |
| 655 | + // update the db entry with the appropriate status and message | |
| 656 | + $this->setItemStatus($code, 2, serialize(array($zip->getTmpPath(), $zip->getZipFileName())), true); | |
| 657 | + // Here was an attempt to allow the download notification to occur if the user left the page, which was using a session value (which didn't work properly) and then | |
| 658 | + // we were trying a file, which was untested and in process when the file corruption occurred. Will continue this once the rest of the code is committed & safe. | |
| 659 | + $config = KTConfig::getSingleton(); | |
| 660 | + @touch($config->get('cache/cacheDirectory') . '/' . self::$notificationFile); | |
| 661 | + } | |
| 620 | 662 | |
| 621 | 663 | // Remove lock file |
| 622 | 664 | @unlink($this->lockFile); |
| ... | ... | @@ -757,7 +799,8 @@ class DownloadQueue |
| 757 | 799 | * @param Folder array $aFolderList |
| 758 | 800 | * @return unknown |
| 759 | 801 | */ |
| 760 | - function getLinkingEntities($aFolderList){ | |
| 802 | + function getLinkingEntities($aFolderList) | |
| 803 | + { | |
| 761 | 804 | $aSearchFolders = array(); |
| 762 | 805 | if(!empty($aFolderList)){ |
| 763 | 806 | foreach($aFolderList as $oFolderItem){ |
| ... | ... | @@ -846,5 +889,142 @@ class DownloadQueue |
| 846 | 889 | { |
| 847 | 890 | return file_exists($this->lockFile); |
| 848 | 891 | } |
| 892 | + | |
| 893 | + /** | |
| 894 | + * The code below has all been added for bulk download notifications | |
| 895 | + * | |
| 896 | + * The functions were declared as static because they are related to but not entirely part of the download queue process | |
| 897 | + * and I wanted to use them without having to instantiate the class | |
| 898 | + */ | |
| 899 | + | |
| 900 | + /** | |
| 901 | + * Checks whether there are any bulk downloads which have passed the timeout limit | |
| 902 | + * Default limit is set to 48 hours but this can be changed in the calling code | |
| 903 | + * | |
| 904 | + * @param int $limit the number of hours after which a download should be considered timed out | |
| 905 | + */ | |
| 906 | + static public function timeout($limit = 48) | |
| 907 | + { | |
| 908 | + DBUtil::runQuery('DELETE FROM download_queue WHERE DATE_ADD(date_added, INTERVAL ' . $limit . ' HOUR) < NOW()'); | |
| 909 | + } | |
| 910 | + | |
| 911 | + /** | |
| 912 | + * Checks whether there is a bulk download available and waiting for the supplied user | |
| 913 | + * | |
| 914 | + * @param int $userID | |
| 915 | + */ | |
| 916 | + static public function userDownloadAvailable($userID) | |
| 917 | + { | |
| 918 | + $result = DBUtil::getOneResult('SELECT code, errors FROM download_queue WHERE user_id = ' . $userID | |
| 919 | + . ' AND object_type = "zip" AND status = 2'); | |
| 920 | + if (PEAR::isError($result)) { | |
| 921 | + return false; | |
| 922 | + } | |
| 923 | + | |
| 924 | + $code = $result['code']; | |
| 925 | + | |
| 926 | + $message = $result['errors']; | |
| 927 | + $message = json_decode($message, true); | |
| 928 | + $data = unserialize($message); | |
| 929 | + | |
| 930 | + // Create the archive session variables - I can't recall if this was needed, will have to find out by testing... | |
| 931 | + $_SESSION['zipcompression'][$code]['file'] = $data[0] . DIRECTORY_SEPARATOR . $data[1]; | |
| 932 | + $_SESSION['zipcompression'][$code]['dir'] = $data[0]; | |
| 933 | + | |
| 934 | + // Check that the archive file has been created | |
| 935 | + // NOTE If it does not exist, consider deleting the db entry and looping back to check again, only returning when no more results are found in the db? | |
| 936 | + // The reason for this is that it is sometimes possible to end up with multiple zips listed in the db as waiting for the same user, | |
| 937 | + // some of which may no longer exist as physical files, and since the request only checks for one, it may miss am existing download. | |
| 938 | + // NOTE the above issue may only occur due to the way I have been testing, often breaking the process before it is finished, | |
| 939 | + // but conceivably this could actually happen in the real world also. | |
| 940 | + $zip = new ZipFolder('', $code); | |
| 941 | + if($zip->checkArchiveExists($code)) { | |
| 942 | + return $code; | |
| 943 | + } | |
| 944 | + | |
| 945 | + return false; | |
| 946 | + } | |
| 947 | + | |
| 948 | + /** | |
| 949 | + * Delete the download, including the database entry | |
| 950 | + * | |
| 951 | + * @param string $code | |
| 952 | + */ | |
| 953 | + static public function deleteDownload($code) | |
| 954 | + { | |
| 955 | + // retrieve the data to allow deletion of the physical file | |
| 956 | + $result = DBUtil::getOneResult('SELECT errors FROM download_queue WHERE code = "' . $code . '"' | |
| 957 | + . ' AND object_type = "zip" AND status = 2'); | |
| 958 | + | |
| 959 | + if (PEAR::isError($result)) { | |
| 960 | + return $result; | |
| 961 | + } | |
| 962 | + | |
| 963 | + $message = $result['errors']; | |
| 964 | + $message = json_decode($message, true); | |
| 965 | + $data = unserialize($message); | |
| 966 | + | |
| 967 | + // remove the database entry | |
| 968 | + DBUtil::whereDelete('download_queue', array('code' => $code)); | |
| 969 | + | |
| 970 | + // remove the actual file/directory | |
| 971 | + KTUtil::deleteDirectory($data[0]); | |
| 972 | + | |
| 973 | + // remove the notification file if present | |
| 974 | + self::removeNotificationFile(); | |
| 975 | + } | |
| 976 | + | |
| 977 | + /** | |
| 978 | + * Removes the notification file, if it exists, in a safe manner | |
| 979 | + * | |
| 980 | + * @param string $code | |
| 981 | + */ | |
| 982 | + static public function removeNotificationFile() { | |
| 983 | + $config = KTConfig::getSingleton(); | |
| 984 | + $file = DownloadQueue::getNotificationFileName(); | |
| 985 | + if (!PEAR::isError($file)) { | |
| 986 | + $notificationFile = $config->get('cache/cacheDirectory') . '/' . $file; | |
| 987 | + } | |
| 988 | + | |
| 989 | + // ensure the file is actually a file and not a directory | |
| 990 | + if (is_file($notificationFile)) { | |
| 991 | + @unlink($notificationFile); | |
| 992 | + } | |
| 993 | + } | |
| 994 | + | |
| 995 | + /** | |
| 996 | + * Fetches a link to the download | |
| 997 | + * | |
| 998 | + * @param string $code | |
| 999 | + */ | |
| 1000 | + static public function getDownloadLink($code) | |
| 1001 | + { | |
| 1002 | + return KTUtil::kt_url() . '/action.php?kt_path_info=ktcore.actions.bulk.export&action=downloadZipFile&fFolderId=' . self::getFolderId($code) . '&exportcode=' . $code; | |
| 1003 | + } | |
| 1004 | + | |
| 1005 | + /** | |
| 1006 | + * Fetches the folder id associated with the supplied code | |
| 1007 | + * Based on testing just before file corruption this may not actually be necessary, but we'll do it anyway | |
| 1008 | + * | |
| 1009 | + * @param string $code | |
| 1010 | + */ | |
| 1011 | + static public function getFolderId($code) | |
| 1012 | + { | |
| 1013 | + $result = DBUtil::getOneResult('SELECT folder_id FROM download_queue WHERE code = "' . $code . '"'); | |
| 1014 | + | |
| 1015 | + if (PEAR::isError($result)) { | |
| 1016 | + return -1; | |
| 1017 | + } | |
| 1018 | + | |
| 1019 | + return $result['folder_id']; | |
| 1020 | + } | |
| 1021 | + | |
| 1022 | + static public function getNotificationFileName() { | |
| 1023 | + if (!empty(self::$notificationFile)) { | |
| 1024 | + return self::$notificationFile; | |
| 1025 | + } | |
| 1026 | + | |
| 1027 | + return new PEAR_Error('Unable to get file name'); | |
| 1028 | + } | |
| 849 | 1029 | } |
| 850 | 1030 | ?> | ... | ... |
lib/foldermanagement/downloadNotification.inc.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Class handles the bulk download notification | |
| 5 | + * | |
| 6 | + * @author KnowledgeTree Team | |
| 7 | + * @package Bulk Downloads | |
| 8 | + */ | |
| 9 | +class KTDownloadNotification | |
| 10 | +{ | |
| 11 | + /** | |
| 12 | + * The error returned | |
| 13 | + * | |
| 14 | + * @access public | |
| 15 | + * @var $error | |
| 16 | + */ | |
| 17 | + public $error; | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * The user for which the download notification is being generated | |
| 21 | + * | |
| 22 | + * @access private | |
| 23 | + * @var $code | |
| 24 | + */ | |
| 25 | + private $code; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * Constructor function for the class | |
| 29 | + * | |
| 30 | + * @author KnowledgeTree Team | |
| 31 | + * @access public | |
| 32 | + * @return KTElectronicSignatures | |
| 33 | + */ | |
| 34 | + public function KTDownloadNotification($code) | |
| 35 | + { | |
| 36 | + $this->code = $code; | |
| 37 | + } | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Returns the form displaying the download link (and option to cancel the download?) | |
| 41 | + * | |
| 42 | + * @author KnowledgeTree Team | |
| 43 | + * @access public | |
| 44 | + * @param string $head The heading for the form | |
| 45 | + * @param string $request_type Determines the actions for the buttons | |
| 46 | + * @return html | |
| 47 | + */ | |
| 48 | + public function getNotificationForm($head) | |
| 49 | + { | |
| 50 | + global $default; | |
| 51 | + | |
| 52 | + // check for the download link | |
| 53 | + | |
| 54 | + $link = DownloadQueue::getDownloadLink($this->code); | |
| 55 | + $text = 'Download Now'; | |
| 56 | + | |
| 57 | + $cancelAction = 'deleteDownload()'; | |
| 58 | + $closeAction = 'deferDownload()'; | |
| 59 | + | |
| 60 | + $oTemplating =& KTTemplating::getSingleton(); | |
| 61 | + $oTemplate = $oTemplating->loadTemplate('kt3/notifications/notification.BulkDownload'); | |
| 62 | + $aTemplateData = array( | |
| 63 | + 'head' => $head, | |
| 64 | + 'downloadLink' => $link, | |
| 65 | + 'downloadText' => $text, | |
| 66 | + 'exportCode' => $this->code, | |
| 67 | + 'cancelAction' => $cancelAction, | |
| 68 | + 'closeAction' => $closeAction | |
| 69 | + ); | |
| 70 | + | |
| 71 | + return $oTemplate->render($aTemplateData); | |
| 72 | + } | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Returns the error from the attempted signature | |
| 76 | + * | |
| 77 | + * @author KnowledgeTree Team | |
| 78 | + * @access public | |
| 79 | + * @return string | |
| 80 | + */ | |
| 81 | + public function getError() | |
| 82 | + { | |
| 83 | + return '<div class="error">'.$this->error.'</div>'; | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Displays a button for closing the panel | |
| 88 | + * | |
| 89 | + * @author KnowledgeTree Team | |
| 90 | + * @access public | |
| 91 | + * @param string $request_type Determines the action taken on close - close = redirect action | null = close panel action | |
| 92 | + * @param string $request Optional. Used within the close action. | |
| 93 | + * @return string | |
| 94 | + */ | |
| 95 | + public function getCloseButton($request_type, $request = null) | |
| 96 | + { | |
| 97 | + switch ($request_type){ | |
| 98 | + case 'close': | |
| 99 | + $cancelAction = "window.location.href = '{$request}'"; | |
| 100 | + break; | |
| 101 | + | |
| 102 | + default: | |
| 103 | + $cancelAction = "panel_close()"; | |
| 104 | + } | |
| 105 | + | |
| 106 | + return '<div class="form_actions" style="margin-top: 30px;"> | |
| 107 | + <a href="#" onclick="javascript: '.$cancelAction.'">'._kt('Close').'</a> | |
| 108 | + </div>'; | |
| 109 | + } | |
| 110 | +} | |
| 111 | + | |
| 112 | +?> | |
| 0 | 113 | \ No newline at end of file | ... | ... |
lib/templating/kt3template.inc.php
| ... | ... | @@ -353,8 +353,9 @@ class KTPage { |
| 353 | 353 | function setSecondaryTitle($sSecondary) { $this->secondary_title = $sSecondary; } |
| 354 | 354 | |
| 355 | 355 | /* final render call. */ |
| 356 | - function render() { | |
| 357 | - global $default; | |
| 356 | + function render() | |
| 357 | + { | |
| 358 | + global $default; | |
| 358 | 359 | $oConfig = KTConfig::getSingleton(); |
| 359 | 360 | |
| 360 | 361 | if (empty($this->contents)) { |
| ... | ... | @@ -366,70 +367,68 @@ class KTPage { |
| 366 | 367 | $this->contents = ""; |
| 367 | 368 | } |
| 368 | 369 | |
| 369 | - if (!is_string($this->contents)) { | |
| 370 | - $this->contents = $this->contents->render(); | |
| 371 | - } | |
| 372 | - | |
| 373 | - // if we have no portlets, make the ui a tad nicer. | |
| 374 | - if (empty($this->portlets)) { | |
| 375 | - $this->show_portlets = false; | |
| 376 | - } | |
| 377 | - | |
| 378 | - if (empty($this->title)) { | |
| 379 | - if (!empty($this->breadcrumbDetails)) { | |
| 380 | - $this->title = $this->breadcrumbDetails; | |
| 381 | - } else if (!empty($this->breadcrumbs)) { | |
| 382 | - $this->title = array_slice($this->breadcrumbs, -1); | |
| 383 | - $this->title = $this->title[0]['label']; | |
| 384 | - } else if (!empty($this->breadcrumbSection)) { | |
| 385 | - $this->title = $this->breadcrumbSection['label']; | |
| 386 | - } else { | |
| 387 | - $this->title = $this->componentLabel; | |
| 388 | - } | |
| 389 | - } | |
| 390 | - | |
| 391 | - $this->userMenu = array(); | |
| 392 | - $sBaseUrl = KTUtil::kt_url(); | |
| 370 | + if (!is_string($this->contents)) { | |
| 371 | + $this->contents = $this->contents->render(); | |
| 372 | + } | |
| 393 | 373 | |
| 394 | - if (!(PEAR::isError($this->user) || is_null($this->user) || $this->user->isAnonymous())) { | |
| 395 | - if ($oConfig->get("user_prefs/restrictPreferences", false) && !Permission::userIsSystemAdministrator($this->user->getId())) { | |
| 396 | - $this->userMenu['logout'] = array('label' => _kt('Logout'), 'url' => $sBaseUrl.'/presentation/logout.php'); | |
| 397 | - } else { | |
| 374 | + // if we have no portlets, make the ui a tad nicer. | |
| 375 | + if (empty($this->portlets)) { | |
| 376 | + $this->show_portlets = false; | |
| 377 | + } | |
| 398 | 378 | |
| 399 | - if($default->enableESignatures){ | |
| 400 | - $sUrl = KTPluginUtil::getPluginPath('electronic.signatures.plugin', true); | |
| 401 | - $heading = _kt('You are attempting to modify Preferences'); | |
| 402 | - $this->userMenu['preferences']['url'] = '#'; | |
| 403 | - $this->userMenu['preferences']['onclick'] = "javascript: showSignatureForm('{$sUrl}', '{$heading}', 'dms.administration.accessing_preferences', 'system', '{$sBaseUrl}/preferences.php', 'redirect');"; | |
| 404 | - }else{ | |
| 405 | - $this->userMenu['preferences']['url'] = $sBaseUrl.'/preferences.php'; | |
| 379 | + if (empty($this->title)) { | |
| 380 | + if (!empty($this->breadcrumbDetails)) { | |
| 381 | + $this->title = $this->breadcrumbDetails; | |
| 382 | + } else if (!empty($this->breadcrumbs)) { | |
| 383 | + $this->title = array_slice($this->breadcrumbs, -1); | |
| 384 | + $this->title = $this->title[0]['label']; | |
| 385 | + } else if (!empty($this->breadcrumbSection)) { | |
| 386 | + $this->title = $this->breadcrumbSection['label']; | |
| 387 | + } else { | |
| 388 | + $this->title = $this->componentLabel; | |
| 406 | 389 | } |
| 390 | + } | |
| 407 | 391 | |
| 408 | -// $this->userMenu['preferences'] = array('label' => _kt('Preferences'), 'url' => $sBaseUrl.'/preferences.php'); | |
| 409 | - $this->userMenu['preferences']['label'] = _kt('Preferences'); | |
| 410 | - $this->userMenu['aboutkt'] = array('label' => _kt('About'), 'url' => $sBaseUrl.'/about.php'); | |
| 411 | - $this->userMenu['logout'] = array('label' => _kt('Logout'), 'url' => $sBaseUrl.'/presentation/logout.php'); | |
| 412 | - } | |
| 413 | - } else { | |
| 414 | - $this->userMenu['login'] = array('label' => _kt('Login'), 'url' => $sBaseUrl.'/login.php'); | |
| 415 | - } | |
| 416 | - | |
| 417 | - // FIXME we need a more complete solution to navigation restriction | |
| 418 | - if (!is_null($this->menu['administration']) && !is_null($this->user)) { | |
| 419 | - if (!Permission::userIsSystemAdministrator($this->user->getId())) { | |
| 420 | - unset($this->menu['administration']); | |
| 421 | - } | |
| 422 | - } | |
| 392 | + $this->userMenu = array(); | |
| 393 | + $sBaseUrl = KTUtil::kt_url(); | |
| 394 | + | |
| 395 | + if (!(PEAR::isError($this->user) || is_null($this->user) || $this->user->isAnonymous())) { | |
| 396 | + if ($oConfig->get("user_prefs/restrictPreferences", false) && !Permission::userIsSystemAdministrator($this->user->getId())) { | |
| 397 | + $this->userMenu['logout'] = array('label' => _kt('Logout'), 'url' => $sBaseUrl.'/presentation/logout.php'); | |
| 398 | + } else { | |
| 399 | + if($default->enableESignatures) { | |
| 400 | + $sUrl = KTPluginUtil::getPluginPath('electronic.signatures.plugin', true); | |
| 401 | + $heading = _kt('You are attempting to modify Preferences'); | |
| 402 | + $this->userMenu['preferences']['url'] = '#'; | |
| 403 | + $this->userMenu['preferences']['onclick'] = "javascript: showSignatureForm('{$sUrl}', '{$heading}', 'dms.administration.accessing_preferences', 'system', '{$sBaseUrl}/preferences.php', 'redirect');"; | |
| 404 | + } else { | |
| 405 | + $this->userMenu['preferences']['url'] = $sBaseUrl.'/preferences.php'; | |
| 406 | + } | |
| 407 | + | |
| 408 | + // $this->userMenu['preferences'] = array('label' => _kt('Preferences'), 'url' => $sBaseUrl.'/preferences.php'); | |
| 409 | + $this->userMenu['preferences']['label'] = _kt('Preferences'); | |
| 410 | + $this->userMenu['aboutkt'] = array('label' => _kt('About'), 'url' => $sBaseUrl.'/about.php'); | |
| 411 | + $this->userMenu['logout'] = array('label' => _kt('Logout'), 'url' => $sBaseUrl.'/presentation/logout.php'); | |
| 412 | + } | |
| 413 | + } else { | |
| 414 | + $this->userMenu['login'] = array('label' => _kt('Login'), 'url' => $sBaseUrl.'/login.php'); | |
| 415 | + } | |
| 423 | 416 | |
| 424 | - $sContentType = 'Content-type: ' . $this->contentType; | |
| 425 | - if(!empty($this->charset)) { | |
| 426 | - $sContentType .= '; charset=' . $this->charset; | |
| 427 | - }; | |
| 417 | + // FIXME we need a more complete solution to navigation restriction | |
| 418 | + if (!is_null($this->menu['administration']) && !is_null($this->user)) { | |
| 419 | + if (!Permission::userIsSystemAdministrator($this->user->getId())) { | |
| 420 | + unset($this->menu['administration']); | |
| 421 | + } | |
| 422 | + } | |
| 428 | 423 | |
| 424 | + $sContentType = 'Content-type: ' . $this->contentType; | |
| 425 | + if(!empty($this->charset)) { | |
| 426 | + $sContentType .= '; charset=' . $this->charset; | |
| 427 | + }; | |
| 429 | 428 | |
| 430 | - header($sContentType); | |
| 429 | + header($sContentType); | |
| 431 | 430 | |
| 432 | - $savedSearches = SearchHelper::getSavedSearches($_SESSION['userID']); | |
| 431 | + $savedSearches = SearchHelper::getSavedSearches($_SESSION['userID']); | |
| 433 | 432 | |
| 434 | 433 | $oTemplating =& KTTemplating::getSingleton(); |
| 435 | 434 | $oTemplate = $oTemplating->loadTemplate($this->template); |
| ... | ... | @@ -442,13 +441,24 @@ class KTPage { |
| 442 | 441 | if ($oConfig->get("ui/automaticRefresh", false)) { |
| 443 | 442 | $aTemplateData['refreshTimeout'] = (int)$oConfig->get("session/sessionTimeout") + 3; |
| 444 | 443 | } |
| 444 | + | |
| 445 | + // Trigger for pending downloads | |
| 446 | + $aTemplateData['downloadNotification'] = null; | |
| 447 | + require_once(KT_LIB_DIR . '/triggers/triggerregistry.inc.php'); | |
| 448 | + $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); | |
| 449 | + $aTriggers = $oKTTriggerRegistry->getTriggers('ktcore', 'pageLoad'); | |
| 450 | + foreach ($aTriggers as $aTrigger) { | |
| 451 | + $sTrigger = $aTrigger[0]; | |
| 452 | + $oTrigger = new $sTrigger; | |
| 453 | + $aTemplateData['downloadNotification'] = $oTrigger->invoke(); | |
| 454 | + } | |
| 445 | 455 | |
| 446 | 456 | // unlike the rest of KT, we use echo here. |
| 447 | 457 | echo $oTemplate->render($aTemplateData); |
| 448 | 458 | } |
| 449 | 459 | |
| 450 | 460 | |
| 451 | - /** heler functions */ | |
| 461 | + /** helper functions */ | |
| 452 | 462 | // returns an array ("url", "label") |
| 453 | 463 | function _actionhelper($aActionTuple) { |
| 454 | 464 | $aTuple = Array("label" => $aActionTuple["name"]); | ... | ... |
login.php
| ... | ... | @@ -116,6 +116,9 @@ class LoginPageDispatcher extends KTDispatcher { |
| 116 | 116 | if (PEAR::isError($sessionID)) { |
| 117 | 117 | return $sessionID; |
| 118 | 118 | } |
| 119 | + | |
| 120 | + // add a flag to check for bulk downloads after login is succesful; this will be cleared in the code which checks | |
| 121 | + $_SESSION['checkBulkDownload'] = true; | |
| 119 | 122 | |
| 120 | 123 | $redirect = strip_tags(KTUtil::arrayGet($_REQUEST, 'redirect')); |
| 121 | 124 | ... | ... |
plugins/ktcore/KTBulkActions.php
| ... | ... | @@ -1197,7 +1197,7 @@ class KTBrowseBulkExportAction extends KTBulkAction { |
| 1197 | 1197 | * |
| 1198 | 1198 | */ |
| 1199 | 1199 | function perform_action($oEntity) { |
| 1200 | -// TODO find a way to do bulk email | |
| 1200 | + // TODO find a way to do bulk email | |
| 1201 | 1201 | $exportCode = $_SESSION['exportcode']; |
| 1202 | 1202 | $this->oZip = ZipFolder::get($exportCode); |
| 1203 | 1203 | ... | ... |
plugins/ktcore/KTCorePlugin.php
| ... | ... | @@ -169,11 +169,13 @@ class KTCorePlugin extends KTPlugin { |
| 169 | 169 | $this->registerTrigger('add', 'postValidate', 'SavedSearchSubscriptionTrigger', 'ktcore.search2.savedsearch.subscription.add', KT_DIR . '/plugins/search2/Search2Triggers.php'); |
| 170 | 170 | $this->registerTrigger('discussion', 'postValidate', 'SavedSearchSubscriptionTrigger', 'ktcore.search2.savedsearch.subscription.discussion', KT_DIR . '/plugins/search2/Search2Triggers.php'); |
| 171 | 171 | |
| 172 | - //Tag Cloud Triggers | |
| 172 | + // Tag Cloud Triggers | |
| 173 | 173 | $this->registerTrigger('add', 'postValidate', 'KTAddDocumentTrigger', 'ktcore.triggers.tagcloud.add', KT_DIR.'/plugins/tagcloud/TagCloudTriggers.php'); |
| 174 | 174 | $this->registerTrigger('edit', 'postValidate', 'KTEditDocumentTrigger', 'ktcore.triggers.tagcloud.edit', KT_DIR.'/plugins/tagcloud/TagCloudTriggers.php'); |
| 175 | 175 | |
| 176 | - | |
| 176 | + // Bulk Download Trigger | |
| 177 | + $this->registerTrigger('ktcore', 'pageLoad', 'BulkDownloadTrigger', 'ktcore.triggers.pageload', 'KTDownloadTriggers.inc.php'); | |
| 178 | + | |
| 177 | 179 | // widgets |
| 178 | 180 | $this->registerWidget('KTCoreInfoWidget', 'ktcore.widgets.info', 'KTWidgets.php'); |
| 179 | 181 | $this->registerWidget('KTCoreHiddenWidget', 'ktcore.widgets.hidden', 'KTWidgets.php'); | ... | ... |
plugins/ktcore/KTDownloadTriggers.inc.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * $Id$ | |
| 5 | + * | |
| 6 | + * KnowledgeTree Community Edition | |
| 7 | + * Document Management Made Simple | |
| 8 | + * Copyright (C) 2008, 2009 KnowledgeTree Inc. | |
| 9 | + * | |
| 10 | + * | |
| 11 | + * This program is free software; you can redistribute it and/or modify it under | |
| 12 | + * the terms of the GNU General Public License version 3 as published by the | |
| 13 | + * Free Software Foundation. | |
| 14 | + * | |
| 15 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
| 16 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 17 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 18 | + * details. | |
| 19 | + * | |
| 20 | + * You should have received a copy of the GNU General Public License | |
| 21 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 22 | + * | |
| 23 | + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 24 | + * California 94120-7775, or email info@knowledgetree.com. | |
| 25 | + * | |
| 26 | + * The interactive user interfaces in modified source and object code versions | |
| 27 | + * of this program must display Appropriate Legal Notices, as required under | |
| 28 | + * Section 5 of the GNU General Public License version 3. | |
| 29 | + * | |
| 30 | + * In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 31 | + * these Appropriate Legal Notices must retain the display of the "Powered by | |
| 32 | + * KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 33 | + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 34 | + * must display the words "Powered by KnowledgeTree" and retain the original | |
| 35 | + * copyright notice. | |
| 36 | + * Contributor( s): ______________________________________ | |
| 37 | + * | |
| 38 | + */ | |
| 39 | + | |
| 40 | +class BulkDownloadTrigger { | |
| 41 | + | |
| 42 | + var $sNamespace = 'ktcore.triggers.download'; | |
| 43 | + var $sFriendlyName; | |
| 44 | + var $sDescription; | |
| 45 | + | |
| 46 | + function __construct() | |
| 47 | + { | |
| 48 | + $this->sFriendlyName = _kt('Bulk Download Notification'); | |
| 49 | + $this->sDescription = _kt('Notifies the newly logged in user of any waiting bulk downloads.'); | |
| 50 | + } | |
| 51 | + | |
| 52 | + public function invoke() | |
| 53 | + { | |
| 54 | + // TODO get this working with triggers instead of this? | |
| 55 | + // check for timed out downloads - now we may be looking at enough code to justify a trigger instead of all being here...? | |
| 56 | + DownloadQueue::timeout(); | |
| 57 | + | |
| 58 | + // determine whether there is a waiting bulk download | |
| 59 | + global $main; | |
| 60 | + // first check whether there is in fact a download waiting for this user | |
| 61 | + $config = KTConfig::getSingleton(); | |
| 62 | + $file = DownloadQueue::getNotificationFileName(); | |
| 63 | + if (!PEAR::isError($file)) { | |
| 64 | + $notificationFile = $config->get('cache/cacheDirectory') . '/' . $file; | |
| 65 | + } | |
| 66 | + if ((isset($_SESSION['checkBulkDownload']) && ($_SESSION['checkBulkDownload'])) || (file_exists($notificationFile))) { | |
| 67 | + unset($_SESSION['checkBulkDownload']); | |
| 68 | + DownloadQueue::removeNotificationFile(); | |
| 69 | + | |
| 70 | + require_once(KT_LIB_DIR . DIRECTORY_SEPARATOR . 'foldermanagement' . DIRECTORY_SEPARATOR . 'compressionArchiveUtil.inc.php'); | |
| 71 | + | |
| 72 | + $userID = $_SESSION['userID']; | |
| 73 | + $code = DownloadQueue::userDownloadAvailable($userID); | |
| 74 | + if ($code) { | |
| 75 | + $sBaseUrl = KTUtil::kt_url(); | |
| 76 | + $sUrl = $sBaseUrl . '/'; | |
| 77 | + $heading = _kt('You have a download waiting'); | |
| 78 | + $main->requireJSResource('resources/js/download_notification.js'); | |
| 79 | + $notification = "showDownloadNotification('{$sUrl}', '{$heading}', 'dms.users.bulk_download_notification', " | |
| 80 | + . "'{$code}', 'close');"; | |
| 81 | + } | |
| 82 | + | |
| 83 | + return $notification; | |
| 84 | + } | |
| 85 | + | |
| 86 | + return null; | |
| 87 | + } | |
| 88 | + | |
| 89 | +} | |
| 90 | + | |
| 91 | +?> | ... | ... |
resources/js/download_notification.js
0 → 100644
| 1 | +var win; | |
| 2 | +var head; | |
| 3 | +var sUrl; | |
| 4 | +var type; | |
| 5 | +var request; | |
| 6 | +var request_type; | |
| 7 | +var request_details; | |
| 8 | + | |
| 9 | +/* | |
| 10 | +* Create the download notification dialog | |
| 11 | +*/ | |
| 12 | +var showDownloadNotification = function(sUrl, head, action, code, request_type, details){ | |
| 13 | + createNotification(); | |
| 14 | + | |
| 15 | + this.sUrl = sUrl + 'download_notification.php'; | |
| 16 | + | |
| 17 | + if(details === undefined) details = ''; | |
| 18 | + if(request_type === undefined) request_type = 'submit'; | |
| 19 | + if(type === undefined) type = 'system'; | |
| 20 | + | |
| 21 | + this.head = head; | |
| 22 | + this.code = code; | |
| 23 | + this.request = request; | |
| 24 | + this.request_type = request_type; | |
| 25 | + this.request_details = new Array(); | |
| 26 | + this.request_details[0] = action; | |
| 27 | + this.request_details[1] = details; | |
| 28 | + | |
| 29 | + // create the window | |
| 30 | + this.win = new Ext.Window({ | |
| 31 | + applyTo : 'download_notification', | |
| 32 | + layout : 'fit', | |
| 33 | + width : 370, | |
| 34 | + height : 150, | |
| 35 | + resizable : false, | |
| 36 | + closable : false, | |
| 37 | + closeAction :'destroy', | |
| 38 | + y : 150, | |
| 39 | + shadow: false, | |
| 40 | + modal: true | |
| 41 | + }); | |
| 42 | + this.win.show(); | |
| 43 | + | |
| 44 | + var info = document.getElementById('download_link'); | |
| 45 | + | |
| 46 | + Ext.Ajax.request({ | |
| 47 | + url: this.sUrl, | |
| 48 | + success: function(response) { | |
| 49 | + info.innerHTML = response.responseText; | |
| 50 | + document.getElementById('download_link').focus(); | |
| 51 | + }, | |
| 52 | + failure: function(response) { | |
| 53 | + alert('Error. Couldn\'t locate download.'); | |
| 54 | + }, | |
| 55 | + params: { | |
| 56 | + action: 'fetch', | |
| 57 | + head: head, | |
| 58 | + code: this.code, | |
| 59 | + request_type: this.request_type, | |
| 60 | + request: this.request | |
| 61 | + } | |
| 62 | + }); | |
| 63 | +} | |
| 64 | + | |
| 65 | +/* | |
| 66 | +* Create the html required to display the download link | |
| 67 | +*/ | |
| 68 | +var createNotification = function() { | |
| 69 | + | |
| 70 | + if(document.getElementById('download-panel')){ | |
| 71 | + p = document.getElementById('download-panel'); | |
| 72 | + }else { | |
| 73 | + p = document.getElementById('pageBody').appendChild(document.createElement('div')); | |
| 74 | + p.id = 'download-panel'; | |
| 75 | + } | |
| 76 | + | |
| 77 | + inner = '<div id="download_notification" class="x-hidden"><div class="x-window-header">Download Notification</div><div class="x-window-body">'; | |
| 78 | + inner = inner + '<div id="popup_content"><div id="download_link">Loading...</div></div></div></div>'; | |
| 79 | + p.innerHTML = inner; | |
| 80 | +} | |
| 81 | + | |
| 82 | +/* | |
| 83 | +* Close the popup | |
| 84 | +*/ | |
| 85 | +var panel_close = function() { | |
| 86 | + this.win.destroy(); | |
| 87 | +} | |
| 88 | + | |
| 89 | +/** | |
| 90 | + * Defer the download to next login | |
| 91 | + */ | |
| 92 | +var deferDownload = function() { | |
| 93 | + if (confirm("This will defer the download until your next login")) { | |
| 94 | + panel_close(); | |
| 95 | + } | |
| 96 | +} | |
| 97 | + | |
| 98 | +/** | |
| 99 | + * Delete the download and close the window | |
| 100 | + */ | |
| 101 | +var deleteDownload = function() { | |
| 102 | + if (confirm("Cancelling will delete the download.\nYou will not be able to start the download at a later time.\n\nAre you sure?")) { | |
| 103 | + var info = document.getElementById('exportcode'); | |
| 104 | + | |
| 105 | + Ext.Ajax.request({ | |
| 106 | + url: this.sUrl, | |
| 107 | + success: function(response) { | |
| 108 | + if(response.responseText == 'success'){ | |
| 109 | + if(this.request_type == 'close'){ | |
| 110 | + // follow the close action | |
| 111 | + this.win.destroy(); | |
| 112 | + return; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + info.innerHTML = response.responseText; | |
| 116 | + }, | |
| 117 | + failure: function(response) { | |
| 118 | + alert('Error. Couldn\'t delete download.'); | |
| 119 | + }, | |
| 120 | + params: { | |
| 121 | + action: 'delete', | |
| 122 | + code: this.code | |
| 123 | + } | |
| 124 | + }); | |
| 125 | + | |
| 126 | + panel_close(); | |
| 127 | + } | |
| 128 | +} | ... | ... |
templates/kt3/notifications/notification.BulkDownload.smarty
0 → 100644
| 1 | +<h2><span class="warning" />{$head}</h2> | |
| 2 | +<p> </p> | |
| 3 | +<div id="download_form"> | |
| 4 | + <a href="{$downloadLink}" onclick="win.destroy();">{$downloadText}</a> | |
| 5 | +</div> | |
| 6 | +<p> </p> | |
| 7 | +<p> </p> | |
| 8 | +<div class="form_actions"> | |
| 9 | + <a href="#" onclick="javascript: {$cancelAction}">{i18n}Cancel{/i18n}</a> | |
| 10 | + | |
| 11 | + <a href="#" onclick="javascript: {$closeAction}">{i18n}Close{/i18n}</a> | |
| 12 | +</div> | |
| 13 | +<div id="process_msg" style="visibility: hidden;"> | |
| 14 | + {i18n}Starting download, please wait{/i18n}... | |
| 15 | +</div> | |
| 16 | +<input type="hidden" name="exportcode" id="exportcode" value="{$exportCode}" /> | |
| 0 | 17 | \ No newline at end of file | ... | ... |