Commit 208791a19a4a5fbef14dd9aa149e98049e16bad3
Merge branch 'edge' of git@github.com:ktgit/knowledgetree into edge
Showing
17 changed files
with
875 additions
and
206 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,17 @@ class DownloadQueue | @@ -617,6 +647,17 @@ class DownloadQueue | ||
| 617 | $this->errors = null; | 647 | $this->errors = null; |
| 618 | $_SESSION['zipcompression'] = null; | 648 | $_SESSION['zipcompression'] = null; |
| 619 | } | 649 | } |
| 650 | + | ||
| 651 | + if (count($queue) && !PEAR::isError($res) && !PEAR::isError($result)) { | ||
| 652 | + // create the db entry | ||
| 653 | + self::addItem($code, self::getFolderId($code), -1, 'zip'); | ||
| 654 | + // update the db entry with the appropriate status and message | ||
| 655 | + $this->setItemStatus($code, 2, serialize(array($zip->getTmpPath(), $zip->getZipFileName())), true); | ||
| 656 | + // write a file which will be checked if the user has not been logged out and back in | ||
| 657 | + // (in which case the required session value will not be set and this file acts as a trigger instead) | ||
| 658 | + $config = KTConfig::getSingleton(); | ||
| 659 | + @touch($config->get('cache/cacheDirectory') . '/' . self::$notificationFile); | ||
| 660 | + } | ||
| 620 | 661 | ||
| 621 | // Remove lock file | 662 | // Remove lock file |
| 622 | @unlink($this->lockFile); | 663 | @unlink($this->lockFile); |
| @@ -757,7 +798,8 @@ class DownloadQueue | @@ -757,7 +798,8 @@ class DownloadQueue | ||
| 757 | * @param Folder array $aFolderList | 798 | * @param Folder array $aFolderList |
| 758 | * @return unknown | 799 | * @return unknown |
| 759 | */ | 800 | */ |
| 760 | - function getLinkingEntities($aFolderList){ | 801 | + function getLinkingEntities($aFolderList) |
| 802 | + { | ||
| 761 | $aSearchFolders = array(); | 803 | $aSearchFolders = array(); |
| 762 | if(!empty($aFolderList)){ | 804 | if(!empty($aFolderList)){ |
| 763 | foreach($aFolderList as $oFolderItem){ | 805 | foreach($aFolderList as $oFolderItem){ |
| @@ -846,5 +888,142 @@ class DownloadQueue | @@ -846,5 +888,142 @@ class DownloadQueue | ||
| 846 | { | 888 | { |
| 847 | return file_exists($this->lockFile); | 889 | return file_exists($this->lockFile); |
| 848 | } | 890 | } |
| 891 | + | ||
| 892 | + /** | ||
| 893 | + * The code below has all been added for bulk download notifications | ||
| 894 | + * | ||
| 895 | + * The functions were declared as static because they are related to but not entirely part of the download queue process | ||
| 896 | + * and I wanted to use them without having to instantiate the class | ||
| 897 | + */ | ||
| 898 | + | ||
| 899 | + /** | ||
| 900 | + * Checks whether there are any bulk downloads which have passed the timeout limit | ||
| 901 | + * Default limit is set to 48 hours but this can be changed in the calling code | ||
| 902 | + * | ||
| 903 | + * @param int $limit the number of hours after which a download should be considered timed out | ||
| 904 | + */ | ||
| 905 | + static public function timeout($limit = 48) | ||
| 906 | + { | ||
| 907 | + DBUtil::runQuery('DELETE FROM download_queue WHERE DATE_ADD(date_added, INTERVAL ' . $limit . ' HOUR) < NOW()'); | ||
| 908 | + } | ||
| 909 | + | ||
| 910 | + /** | ||
| 911 | + * Checks whether there is a bulk download available and waiting for the supplied user | ||
| 912 | + * | ||
| 913 | + * @param int $userID | ||
| 914 | + */ | ||
| 915 | + static public function userDownloadAvailable($userID) | ||
| 916 | + { | ||
| 917 | + $result = DBUtil::getOneResult('SELECT code, errors FROM download_queue WHERE user_id = ' . $userID | ||
| 918 | + . ' AND object_type = "zip" AND status = 2'); | ||
| 919 | + if (PEAR::isError($result)) { | ||
| 920 | + return false; | ||
| 921 | + } | ||
| 922 | + | ||
| 923 | + $code = $result['code']; | ||
| 924 | + | ||
| 925 | + $message = $result['errors']; | ||
| 926 | + $message = json_decode($message, true); | ||
| 927 | + $data = unserialize($message); | ||
| 928 | + | ||
| 929 | + // Create the archive session variables - I can't recall if this was needed, will have to find out by testing... | ||
| 930 | + $_SESSION['zipcompression'][$code]['file'] = $data[0] . DIRECTORY_SEPARATOR . $data[1]; | ||
| 931 | + $_SESSION['zipcompression'][$code]['dir'] = $data[0]; | ||
| 932 | + | ||
| 933 | + // Check that the archive file has been created | ||
| 934 | + // 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? | ||
| 935 | + // 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, | ||
| 936 | + // some of which may no longer exist as physical files, and since the request only checks for one, it may miss am existing download. | ||
| 937 | + // NOTE the above issue may only occur due to the way I have been testing, often breaking the process before it is finished, | ||
| 938 | + // but conceivably this could actually happen in the real world also. | ||
| 939 | + $zip = new ZipFolder('', $code); | ||
| 940 | + if($zip->checkArchiveExists($code)) { | ||
| 941 | + return $code; | ||
| 942 | + } | ||
| 943 | + | ||
| 944 | + return false; | ||
| 945 | + } | ||
| 946 | + | ||
| 947 | + /** | ||
| 948 | + * Delete the download, including the database entry | ||
| 949 | + * | ||
| 950 | + * @param string $code | ||
| 951 | + */ | ||
| 952 | + static public function deleteDownload($code) | ||
| 953 | + { | ||
| 954 | + // retrieve the data to allow deletion of the physical file | ||
| 955 | + $result = DBUtil::getOneResult('SELECT errors FROM download_queue WHERE code = "' . $code . '"' | ||
| 956 | + . ' AND object_type = "zip" AND status = 2'); | ||
| 957 | + | ||
| 958 | + if (PEAR::isError($result)) { | ||
| 959 | + return $result; | ||
| 960 | + } | ||
| 961 | + | ||
| 962 | + $message = $result['errors']; | ||
| 963 | + $message = json_decode($message, true); | ||
| 964 | + $data = unserialize($message); | ||
| 965 | + | ||
| 966 | + // remove the database entry | ||
| 967 | + DBUtil::whereDelete('download_queue', array('code' => $code)); | ||
| 968 | + | ||
| 969 | + // remove the actual file/directory | ||
| 970 | + KTUtil::deleteDirectory($data[0]); | ||
| 971 | + | ||
| 972 | + // remove the notification file if present | ||
| 973 | + self::removeNotificationFile(); | ||
| 974 | + } | ||
| 975 | + | ||
| 976 | + /** | ||
| 977 | + * Removes the notification file, if it exists, in a safe manner | ||
| 978 | + * | ||
| 979 | + * @param string $code | ||
| 980 | + */ | ||
| 981 | + static public function removeNotificationFile() { | ||
| 982 | + $config = KTConfig::getSingleton(); | ||
| 983 | + $file = DownloadQueue::getNotificationFileName(); | ||
| 984 | + if (!PEAR::isError($file)) { | ||
| 985 | + $notificationFile = $config->get('cache/cacheDirectory') . '/' . $file; | ||
| 986 | + } | ||
| 987 | + | ||
| 988 | + // ensure the file is actually a file and not a directory | ||
| 989 | + if (is_file($notificationFile)) { | ||
| 990 | + @unlink($notificationFile); | ||
| 991 | + } | ||
| 992 | + } | ||
| 993 | + | ||
| 994 | + /** | ||
| 995 | + * Fetches a link to the download | ||
| 996 | + * | ||
| 997 | + * @param string $code | ||
| 998 | + */ | ||
| 999 | + static public function getDownloadLink($code) | ||
| 1000 | + { | ||
| 1001 | + return KTUtil::kt_url() . '/action.php?kt_path_info=ktcore.actions.bulk.export&action=downloadZipFile&fFolderId=' . self::getFolderId($code) . '&exportcode=' . $code; | ||
| 1002 | + } | ||
| 1003 | + | ||
| 1004 | + /** | ||
| 1005 | + * Fetches the folder id associated with the supplied code | ||
| 1006 | + * Based on testing just before file corruption this may not actually be necessary, but we'll do it anyway | ||
| 1007 | + * | ||
| 1008 | + * @param string $code | ||
| 1009 | + */ | ||
| 1010 | + static public function getFolderId($code) | ||
| 1011 | + { | ||
| 1012 | + $result = DBUtil::getOneResult('SELECT folder_id FROM download_queue WHERE code = "' . $code . '"'); | ||
| 1013 | + | ||
| 1014 | + if (PEAR::isError($result)) { | ||
| 1015 | + return -1; | ||
| 1016 | + } | ||
| 1017 | + | ||
| 1018 | + return $result['folder_id']; | ||
| 1019 | + } | ||
| 1020 | + | ||
| 1021 | + static public function getNotificationFileName() { | ||
| 1022 | + if (!empty(self::$notificationFile)) { | ||
| 1023 | + return self::$notificationFile; | ||
| 1024 | + } | ||
| 1025 | + | ||
| 1026 | + return new PEAR_Error('Unable to get file name'); | ||
| 1027 | + } | ||
| 849 | } | 1028 | } |
| 850 | ?> | 1029 | ?> |
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'); |
| @@ -198,6 +200,7 @@ class KTCorePlugin extends KTPlugin { | @@ -198,6 +200,7 @@ class KTCorePlugin extends KTPlugin { | ||
| 198 | $this->registerWidget('KTCoreLayerWidget', 'ktcore.widgets.layer', 'KTWidgets.php'); | 200 | $this->registerWidget('KTCoreLayerWidget', 'ktcore.widgets.layer', 'KTWidgets.php'); |
| 199 | $this->registerWidget('KTCoreConditionalSelectionWidget', 'ktcore.widgets.conditionalselection', 'KTWidgets.php'); | 201 | $this->registerWidget('KTCoreConditionalSelectionWidget', 'ktcore.widgets.conditionalselection', 'KTWidgets.php'); |
| 200 | $this->registerWidget('KTCoreImageWidget', 'ktcore.widgets.image', 'KTWidgets.php'); | 202 | $this->registerWidget('KTCoreImageWidget', 'ktcore.widgets.image', 'KTWidgets.php'); |
| 203 | + $this->registerWidget('KTCoreImageSelectWidget', 'ktcore.widgets.imageselect', 'KTWidgets.php'); | ||
| 201 | $this->registerWidget('KTCoreImageCropWidget', 'ktcore.widgets.imagecrop', 'KTWidgets.php'); | 204 | $this->registerWidget('KTCoreImageCropWidget', 'ktcore.widgets.imagecrop', 'KTWidgets.php'); |
| 202 | 205 | ||
| 203 | $this->registerPage('collection', 'KTCoreCollectionPage', 'KTWidgets.php'); | 206 | $this->registerPage('collection', 'KTCoreCollectionPage', '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 | +?> |
plugins/ktcore/KTWidgets.php
| @@ -1140,6 +1140,56 @@ class KTCoreImageWidget extends KTWidget { | @@ -1140,6 +1140,56 @@ class KTCoreImageWidget extends KTWidget { | ||
| 1140 | return $oTemplate->render($aTemplateData); | 1140 | return $oTemplate->render($aTemplateData); |
| 1141 | } | 1141 | } |
| 1142 | 1142 | ||
| 1143 | +} | ||
| 1144 | + | ||
| 1145 | +class KTCoreImageSelectWidget extends KTWidget { | ||
| 1146 | + var $sNamespace = 'ktcore.widgets.imageselect'; | ||
| 1147 | + var $sTemplate = 'ktcore/forms/widgets/imageselect'; | ||
| 1148 | + | ||
| 1149 | + function configure($aOptions) { | ||
| 1150 | + $res = parent::configure($aOptions); | ||
| 1151 | + if (PEAR::isError($res)) { | ||
| 1152 | + return $res; | ||
| 1153 | + } | ||
| 1154 | + | ||
| 1155 | + } | ||
| 1156 | + | ||
| 1157 | + function render() { | ||
| 1158 | + $oTemplating =& KTTemplating::getSingleton(); | ||
| 1159 | + $oTemplate = $oTemplating->loadTemplate('ktcore/forms/widgets/base'); | ||
| 1160 | + | ||
| 1161 | + $this->aJavascript[] = 'thirdpartyjs/jquery/jquery-1.3.2.js'; | ||
| 1162 | + | ||
| 1163 | + if (!empty($this->aJavascript)) { | ||
| 1164 | + // grab our inner page. | ||
| 1165 | + $oPage =& $GLOBALS['main']; | ||
| 1166 | + $oPage->requireJSResources($this->aJavascript); | ||
| 1167 | + } | ||
| 1168 | + | ||
| 1169 | + $this->aCSS[] = 'resources/css/kt_imageselect.css'; | ||
| 1170 | + | ||
| 1171 | + if (!empty($this->aCSS)) { | ||
| 1172 | + // grab our inner page. | ||
| 1173 | + $oPage =& $GLOBALS['main']; | ||
| 1174 | + $oPage->requireCSSResources($this->aCSS); | ||
| 1175 | + } | ||
| 1176 | + | ||
| 1177 | + $widget_content = $this->getWidget(); | ||
| 1178 | + | ||
| 1179 | + $aTemplateData = array( | ||
| 1180 | + "context" => $this, | ||
| 1181 | + "label" => $this->sLabel, | ||
| 1182 | + "description" => $this->sDescription, | ||
| 1183 | + "name" => $this->sName, | ||
| 1184 | + "has_value" => ($this->value !== null), | ||
| 1185 | + "value" => $this->value, | ||
| 1186 | + "has_errors" => $bHasErrors, | ||
| 1187 | + "errors" => $this->aErrors, | ||
| 1188 | + "options" => $this->aOptions, | ||
| 1189 | + "widget" => $widget_content, | ||
| 1190 | + ); | ||
| 1191 | + return $oTemplate->render($aTemplateData); | ||
| 1192 | + } | ||
| 1143 | 1193 | ||
| 1144 | } | 1194 | } |
| 1145 | 1195 |
plugins/ktcore/admin/manageBranding.php
| @@ -84,7 +84,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -84,7 +84,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 84 | 'encoding' => 'multipart/form-data', | 84 | 'encoding' => 'multipart/form-data', |
| 85 | 'context' => &$this, | 85 | 'context' => &$this, |
| 86 | 'extraargs' => $this->meldPersistQuery("","",true), | 86 | 'extraargs' => $this->meldPersistQuery("","",true), |
| 87 | - 'description' => _kt('The logo upload facility allows you to upload a logo to brand your knowledgetree site.') | 87 | + 'description' => _kt('You can upload a logo to brand your KnowledgeTree site.') |
| 88 | )); | 88 | )); |
| 89 | 89 | ||
| 90 | $oWF =& KTWidgetFactory::getSingleton(); | 90 | $oWF =& KTWidgetFactory::getSingleton(); |
| @@ -99,7 +99,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -99,7 +99,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 99 | 'name' => 'file', | 99 | 'name' => 'file', |
| 100 | 'id' => 'file', | 100 | 'id' => 'file', |
| 101 | 'value' => '', | 101 | 'value' => '', |
| 102 | - 'description' => _kt('The logo should be 313px by 50px in dimension. If you don\'t have a 313x50 logo you should choose to either "crop" or "scale" it. If you are certain that your logo has the correct dimentions you can safely skip by the selecting "Don\'t do anything"'), | 102 | + 'description' => _kt("The logo's dimensions should be 313px width by 50px height. If your logo doesn't fit these dimensions, you can choose to crop or scale it."), |
| 103 | )); | 103 | )); |
| 104 | 104 | ||
| 105 | $aVocab['crop'] = 'Crop - Cut out a selection'; | 105 | $aVocab['crop'] = 'Crop - Cut out a selection'; |
| @@ -142,6 +142,61 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -142,6 +142,61 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 142 | 142 | ||
| 143 | 143 | ||
| 144 | /** | 144 | /** |
| 145 | + * Returns the scale logo form | ||
| 146 | + * | ||
| 147 | + * This form will display a preview of all the possible sclaled combinations. | ||
| 148 | + * This includes: | ||
| 149 | + * | ||
| 150 | + * Stretched, Top Left Cropped, Proportional Stretch, Proportional Top Left Cropped | ||
| 151 | + * | ||
| 152 | + * @return KTForm | ||
| 153 | + * | ||
| 154 | + */ | ||
| 155 | + | ||
| 156 | + function getScaleLogoForm($logoItems = array()) { | ||
| 157 | + $this->oPage->setBreadcrumbDetails(_kt("Scale Logo")); | ||
| 158 | + | ||
| 159 | + $oForm = new KTForm; | ||
| 160 | + $oForm->setOptions(array( | ||
| 161 | + 'identifier' => 'ktcore.folder.branding', | ||
| 162 | + 'label' => _kt('Choose Logo'), | ||
| 163 | + 'submit_label' => _kt('Select'), | ||
| 164 | + 'action' => 'selectLogo', | ||
| 165 | + 'fail_action' => 'main', | ||
| 166 | + 'encoding' => 'multipart/form-data', | ||
| 167 | + 'context' => &$this, | ||
| 168 | + 'extraargs' => $this->meldPersistQuery("","",true), | ||
| 169 | + 'description' => _kt('Choose a logo by clicking on one of the images') | ||
| 170 | + )); | ||
| 171 | + | ||
| 172 | + $oWF =& KTWidgetFactory::getSingleton(); | ||
| 173 | + | ||
| 174 | + $widgets = array(); | ||
| 175 | + $validators = array(); | ||
| 176 | + | ||
| 177 | + $logoFileName = 'var'.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR.$logoFileName; | ||
| 178 | + | ||
| 179 | + // Adding the image select widget (User will select the best image) | ||
| 180 | + $widgets[] = $oWF->get('ktcore.widgets.imageselect', array( | ||
| 181 | + 'label' => _kt('Logo Preview'), | ||
| 182 | + 'name' => $logoFileName, | ||
| 183 | + 'value' => $logoItems, | ||
| 184 | + )); | ||
| 185 | + | ||
| 186 | + // Adding the Hidden FileName Input String | ||
| 187 | + $widgets[] = $oWF->get('ktcore.widgets.hidden', array( | ||
| 188 | + 'name' => 'kt_imageselect', | ||
| 189 | + 'value' => $logoItems[0], | ||
| 190 | + )); | ||
| 191 | + | ||
| 192 | + $oForm->setWidgets($widgets); | ||
| 193 | + $oForm->setValidators($validators); | ||
| 194 | + | ||
| 195 | + return $oForm; | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + | ||
| 199 | + /** | ||
| 145 | * Returns the crop logo form | 200 | * Returns the crop logo form |
| 146 | * | 201 | * |
| 147 | * This form will assist the user in selecting an area of the image to use as the logo | 202 | * This form will assist the user in selecting an area of the image to use as the logo |
| @@ -311,7 +366,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -311,7 +366,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 311 | 366 | ||
| 312 | //Changing to logo.jpg (Need to preserve extention as GD requires the exact image type to work) | 367 | //Changing to logo.jpg (Need to preserve extention as GD requires the exact image type to work) |
| 313 | $ext = end(explode('.', $logoFileName)); | 368 | $ext = end(explode('.', $logoFileName)); |
| 314 | - $logoFileName = 'logo_tmp.'.$ext; | 369 | + $logoFileName = 'logo_tmp_'.md5(Date('ymd-hms')).'.'.$ext; //Fighting the browser cache here |
| 315 | $logoFile = $logoDir.DIRECTORY_SEPARATOR.$logoFileName; | 370 | $logoFile = $logoDir.DIRECTORY_SEPARATOR.$logoFileName; |
| 316 | 371 | ||
| 317 | // deleting old tmp file | 372 | // deleting old tmp file |
| @@ -329,6 +384,8 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -329,6 +384,8 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 329 | 384 | ||
| 330 | $resizeMethod = $_REQUEST['data']['resize_method']; | 385 | $resizeMethod = $_REQUEST['data']['resize_method']; |
| 331 | 386 | ||
| 387 | + $relDir = 'var'.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR; | ||
| 388 | + | ||
| 332 | switch ($resizeMethod) { | 389 | switch ($resizeMethod) { |
| 333 | case 'crop': | 390 | case 'crop': |
| 334 | $cropLogoForm = $this->getCropLogoForm($logoFileName); | 391 | $cropLogoForm = $this->getCropLogoForm($logoFileName); |
| @@ -336,9 +393,24 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -336,9 +393,24 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 336 | 393 | ||
| 337 | case 'scale': | 394 | case 'scale': |
| 338 | $type = $_FILES['_kt_attempt_unique_file']['type']; | 395 | $type = $_FILES['_kt_attempt_unique_file']['type']; |
| 339 | - $res = $this->scaleImage($logoFile, $logoFile, $this->maxLogoWidth, $this->maxLogoHeight, $type); | ||
| 340 | 396 | ||
| 341 | - $form = $this->getApplyLogoForm($logoFileName); | 397 | + $logoFileNameStretched = 'logo_tmp_stretched_'.md5(Date('ymd-hms')).'.'.$ext; //Fighting the browser cache here |
| 398 | + $logoFileStretched = $logoDir.DIRECTORY_SEPARATOR.$logoFileNameStretched; | ||
| 399 | + | ||
| 400 | + $logoFileNameCropped = 'logo_tmp_cropped_'.md5(Date('ymd-hms')).'.'.$ext; //Fighting the browser cache here | ||
| 401 | + $logoFileCropped = $logoDir.DIRECTORY_SEPARATOR.$logoFileNameCropped; | ||
| 402 | + | ||
| 403 | + //Creating stretched image | ||
| 404 | + $res = $this->scaleImage($logoFile, $logoFileStretched, $this->maxLogoWidth, $this->maxLogoHeight, $type, false, false); | ||
| 405 | + | ||
| 406 | + //Creating top-left cropped image | ||
| 407 | + $res = $this->scaleImage($logoFile, $logoFileCropped, $this->maxLogoWidth, $this->maxLogoHeight, $type, false, true); | ||
| 408 | + $res = $this->cropImage($logoFileCropped, $logoFileCropped, 0, 0, $this->maxLogoWidth, $this->maxLogoHeight, $type); | ||
| 409 | + | ||
| 410 | + $logoItem[] = $relDir.$logoFileNameStretched; | ||
| 411 | + $logoItem[] = $relDir.$logoFileNameCropped; | ||
| 412 | + | ||
| 413 | + $form = $this->getScaleLogoForm($logoItem); | ||
| 342 | return $form->render(); | 414 | return $form->render(); |
| 343 | 415 | ||
| 344 | default: | 416 | default: |
| @@ -354,7 +426,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -354,7 +426,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 354 | * - Supported images are jpeg, png and gif | 426 | * - Supported images are jpeg, png and gif |
| 355 | * | 427 | * |
| 356 | */ | 428 | */ |
| 357 | - public function scaleImage( $origFile, $destFile, $width, $height, $type = 'image/jpeg', $scaleUp = true) { | 429 | + public function scaleImage( $origFile, $destFile, $width, $height, $type = 'image/jpeg', $scaleUp = false, $keepProportion = true) { |
| 358 | global $default; | 430 | global $default; |
| 359 | 431 | ||
| 360 | //Requires the GD library if not exit gracefully | 432 | //Requires the GD library if not exit gracefully |
| @@ -399,7 +471,11 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -399,7 +471,11 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 399 | 471 | ||
| 400 | $image_x = $width; | 472 | $image_x = $width; |
| 401 | $image_y = $height; | 473 | $image_y = $height; |
| 402 | - //$image_y = round(($orig_y * $image_x) / $orig_x); //Preserve proportion | 474 | + |
| 475 | + //Constraining proportion | ||
| 476 | + if ($keepProportion) { | ||
| 477 | + $image_y = round(($orig_y * $image_x) / $orig_x); //Preserve proportion | ||
| 478 | + } | ||
| 403 | 479 | ||
| 404 | /* | 480 | /* |
| 405 | * create the new image, and scale the original into it. | 481 | * create the new image, and scale the original into it. |
| @@ -426,7 +502,6 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -426,7 +502,6 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 426 | return false; | 502 | return false; |
| 427 | } | 503 | } |
| 428 | 504 | ||
| 429 | - | ||
| 430 | } else { | 505 | } else { |
| 431 | //Handle Error | 506 | //Handle Error |
| 432 | $default->log->error("Couldn't obtain a valid GD resource"); | 507 | $default->log->error("Couldn't obtain a valid GD resource"); |
| @@ -446,9 +521,13 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -446,9 +521,13 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 446 | function do_crop(){ | 521 | function do_crop(){ |
| 447 | global $default; | 522 | global $default; |
| 448 | 523 | ||
| 449 | - $logoFileName = $_REQUEST['data']['logo_file_name']; | 524 | + $logoFileName = $_REQUEST['data']['logo_file_name']; |
| 450 | $logoFile = 'var'.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR.$logoFileName; | 525 | $logoFile = 'var'.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR.$logoFileName; |
| 451 | - | 526 | + |
| 527 | + $ext = end(explode('.', $logoFileName)); | ||
| 528 | + $destFileName = 'logo_tmp_'.md5(Date('ymd-hms')).'.'.$ext; | ||
| 529 | + $destFile = 'var'.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR.$destFileName; | ||
| 530 | + | ||
| 452 | $x1 = $_REQUEST['data']['crop_x1']; | 531 | $x1 = $_REQUEST['data']['crop_x1']; |
| 453 | $y1 = $_REQUEST['data']['crop_y1']; | 532 | $y1 = $_REQUEST['data']['crop_y1']; |
| 454 | 533 | ||
| @@ -458,7 +537,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -458,7 +537,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 458 | $type = $this->getMime($logoFileName); | 537 | $type = $this->getMime($logoFileName); |
| 459 | 538 | ||
| 460 | //GD Crop | 539 | //GD Crop |
| 461 | - $res = $this->cropImage($logoFile, $logoFile, $x1, $y1, $x2, $y2, $type); | 540 | + $res = $this->cropImage($logoFile, $destFile, $x1, $y1, $x2, $y2, $type); |
| 462 | 541 | ||
| 463 | //If dimensions don't conform then will scale it further | 542 | //If dimensions don't conform then will scale it further |
| 464 | $width = $x2 - $x1; | 543 | $width = $x2 - $x1; |
| @@ -466,7 +545,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -466,7 +545,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 466 | 545 | ||
| 467 | if (($width > $this->maxLogoWidth) || ($height > $this->maxLogoHeight)) { | 546 | if (($width > $this->maxLogoWidth) || ($height > $this->maxLogoHeight)) { |
| 468 | $default->log->info('SCALING IMAGE AFTER CROP'); | 547 | $default->log->info('SCALING IMAGE AFTER CROP'); |
| 469 | - $res = $this->scaleImage($logoFile, $logoFile, $this->maxLogoWidth, $this->maxLogoHeight, $type); | 548 | + $res = $this->scaleImage($destFile, $destFile, $this->maxLogoWidth, $this->maxLogoHeight, $type, false, false); |
| 470 | } | 549 | } |
| 471 | 550 | ||
| 472 | // ImageMagick Crop | 551 | // ImageMagick Crop |
| @@ -485,7 +564,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -485,7 +564,7 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 485 | $result = KTUtil::pexec($cmd); | 564 | $result = KTUtil::pexec($cmd); |
| 486 | */ | 565 | */ |
| 487 | 566 | ||
| 488 | - $applyLogoForm = $this->getApplyLogoForm($logoFileName); | 567 | + $applyLogoForm = $this->getApplyLogoForm($destFileName); |
| 489 | return $applyLogoForm->render(); | 568 | return $applyLogoForm->render(); |
| 490 | 569 | ||
| 491 | } | 570 | } |
| @@ -600,6 +679,21 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -600,6 +679,21 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 600 | } | 679 | } |
| 601 | 680 | ||
| 602 | 681 | ||
| 682 | + /* | ||
| 683 | + * Action responsible for selecting the logo after it has been scaled. | ||
| 684 | + * | ||
| 685 | + */ | ||
| 686 | + function do_selectLogo(){ | ||
| 687 | + global $default; | ||
| 688 | + | ||
| 689 | + $tmpLogoFileName = end(explode(DIRECTORY_SEPARATOR, $_REQUEST['kt_imageselect'])); | ||
| 690 | + | ||
| 691 | + $form = $this->getApplyLogoForm($tmpLogoFileName); | ||
| 692 | + return $form->render(); | ||
| 693 | + | ||
| 694 | + } | ||
| 695 | + | ||
| 696 | + | ||
| 603 | 697 | ||
| 604 | /* | 698 | /* |
| 605 | * Action responsible for applying the logo | 699 | * Action responsible for applying the logo |
| @@ -628,10 +722,12 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -628,10 +722,12 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 628 | $brandDir = $default->varDirectory.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR; | 722 | $brandDir = $default->varDirectory.DIRECTORY_SEPARATOR.'branding'.DIRECTORY_SEPARATOR.'logo'.DIRECTORY_SEPARATOR; |
| 629 | $handle = opendir($brandDir); | 723 | $handle = opendir($brandDir); |
| 630 | while (false !== ($file = readdir($handle))) { | 724 | while (false !== ($file = readdir($handle))) { |
| 631 | - if (!is_dir($file) && $file != 'logo_tmp.jpg' && $file != $logoFileName) { | 725 | + if (!is_dir($file) && $file != $tmpLogoFileName && $file != $logoFileName) { |
| 632 | if (!@unlink($brandDir.$file)) { | 726 | if (!@unlink($brandDir.$file)) { |
| 633 | $default->log->error("Couldn't delete '".$brandDir.$file."'"); | 727 | $default->log->error("Couldn't delete '".$brandDir.$file."'"); |
| 634 | - } | 728 | + } else { |
| 729 | + $default->log->error("Cleaning Brand Logo Dir: Deleted '".$brandDir.$file."'"); | ||
| 730 | + } | ||
| 635 | } | 731 | } |
| 636 | } | 732 | } |
| 637 | } | 733 | } |
| @@ -665,128 +761,6 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | @@ -665,128 +761,6 @@ class ManageBrandDispatcher extends KTAdminDispatcher { | ||
| 665 | $this->successRedirectTo('', _kt("Logo succesfully applied.")); | 761 | $this->successRedirectTo('', _kt("Logo succesfully applied.")); |
| 666 | } | 762 | } |
| 667 | 763 | ||
| 668 | - | ||
| 669 | - /* | ||
| 670 | - | ||
| 671 | - Old Manage Views Code! | ||
| 672 | - Crap, must delete | ||
| 673 | - | ||
| 674 | - */ | ||
| 675 | - function do_editView() { | ||
| 676 | - $oTemplating =& KTTemplating::getSingleton(); | ||
| 677 | - $oTemplate = $oTemplating->loadTemplate('ktcore/misc/columns/edit_view'); | ||
| 678 | - | ||
| 679 | - $oColumnRegistry =& KTColumnRegistry::getSingleton(); | ||
| 680 | - $aColumns = $oColumnRegistry->getColumnsForView($_REQUEST['viewNS']); | ||
| 681 | - //var_dump($aColumns); exit(0); | ||
| 682 | - $aAllColumns = $oColumnRegistry->getColumns(); | ||
| 683 | - | ||
| 684 | - $view_name = $oColumnRegistry->getViewName(($_REQUEST['viewNS'])); | ||
| 685 | - $this->oPage->setTitle($view_name); | ||
| 686 | - $this->oPage->setBreadcrumbDetails($view_name); | ||
| 687 | - | ||
| 688 | - $aOptions = array(); | ||
| 689 | - $vocab = array(); | ||
| 690 | - foreach ($aAllColumns as $aInfo) { | ||
| 691 | - $vocab[$aInfo['namespace']] = $aInfo['name']; | ||
| 692 | - } | ||
| 693 | - $aOptions['vocab'] = $vocab; | ||
| 694 | - $add_field = new KTLookupWidget(_kt("Columns"), _kt("Select a column to add to the view. Please note that while you can add multiple copies of a column, they will all behave as a single column"), 'column_ns', null, $this->oPage, true, null, $aErrors = null, $aOptions); | ||
| 695 | - | ||
| 696 | - $aTemplateData = array( | ||
| 697 | - 'context' => $this, | ||
| 698 | - 'current_columns' => $aColumns, | ||
| 699 | - 'all_columns' => $aAllColumns, | ||
| 700 | - 'view' => $_REQUEST['viewNS'], | ||
| 701 | - 'add_field' => $add_field, | ||
| 702 | - ); | ||
| 703 | - return $oTemplate->render($aTemplateData); | ||
| 704 | - } | ||
| 705 | - | ||
| 706 | - function do_deleteEntry() { | ||
| 707 | - $entry_id = KTUtil::arrayGet($_REQUEST, 'entry_id'); | ||
| 708 | - $view = KTUtil::arrayGet($_REQUEST, 'viewNS'); | ||
| 709 | - | ||
| 710 | - // none of these conditions can be reached "normally". | ||
| 711 | - | ||
| 712 | - $oEntry = KTColumnEntry::get($entry_id); | ||
| 713 | - if (PEAR::isError($oEntry)) { | ||
| 714 | - $this->errorRedirectToMain(_kt("Unable to locate the entry")); | ||
| 715 | - } | ||
| 716 | - | ||
| 717 | - if ($oEntry->getRequired()) { | ||
| 718 | - $this->errorRedirectToMain(_kt("That column is required")); | ||
| 719 | - } | ||
| 720 | - | ||
| 721 | - if ($oEntry->getViewNamespace() != $view) { | ||
| 722 | - $this->errorRedirectToMain(_kt("That column is not for the specified view")); | ||
| 723 | - } | ||
| 724 | - | ||
| 725 | - $res = $oEntry->delete(); | ||
| 726 | - | ||
| 727 | - if (PEAR::isError($res)) { | ||
| 728 | - $this->errorRedirectToMain(sprintf(_kt("Failed to remove that column: %s"), $res->getMessage())); | ||
| 729 | - } | ||
| 730 | - | ||
| 731 | - $this->successRedirectTo("editView", _kt("Deleted Entry"), sprintf("viewNS=%s", $view)); | ||
| 732 | - } | ||
| 733 | - | ||
| 734 | - function do_addEntry() { | ||
| 735 | - $column_ns = KTUtil::arrayGet($_REQUEST, 'column_ns'); | ||
| 736 | - $view = KTUtil::arrayGet($_REQUEST, 'viewNS'); | ||
| 737 | - | ||
| 738 | - $this->startTransaction(); | ||
| 739 | - | ||
| 740 | - $position = KTColumnEntry::getNextEntryPosition($view); | ||
| 741 | - $oEntry = KTColumnEntry::createFromArray(array( | ||
| 742 | - 'ColumnNamespace' => $column_ns, | ||
| 743 | - 'ViewNamespace' => $view, | ||
| 744 | - 'Position' => $position, // start it at the bottom | ||
| 745 | - 'config' => array(), // stub, for now. | ||
| 746 | - 'Required' => 0 | ||
| 747 | - )); | ||
| 748 | - | ||
| 749 | - $this->successRedirectTo("editView", _kt("Added Entry"), sprintf("viewNS=%s", $view)); | ||
| 750 | - } | ||
| 751 | - | ||
| 752 | - function do_orderUp(){ | ||
| 753 | - $entryId = $_REQUEST['entry_id']; | ||
| 754 | - $view = $_REQUEST['viewNS']; | ||
| 755 | - | ||
| 756 | - $oEntry = KTColumnEntry::get($entryId); | ||
| 757 | - if (PEAR::isError($oEntry)) { | ||
| 758 | - $this->errorRedirectTo('editView', _kt('Unable to locate the column entry'), "viewNS={$view}"); | ||
| 759 | - exit(); | ||
| 760 | - } | ||
| 761 | - | ||
| 762 | - $res = $oEntry->movePosition($view, $entryId, 'up'); | ||
| 763 | - if (PEAR::isError($res)) { | ||
| 764 | - $this->errorRedirectTo('editView', $res->getMessage(), "viewNS={$view}"); | ||
| 765 | - exit(); | ||
| 766 | - } | ||
| 767 | - | ||
| 768 | - $this->redirectTo('editView', "viewNS={$view}"); | ||
| 769 | - } | ||
| 770 | - | ||
| 771 | - function do_orderDown(){ | ||
| 772 | - $entryId = $_REQUEST['entry_id']; | ||
| 773 | - $view = $_REQUEST['viewNS']; | ||
| 774 | - | ||
| 775 | - $oEntry = KTColumnEntry::get($entryId); | ||
| 776 | - if (PEAR::isError($oEntry)) { | ||
| 777 | - $this->errorRedirectTo('editView', _kt('Unable to locate the column entry'), "viewNS={$view}"); | ||
| 778 | - exit(); | ||
| 779 | - } | ||
| 780 | - | ||
| 781 | - $res = $oEntry->movePosition($view, $entryId, 'down'); | ||
| 782 | - if (PEAR::isError($res)) { | ||
| 783 | - $this->errorRedirectTo('editView', $res->getMessage(), "viewNS={$view}"); | ||
| 784 | - exit(); | ||
| 785 | - } | ||
| 786 | - | ||
| 787 | - $this->redirectTo("editView", "viewNS={$view}"); | ||
| 788 | - } | ||
| 789 | - | ||
| 790 | } | 764 | } |
| 791 | 765 | ||
| 792 | ?> | 766 | ?> |
resources/css/kt_imageselect.css
0 → 100644
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 | +} |
sql/mysql/install/structure.sql
| @@ -648,7 +648,7 @@ CREATE TABLE `download_queue` ( | @@ -648,7 +648,7 @@ CREATE TABLE `download_queue` ( | ||
| 648 | `code` char(16) NOT NULL, | 648 | `code` char(16) NOT NULL, |
| 649 | `folder_id` int(11) NOT NULL, | 649 | `folder_id` int(11) NOT NULL, |
| 650 | `object_id` int(11) NOT NULL, | 650 | `object_id` int(11) NOT NULL, |
| 651 | - `object_type` enum('document', 'folder') NOT NULL default 'folder', | 651 | + `object_type` enum('document', 'folder', 'zip') NOT NULL default 'folder', |
| 652 | `user_id` int(11) NOT NULL, | 652 | `user_id` int(11) NOT NULL, |
| 653 | `date_added` timestamp NOT NULL default CURRENT_TIMESTAMP, | 653 | `date_added` timestamp NOT NULL default CURRENT_TIMESTAMP, |
| 654 | `status` tinyint(4) NOT NULL default 0, | 654 | `status` tinyint(4) NOT NULL default 0, |
sql/mysql/upgrade/3.7.0.3/download_queue_zip.sql
0 → 100644
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 |
templates/kt3/standard_page.smarty
templates/ktcore/forms/widgets/imageselect.smarty
0 → 100755
| 1 | +<fieldset {if $has_name}title="{$name}"{/if}> | ||
| 2 | + <field> | ||
| 3 | + <div id="kt_image_select_container"> | ||
| 4 | + | ||
| 5 | + {foreach key=id item=src from=$value} | ||
| 6 | + | ||
| 7 | + <img class="kt_image_select" id="kt_image_select_{$id}" src="{$src}" border="0"/> | ||
| 8 | + | ||
| 9 | + <script type="text/javascript"> | ||
| 10 | + var toggle_{$id} = 1; | ||
| 11 | + var selected = ''; | ||
| 12 | + | ||
| 13 | + var multiselect = false; | ||
| 14 | + | ||
| 15 | + var hover = '#f9f9f9'; | ||
| 16 | + var click = '#f2943a'; //Orange | ||
| 17 | + var background_color = 'white'; //also set in css | ||
| 18 | + | ||
| 19 | + jQuery('#kt_image_select_{$id}').click(function(){ldelim} | ||
| 20 | + jQuery('#kt_image_select').val('{$src}'); | ||
| 21 | + | ||
| 22 | + //Resetting background: | ||
| 23 | + jQuery("img[id*='kt_image_select_']").css('border', '10px solid ' + background_color); | ||
| 24 | + jQuery('#kt_image_select_{$id}').css('border', '10px solid ' + click); | ||
| 25 | + | ||
| 26 | + {rdelim}) | ||
| 27 | + </script> | ||
| 28 | + | ||
| 29 | + {/foreach} | ||
| 30 | + | ||
| 31 | + </div> | ||
| 32 | + | ||
| 33 | + <input type="hidden" name="kt_imageselect" value="" id="kt_image_select"/> | ||
| 34 | + </field> | ||
| 35 | +</fieldset> |