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 | \ No newline at end of file | 52 | \ No newline at end of file |
lib/foldermanagement/compressionArchiveUtil.inc.php
| @@ -311,6 +311,12 @@ class ZipFolder { | @@ -311,6 +311,12 @@ class ZipFolder { | ||
| 311 | 311 | ||
| 312 | KTUtil::download($sZipFile, $mimeType, $fileSize, $fileName); | 312 | KTUtil::download($sZipFile, $mimeType, $fileSize, $fileName); |
| 313 | KTUtil::deleteDirectory($sTmpPath); | 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 | return true; | 320 | return true; |
| 315 | } | 321 | } |
| 316 | 322 | ||
| @@ -398,6 +404,26 @@ class ZipFolder { | @@ -398,6 +404,26 @@ class ZipFolder { | ||
| 398 | 404 | ||
| 399 | return false; | 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,6 +436,7 @@ class DownloadQueue | ||
| 410 | private $bNotifications; | 436 | private $bNotifications; |
| 411 | private $errors; | 437 | private $errors; |
| 412 | private $lockFile; | 438 | private $lockFile; |
| 439 | + static private $notificationFile = 'download_queue_notification'; | ||
| 413 | 440 | ||
| 414 | /** | 441 | /** |
| 415 | * Construct download queue object | 442 | * Construct download queue object |
| @@ -446,25 +473,25 @@ class DownloadQueue | @@ -446,25 +473,25 @@ class DownloadQueue | ||
| 446 | 473 | ||
| 447 | /** | 474 | /** |
| 448 | * Remove an item from the download queue | 475 | * Remove an item from the download queue |
| 476 | + * Will not remove zip object types, these must be independently removed | ||
| 449 | * | 477 | * |
| 450 | * @param string $code Identification string for the download item | 478 | * @param string $code Identification string for the download item |
| 451 | * @return boolean | PEAR_Error | 479 | * @return boolean | PEAR_Error |
| 452 | */ | 480 | */ |
| 453 | public function removeItem($code) | 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 | return $res; | 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 | * @return Queue array | PEAR_Error | 490 | * @return Queue array | PEAR_Error |
| 464 | */ | 491 | */ |
| 465 | public function getQueue() | 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 | $rows = DBUtil::getResultArray($sql); | 495 | $rows = DBUtil::getResultArray($sql); |
| 469 | 496 | ||
| 470 | if(PEAR::isError($rows)){ | 497 | if(PEAR::isError($rows)){ |
| @@ -502,12 +529,15 @@ class DownloadQueue | @@ -502,12 +529,15 @@ class DownloadQueue | ||
| 502 | * @param string $error Optional. The error's generated during the archive | 529 | * @param string $error Optional. The error's generated during the archive |
| 503 | * @return boolean | 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 | $fields = array(); | 534 | $fields = array(); |
| 508 | $fields['status'] = $status; | 535 | $fields['status'] = $status; |
| 509 | $fields['errors'] = !empty($error) ? json_encode($error) : null; | 536 | $fields['errors'] = !empty($error) ? json_encode($error) : null; |
| 510 | $where = array('code' => $code); | 537 | $where = array('code' => $code); |
| 538 | + if ($zip) { | ||
| 539 | + $where['object_type'] = 'zip'; | ||
| 540 | + } | ||
| 511 | $res = DBUtil::whereUpdate('download_queue', $fields, $where); | 541 | $res = DBUtil::whereUpdate('download_queue', $fields, $where); |
| 512 | return $res; | 542 | return $res; |
| 513 | } | 543 | } |
| @@ -617,6 +647,18 @@ class DownloadQueue | @@ -617,6 +647,18 @@ class DownloadQueue | ||
| 617 | $this->errors = null; | 647 | $this->errors = null; |
| 618 | $_SESSION['zipcompression'] = null; | 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 | // Remove lock file | 663 | // Remove lock file |
| 622 | @unlink($this->lockFile); | 664 | @unlink($this->lockFile); |
| @@ -757,7 +799,8 @@ class DownloadQueue | @@ -757,7 +799,8 @@ class DownloadQueue | ||
| 757 | * @param Folder array $aFolderList | 799 | * @param Folder array $aFolderList |
| 758 | * @return unknown | 800 | * @return unknown |
| 759 | */ | 801 | */ |
| 760 | - function getLinkingEntities($aFolderList){ | 802 | + function getLinkingEntities($aFolderList) |
| 803 | + { | ||
| 761 | $aSearchFolders = array(); | 804 | $aSearchFolders = array(); |
| 762 | if(!empty($aFolderList)){ | 805 | if(!empty($aFolderList)){ |
| 763 | foreach($aFolderList as $oFolderItem){ | 806 | foreach($aFolderList as $oFolderItem){ |
| @@ -846,5 +889,142 @@ class DownloadQueue | @@ -846,5 +889,142 @@ class DownloadQueue | ||
| 846 | { | 889 | { |
| 847 | return file_exists($this->lockFile); | 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 | \ No newline at end of file | 113 | \ No newline at end of file |
lib/templating/kt3template.inc.php
| @@ -353,8 +353,9 @@ class KTPage { | @@ -353,8 +353,9 @@ class KTPage { | ||
| 353 | function setSecondaryTitle($sSecondary) { $this->secondary_title = $sSecondary; } | 353 | function setSecondaryTitle($sSecondary) { $this->secondary_title = $sSecondary; } |
| 354 | 354 | ||
| 355 | /* final render call. */ | 355 | /* final render call. */ |
| 356 | - function render() { | ||
| 357 | - global $default; | 356 | + function render() |
| 357 | + { | ||
| 358 | + global $default; | ||
| 358 | $oConfig = KTConfig::getSingleton(); | 359 | $oConfig = KTConfig::getSingleton(); |
| 359 | 360 | ||
| 360 | if (empty($this->contents)) { | 361 | if (empty($this->contents)) { |
| @@ -366,70 +367,68 @@ class KTPage { | @@ -366,70 +367,68 @@ class KTPage { | ||
| 366 | $this->contents = ""; | 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 | $oTemplating =& KTTemplating::getSingleton(); | 433 | $oTemplating =& KTTemplating::getSingleton(); |
| 435 | $oTemplate = $oTemplating->loadTemplate($this->template); | 434 | $oTemplate = $oTemplating->loadTemplate($this->template); |
| @@ -442,13 +441,24 @@ class KTPage { | @@ -442,13 +441,24 @@ class KTPage { | ||
| 442 | if ($oConfig->get("ui/automaticRefresh", false)) { | 441 | if ($oConfig->get("ui/automaticRefresh", false)) { |
| 443 | $aTemplateData['refreshTimeout'] = (int)$oConfig->get("session/sessionTimeout") + 3; | 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 | // unlike the rest of KT, we use echo here. | 456 | // unlike the rest of KT, we use echo here. |
| 447 | echo $oTemplate->render($aTemplateData); | 457 | echo $oTemplate->render($aTemplateData); |
| 448 | } | 458 | } |
| 449 | 459 | ||
| 450 | 460 | ||
| 451 | - /** heler functions */ | 461 | + /** helper functions */ |
| 452 | // returns an array ("url", "label") | 462 | // returns an array ("url", "label") |
| 453 | function _actionhelper($aActionTuple) { | 463 | function _actionhelper($aActionTuple) { |
| 454 | $aTuple = Array("label" => $aActionTuple["name"]); | 464 | $aTuple = Array("label" => $aActionTuple["name"]); |
login.php
| @@ -116,6 +116,9 @@ class LoginPageDispatcher extends KTDispatcher { | @@ -116,6 +116,9 @@ class LoginPageDispatcher extends KTDispatcher { | ||
| 116 | if (PEAR::isError($sessionID)) { | 116 | if (PEAR::isError($sessionID)) { |
| 117 | return $sessionID; | 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 | $redirect = strip_tags(KTUtil::arrayGet($_REQUEST, 'redirect')); | 123 | $redirect = strip_tags(KTUtil::arrayGet($_REQUEST, 'redirect')); |
| 121 | 124 |
plugins/ktcore/KTBulkActions.php
| @@ -1197,7 +1197,7 @@ class KTBrowseBulkExportAction extends KTBulkAction { | @@ -1197,7 +1197,7 @@ class KTBrowseBulkExportAction extends KTBulkAction { | ||
| 1197 | * | 1197 | * |
| 1198 | */ | 1198 | */ |
| 1199 | function perform_action($oEntity) { | 1199 | function perform_action($oEntity) { |
| 1200 | -// TODO find a way to do bulk email | 1200 | + // TODO find a way to do bulk email |
| 1201 | $exportCode = $_SESSION['exportcode']; | 1201 | $exportCode = $_SESSION['exportcode']; |
| 1202 | $this->oZip = ZipFolder::get($exportCode); | 1202 | $this->oZip = ZipFolder::get($exportCode); |
| 1203 | 1203 |
plugins/ktcore/KTCorePlugin.php
| @@ -169,11 +169,13 @@ class KTCorePlugin extends KTPlugin { | @@ -169,11 +169,13 @@ class KTCorePlugin extends KTPlugin { | ||
| 169 | $this->registerTrigger('add', 'postValidate', 'SavedSearchSubscriptionTrigger', 'ktcore.search2.savedsearch.subscription.add', KT_DIR . '/plugins/search2/Search2Triggers.php'); | 169 | $this->registerTrigger('add', 'postValidate', 'SavedSearchSubscriptionTrigger', 'ktcore.search2.savedsearch.subscription.add', KT_DIR . '/plugins/search2/Search2Triggers.php'); |
| 170 | $this->registerTrigger('discussion', 'postValidate', 'SavedSearchSubscriptionTrigger', 'ktcore.search2.savedsearch.subscription.discussion', KT_DIR . '/plugins/search2/Search2Triggers.php'); | 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 | $this->registerTrigger('add', 'postValidate', 'KTAddDocumentTrigger', 'ktcore.triggers.tagcloud.add', KT_DIR.'/plugins/tagcloud/TagCloudTriggers.php'); | 173 | $this->registerTrigger('add', 'postValidate', 'KTAddDocumentTrigger', 'ktcore.triggers.tagcloud.add', KT_DIR.'/plugins/tagcloud/TagCloudTriggers.php'); |
| 174 | $this->registerTrigger('edit', 'postValidate', 'KTEditDocumentTrigger', 'ktcore.triggers.tagcloud.edit', KT_DIR.'/plugins/tagcloud/TagCloudTriggers.php'); | 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 | // widgets | 179 | // widgets |
| 178 | $this->registerWidget('KTCoreInfoWidget', 'ktcore.widgets.info', 'KTWidgets.php'); | 180 | $this->registerWidget('KTCoreInfoWidget', 'ktcore.widgets.info', 'KTWidgets.php'); |
| 179 | $this->registerWidget('KTCoreHiddenWidget', 'ktcore.widgets.hidden', 'KTWidgets.php'); | 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 | \ No newline at end of file | 17 | \ No newline at end of file |