diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index 5ca0d5e81173edbff5c616393b7029267be7a2aa..40da32b223a4cf37259476dafc714f3617db80ef 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -3,10 +3,6 @@ // only need filesystem apps $RUNTIME_APPTYPES=array('filesystem'); -// Init owncloud - -require_once 'lib/template.php'; - OCP\JSON::checkLoggedIn(); // Load the files @@ -26,7 +22,7 @@ $files = array(); if($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) { foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, 'httpd/unix-directory' ) as $file ) { $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($file['mimetype']); + $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); $file["date"] = OCP\Util::formatDate($file["mtime"]); $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); $files[] = $file; @@ -37,7 +33,7 @@ if (is_array($mimetypes) && count($mimetypes)) { foreach ($mimetypes as $mimetype) { foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $file ) { $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($file['mimetype']); + $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); $file["date"] = OCP\Util::formatDate($file["mtime"]); $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); $files[] = $file; @@ -46,7 +42,7 @@ if (is_array($mimetypes) && count($mimetypes)) { } else { foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $file ) { $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($file['mimetype']); + $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); $file["date"] = OCP\Util::formatDate($file["mtime"]); $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); $files[] = $file; diff --git a/apps/files/css/files.css b/apps/files/css/files.css index b3ecd1dab93e4cb62cb167881960c7b6aba9f49b..138b15db04fff6c8fb950738e1a62209155b38cb 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -7,68 +7,54 @@ .actions input, .actions button, .actions .button { margin:0; float:left; } .actions .button a { color: #555; } .actions .button a:hover, .actions .button a:active { color: #333; } -#new { - height:17px; margin:0 0 0 1em; z-index:1010; float:left; +#new, #trash { + z-index: 1010; + float: left; + padding: 0 !important; /* override default control bar button padding */ +} +#trash { + margin: 0 1em; + float: right; +} +#new>a, #trash>a { + padding: 14px 10px; + position: relative; + top: 7px; +} +#new.active { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: none; } -#new.active { border-bottom-left-radius:0; border-bottom-right-radius:0; border-bottom:none; } -#new>a { padding:.5em 1.2em .3em; } #new>ul { - display:none; position:fixed; min-width:7em; z-index:10; - padding:.5em; padding-bottom:0; margin-top:.075em; margin-left:-.5em; + display: none; + position: fixed; + min-width: 7em; + z-index: 10; + padding: .5em; + padding-bottom: 0; + margin-top: 14px; + margin-left: -1px; text-align:left; - background:#f8f8f8; border:1px solid #ddd; border-radius:10px; border-top-left-radius:0; + background: #f8f8f8; + border: 1px solid #ddd; + border-radius: 5px; + border-top-left-radius: 0; box-shadow:0 2px 7px rgba(170,170,170,.4); } #new>ul>li { height:36px; margin:.3em; padding-left:3em; padding-bottom:0.1em; background-repeat:no-repeat; cursor:pointer; } #new>ul>li>p { cursor:pointer; padding-top: 7px; padding-bottom: 7px;} -#new>ul>li>form>input { - padding: 5px; - margin: 2px 0; -} -#trash { margin: 0 1em; z-index:1010; float: right; } - -#upload { - height:27px; padding:0; margin-left:0.2em; overflow:hidden; -} -#upload a { - position:relative; display:block; width:100%; height:27px; - cursor:pointer; z-index:10; - background-image:url('%webroot%/core/img/actions/upload.svg'); - background-repeat:no-repeat; - background-position:7px 6px; - opacity:0.65; -} -.file_upload_target { display:none; } -.file_upload_form { display:inline; float:left; margin:0; padding:0; cursor:pointer; overflow:visible; } -#file_upload_start { - left:0; top:0; width:28px; height:27px; padding:0; - font-size:1em; - -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; - z-index:20; position:relative; cursor:pointer; overflow:hidden; -} - -#uploadprogresswrapper { - position: relative; - display: inline; -} -#uploadprogressbar { - position:relative; - float: left; - margin-left: 12px; - width: 130px; - height: 26px; - display:inline-block; -} -#uploadprogressbar + stop { - font-size: 13px; -} /* FILE TABLE */ -#filestable { position: relative; top:37px; width:100%; } +#filestable { + position: relative; + top: 44px; + width: 100%; +} #filestable tbody tr { background-color:#fff; height:2.5em; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); @@ -122,9 +108,18 @@ table th#headerDate, table td.date { /* Multiselect bar */ #filestable.multiselect { - top: 88px; + top: 95px; +} +table.multiselect thead { + position: fixed; + top: 89px; + z-index: 1; + -moz-box-sizing: border-box; + box-sizing: border-box; + left: 0; + padding-left: 80px; + width: 100%; } -table.multiselect thead { position:fixed; top:82px; z-index:1; -moz-box-sizing: border-box; box-sizing: border-box; left: 0; padding-left: 80px; width:100%; } table.multiselect thead th { background-color: rgba(210,210,210,.7); @@ -228,6 +223,12 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; } -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; } +#fileList tr td.filename a.name label { + position: absolute; + width: 100%; + height: 50px; +} + #uploadsize-message,#delete-confirm { display:none; } /* File actions */ @@ -319,8 +320,6 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } #scanning-message{ top:40%; left:40%; position:absolute; display:none; } -div.crumb a{ padding:0.9em 0 0.7em 0; color:#555; } - table.dragshadow { width:auto; } diff --git a/apps/files/css/upload.css b/apps/files/css/upload.css index 2d11e41ba88e3b09520d421d4decf28a95a6c339..ef0435690945e0f9878f085f8024d6ac7c30c981 100644 --- a/apps/files/css/upload.css +++ b/apps/files/css/upload.css @@ -1,38 +1,63 @@ - #upload { - height:27px; padding:0; margin-left:0.2em; overflow:hidden; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: 36px; + width: 39px; + padding: 0 !important; /* override default control bar button padding */ + margin-left: .2em; + overflow: hidden; vertical-align: top; } #upload a { - position:relative; display:block; width:100%; height:27px; - cursor:pointer; z-index:10; - background-image:url('%webroot%/core/img/actions/upload.svg'); - background-repeat:no-repeat; - background-position:7px 6px; - opacity:0.65; + position: relative; + display: block; + width: 100%; + height: 44px; + width: 44px; + margin: -5px -3px; + cursor: pointer; + z-index: 10; + background-image: url('%webroot%/core/img/actions/upload.svg'); + background-repeat: no-repeat; + background-position: center; + opacity: .65; } .file_upload_target { display:none; } .file_upload_form { display:inline; float:left; margin:0; padding:0; cursor:pointer; overflow:visible; } #file_upload_start { - float: left; - left:0; top:0; width:28px; height:27px; padding:0; - font-size:1em; + position: relative; + left: 0; + top: 0; + width: 44px; + height: 44px; + margin: -5px -3px; + padding: 0; + font-size: 1em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; - z-index:20; position:relative; cursor:pointer; overflow:hidden; + z-index: 20; + cursor: pointer; + overflow: hidden; } #uploadprogresswrapper { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; display: inline-block; vertical-align: top; - margin:0.3em; - height: 29px; + height: 36px; + box-sizing: border-box; +} +#uploadprogresswrapper > input[type='button'] { + height: 36px; } #uploadprogressbar { position:relative; float: left; margin-left: 12px; width: 130px; - height: 26px; + height: 36px; display:inline-block; } #uploadprogressbar + stop { diff --git a/apps/files/index.php b/apps/files/index.php index 6f22fdfdc19bb4fccfbfae5d0b8b5d2c7b2dd9d5..8d877be8ac981a9a2f0ffb6e4861dcf8ed6653d7 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -104,8 +104,12 @@ if ($needUpgrade) { $storageInfo=OC_Helper::getStorageInfo($dir); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code) + $encryptionInitStatus = 2; if (OC_App::isEnabled('files_encryption')) { $publicUploadEnabled = 'no'; + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $encryptionInitStatus = $session->getInitialized(); } $trashEnabled = \OCP\App::isEnabled('files_trashbin'); @@ -113,7 +117,7 @@ if ($needUpgrade) { if ($trashEnabled) { $trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user); } - + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); @@ -133,7 +137,10 @@ if ($needUpgrade) { $tmpl->assign('isPublic', false); $tmpl->assign('publicUploadEnabled', $publicUploadEnabled); $tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles()); + $tmpl->assign("mailNotificationEnabled", \OC_Appconfig::getValue('core', 'shareapi_allow_mail_notification', 'yes')); + $tmpl->assign("encryptionInitStatus", $encryptionInitStatus); $tmpl->assign('disableSharing', false); $tmpl->assign('ajaxLoad', $ajaxLoad); + $tmpl->printPage(); } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index ec688eaf63efff3ea5d0dc70db8e85e08a45f2ac..899bc6469e503a74bf8b99a2bc7381ca5e169878 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -63,6 +63,15 @@ Files={ } var encryptedFiles = $('#encryptedFiles').val(); + var initStatus = $('#encryptionInitStatus').val(); + if (initStatus === '0') { // enc not initialized, but should be + OC.Notification.show(t('files_encryption', 'Encryption App is enabled but your keys are not initialized, please log-out and log-in again')); + return; + } + if (initStatus === '1') { // encryption tried to init but failed + OC.Notification.showHtml(t('files_encryption', 'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.')); + return; + } if (encryptedFiles === '1') { OC.Notification.show(t('files_encryption', 'Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files.')); return; diff --git a/apps/files/l10n/cs_CZ.php b/apps/files/l10n/cs_CZ.php index f67283ec6e846efd790f211500c9490fa1aacad5..f1e54ee5fc39e9581300141c094827a05dc33022 100644 --- a/apps/files/l10n/cs_CZ.php +++ b/apps/files/l10n/cs_CZ.php @@ -42,6 +42,7 @@ $TRANSLATIONS = array( "Your storage is almost full ({usedSpacePercent}%)" => "Vaše úložiště je téměř plné ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifrování bylo vypnuto, vaše soubory jsou však stále zašifrované. Běžte prosím do osobního nastavení, kde soubory odšifrujete.", "Your download is being prepared. This might take some time if the files are big." => "Vaše soubory ke stažení se připravují. Pokud jsou velké, může to chvíli trvat.", +"Error moving file" => "Chyba při přesunu souboru", "Name" => "Název", "Size" => "Velikost", "Modified" => "Upraveno", diff --git a/apps/files/l10n/it.php b/apps/files/l10n/it.php index c24d30ae368279ade51cf29d4a44752dde50eefd..44b4e341956df3b771bfdee982230d317ff87296 100644 --- a/apps/files/l10n/it.php +++ b/apps/files/l10n/it.php @@ -13,11 +13,11 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Manca una cartella temporanea", "Failed to write to disk" => "Scrittura su disco non riuscita", "Not enough storage available" => "Spazio di archiviazione insufficiente", -"Upload failed. Could not get file info." => "Upload fallito. Impossibile ottenere informazioni sul file", -"Upload failed. Could not find uploaded file" => "Upload fallit. Impossibile trovare file caricato", +"Upload failed. Could not get file info." => "Caricamento non riuscito. Impossibile ottenere informazioni sul file.", +"Upload failed. Could not find uploaded file" => "Caricamento non riuscito. Impossibile trovare il file caricato.", "Invalid directory." => "Cartella non valida.", "Files" => "File", -"Unable to upload {filename} as it is a directory or has 0 bytes" => "Impossibile caricare {filename} poiché è una cartella oppure è di 0 byte", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Impossibile caricare {filename} poiché è una cartella oppure ha una dimensione di 0 byte.", "Not enough space available" => "Spazio disponibile insufficiente", "Upload cancelled." => "Invio annullato", "Could not get result from server." => "Impossibile ottenere il risultato dal server.", diff --git a/apps/files/l10n/ja_JP.php b/apps/files/l10n/ja_JP.php index 5944b47434da4947bd07eef8271347888c722d32..07ee96f1eb6c1d36aff8205ee7773bee55a76064 100644 --- a/apps/files/l10n/ja_JP.php +++ b/apps/files/l10n/ja_JP.php @@ -13,10 +13,14 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "一時保存フォルダが見つかりません", "Failed to write to disk" => "ディスクへの書き込みに失敗しました", "Not enough storage available" => "ストレージに十分な空き容量がありません", +"Upload failed. Could not get file info." => "アップロードに失敗。ファイル情報を取得できませんでした。", +"Upload failed. Could not find uploaded file" => "アップロードに失敗。アップロード済みのファイルを見つけることができませんでした。", "Invalid directory." => "無効なディレクトリです。", "Files" => "ファイル", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "ディレクトリもしくは0バイトのため {filename} をアップロードできません", "Not enough space available" => "利用可能なスペースが十分にありません", "Upload cancelled." => "アップロードはキャンセルされました。", +"Could not get result from server." => "サーバから結果を取得できませんでした。", "File upload is in progress. Leaving the page now will cancel the upload." => "ファイル転送を実行中です。今このページから移動するとアップロードが中止されます。", "URL cannot be empty." => "URLは空にできません。", "Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "無効なフォルダ名です。'Shared' の利用はownCloudで予約済みです", @@ -42,6 +46,7 @@ $TRANSLATIONS = array( "Your storage is almost full ({usedSpacePercent}%)" => "あなたのストレージはほぼ一杯です({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "暗号化の機能は無効化されましたが、ファイルはすでに暗号化されています。個人設定からファイルを複合を行ってください。", "Your download is being prepared. This might take some time if the files are big." => "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。", +"Error moving file" => "ファイルの移動エラー", "Name" => "名前", "Size" => "サイズ", "Modified" => "変更", diff --git a/apps/files/l10n/ko.php b/apps/files/l10n/ko.php index 502acefcf3aa56fa3b0aadd553dd679126625ce3..0174f8d0d21a4b480587d5190bea6f202d713057 100644 --- a/apps/files/l10n/ko.php +++ b/apps/files/l10n/ko.php @@ -2,6 +2,8 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s 항목을 이동시키지 못하였음 - 파일 이름이 이미 존재함", "Could not move %s" => "%s 항목을 이딩시키지 못하였음", +"Unable to set upload directory." => "업로드 디렉터리를 정할수 없습니다", +"Invalid Token" => "잘못된 토큰", "No file was uploaded. Unknown error" => "파일이 업로드되지 않았습니다. 알 수 없는 오류입니다", "There is no error, the file uploaded with success" => "파일 업로드에 성공하였습니다.", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "업로드한 파일이 php.ini의 upload_max_filesize보다 큽니다:", @@ -11,12 +13,17 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "임시 폴더가 없음", "Failed to write to disk" => "디스크에 쓰지 못했습니다", "Not enough storage available" => "저장소가 용량이 충분하지 않습니다.", +"Upload failed. Could not get file info." => "업로드에 실패했습니다. 파일 정보를 가져올수 없습니다.", +"Upload failed. Could not find uploaded file" => "업로드에 실패했습니다. 업로드할 파일을 찾을수 없습니다", "Invalid directory." => "올바르지 않은 디렉터리입니다.", "Files" => "파일", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "{filename}을 업로드 할수 없습니다. 폴더이거나 0 바이트 파일입니다.", "Not enough space available" => "여유 공간이 부족합니다", "Upload cancelled." => "업로드가 취소되었습니다.", +"Could not get result from server." => "서버에서 결과를 가져올수 없습니다.", "File upload is in progress. Leaving the page now will cancel the upload." => "파일 업로드가 진행 중입니다. 이 페이지를 벗어나면 업로드가 취소됩니다.", "URL cannot be empty." => "URL을 입력해야 합니다.", +"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "유효하지 않은 폴더명입니다. \"Shared\" 이름의 사용은 OwnCloud 가 이미 예약하고 있습니다.", "Error" => "오류", "Share" => "공유", "Delete permanently" => "영원히 삭제", @@ -28,18 +35,22 @@ $TRANSLATIONS = array( "cancel" => "취소", "replaced {new_name} with {old_name}" => "{old_name}이(가) {new_name}(으)로 대체됨", "undo" => "되돌리기", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), -"_Uploading %n file_::_Uploading %n files_" => array(""), +"_%n folder_::_%n folders_" => array("폴더 %n"), +"_%n file_::_%n files_" => array("파일 %n 개"), +"{dirs} and {files}" => "{dirs} 그리고 {files}", +"_Uploading %n file_::_Uploading %n files_" => array("%n 개의 파일을 업로드중"), "'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름 입니다.", "File name cannot be empty." => "파일 이름이 비어 있을 수 없습니다.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "폴더 이름이 올바르지 않습니다. 이름에 문자 '\\', '/', '<', '>', ':', '\"', '|', '? ', '*'는 사용할 수 없습니다.", "Your storage is full, files can not be updated or synced anymore!" => "저장 공간이 가득 찼습니다. 파일을 업데이트하거나 동기화할 수 없습니다!", "Your storage is almost full ({usedSpacePercent}%)" => "저장 공간이 거의 가득 찼습니다 ({usedSpacePercent}%)", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "암호화는 해제되어 있지만, 파일은 아직 암호화 되어 있습니다. 개인 설저에 가셔서 암호를 해제하십시오", "Your download is being prepared. This might take some time if the files are big." => "다운로드가 준비 중입니다. 파일 크기가 크다면 시간이 오래 걸릴 수도 있습니다.", +"Error moving file" => "파일 이동 오류", "Name" => "이름", "Size" => "크기", "Modified" => "수정됨", +"%s could not be renamed" => "%s 의 이름을 변경할수 없습니다", "Upload" => "업로드", "File handling" => "파일 처리", "Maximum upload size" => "최대 업로드 크기", diff --git a/apps/files/l10n/lt_LT.php b/apps/files/l10n/lt_LT.php index 2b32a129d55a3c183a8c1b36b6acc02512211120..d064b0c6523c23e9a8fcd96d3c902ad0e3369629 100644 --- a/apps/files/l10n/lt_LT.php +++ b/apps/files/l10n/lt_LT.php @@ -13,10 +13,14 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Nėra laikinojo katalogo", "Failed to write to disk" => "Nepavyko įrašyti į diską", "Not enough storage available" => "Nepakanka vietos serveryje", +"Upload failed. Could not get file info." => "Įkėlimas nepavyko. Nepavyko gauti failo informacijos.", +"Upload failed. Could not find uploaded file" => "Įkėlimas nepavyko. Nepavyko rasti įkelto failo", "Invalid directory." => "Neteisingas aplankas", "Files" => "Failai", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Nepavyksta įkelti {filename}, nes tai katalogas arba yra 0 baitų dydžio", "Not enough space available" => "Nepakanka vietos", "Upload cancelled." => "Įkėlimas atšauktas.", +"Could not get result from server." => "Nepavyko gauti rezultato iš serverio.", "File upload is in progress. Leaving the page now will cancel the upload." => "Failo įkėlimas pradėtas. Jei paliksite šį puslapį, įkėlimas nutrūks.", "URL cannot be empty." => "URL negali būti tuščias.", "Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Negalimas aplanko pavadinimas. 'Shared' pavadinimas yra rezervuotas ownCloud", @@ -42,6 +46,7 @@ $TRANSLATIONS = array( "Your storage is almost full ({usedSpacePercent}%)" => "Jūsų vieta serveryje beveik visa užimta ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifravimas buvo išjungtas, bet Jūsų failai vis dar užšifruoti. Prašome eiti į asmeninius nustatymus ir iššifruoti savo failus.", "Your download is being prepared. This might take some time if the files are big." => "Jūsų atsisiuntimas yra paruošiamas. tai gali užtrukti jei atsisiunčiamas didelis failas.", +"Error moving file" => "Klaida perkeliant failą", "Name" => "Pavadinimas", "Size" => "Dydis", "Modified" => "Pakeista", diff --git a/apps/files/l10n/pl.php b/apps/files/l10n/pl.php index 3ad80975810ad1a0e85e56486103deff9e8a3134..50a247d2e0f4acd85b1b58d7e8f7080cbe489b0e 100644 --- a/apps/files/l10n/pl.php +++ b/apps/files/l10n/pl.php @@ -13,10 +13,14 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Brak folderu tymczasowego", "Failed to write to disk" => "Błąd zapisu na dysk", "Not enough storage available" => "Za mało dostępnego miejsca", +"Upload failed. Could not get file info." => "Nieudane przesłanie. Nie można pobrać informacji o pliku.", +"Upload failed. Could not find uploaded file" => "Nieudane przesłanie. Nie można znaleźć przesyłanego pliku", "Invalid directory." => "Zła ścieżka.", "Files" => "Pliki", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Nie można przesłać {filename} być może jest katalogiem lub posiada 0 bajtów", "Not enough space available" => "Za mało miejsca", "Upload cancelled." => "Wczytywanie anulowane.", +"Could not get result from server." => "Nie można uzyskać wyniku z serwera.", "File upload is in progress. Leaving the page now will cancel the upload." => "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.", "URL cannot be empty." => "URL nie może być pusty.", "Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nieprawidłowa nazwa folderu. Wykorzystanie 'Shared' jest zarezerwowane przez ownCloud", @@ -42,6 +46,7 @@ $TRANSLATIONS = array( "Your storage is almost full ({usedSpacePercent}%)" => "Twój magazyn jest prawie pełny ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Szyfrowanie zostało wyłączone, ale nadal pliki są zaszyfrowane. Przejdź do ustawień osobistych i tam odszyfruj pliki.", "Your download is being prepared. This might take some time if the files are big." => "Pobieranie jest przygotowywane. Może to zająć trochę czasu jeśli pliki są duże.", +"Error moving file" => "Błąd prz przenoszeniu pliku", "Name" => "Nazwa", "Size" => "Rozmiar", "Modified" => "Modyfikacja", diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 1d431df04f15b7d81fdaf77a9db1f41a0da471a2..709d78a4d45cb65aab21c3f8f00613e141337055 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -84,7 +84,7 @@ class Helper } } $i['directory'] = $dir; - $i['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($i['mimetype']); + $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']); $i['icon'] = \OCA\Files\Helper::determineIcon($i); $files[] = $i; } diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 96a80738989667198f4605f7705a0b55b6e9e858..7067b854f50a619dc8fb73f185658088d237228f 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -9,7 +9,7 @@ data-type='file'><p><?php p($l->t('Text file'));?></p></li> <li style="background-image:url('<?php p(OCP\mimetype_icon('dir')) ?>')" data-type='folder'><p><?php p($l->t('Folder'));?></p></li> - <li style="background-image:url('<?php p(OCP\image_path('core', 'filetypes/web.svg')) ?>')" + <li style="background-image:url('<?php p(OCP\image_path('core', 'places/link.svg')) ?>')" data-type='web'><p><?php p($l->t('From link'));?></p></li> </ul> </div> @@ -116,3 +116,5 @@ <input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php p($_['allowZipDownload']); ?>" /> <input type="hidden" name="usedSpacePercent" id="usedSpacePercent" value="<?php p($_['usedSpacePercent']); ?>" /> <input type="hidden" name="encryptedFiles" id="encryptedFiles" value="<?php $_['encryptedFiles'] ? p('1') : p('0'); ?>" /> +<input type="hidden" name="encryptedInitStatus" id="encryptionInitStatus" value="<?php p($_['encryptionInitStatus']) ?>" /> +<input type="hidden" name="mailNotificationEnabled" id="mailNotificationEnabled" value="<?php p($_['mailNotificationEnabled']) ?>" /> diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index 1e4d4d11c98dbfa6344abe6ec9a1f48e993d7588..0679da334dedbe907a3b683552bcae6a619230be 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -30,16 +30,15 @@ $totalsize = 0; ?> <?php endif; ?> <?php if($file['type'] == 'dir'): ?> <a class="name" href="<?php p(rtrim($_['baseURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>" title=""> + <span class="nametext"> + <?php print_unescaped(htmlspecialchars($file['name']));?> + </span> <?php else: ?> - <a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>" title=""> + <a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>"> + <label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label> + <span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span> + </a> <?php endif; ?> - <span class="nametext"> - <?php if($file['type'] == 'dir'):?> - <?php print_unescaped(htmlspecialchars($file['name']));?> - <?php else:?> - <?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span> - <?php endif;?> - </span> <?php if($file['type'] == 'dir'):?> <span class="uploadtext" currentUploads="0"> </span> diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php index 1e6644da576f56bd8d8daae01506f2032942658a..29c72952ae9de4457cc5d63340c4caef9658615f 100644 --- a/apps/files_encryption/ajax/updatePrivateKeyPassword.php +++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php @@ -48,6 +48,7 @@ if ($decryptedKey) { // success or failure if ($return) { + $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.')))); diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 5b62b84e22366a2ed5233d6fa1bcf72b4bb2e7a7..c930ac9eca8be5cb9b88e3651a8771428613bf4c 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -43,23 +43,6 @@ if (!OC_Config::getValue('maintenance', false)) { if($sessionReady) { $session = new \OCA\Encryption\Session($view); } - - $user = \OCP\USER::getUser(); - // check if user has a private key - if ($sessionReady === false - || (!$view->file_exists('/' . $user . '/files_encryption/' . $user . '.private.key') - && OCA\Encryption\Crypt::mode() === 'server') - ) { - - // Force the user to log-in again if the encryption key isn't unlocked - // (happens when a user is logged in before the encryption app is - // enabled) - OCP\User::logout(); - - header("Location: " . OC::$WEBROOT . '/'); - - exit(); - } } } else { // logout user if we are in maintenance to force re-login diff --git a/apps/files_encryption/appinfo/info.xml b/apps/files_encryption/appinfo/info.xml index 46f1375c9875a41bc558a29e49db1db619d93b8e..9d495916d26495482312b6838e70e5e1772ea9ec 100644 --- a/apps/files_encryption/appinfo/info.xml +++ b/apps/files_encryption/appinfo/info.xml @@ -7,6 +7,7 @@ <author>Sam Tuke, Bjoern Schiessle, Florin Peter</author> <require>4</require> <shipped>true</shipped> + <rememberlogin>false</rememberlogin> <types> <filesystem/> </types> diff --git a/apps/files_encryption/appinfo/version b/apps/files_encryption/appinfo/version index bd73f47072b1fe4b9914ec14a7f6d47fcc8f816a..2eb3c4fe4eebcdea3da0790cc0ba74cb286ec4f4 100644 --- a/apps/files_encryption/appinfo/version +++ b/apps/files_encryption/appinfo/version @@ -1 +1 @@ -0.4 +0.5 diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php index 2dd27257abe45381c9cf357ffa51e23da9f1df91..ac0c0269164fd9ecc6437c617e143d3e16d56e2d 100644 --- a/apps/files_encryption/files/error.php +++ b/apps/files_encryption/files/error.php @@ -1,23 +1,33 @@ <?php + if (!isset($_)) { //also provide standalone error page require_once __DIR__ . '/../../../lib/base.php'; $l = OC_L10N::get('files_encryption'); - $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); + if (isset($_GET['i']) && $_GET['i'] === '0') { + $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); + $init = '0'; + } else { + $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); + $init = '1'; + } - if(isset($_GET['p']) && $_GET['p'] === '1') { + if (isset($_GET['p']) && $_GET['p'] === '1') { header('HTTP/1.0 404 ' . $errorMsg); } - // check if ajax request - if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { +// check if ajax request + if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { \OCP\JSON::error(array('data' => array('message' => $errorMsg))); } else { header('HTTP/1.0 404 ' . $errorMsg); $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); + $tmpl->assign('message', $errorMsg); + $tmpl->assign('init', $init); $tmpl->printPage(); } exit; } + diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index d9221c6e828a2539ed61ffe184f7e589ca978444..2df860a8e5772d49526e3bf8ac32f13d0c1b3ee3 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -159,7 +159,6 @@ class Hooks { * @param array $params keys: uid, password */ public static function setPassphrase($params) { - // Only attempt to change passphrase if server-side encryption // is in use (client-side encryption does not have access to // the necessary keys) @@ -543,14 +542,18 @@ class Hooks { } /** - * set migration status back to '0' so that all new files get encrypted + * set migration status and the init status back to '0' so that all new files get encrypted * if the app gets enabled again * @param array $params contains the app ID */ public static function preDisable($params) { if ($params['app'] === 'files_encryption') { - $query = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); - $query->execute(); + + $setMigrationStatus = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); + $setMigrationStatus->execute(); + + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $session->setInitialized(\OCA\Encryption\Session::NOT_INITIALIZED); } } diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js index 6647c621e7b90f3f12c94ed779de577023fd0904..c2140a6f1eb152692e8da411e21099660d5e329c 100644 --- a/apps/files_encryption/js/settings-admin.js +++ b/apps/files_encryption/js/settings-admin.js @@ -1,6 +1,8 @@ /** - * Copyright (c) 2013, Sam Tuke <samtuke@owncloud.com>, Robin Appelman - * <icewind1991@gmail.com> + * Copyright (c) 2013 + * Sam Tuke <samtuke@owncloud.com> + * Robin Appelman <icewind1991@gmail.com> + * Bjoern Schiessle <schiessle@owncloud.com> * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. */ @@ -31,22 +33,23 @@ $(document).ready(function(){ // Trigger ajax on recoveryAdmin status change var enabledStatus = $('#adminEnableRecovery').val(); - $('input:password[name="recoveryPassword"]').keyup(function(event) { - var recoveryPassword = $( '#recoveryPassword' ).val(); + $('input:password[name="encryptionRecoveryPassword"]').keyup(function(event) { + var recoveryPassword = $( '#encryptionRecoveryPassword' ).val(); + var recoveryPasswordRepeated = $( '#repeatEncryptionRecoveryPassword' ).val(); var checkedButton = $('input:radio[name="adminEnableRecovery"]:checked').val(); var uncheckedValue = (1+parseInt(checkedButton)) % 2; - if (recoveryPassword != '' ) { + if (recoveryPassword !== '' && recoveryPassword === recoveryPasswordRepeated) { $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').removeAttr("disabled"); } else { $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').attr("disabled", "true"); } }); - $( 'input:radio[name="adminEnableRecovery"]' ).change( + $( 'input:radio[name="adminEnableRecovery"]' ).change( function() { var recoveryStatus = $( this ).val(); var oldStatus = (1+parseInt(recoveryStatus)) % 2; - var recoveryPassword = $( '#recoveryPassword' ).val(); + var recoveryPassword = $( '#encryptionRecoveryPassword' ).val(); $.post( OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword } @@ -57,11 +60,10 @@ $(document).ready(function(){ } else { OC.Notification.hide(); if (recoveryStatus === "0") { - $('button:button[name="submitChangeRecoveryKey"]').attr("disabled", "true"); - $('input:password[name="changeRecoveryPassword"]').attr("disabled", "true"); - $('input:password[name="changeRecoveryPassword"]').val(""); + $('p[name="changeRecoveryPasswordBlock"]').addClass("hidden"); } else { - $('input:password[name="changeRecoveryPassword"]').removeAttr("disabled"); + $('input:password[name="changeRecoveryPassword"]').val(""); + $('p[name="changeRecoveryPasswordBlock"]').removeClass("hidden"); } } } @@ -72,9 +74,11 @@ $(document).ready(function(){ // change recovery password $('input:password[name="changeRecoveryPassword"]').keyup(function(event) { - var oldRecoveryPassword = $('input:password[id="oldRecoveryPassword"]').val(); - var newRecoveryPassword = $('input:password[id="newRecoveryPassword"]').val(); - if (newRecoveryPassword != '' && oldRecoveryPassword != '' ) { + var oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val(); + var newRecoveryPassword = $('#newEncryptionRecoveryPassword').val(); + var newRecoveryPasswordRepeated = $('#repeatedNewEncryptionRecoveryPassword').val(); + + if (newRecoveryPassword !== '' && oldRecoveryPassword !== '' && newRecoveryPassword === newRecoveryPasswordRepeated) { $('button:button[name="submitChangeRecoveryKey"]').removeAttr("disabled"); } else { $('button:button[name="submitChangeRecoveryKey"]').attr("disabled", "true"); @@ -83,8 +87,8 @@ $(document).ready(function(){ $('button:button[name="submitChangeRecoveryKey"]').click(function() { - var oldRecoveryPassword = $('input:password[id="oldRecoveryPassword"]').val(); - var newRecoveryPassword = $('input:password[id="newRecoveryPassword"]').val(); + var oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val(); + var newRecoveryPassword = $('#newEncryptionRecoveryPassword').val(); OC.msg.startSaving('#encryption .msg'); $.post( OC.filePath( 'files_encryption', 'ajax', 'changeRecoveryPassword.php' ) @@ -98,5 +102,5 @@ $(document).ready(function(){ } ); }); - + }); diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 445d7ff8ca796ed911833df22685935578d2b316..ebfc00157f71820982baa7806b26cd49ee687486 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -199,12 +199,12 @@ class Helper { public static function stripUserFilesPath($path) { $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); - + // it is not a file relative to data/user/files if (count($split) < 3 || $split[1] !== 'files') { return false; } - + $sliced = array_slice($split, 2); $relPath = implode('/', $sliced); @@ -219,30 +219,33 @@ class Helper { public static function getPathToRealFile($path) { $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); - + if (count($split) < 3 || $split[1] !== "files_versions") { return false; } - + $sliced = array_slice($split, 2); $realPath = implode('/', $sliced); //remove the last .v $realPath = substr($realPath, 0, strrpos($realPath, '.v')); return $realPath; - } - + } + /** * @brief redirect to a error page */ - public static function redirectToErrorPage() { + public static function redirectToErrorPage($session) { + + $init = $session->getInitialized(); + $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php'); $post = 0; if(count($_POST) > 0) { $post = 1; - } - header('Location: ' . $location . '?p=' . $post); - exit(); + } + header('Location: ' . $location . '?p=' . $post . '&i=' . $init); + exit(); } /** @@ -259,7 +262,7 @@ class Helper { return (bool) $result; } - + /** * check some common errors if the server isn't configured properly for encryption * @return bool true if configuration seems to be OK diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 1911386cd12f06832d2406071a4092942191c7d7..25f2198181f3db0baddd7924db9c5806da10179e 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -30,6 +30,11 @@ class Session { private $view; + const NOT_INITIALIZED = '0'; + const INIT_EXECUTED = '1'; + const INIT_SUCCESSFUL = '2'; + + /** * @brief if session is started, check if ownCloud key pair is set up, if not create it * @param \OC_FilesystemView $view @@ -112,6 +117,36 @@ class Session { } + /** + * @brief Sets status of encryption app + * @param string $init INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED + * @return bool + * + * @note this doesn not indicate of the init was successful, we just remeber the try! + */ + public function setInitialized($init) { + + \OC::$session->set('encryptionInitialized', $init); + + return true; + + } + + + /** + * @brief Gets status if we already tried to initialize the encryption app + * @returns init status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED + * + * @note this doesn not indicate of the init was successful, we just remeber the try! + */ + public function getInitialized() { + if (!is_null(\OC::$session->get('encryptionInitialized'))) { + return \OC::$session->get('encryptionInitialized'); + } else { + return self::NOT_INITIALIZED; + } + } + /** * @brief Gets user or public share private key from session * @returns string $privateKey The user's plaintext private key diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 083b33c03cbf2be40e674a8e509c3d5743975fb7..02955bb064e982b9020a90b788021e95c59011a0 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -131,7 +131,7 @@ class Stream { if($this->privateKey === false) { // if private key is not valid redirect user to a error page - \OCA\Encryption\Helper::redirectToErrorPage(); + \OCA\Encryption\Helper::redirectToErrorPage($this->session); } $this->size = $this->rootView->filesize($this->rawPath, $mode); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index df4d35cab0b42076108403b380e0249425f13e33..53d58fbf40d601c6951d052f2f643f3a5b0a9b24 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -37,7 +37,6 @@ class Util { const MIGRATION_IN_PROGRESS = -1; // migration is running const MIGRATION_OPEN = 0; // user still needs to be migrated - private $view; // OC_FilesystemView object for filesystem operations private $userId; // ID of the currently logged-in user private $client; // Client side encryption mode flag @@ -1752,6 +1751,11 @@ class Util { */ public function initEncryption($params) { + $session = new \OCA\Encryption\Session($this->view); + + // we tried to initialize the encryption app for this session + $session->setInitialized(\OCA\Encryption\Session::INIT_EXECUTED); + $encryptedKey = Keymanager::getPrivateKey($this->view, $params['uid']); $privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']); @@ -1762,9 +1766,8 @@ class Util { return false; } - $session = new \OCA\Encryption\Session($this->view); - $session->setPrivateKey($privateKey); + $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); return $session; } diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index 589219f32ada5c05fcc112140861fe535ae62ce9..ffcb99602e2f6350affd7523a8b46d0d432572fa 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -16,7 +16,9 @@ $view = new \OC_FilesystemView('/'); $util = new \OCA\Encryption\Util($view, $user); $session = new \OCA\Encryption\Session($view); -$privateKeySet = $session->getPrivateKey() !== false; +$privateKeySet = $session->getPrivateKey() !== false; +// did we tried to initialize the keys for this session? +$initialized = $session->getInitialized(); $recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); @@ -31,6 +33,7 @@ if ($recoveryAdminEnabled || !$privateKeySet) { $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser); $tmpl->assign('privateKeySet', $privateKeySet); + $tmpl->assign('initialized', $initialized); $result = $tmpl->fetchPage(); } diff --git a/apps/files_encryption/templates/invalid_private_key.php b/apps/files_encryption/templates/invalid_private_key.php index 5c086d6514c1297fb80d5aaea13b9cf90ff3a5ba..9af65f831b43949b8c9c2060351e73079ad154f8 100644 --- a/apps/files_encryption/templates/invalid_private_key.php +++ b/apps/files_encryption/templates/invalid_private_key.php @@ -2,9 +2,11 @@ <li class='error'> <?php $location = \OC_Helper::linkToRoute( "settings_personal" ).'#changePKPasswd' ?> - <?php p($l->t('Your private key is not valid! Maybe the your password was changed from outside.')); ?> + <?php p($_['message']); ?> <br/> - <?php p($l->t('You can unlock your private key in your ')); ?> <a href="<?php echo $location?>"><?php p($l->t('personal settings')); ?>.</a> + <?php if($_['init']): ?> + <?php>p($l->t('Go directly to your ')); ?> <a href="<?php echo $location?>"><?php p($l->t('personal settings')); ?>.</a> + <?php endif; ?> <br/> </li> </ul> diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php index f5f7582c2a69d141e49232f76e49e9fc14c708ac..3a6adc09f4b55ea2fee868aaee61de506891a033 100644 --- a/apps/files_encryption/templates/settings-admin.php +++ b/apps/files_encryption/templates/settings-admin.php @@ -10,14 +10,17 @@ <?php p($l->t("Enable recovery key (allow to recover users files in case of password loss):")); ?> <br/> <br/> - <input type="password" name="recoveryPassword" id="recoveryPassword"/> + <input type="password" name="encryptionRecoveryPassword" id="encryptionRecoveryPassword"/> <label for="recoveryPassword"><?php p($l->t("Recovery key password")); ?></label> <br/> + <input type="password" name="encryptionRecoveryPassword" id="repeatEncryptionRecoveryPassword"/> + <label for="repeatEncryptionRecoveryPassword"><?php p($l->t("Repeat Recovery key password")); ?></label> + <br/> <input type='radio' name='adminEnableRecovery' value='1' - <?php echo($_["recoveryEnabled"] == 1 ? 'checked="checked"' : 'disabled'); ?> /> + <?php echo($_["recoveryEnabled"] === '1' ? 'checked="checked"' : 'disabled'); ?> /> <?php p($l->t("Enabled")); ?> <br/> @@ -25,27 +28,32 @@ type='radio' name='adminEnableRecovery' value='0' - <?php echo($_["recoveryEnabled"] == 0 ? 'checked="checked"' : 'disabled'); ?> /> + <?php echo($_["recoveryEnabled"] === '0' ? 'checked="checked"' : 'disabled'); ?> /> <?php p($l->t("Disabled")); ?> </p> <br/><br/> - <p> + <p name="changeRecoveryPasswordBlock" <?php if ($_['recoveryEnabled'] === '0') print_unescaped('class="hidden"');?>> <strong><?php p($l->t("Change recovery key password:")); ?></strong> <br/><br/> <input type="password" name="changeRecoveryPassword" - id="oldRecoveryPassword" - <?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> /> - <label for="oldRecoveryPassword"><?php p($l->t("Old Recovery key password")); ?></label> + id="oldEncryptionRecoveryPassword" + <label for="oldEncryptionRecoveryPassword"><?php p($l->t("Old Recovery key password")); ?></label> + <br/> + <br/> + <input + type="password" + name="changeRecoveryPassword" + id="newEncryptionRecoveryPassword" + <label for="newEncryptionRecoveryPassword"><?php p($l->t("New Recovery key password")); ?></label> <br/> <input type="password" name="changeRecoveryPassword" - id="newRecoveryPassword" - <?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> /> - <label for="newRecoveryPassword"><?php p($l->t("New Recovery key password")); ?></label> + id="repeatedNewEncryptionRecoveryPassword" + <label for="repeatEncryptionRecoveryPassword"><?php p($l->t("Repeat New Recovery key password")); ?></label> <br/> <button type="button" diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 38512453207a0af2ab836589d427f1abc394ef16..ff04556dd53ef9e9d5e104e6aa05fc6db857562c 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -4,7 +4,7 @@ <?php p( $l->t( 'Encryption' ) ); ?> </legend> - <?php if ( ! $_["privateKeySet"] ): ?> + <?php if ( ! $_["privateKeySet"] && $_["initialized"] ): ?> <p> <a name="changePKPasswd" /> <label for="changePrivateKeyPasswd"> @@ -39,22 +39,22 @@ <?php endif; ?> <br /> - + <?php if ( $_["recoveryEnabled"] && $_["privateKeySet"] ): ?> <p> <label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label> <br /> <em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" ) ); ?></em> <br /> - <input + <input type='radio' name='userEnableRecovery' value='1' <?php echo ( $_["recoveryEnabledForUser"] == 1 ? 'checked="checked"' : '' ); ?> /> <?php p( $l->t( "Enabled" ) ); ?> <br /> - - <input + + <input type='radio' name='userEnableRecovery' value='0' diff --git a/apps/files_sharing/l10n/ko.php b/apps/files_sharing/l10n/ko.php index f3a94a70979a25676f57553b41abb90b41c48446..f7eab1ac5500c2e6169c33ddeba0f9a0be7a85aa 100644 --- a/apps/files_sharing/l10n/ko.php +++ b/apps/files_sharing/l10n/ko.php @@ -1,7 +1,14 @@ <?php $TRANSLATIONS = array( +"The password is wrong. Try again." => "비밀번호가 틀립니다. 다시 입력해주세요.", "Password" => "암호", "Submit" => "제출", +"Sorry, this link doesn’t seem to work anymore." => "죄송합니다만 이 링크는 더이상 작동되지 않습니다.", +"Reasons might be:" => "이유는 다음과 같을 수 있습니다:", +"the item was removed" => "이 항목은 삭제되었습니다", +"the link expired" => "링크가 만료되었습니다", +"sharing is disabled" => "공유가 비활성되었습니다", +"For more info, please ask the person who sent this link." => "더 자세한 설명은 링크를 보내신 분에게 여쭤보십시오", "%s shared the folder %s with you" => "%s 님이 폴더 %s을(를) 공유하였습니다", "%s shared the file %s with you" => "%s 님이 파일 %s을(를) 공유하였습니다", "Download" => "다운로드", diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 136767aeb456b39ba2c8c563590d9f73d0eb6042..eff38dcc0fd5fce37baf3d39ae3206381d1cfdfa 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -188,7 +188,7 @@ if (isset($path)) { } else { $i['extension'] = ''; } - $i['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($i['mimetype']); + $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']); } $i['directory'] = $getPath; $i['permissions'] = OCP\PERMISSION_READ; diff --git a/apps/files_trashbin/l10n/ko.php b/apps/files_trashbin/l10n/ko.php index f2e604d75915416e9825bae5b97db30f9f1883a7..9ac5f9802c683671fe3d156e9fb39655fddbcda9 100644 --- a/apps/files_trashbin/l10n/ko.php +++ b/apps/files_trashbin/l10n/ko.php @@ -1,11 +1,19 @@ <?php $TRANSLATIONS = array( +"Couldn't delete %s permanently" => "%s를 영구적으로 삭제할수 없습니다", +"Couldn't restore %s" => "%s를 복원할수 없습니다", +"perform restore operation" => "복원 작업중", "Error" => "오류", +"delete file permanently" => "영구적으로 파일 삭제하기", "Delete permanently" => "영원히 삭제", "Name" => "이름", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), +"Deleted" => "삭제됨", +"_%n folder_::_%n folders_" => array("폴더 %n개"), +"_%n file_::_%n files_" => array("파일 %n개 "), +"restored" => "복원됨", +"Nothing in here. Your trash bin is empty!" => "현재 휴지통은 비어있습니다!", "Restore" => "복원", -"Delete" => "삭제" +"Delete" => "삭제", +"Deleted Files" => "삭제된 파일들" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php index 99f534565f943dcae8970eb4b59d00f584b5d74c..4f442ee930471cf39023059c071a79cd53376bf8 100644 --- a/apps/files_trashbin/lib/helper.php +++ b/apps/files_trashbin/lib/helper.php @@ -61,7 +61,7 @@ class Helper $i['directory'] = ''; } $i['permissions'] = \OCP\PERMISSION_READ; - $i['isPreviewAvailable'] = \OCP\Preview::isMimeSupported($r['mime']); + $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($r['mime']); $i['icon'] = \OCA\Files\Helper::determineIcon($i); $files[] = $i; } diff --git a/apps/files_versions/l10n/ko.php b/apps/files_versions/l10n/ko.php index 365adc25115977ce91d91d504df6e14c398cbf87..ba951c4107a1d68cb5f3988d1f66f45ce90ebd0b 100644 --- a/apps/files_versions/l10n/ko.php +++ b/apps/files_versions/l10n/ko.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "되돌릴 수 없습니다: %s", "Versions" => "버전", +"Failed to revert {file} to revision {timestamp}." => "{timestamp} 판의 {file}로 돌리는데 실패했습니다.", +"More versions..." => "더 많은 버전들...", +"No other versions available" => "다른 버전을 사용할수 없습니다", "Restore" => "복원" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/ajax/getConfiguration.php b/apps/user_ldap/ajax/getConfiguration.php index baca588976fc8a8a7755d059d88173477f26dab3..fc51b459a25b0b672900815ff9f68fc8a731e4ed 100644 --- a/apps/user_ldap/ajax/getConfiguration.php +++ b/apps/user_ldap/ajax/getConfiguration.php @@ -27,5 +27,6 @@ OCP\JSON::checkAppEnabled('user_ldap'); OCP\JSON::callCheck(); $prefix = $_POST['ldap_serverconfig_chooser']; -$connection = new \OCA\user_ldap\lib\Connection($prefix); +$ldapWrapper = new OCA\user_ldap\lib\LDAP(); +$connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, $prefix); OCP\JSON::success(array('configuration' => $connection->getConfiguration())); diff --git a/apps/user_ldap/ajax/setConfiguration.php b/apps/user_ldap/ajax/setConfiguration.php index d850bda24706830145d965059b7bb1be8e375f22..94de8835fbcf9540367c2dd3c6d2cd060e940498 100644 --- a/apps/user_ldap/ajax/setConfiguration.php +++ b/apps/user_ldap/ajax/setConfiguration.php @@ -27,7 +27,8 @@ OCP\JSON::checkAppEnabled('user_ldap'); OCP\JSON::callCheck(); $prefix = $_POST['ldap_serverconfig_chooser']; -$connection = new \OCA\user_ldap\lib\Connection($prefix); +$ldapWrapper = new OCA\user_ldap\lib\LDAP(); +$connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, $prefix); $connection->setConfiguration($_POST); $connection->saveConfiguration(); OCP\JSON::success(); diff --git a/apps/user_ldap/ajax/testConfiguration.php b/apps/user_ldap/ajax/testConfiguration.php index 7ce1258a7967e7b8cd711f021b4f0fe4346b213d..0b8e4ccfe2048dac6248a43eb667dc75b64b5ddf 100644 --- a/apps/user_ldap/ajax/testConfiguration.php +++ b/apps/user_ldap/ajax/testConfiguration.php @@ -28,7 +28,8 @@ OCP\JSON::callCheck(); $l=OC_L10N::get('user_ldap'); -$connection = new \OCA\user_ldap\lib\Connection('', null); +$ldapWrapper = new OCA\user_ldap\lib\LDAP(); +$connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, '', null); if($connection->setConfiguration($_POST)) { //Configuration is okay if($connection->bind()) { diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 593e846bc03f8dea4514bd05cf32c99672e90717..9d6327181afb3b67181eac2afa88267ad6789399 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -24,15 +24,15 @@ OCP\App::registerAdmin('user_ldap', 'settings'); $configPrefixes = OCA\user_ldap\lib\Helper::getServerConfigurationPrefixes(true); +$ldapWrapper = new OCA\user_ldap\lib\LDAP(); if(count($configPrefixes) === 1) { - $connector = new OCA\user_ldap\lib\Connection($configPrefixes[0]); - $userBackend = new OCA\user_ldap\USER_LDAP(); - $userBackend->setConnector($connector); - $groupBackend = new OCA\user_ldap\GROUP_LDAP(); - $groupBackend->setConnector($connector); + $connector = new OCA\user_ldap\lib\Connection($ldapWrapper, $configPrefixes[0]); + $ldapAccess = new OCA\user_ldap\lib\Access($connector, $ldapWrapper); + $userBackend = new OCA\user_ldap\USER_LDAP($ldapAccess); + $groupBackend = new OCA\user_ldap\GROUP_LDAP($ldapAccess); } else { - $userBackend = new OCA\user_ldap\User_Proxy($configPrefixes); - $groupBackend = new OCA\user_ldap\Group_Proxy($configPrefixes); + $userBackend = new OCA\user_ldap\User_Proxy($configPrefixes, $ldapWrapper); + $groupBackend = new OCA\user_ldap\Group_Proxy($configPrefixes, $ldapWrapper); } if(count($configPrefixes) > 0) { diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 04ff392f9205ab88f692e4994abc47a19b080a6d..32e2cec5960ade394ef892a661e2a9b6d1f8c4eb 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -23,13 +23,16 @@ namespace OCA\user_ldap; -class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { +use OCA\user_ldap\lib\Access; +use OCA\user_ldap\lib\BackendUtility; + +class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { protected $enabled = false; - public function setConnector(lib\Connection &$connection) { - parent::setConnector($connection); - $filter = $this->connection->ldapGroupFilter; - $gassoc = $this->connection->ldapGroupMemberAssocAttr; + public function __construct(Access $access) { + parent::__construct($access); + $filter = $this->access->connection->ldapGroupFilter; + $gassoc = $this->access->connection->ldapGroupMemberAssocAttr; if(!empty($filter) && !empty($gassoc)) { $this->enabled = true; } @@ -47,30 +50,31 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$this->enabled) { return false; } - if($this->connection->isCached('inGroup'.$uid.':'.$gid)) { - return $this->connection->getFromCache('inGroup'.$uid.':'.$gid); + if($this->access->connection->isCached('inGroup'.$uid.':'.$gid)) { + return $this->access->connection->getFromCache('inGroup'.$uid.':'.$gid); } - $dn_user = $this->username2dn($uid); - $dn_group = $this->groupname2dn($gid); + $dn_user = $this->access->username2dn($uid); + $dn_group = $this->access->groupname2dn($gid); // just in case if(!$dn_group || !$dn_user) { - $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); + $this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr); + $members = $this->access->readAttribute($dn_group, + $this->access->connection->ldapGroupMemberAssocAttr); if(!$members) { - $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); + $this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } //extra work if we don't get back user DNs //TODO: this can be done with one LDAP query - if(strtolower($this->connection->ldapGroupMemberAssocAttr) === 'memberuid') { + if(strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') { $dns = array(); foreach($members as $mid) { - $filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter); - $ldap_users = $this->fetchListOfUsers($filter, 'dn'); + $filter = str_replace('%uid', $mid, $this->access->connection->ldapLoginFilter); + $ldap_users = $this->access->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } @@ -80,7 +84,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { } $isInGroup = in_array($dn_user, $members); - $this->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup); + $this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup); return $isInGroup; } @@ -98,35 +102,36 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { return array(); } $cacheKey = 'getUserGroups'.$uid; - if($this->connection->isCached($cacheKey)) { - return $this->connection->getFromCache($cacheKey); + if($this->access->connection->isCached($cacheKey)) { + return $this->access->connection->getFromCache($cacheKey); } - $userDN = $this->username2dn($uid); + $userDN = $this->access->username2dn($uid); if(!$userDN) { - $this->connection->writeToCache($cacheKey, array()); + $this->access->connection->writeToCache($cacheKey, array()); return array(); } //uniqueMember takes DN, memberuid the uid, so we need to distinguish - if((strtolower($this->connection->ldapGroupMemberAssocAttr) === 'uniquemember') - || (strtolower($this->connection->ldapGroupMemberAssocAttr) === 'member') + if((strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'uniquemember') + || (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'member') ) { $uid = $userDN; - } else if(strtolower($this->connection->ldapGroupMemberAssocAttr) === 'memberuid') { - $result = $this->readAttribute($userDN, 'uid'); + } else if(strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') { + $result = $this->access->readAttribute($userDN, 'uid'); $uid = $result[0]; } else { // just in case $uid = $userDN; } - $filter = $this->combineFilterWithAnd(array( - $this->connection->ldapGroupFilter, - $this->connection->ldapGroupMemberAssocAttr.'='.$uid + $filter = $this->access->combineFilterWithAnd(array( + $this->access->connection->ldapGroupFilter, + $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid )); - $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName, 'dn')); - $groups = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING); - $this->connection->writeToCache($cacheKey, $groups); + $groups = $this->access->fetchListOfGroups($filter, + array($this->access->connection->ldapGroupDisplayName, 'dn')); + $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $this->access->connection->writeToCache($cacheKey, $groups); return $groups; } @@ -144,70 +149,71 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { } $cachekey = 'usersInGroup-'.$gid.'-'.$search.'-'.$limit.'-'.$offset; // check for cache of the exact query - $groupUsers = $this->connection->getFromCache($cachekey); + $groupUsers = $this->access->connection->getFromCache($cachekey); if(!is_null($groupUsers)) { return $groupUsers; } // check for cache of the query without limit and offset - $groupUsers = $this->connection->getFromCache('usersInGroup-'.$gid.'-'.$search); + $groupUsers = $this->access->connection->getFromCache('usersInGroup-'.$gid.'-'.$search); if(!is_null($groupUsers)) { $groupUsers = array_slice($groupUsers, $offset, $limit); - $this->connection->writeToCache($cachekey, $groupUsers); + $this->access->connection->writeToCache($cachekey, $groupUsers); return $groupUsers; } if($limit === -1) { $limit = null; } - $groupDN = $this->groupname2dn($gid); + $groupDN = $this->access->groupname2dn($gid); if(!$groupDN) { // group couldn't be found, return empty resultset - $this->connection->writeToCache($cachekey, array()); + $this->access->connection->writeToCache($cachekey, array()); return array(); } - $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr); + $members = $this->access->readAttribute($groupDN, + $this->access->connection->ldapGroupMemberAssocAttr); if(!$members) { //in case users could not be retrieved, return empty resultset - $this->connection->writeToCache($cachekey, array()); + $this->access->connection->writeToCache($cachekey, array()); return array(); } $groupUsers = array(); - $isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) === 'memberuid'); + $isMemberUid = (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid'); foreach($members as $member) { if($isMemberUid) { //we got uids, need to get their DNs to 'tranlsate' them to usernames - $filter = $this->combineFilterWithAnd(array( + $filter = $this->access->combineFilterWithAnd(array( \OCP\Util::mb_str_replace('%uid', $member, - $this->connection->ldapLoginFilter, 'UTF-8'), - $this->getFilterPartForUserSearch($search) + $this->access->connection->ldapLoginFilter, 'UTF-8'), + $this->access->getFilterPartForUserSearch($search) )); - $ldap_users = $this->fetchListOfUsers($filter, 'dn'); + $ldap_users = $this->access->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } - $groupUsers[] = $this->dn2username($ldap_users[0]); + $groupUsers[] = $this->access->dn2username($ldap_users[0]); } else { //we got DNs, check if we need to filter by search or we can give back all of them if(!empty($search)) { - if(!$this->readAttribute($member, - $this->connection->ldapUserDisplayName, - $this->getFilterPartForUserSearch($search))) { + if(!$this->access->readAttribute($member, + $this->access->connection->ldapUserDisplayName, + $this->access->getFilterPartForUserSearch($search))) { continue; } } // dn2username will also check if the users belong to the allowed base - if($ocname = $this->dn2username($member)) { + if($ocname = $this->access->dn2username($member)) { $groupUsers[] = $ocname; } } } natsort($groupUsers); - $this->connection->writeToCache('usersInGroup-'.$gid.'-'.$search, $groupUsers); + $this->access->connection->writeToCache('usersInGroup-'.$gid.'-'.$search, $groupUsers); $groupUsers = array_slice($groupUsers, $offset, $limit); - $this->connection->writeToCache($cachekey, $groupUsers); + $this->access->connection->writeToCache($cachekey, $groupUsers); return $groupUsers; } @@ -245,7 +251,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { //Check cache before driving unnecessary searches \OCP\Util::writeLog('user_ldap', 'getGroups '.$cachekey, \OCP\Util::DEBUG); - $ldap_groups = $this->connection->getFromCache($cachekey); + $ldap_groups = $this->access->connection->getFromCache($cachekey); if(!is_null($ldap_groups)) { return $ldap_groups; } @@ -255,16 +261,18 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if($limit <= 0) { $limit = null; } - $filter = $this->combineFilterWithAnd(array( - $this->connection->ldapGroupFilter, - $this->getFilterPartForGroupSearch($search) + $filter = $this->access->combineFilterWithAnd(array( + $this->access->connection->ldapGroupFilter, + $this->access->getFilterPartForGroupSearch($search) )); \OCP\Util::writeLog('user_ldap', 'getGroups Filter '.$filter, \OCP\Util::DEBUG); - $ldap_groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName, 'dn'), - $limit, $offset); - $ldap_groups = $this->ownCloudGroupNames($ldap_groups); + $ldap_groups = $this->access->fetchListOfGroups($filter, + array($this->access->connection->ldapGroupDisplayName, 'dn'), + $limit, + $offset); + $ldap_groups = $this->access->ownCloudGroupNames($ldap_groups); - $this->connection->writeToCache($cachekey, $ldap_groups); + $this->access->connection->writeToCache($cachekey, $ldap_groups); return $ldap_groups; } @@ -278,25 +286,26 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { * @return bool */ public function groupExists($gid) { - if($this->connection->isCached('groupExists'.$gid)) { - return $this->connection->getFromCache('groupExists'.$gid); + if($this->access->connection->isCached('groupExists'.$gid)) { + return $this->access->connection->getFromCache('groupExists'.$gid); } - //getting dn, if false the group does not exist. If dn, it may be mapped only, requires more checking. - $dn = $this->groupname2dn($gid); + //getting dn, if false the group does not exist. If dn, it may be mapped + //only, requires more checking. + $dn = $this->access->groupname2dn($gid); if(!$dn) { - $this->connection->writeToCache('groupExists'.$gid, false); + $this->access->connection->writeToCache('groupExists'.$gid, false); return false; } //if group really still exists, we will be able to read its objectclass - $objcs = $this->readAttribute($dn, 'objectclass'); + $objcs = $this->access->readAttribute($dn, 'objectclass'); if(!$objcs || empty($objcs)) { - $this->connection->writeToCache('groupExists'.$gid, false); + $this->access->connection->writeToCache('groupExists'.$gid, false); return false; } - $this->connection->writeToCache('groupExists'.$gid, true); + $this->access->connection->writeToCache('groupExists'.$gid, true); return true; } diff --git a/apps/user_ldap/group_proxy.php b/apps/user_ldap/group_proxy.php index eb6f176c58ce6e5e70da2d151f086299562690c1..acc563c9532e14ebde97a792686e2b9dce76e178 100644 --- a/apps/user_ldap/group_proxy.php +++ b/apps/user_ldap/group_proxy.php @@ -23,6 +23,8 @@ namespace OCA\user_ldap; +use OCA\user_ldap\lib\ILDAPWrapper; + class Group_Proxy extends lib\Proxy implements \OCP\GroupInterface { private $backends = array(); private $refBackend = null; @@ -31,12 +33,11 @@ class Group_Proxy extends lib\Proxy implements \OCP\GroupInterface { * @brief Constructor * @param $serverConfigPrefixes array containing the config Prefixes */ - public function __construct($serverConfigPrefixes) { - parent::__construct(); + public function __construct($serverConfigPrefixes, ILDAPWrapper $ldap) { + parent::__construct($ldap); foreach($serverConfigPrefixes as $configPrefix) { - $this->backends[$configPrefix] = new \OCA\user_ldap\GROUP_LDAP(); - $connector = $this->getConnector($configPrefix); - $this->backends[$configPrefix]->setConnector($connector); + $this->backends[$configPrefix] = + new \OCA\user_ldap\GROUP_LDAP($this->getAccess($configPrefix)); if(is_null($this->refBackend)) { $this->refBackend = &$this->backends[$configPrefix]; } diff --git a/apps/user_ldap/l10n/hu_HU.php b/apps/user_ldap/l10n/hu_HU.php index b41cf98e2b963c0ea620214ed51c8230428d6973..b43dcbc2c8769cbed8d6b2a23b6bb23e24479758 100644 --- a/apps/user_ldap/l10n/hu_HU.php +++ b/apps/user_ldap/l10n/hu_HU.php @@ -72,6 +72,7 @@ $TRANSLATIONS = array( "User Home Folder Naming Rule" => "A home könyvtár elérési útvonala", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Hagyja üresen, ha a felhasználónevet kívánja használni. Ellenkező esetben adjon meg egy LDAP/AD attribútumot!", "Internal Username" => "Belső felhasználónév", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "Alapértelmezetten a belső felhasználónév az UUID tulajdonságból jön létre. Ez biztosítja a felhasználónév egyediségét és hogy a nem kell konvertálni a karaktereket benne. A belső felhasználónévnél a megkötés az, hogy csak a következő karakterek engdélyezettek benne: [ a-zA-Z0-9_.@- ]. Ezeken a karaktereken kivül minden karakter le lesz cserélve az adott karakter ASCII kódtáblában használható párjára vagy ha ilyen nincs akkor egyszerűen ki lesz hagyva. Ha így mégis ütköznének a nevek akkor hozzá lesz füzve egy folyamatosan növekvő számláló rész. A belső felhasználónevet lehet használni a felhasználó azonosítására a programon belül. Illetve ez lesz az alapáértelmezett neve a felhasználó kezdő könyvtárának az ownCloud-ban. Illetve...............................", "Internal Username Attribute:" => "A belső felhasználónév attribútuma:", "Override UUID detection" => "Az UUID-felismerés felülbírálása", "UUID Attribute:" => "UUID attribútum:", diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 52aa39012fd0b2788403169ef45d4d0c658d73c0..fdf9c24612d13e11907d4a29d93477521b007c44 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -23,12 +23,13 @@ namespace OCA\user_ldap\lib; -abstract class Access { - protected $connection; +class Access extends LDAPUtility { + public $connection; //never ever check this var directly, always use getPagedSearchResultState protected $pagedSearchedSuccessful; - public function setConnector(Connection &$connection) { + public function __construct(Connection $connection, ILDAPWrapper $ldap) { + parent::__construct($ldap); $this->connection = $connection; } @@ -54,14 +55,14 @@ abstract class Access { return false; } $cr = $this->connection->getConnectionResource(); - if(!is_resource($cr)) { + if(!$this->ldap->isResource($cr)) { //LDAP not available \OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG); return false; } $dn = $this->DNasBaseParameter($dn); - $rr = @ldap_read($cr, $dn, $filter, array($attr)); - if(!is_resource($rr)) { + $rr = @$this->ldap->read($cr, $dn, $filter, array($attr)); + if(!$this->ldap->isResource($rr)) { if(!empty($attr)) { //do not throw this message on userExists check, irritates \OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG); @@ -73,13 +74,14 @@ abstract class Access { \OCP\Util::writeLog('user_ldap', 'readAttribute: '.$dn.' found', \OCP\Util::DEBUG); return array(); } - $er = ldap_first_entry($cr, $rr); - if(!is_resource($er)) { + $er = $this->ldap->firstEntry($cr, $rr); + if(!$this->ldap->isResource($er)) { //did not match the filter, return false return false; } //LDAP attributes are not case sensitive - $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); + $result = \OCP\Util::mb_array_change_key_case( + $this->ldap->getAttributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); $attr = mb_strtolower($attr, 'UTF-8'); if(isset($result[$attr]) && $result[$attr]['count'] > 0) { @@ -653,7 +655,7 @@ abstract class Access { // See if we have a resource, in case not cancel with message $link_resource = $this->connection->getConnectionResource(); - if(!is_resource($link_resource)) { + if(!$this->ldap->isResource($link_resource)) { // Seems like we didn't find any resource. // Return an empty array just like before. \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); @@ -664,11 +666,12 @@ abstract class Access { $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset); $linkResources = array_pad(array(), count($base), $link_resource); - $sr = ldap_search($linkResources, $base, $filter, $attr); - $error = ldap_errno($link_resource); + $sr = $this->ldap->search($linkResources, $base, $filter, $attr); + $error = $this->ldap->errno($link_resource); if(!is_array($sr) || $error !== 0) { \OCP\Util::writeLog('user_ldap', - 'Error when searching: '.ldap_error($link_resource).' code '.ldap_errno($link_resource), + 'Error when searching: '.$this->ldap->error($link_resource). + ' code '.$this->ldap->errno($link_resource), \OCP\Util::ERROR); \OCP\Util::writeLog('user_ldap', 'Attempt for Paging? '.print_r($pagedSearchOK, true), \OCP\Util::ERROR); return array(); @@ -677,19 +680,19 @@ abstract class Access { // Do the server-side sorting foreach(array_reverse($attr) as $sortAttr){ foreach($sr as $searchResource) { - ldap_sort($link_resource, $searchResource, $sortAttr); + $this->ldap->sort($link_resource, $searchResource, $sortAttr); } } $findings = array(); foreach($sr as $key => $res) { - $findings = array_merge($findings, ldap_get_entries($link_resource, $res )); + $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res )); } if($pagedSearchOK) { \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO); foreach($sr as $key => $res) { $cookie = null; - if(ldap_control_paged_result_response($link_resource, $res, $cookie)) { + if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) { \OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO); $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie); } @@ -1103,8 +1106,9 @@ abstract class Access { if($offset > 0) { \OCP\Util::writeLog('user_ldap', 'Cookie '.$cookie, \OCP\Util::INFO); } - $pagedSearchOK = ldap_control_paged_result($this->connection->getConnectionResource(), - $limit, false, $cookie); + $pagedSearchOK = $this->ldap->controlPagedResult( + $this->connection->getConnectionResource(), $limit, + false, $cookie); if(!$pagedSearchOK) { return false; } diff --git a/apps/user_ldap/lib/backendutility.php b/apps/user_ldap/lib/backendutility.php new file mode 100644 index 0000000000000000000000000000000000000000..815757a1a11682bb360bbb923348fe7331662d45 --- /dev/null +++ b/apps/user_ldap/lib/backendutility.php @@ -0,0 +1,38 @@ +<?php + +/** + * ownCloud – LDAP BackendUtility + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +use OCA\user_ldap\lib\Access; + +abstract class BackendUtility { + protected $access; + + /** + * @brief constructor, make sure the subclasses call this one! + * @param $access an instance of Access for LDAP interaction + */ + public function __construct(Access $access) { + $this->access = $access; + } +} diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index e5d9b4d5b40eaf99135c3333f4d87b747a165d9c..a53022c27b3231b23c5aee02a92288402e490c56 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -23,7 +23,7 @@ namespace OCA\user_ldap\lib; -class Connection { +class Connection extends LDAPUtility { private $ldapConnectionRes = null; private $configPrefix; private $configID; @@ -60,7 +60,7 @@ class Connection { 'ldapQuotaDefault' => null, 'ldapEmailAttribute' => null, 'ldapCacheTTL' => null, - 'ldapUuidAttribute' => null, + 'ldapUuidAttribute' => 'auto', 'ldapOverrideUuidAttribute' => null, 'ldapOverrideMainServer' => false, 'ldapConfigurationActive' => false, @@ -77,7 +77,8 @@ class Connection { * @param $configPrefix a string with the prefix for the configkey column (appconfig table) * @param $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections */ - public function __construct($configPrefix = '', $configID = 'user_ldap') { + public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') { + parent::__construct($ldap); $this->configPrefix = $configPrefix; $this->configID = $configID; $memcache = new \OC\Memcache\Factory(); @@ -86,13 +87,14 @@ class Connection { } else { $this->cache = \OC_Cache::getGlobalCache(); } - $this->config['hasPagedResultSupport'] = (function_exists('ldap_control_paged_result') - && function_exists('ldap_control_paged_result_response')); + $this->config['hasPagedResultSupport'] = + $this->ldap->hasPagedResultSupport(); } public function __destruct() { - if(!$this->dontDestruct && is_resource($this->ldapConnectionRes)) { - @ldap_unbind($this->ldapConnectionRes); + if(!$this->dontDestruct && + $this->ldap->isResource($this->ldapConnectionRes)) { + @$this->ldap->unbind($this->ldapConnectionRes); }; } @@ -148,7 +150,7 @@ class Connection { public function getConnectionResource() { if(!$this->ldapConnectionRes) { $this->init(); - } else if(!is_resource($this->ldapConnectionRes)) { + } else if(!$this->ldap->isResource($this->ldapConnectionRes)) { $this->ldapConnectionRes = null; $this->establishConnection(); } @@ -361,6 +363,14 @@ class Connection { && $params[$parameter] === 'homeFolderNamingRule')) && !empty($value)) { $value = 'attr:'.$value; + } else if (strpos($parameter, 'ldapBase') !== false + || (isset($params[$parameter]) + && strpos($params[$parameter], 'ldapBase') !== false)) { + $this->readBase($params[$parameter], $value); + if(is_array($setParameters)) { + $setParameters[] = $parameter; + } + continue; } if(isset($this->config[$parameter])) { $this->config[$parameter] = $value; @@ -386,7 +396,8 @@ class Connection { public function saveConfiguration() { $trans = array_flip($this->getConfigTranslationArray()); foreach($this->config as $key => $value) { - \OCP\Util::writeLog('user_ldap', 'LDAP: storing key '.$key.' value '.$value, \OCP\Util::DEBUG); + \OCP\Util::writeLog('user_ldap', 'LDAP: storing key '.$key. + ' value '.print_r($value, true), \OCP\Util::DEBUG); switch ($key) { case 'ldapAgentPassword': $value = base64_encode($value); @@ -431,8 +442,9 @@ class Connection { $config[$dbKey] = ''; } continue; - } else if((strpos($classKey, 'ldapBase') !== false) - || (strpos($classKey, 'ldapAttributes') !== false)) { + } else if((strpos($classKey, 'ldapBase') !== false + || strpos($classKey, 'ldapAttributes') !== false) + && is_array($this->config[$classKey])) { $config[$dbKey] = implode("\n", $this->config[$classKey]); continue; } @@ -551,7 +563,7 @@ class Connection { * @returns an associative array with the default values. Keys are correspond * to config-value entries in the database table */ - public function getDefaults() { + static public function getDefaults() { return array( 'ldap_host' => '', 'ldap_port' => '389', @@ -603,7 +615,7 @@ class Connection { return false; } if(!$this->ldapConnectionRes) { - if(!function_exists('ldap_connect')) { + if(!$this->ldap->areLDAPFunctionsAvailable()) { $phpLDAPinstalled = false; \OCP\Util::writeLog('user_ldap', 'function ldap_connect is not available. Make sure that the PHP ldap module is installed.', @@ -623,7 +635,8 @@ class Connection { if(!$this->config['ldapOverrideMainServer'] && !$this->getFromCache('overrideMainServer')) { $this->doConnect($this->config['ldapHost'], $this->config['ldapPort']); $bindStatus = $this->bind(); - $error = is_resource($this->ldapConnectionRes) ? ldap_errno($this->ldapConnectionRes) : -1; + $error = $this->ldap->isResource($this->ldapConnectionRes) ? + $this->ldap->errno($this->ldapConnectionRes) : -1; } else { $bindStatus = false; $error = null; @@ -653,11 +666,11 @@ class Connection { //ldap_connect ignores port paramater when URLs are passed $host .= ':' . $port; } - $this->ldapConnectionRes = ldap_connect($host, $port); - if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { - if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) { + $this->ldapConnectionRes = $this->ldap->connect($host, $port); + if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { + if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) { if($this->config['ldapTLS']) { - ldap_start_tls($this->ldapConnectionRes); + $this->ldap->startTls($this->ldapConnectionRes); } } } @@ -678,13 +691,15 @@ class Connection { $getConnectionResourceAttempt = true; $cr = $this->getConnectionResource(); $getConnectionResourceAttempt = false; - if(!is_resource($cr)) { + if(!$this->ldap->isResource($cr)) { return false; } - $ldapLogin = @ldap_bind($cr, $this->config['ldapAgentName'], $this->config['ldapAgentPassword']); + $ldapLogin = @$this->ldap->bind($cr, + $this->config['ldapAgentName'], + $this->config['ldapAgentPassword']); if(!$ldapLogin) { \OCP\Util::writeLog('user_ldap', - 'Bind failed: ' . ldap_errno($cr) . ': ' . ldap_error($cr), + 'Bind failed: ' . $this->ldap->errno($cr) . ': ' . $this->ldap->error($cr), \OCP\Util::ERROR); $this->ldapConnectionRes = null; return false; diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php new file mode 100644 index 0000000000000000000000000000000000000000..9e6bd56ef2a0920087e259030b02ce756bafdc4f --- /dev/null +++ b/apps/user_ldap/lib/ildapwrapper.php @@ -0,0 +1,180 @@ +<?php + +/** + * ownCloud – LDAP Wrapper Interface + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +interface ILDAPWrapper { + + //LDAP functions in use + + /** + * @brief Bind to LDAP directory + * @param $link LDAP link resource + * @param $dn an RDN to log in with + * @param $password the password + * @return true on success, false otherwise + * + * with $dn and $password as null a anonymous bind is attempted. + */ + public function bind($link, $dn, $password); + + /** + * @brief connect to an LDAP server + * @param $host The host to connect to + * @param $port The port to connect to + * @return a link resource on success, otherwise false + */ + public function connect($host, $port); + + /** + * @brief Send LDAP pagination control + * @param $link LDAP link resource + * @param $pagesize number of results per page + * @param $isCritical Indicates whether the pagination is critical of not. + * @param $cookie structure sent by LDAP server + * @return true on success, false otherwise + */ + public function controlPagedResult($link, $pagesize, $isCritical, $cookie); + + /** + * @brief Retrieve the LDAP pagination cookie + * @param $link LDAP link resource + * @param $result LDAP result resource + * @param $cookie structure sent by LDAP server + * @return true on success, false otherwise + * + * Corresponds to ldap_control_paged_result_response + */ + public function controlPagedResultResponse($link, $result, &$cookie); + + /** + * @brief Return the LDAP error number of the last LDAP command + * @param $link LDAP link resource + * @return error message as string + */ + public function errno($link); + + /** + * @brief Return the LDAP error message of the last LDAP command + * @param $link LDAP link resource + * @return error code as integer + */ + public function error($link); + + /** + * @brief Return first result id + * @param $link LDAP link resource + * @param $result LDAP result resource + * @return an LDAP search result resource + * */ + public function firstEntry($link, $result); + + /** + * @brief Get attributes from a search result entry + * @param $link LDAP link resource + * @param $result LDAP result resource + * @return array containing the results, false on error + * */ + public function getAttributes($link, $result); + + /** + * @brief Get all result entries + * @param $link LDAP link resource + * @param $result LDAP result resource + * @return array containing the results, false on error + */ + public function getEntries($link, $result); + + /** + * @brief Read an entry + * @param $link LDAP link resource + * @param $baseDN The DN of the entry to read from + * @param $filter An LDAP filter + * @param $attr array of the attributes to read + * @return an LDAP search result resource + */ + public function read($link, $baseDN, $filter, $attr); + + /** + * @brief Search LDAP tree + * @param $link LDAP link resource + * @param $baseDN The DN of the entry to read from + * @param $filter An LDAP filter + * @param $attr array of the attributes to read + * @return an LDAP search result resource, false on error + */ + public function search($link, $baseDN, $filter, $attr); + + /** + * @brief Sets the value of the specified option to be $value + * @param $link LDAP link resource + * @param $option a defined LDAP Server option + * @param $value the new value for the option + * @return true on success, false otherwise + */ + public function setOption($link, $option, $value); + + /** + * @brief establish Start TLS + * @param $link LDAP link resource + * @return true on success, false otherwise + */ + public function startTls($link); + + /** + * @brief Sort the result of a LDAP search + * @param $link LDAP link resource + * @param $result LDAP result resource + * @param $sortfilter attribute to use a key in sort + */ + public function sort($link, $result, $sortfilter); + + /** + * @brief Unbind from LDAP directory + * @param $link LDAP link resource + * @return true on success, false otherwise + */ + public function unbind($link); + + //additional required methods in owncloud + + /** + * @brief Checks whether the server supports LDAP + * @return true if it the case, false otherwise + * */ + public function areLDAPFunctionsAvailable(); + + /** + * @brief Checks whether PHP supports LDAP Paged Results + * @return true if it the case, false otherwise + * */ + public function hasPagedResultSupport(); + + /** + * @brief Checks whether the submitted parameter is a resource + * @param $resource the resource variable to check + * @return true if it is a resource, false otherwise + */ + public function isResource($resource); + +} diff --git a/apps/user_ldap/lib/jobs.php b/apps/user_ldap/lib/jobs.php index 6b7666d4ca1752ee869221fb41ff03ee9998832e..2f90da3bfb617e082e44e6d2a6db5707519cabe9 100644 --- a/apps/user_ldap/lib/jobs.php +++ b/apps/user_ldap/lib/jobs.php @@ -139,13 +139,14 @@ class Jobs extends \OC\BackgroundJob\TimedJob { return self::$groupBE; } $configPrefixes = Helper::getServerConfigurationPrefixes(true); - if(count($configPrefixes) == 1) { + $ldapWrapper = new OCA\user_ldap\lib\LDAP(); + if(count($configPrefixes) === 1) { //avoid the proxy when there is only one LDAP server configured - $connector = new Connection($configPrefixes[0]); - self::$groupBE = new \OCA\user_ldap\GROUP_LDAP(); - self::$groupBE->setConnector($connector); + $connector = new OCA\user_ldap\lib\Connection($ldapWrapper, $configPrefixes[0]); + $ldapAccess = new OCA\user_ldap\lib\Access($connector, $ldapWrapper); + self::$groupBE = new OCA\user_ldap\GROUP_LDAP($ldapAccess); } else { - self::$groupBE = new \OCA\user_ldap\Group_Proxy($configPrefixes); + self::$groupBE = new \OCA\user_ldap\Group_Proxy($configPrefixes, $ldapWrapper); } return self::$groupBE; diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php new file mode 100644 index 0000000000000000000000000000000000000000..b63e969912a129515f7f5977e3c1b613229f5c2e --- /dev/null +++ b/apps/user_ldap/lib/ldap.php @@ -0,0 +1,167 @@ +<?php + +/** + * ownCloud – LDAP Wrapper + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class LDAP implements ILDAPWrapper { + protected $curFunc = ''; + protected $curArgs = array(); + + public function bind($link, $dn, $password) { + return $this->invokeLDAPMethod('bind', $link, $dn, $password); + } + + public function connect($host, $port) { + return $this->invokeLDAPMethod('connect', $host, $port); + } + + public function controlPagedResultResponse($link, $result, &$cookie) { + $this->preFunctionCall('ldap_control_paged_result_response', + array($link, $result, $cookie)); + $result = ldap_control_paged_result_response($link, $result, $cookie); + $this->postFunctionCall(); + + return $result; + } + + public function controlPagedResult($link, $pagesize, $isCritical, $cookie) { + return $this->invokeLDAPMethod('control_paged_result', $link, $pagesize, + $isCritical, $cookie); + } + + public function errno($link) { + return $this->invokeLDAPMethod('errno', $link); + } + + public function error($link) { + return $this->invokeLDAPMethod('error', $link); + } + + public function firstEntry($link, $result) { + return $this->invokeLDAPMethod('first_entry', $link, $result); + } + + public function getAttributes($link, $result) { + return $this->invokeLDAPMethod('get_attributes', $link, $result); + } + + public function getEntries($link, $result) { + return $this->invokeLDAPMethod('get_entries', $link, $result); + } + + public function read($link, $baseDN, $filter, $attr) { + return $this->invokeLDAPMethod('read', $link, $baseDN, $filter, $attr); + } + + public function search($link, $baseDN, $filter, $attr) { + return $this->invokeLDAPMethod('search', $link, $baseDN, + $filter, $attr); + } + + public function setOption($link, $option, $value) { + $this->invokeLDAPMethod('set_option', $link, $option, $value); + } + + public function sort($link, $result, $sortfilter) { + return $this->invokeLDAPMethod('sort', $link, $result, $sortfilter); + } + + public function startTls($link) { + return $this->invokeLDAPMethod('start_tls', $link); + } + + public function unbind($link) { + return $this->invokeLDAPMethod('unbind', $link); + } + + /** + * @brief Checks whether the server supports LDAP + * @return true if it the case, false otherwise + * */ + public function areLDAPFunctionsAvailable() { + return function_exists('ldap_connect'); + } + + /** + * @brief Checks whether PHP supports LDAP Paged Results + * @return true if it the case, false otherwise + * */ + public function hasPagedResultSupport() { + $hasSupport = function_exists('ldap_control_paged_result') + && function_exists('ldap_control_paged_result_response'); + return $hasSupport; + } + + /** + * @brief Checks whether the submitted parameter is a resource + * @param $resource the resource variable to check + * @return true if it is a resource, false otherwise + */ + public function isResource($resource) { + return is_resource($resource); + } + + private function invokeLDAPMethod() { + $arguments = func_get_args(); + $func = 'ldap_' . array_shift($arguments); + if(function_exists($func)) { + $this->preFunctionCall($func, $arguments); + $result = call_user_func_array($func, $arguments); + $this->postFunctionCall(); + return $result; + } + } + + private function preFunctionCall($functionName, $args) { + $this->curFunc = $functionName; + $this->curArgs = $args; + } + + private function postFunctionCall() { + if($this->isResource($this->curArgs[0])) { + $errorCode = ldap_errno($this->curArgs[0]); + $errorMsg = ldap_error($this->curArgs[0]); + if($errorCode !== 0) { + if($this->curFunc === 'ldap_sort' && $errorCode === -4) { + //You can safely ignore that decoding error. + //… says https://bugs.php.net/bug.php?id=18023 + } else if($this->curFunc === 'ldap_get_entries' + && $errorCode === -4) { + } else if ($errorCode === 32) { + //for now + } else if ($errorCode === 10) { + //referrals, we switch them off, but then there is AD :) + } else { + \OCP\Util::writeLog('user_ldap', + 'LDAP error '.$errorMsg.' (' . + $errorCode.') after calling '. + $this->curFunc, + \OCP\Util::DEBUG); + } + } + } + + $this->curFunc = ''; + $this->curArgs = array(); + } +} \ No newline at end of file diff --git a/apps/user_ldap/lib/ldaputility.php b/apps/user_ldap/lib/ldaputility.php new file mode 100644 index 0000000000000000000000000000000000000000..7fffd9c88d18c1efe5cdd97624738594b830bceb --- /dev/null +++ b/apps/user_ldap/lib/ldaputility.php @@ -0,0 +1,36 @@ +<?php + +/** + * ownCloud – LDAP LDAPUtility + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +abstract class LDAPUtility { + protected $ldap; + + /** + * @brief constructor, make sure the subclasses call this one! + * @param $ldapWrapper an instance of an ILDAPWrapper + */ + public function __construct(ILDAPWrapper $ldapWrapper) { + $this->ldap = $ldapWrapper; + } +} diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php index ae3e3be73611e355c3b16dfca5d0662e537424e3..c74b357bdd2fa77fdb564878fe31d9f6e6b4cac0 100644 --- a/apps/user_ldap/lib/proxy.php +++ b/apps/user_ldap/lib/proxy.php @@ -23,26 +23,27 @@ namespace OCA\user_ldap\lib; +use OCA\user_ldap\lib\Access; + abstract class Proxy { - static private $connectors = array(); + static private $accesses = array(); + private $ldap = null; - public function __construct() { + public function __construct(ILDAPWrapper $ldap) { + $this->ldap = $ldap; $this->cache = \OC_Cache::getGlobalCache(); } - private function addConnector($configPrefix) { - self::$connectors[$configPrefix] = new \OCA\user_ldap\lib\Connection($configPrefix); + private function addAccess($configPrefix) { + $connector = new Connection($this->ldap, $configPrefix); + self::$accesses[$configPrefix] = new Access($connector, $this->ldap); } - protected function getConnector($configPrefix) { - if(!isset(self::$connectors[$configPrefix])) { - $this->addConnector($configPrefix); + protected function getAccess($configPrefix) { + if(!isset(self::$accesses[$configPrefix])) { + $this->addAccess($configPrefix); } - return self::$connectors[$configPrefix]; - } - - protected function getConnectors() { - return self::$connectors; + return self::$accesses[$configPrefix]; } protected function getUserCacheKey($uid) { diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index 7169192a18e4a94e4eb3d087e594577aed43a8e5..b7070f23183b00b2c5cd73fe6d62b21ae7f2652f 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -49,14 +49,9 @@ $tmpl->assign('serverConfigurationPrefixes', $prefixes); $tmpl->assign('serverConfigurationHosts', $hosts); // assign default values -if(!isset($ldap)) { - $ldap = new \OCA\user_ldap\lib\Connection(); -} -$defaults = $ldap->getDefaults(); +$defaults = \OCA\user_ldap\lib\Connection::getDefaults(); foreach($defaults as $key => $default) { $tmpl->assign($key.'_default', $default); } -// $tmpl->assign(); - return $tmpl->fetchPage(); diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php deleted file mode 100644 index ae635597b71fcd15de2fa6b707e58fead4f3fc00..0000000000000000000000000000000000000000 --- a/apps/user_ldap/tests/group_ldap.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** -* ownCloud -* -* @author Arthur Schiwon -* @copyright 2012 Arthur Schiwon blizzz@owncloud.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -class Test_Group_Ldap extends PHPUnit_Framework_TestCase { - function setUp() { - OC_Group::clearBackends(); - } - - function testSingleBackend() { - OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP()); - $group_ldap = new OCA\user_ldap\GROUP_LDAP(); - - $this->assertIsA(OC_Group::getGroups(), gettype(array())); - $this->assertIsA($group_ldap->getGroups(), gettype(array())); - - $this->assertFalse(OC_Group::inGroup('john', 'dosers'), gettype(false)); - $this->assertFalse($group_ldap->inGroup('john', 'dosers'), gettype(false)); - //TODO: check also for expected true result. This backend won't be able to do any modifications, maybe use a dummy for this. - - $this->assertIsA(OC_Group::getUserGroups('john doe'), gettype(array())); - $this->assertIsA($group_ldap->getUserGroups('john doe'), gettype(array())); - - $this->assertIsA(OC_Group::usersInGroup('campers'), gettype(array())); - $this->assertIsA($group_ldap->usersInGroup('campers'), gettype(array())); - } - -} diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php new file mode 100644 index 0000000000000000000000000000000000000000..6b9b8b3e18503162fcfc90638c5b09250df6b126 --- /dev/null +++ b/apps/user_ldap/tests/user_ldap.php @@ -0,0 +1,411 @@ +<?php +/** +* ownCloud +* +* @author Arthur Schiwon +* @copyright 2013 Arthur Schiwon blizzz@owncloud.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +namespace OCA\user_ldap\tests; + +use \OCA\user_ldap\USER_LDAP as UserLDAP; +use \OCA\user_ldap\lib\Access; +use \OCA\user_ldap\lib\Connection; +use \OCA\user_ldap\lib\ILDAPWrapper; + +class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { + protected $backend; + + public function setUp() { + \OC_User::clearBackends(); + \OC_Group::clearBackends(); + } + + private function getAccessMock() { + static $conMethods; + static $accMethods; + + if(is_null($conMethods) || is_null($accMethods)) { + $conMethods = get_class_methods('\OCA\user_ldap\lib\Connection'); + $accMethods = get_class_methods('\OCA\user_ldap\lib\Access'); + } + $lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); + $connector = $this->getMock('\OCA\user_ldap\lib\Connection', + $conMethods, + array($lw, null, null)); + $access = $this->getMock('\OCA\user_ldap\lib\Access', + $accMethods, + array($connector, $lw)); + + return $access; + } + + private function prepareMockForUserExists(&$access) { + $access->expects($this->any()) + ->method('username2dn') + ->will($this->returnCallback(function($uid) { + switch ($uid) { + case 'gunslinger': + return 'dnOfRoland'; + break; + case 'formerUser': + return 'dnOfFormerUser'; + break; + case 'newyorker': + return 'dnOfNewYorker'; + break; + case 'ladyofshadows': + return 'dnOfLadyOfShadows'; + break; + defautl: + return false; + } + })); + } + + /** + * @brief Prepares the Access mock for checkPassword tests + * @param $access mock of \OCA\user_ldap\lib\Access + * @return void + */ + private function prepareAccessForCheckPassword(&$access) { + $access->connection->expects($this->any()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return '%uid'; + } + return null; + })); + + $access->expects($this->any()) + ->method('fetchListOfUsers') + ->will($this->returnCallback(function($filter) { + if($filter === 'roland') { + return array('dnOfRoland'); + } + return array(); + })); + + $access->expects($this->any()) + ->method('dn2username') + ->with($this->equalTo('dnOfRoland')) + ->will($this->returnValue('gunslinger')); + + $access->expects($this->any()) + ->method('areCredentialsValid') + ->will($this->returnCallback(function($dn, $pwd) { + if($pwd === 'dt19') { + return true; + } + return false; + })); + } + + public function testCheckPassword() { + $access = $this->getAccessMock(); + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); + + $result = $backend->checkPassword('roland', 'dt19'); + $this->assertEquals('gunslinger', $result); + + $result = $backend->checkPassword('roland', 'wrong'); + $this->assertFalse($result); + + $result = $backend->checkPassword('mallory', 'evil'); + $this->assertFalse($result); + } + + public function testCheckPasswordPublicAPI() { + $access = $this->getAccessMock(); + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); + + $result = \OCP\User::checkPassword('roland', 'dt19'); + $this->assertEquals('gunslinger', $result); + + $result = \OCP\User::checkPassword('roland', 'wrong'); + $this->assertFalse($result); + + $result = \OCP\User::checkPassword('mallory', 'evil'); + $this->assertFalse($result); + } + + /** + * @brief Prepares the Access mock for getUsers tests + * @param $access mock of \OCA\user_ldap\lib\Access + * @return void + */ + private function prepareAccessForGetUsers(&$access) { + $access->expects($this->any()) + ->method('getFilterPartForUserSearch') + ->will($this->returnCallback(function($search) { + return $search; + })); + + $access->expects($this->any()) + ->method('combineFilterWithAnd') + ->will($this->returnCallback(function($param) { + return $param[1]; + })); + + $access->expects($this->any()) + ->method('fetchListOfUsers') + ->will($this->returnCallback(function($search, $a, $l, $o) { + $users = array('gunslinger', 'newyorker', 'ladyofshadows'); + if(empty($search)) { + $result = $users; + } else { + $result = array(); + foreach($users as $user) { + if(stripos($user, $search) !== false) { + $result[] = $user; + } + } + } + if(!is_null($l) || !is_null($o)) { + $result = array_slice($result, $o, $l); + } + return $result; + })); + + $access->expects($this->any()) + ->method('ownCloudUserNames') + ->will($this->returnArgument(0)); + } + + public function testGetUsers() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + + $result = $backend->getUsers(); + $this->assertEquals(3, count($result)); + + $result = $backend->getUsers('', 1, 2); + $this->assertEquals(1, count($result)); + + $result = $backend->getUsers('', 2, 1); + $this->assertEquals(2, count($result)); + + $result = $backend->getUsers('yo'); + $this->assertEquals(2, count($result)); + + $result = $backend->getUsers('nix'); + $this->assertEquals(0, count($result)); + } + + public function testGetUsersViaAPI() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); + + $result = \OCP\User::getUsers(); + $this->assertEquals(3, count($result)); + + $result = \OCP\User::getUsers('', 1, 2); + $this->assertEquals(1, count($result)); + + $result = \OCP\User::getUsers('', 2, 1); + $this->assertEquals(2, count($result)); + + $result = \OCP\User::getUsers('yo'); + $this->assertEquals(2, count($result)); + + $result = \OCP\User::getUsers('nix'); + $this->assertEquals(0, count($result)); + } + + public function testUserExists() { + $access = $this->getAccessMock(); + $backend = new UserLDAP($access); + $this->prepareMockForUserExists($access); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn) { + if($dn === 'dnOfRoland') { + return array(); + } + return false; + })); + + //test for existing user + $result = $backend->userExists('gunslinger'); + $this->assertTrue($result); + + //test for deleted user + $result = $backend->userExists('formerUser'); + $this->assertFalse($result); + + //test for never-existing user + $result = $backend->userExists('mallory'); + $this->assertFalse($result); + } + + public function testUserExistsPublicAPI() { + $access = $this->getAccessMock(); + $backend = new UserLDAP($access); + $this->prepareMockForUserExists($access); + \OC_User::useBackend($backend); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn) { + if($dn === 'dnOfRoland') { + return array(); + } + return false; + })); + + //test for existing user + $result = \OCP\User::userExists('gunslinger'); + $this->assertTrue($result); + + //test for deleted user + $result = \OCP\User::userExists('formerUser'); + $this->assertFalse($result); + + //test for never-existing user + $result = \OCP\User::userExists('mallory'); + $this->assertFalse($result); + } + + public function testDeleteUser() { + $access = $this->getAccessMock(); + $backend = new UserLDAP($access); + + //we do not support deleting users at all + $result = $backend->deleteUser('gunslinger'); + $this->assertFalse($result); + } + + public function testGetHome() { + $access = $this->getAccessMock(); + $backend = new UserLDAP($access); + $this->prepareMockForUserExists($access); + + $access->connection->expects($this->any()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'homeFolderNamingRule') { + return 'attr:testAttribute'; + } + return null; + })); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn, $attr) { + switch ($dn) { + case 'dnOfRoland': + if($attr === 'testAttribute') { + return array('/tmp/rolandshome/'); + } + return array(); + break; + case 'dnOfLadyOfShadows': + if($attr === 'testAttribute') { + return array('susannah/'); + } + return array(); + break; + default: + return false; + } + })); + + //absolut path + $result = $backend->getHome('gunslinger'); + $this->assertEquals('/tmp/rolandshome/', $result); + + //datadir-relativ path + $result = $backend->getHome('ladyofshadows'); + $datadir = \OCP\Config::getSystemValue('datadirectory', + \OC::$SERVERROOT.'/data'); + $this->assertEquals($datadir.'/susannah/', $result); + + //no path at all – triggers OC default behaviour + $result = $backend->getHome('newyorker'); + $this->assertFalse($result); + } + + private function prepareAccessForGetDisplayName(&$access) { + $access->connection->expects($this->any()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapUserDisplayName') { + return 'displayname'; + } + return null; + })); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn, $attr) { + switch ($dn) { + case 'dnOfRoland': + if($attr === 'displayname') { + return array('Roland Deschain'); + } + return array(); + break; + + default: + return false; + } + })); + } + + public function testGetDisplayName() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetDisplayName($access); + $backend = new UserLDAP($access); + $this->prepareMockForUserExists($access); + + //with displayName + $result = $backend->getDisplayName('gunslinger'); + $this->assertEquals('Roland Deschain', $result); + + //empty displayname retrieved + $result = $backend->getDisplayName('newyorker'); + $this->assertEquals(null, $result); + } + + public function testGetDisplayNamePublicAPI() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetDisplayName($access); + $backend = new UserLDAP($access); + $this->prepareMockForUserExists($access); + \OC_User::useBackend($backend); + + //with displayName + $result = \OCP\User::getDisplayName('gunslinger'); + $this->assertEquals('Roland Deschain', $result); + + //empty displayname retrieved + $result = \OCP\User::getDisplayName('newyorker'); + $this->assertEquals('newyorker', $result); + } + + //no test for getDisplayNames, because it just invokes getUsers and + //getDisplayName +} \ No newline at end of file diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 850ca0df99546d339203931242aefe0df324337a..6f52bbdf233b3c85b5ad0b9617073640f7cba9d5 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -25,37 +25,46 @@ namespace OCA\user_ldap; -class USER_LDAP extends lib\Access implements \OCP\UserInterface { +use OCA\user_ldap\lib\ILDAPWrapper; +use OCA\user_ldap\lib\BackendUtility; + +class USER_LDAP extends BackendUtility implements \OCP\UserInterface { private function updateQuota($dn) { $quota = null; - $quotaDefault = $this->connection->ldapQuotaDefault; - $quotaAttribute = $this->connection->ldapQuotaAttribute; + $quotaDefault = $this->access->connection->ldapQuotaDefault; + $quotaAttribute = $this->access->connection->ldapQuotaAttribute; if(!empty($quotaDefault)) { $quota = $quotaDefault; } if(!empty($quotaAttribute)) { - $aQuota = $this->readAttribute($dn, $quotaAttribute); + $aQuota = $this->access->readAttribute($dn, $quotaAttribute); if($aQuota && (count($aQuota) > 0)) { $quota = $aQuota[0]; } } if(!is_null($quota)) { - \OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota)); + \OCP\Config::setUserValue( $this->access->dn2username($dn), + 'files', + 'quota', + \OCP\Util::computerFileSize($quota)); } } private function updateEmail($dn) { $email = null; - $emailAttribute = $this->connection->ldapEmailAttribute; + $emailAttribute = $this->access->connection->ldapEmailAttribute; if(!empty($emailAttribute)) { - $aEmail = $this->readAttribute($dn, $emailAttribute); + $aEmail = $this->access->readAttribute($dn, $emailAttribute); if($aEmail && (count($aEmail) > 0)) { $email = $aEmail[0]; } if(!is_null($email)) { - \OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email); + \OCP\Config::setUserValue( $this->access->dn2username($dn), + 'settings', + 'email', + $email); } } } @@ -70,15 +79,16 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { */ public function checkPassword($uid, $password) { //find out dn of the user name - $filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8'); - $ldap_users = $this->fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace( + '%uid', $uid, $this->access->connection->ldapLoginFilter, 'UTF-8'); + $ldap_users = $this->access->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { return false; } $dn = $ldap_users[0]; //do we have a username for him/her? - $ocname = $this->dn2username($dn); + $ocname = $this->access->dn2username($dn); if($ocname) { //update some settings, if necessary @@ -86,7 +96,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { $this->updateEmail($dn); //are the credentials OK? - if(!$this->areCredentialsValid($dn, $password)) { + if(!$this->access->areCredentialsValid($dn, $password)) { return false; } @@ -107,7 +117,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset; //check if users are cached, if so return - $ldap_users = $this->connection->getFromCache($cachekey); + $ldap_users = $this->access->connection->getFromCache($cachekey); if(!is_null($ldap_users)) { return $ldap_users; } @@ -117,21 +127,23 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { if($limit <= 0) { $limit = null; } - $filter = $this->combineFilterWithAnd(array( - $this->connection->ldapUserFilter, - $this->getFilterPartForUserSearch($search) + $filter = $this->access->combineFilterWithAnd(array( + $this->access->connection->ldapUserFilter, + $this->access->getFilterPartForUserSearch($search) )); \OCP\Util::writeLog('user_ldap', 'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter, \OCP\Util::DEBUG); //do the search and translate results to owncloud names - $ldap_users = $this->fetchListOfUsers($filter, array($this->connection->ldapUserDisplayName, 'dn'), + $ldap_users = $this->access->fetchListOfUsers( + $filter, + array($this->access->connection->ldapUserDisplayName, 'dn'), $limit, $offset); - $ldap_users = $this->ownCloudUserNames($ldap_users); + $ldap_users = $this->access->ownCloudUserNames($ldap_users); \OCP\Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', \OCP\Util::DEBUG); - $this->connection->writeToCache($cachekey, $ldap_users); + $this->access->connection->writeToCache($cachekey, $ldap_users); return $ldap_users; } @@ -141,24 +153,25 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { * @return boolean */ public function userExists($uid) { - if($this->connection->isCached('userExists'.$uid)) { - return $this->connection->getFromCache('userExists'.$uid); + if($this->access->connection->isCached('userExists'.$uid)) { + return $this->access->connection->getFromCache('userExists'.$uid); } - //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking. - $dn = $this->username2dn($uid); + $dn = $this->access->username2dn($uid); if(!$dn) { - $this->connection->writeToCache('userExists'.$uid, false); + \OCP\Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '. + $this->access->connection->ldapHost, \OCP\Util::DEBUG); + $this->access->connection->writeToCache('userExists'.$uid, false); return false; } - //check if user really still exists by reading its entry - if(!is_array($this->readAttribute($dn, ''))) { - $this->connection->writeToCache('userExists'.$uid, false); + if(!is_array($this->access->readAttribute($dn, ''))) { + \OCP\Util::writeLog('user_ldap', 'LDAP says no user '.$dn, \OCP\Util::DEBUG); + $this->access->connection->writeToCache('userExists'.$uid, false); return false; } - $this->connection->writeToCache('userExists'.$uid, true); + $this->access->connection->writeToCache('userExists'.$uid, true); $this->updateQuota($dn); return true; } @@ -186,12 +199,13 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { } $cacheKey = 'getHome'.$uid; - if($this->connection->isCached($cacheKey)) { - return $this->connection->getFromCache($cacheKey); + if($this->access->connection->isCached($cacheKey)) { + return $this->access->connection->getFromCache($cacheKey); } - if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) { - $attr = substr($this->connection->homeFolderNamingRule, strlen('attr:')); - $homedir = $this->readAttribute($this->username2dn($uid), $attr); + if(strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0) { + $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:')); + $homedir = $this->access->readAttribute( + $this->access->username2dn($uid), $attr); if($homedir && isset($homedir[0])) { $path = $homedir[0]; //if attribute's value is an absolute path take this, otherwise append it to data dir @@ -206,13 +220,13 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { $homedir = \OCP\Config::getSystemValue('datadirectory', \OC::$SERVERROOT.'/data' ) . '/' . $homedir[0]; } - $this->connection->writeToCache($cacheKey, $homedir); + $this->access->connection->writeToCache($cacheKey, $homedir); return $homedir; } } //false will apply default behaviour as defined and done by OC_User - $this->connection->writeToCache($cacheKey, false); + $this->access->connection->writeToCache($cacheKey, false); return false; } @@ -227,16 +241,16 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { } $cacheKey = 'getDisplayName'.$uid; - if(!is_null($displayName = $this->connection->getFromCache($cacheKey))) { + if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) { return $displayName; } - $displayName = $this->readAttribute( - $this->username2dn($uid), - $this->connection->ldapUserDisplayName); + $displayName = $this->access->readAttribute( + $this->access->username2dn($uid), + $this->access->connection->ldapUserDisplayName); if($displayName && (count($displayName) > 0)) { - $this->connection->writeToCache($cacheKey, $displayName[0]); + $this->access->connection->writeToCache($cacheKey, $displayName[0]); return $displayName[0]; } @@ -251,7 +265,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { */ public function getDisplayNames($search = '', $limit = null, $offset = null) { $cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset; - if(!is_null($displayNames = $this->connection->getFromCache($cacheKey))) { + if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) { return $displayNames; } @@ -260,7 +274,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { foreach ($users as $user) { $displayNames[$user] = $this->getDisplayName($user); } - $this->connection->writeToCache($cacheKey, $displayNames); + $this->access->connection->writeToCache($cacheKey, $displayNames); return $displayNames; } diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php index 0722d8871a42ce06eb097b7a6f4fe403d200ad17..092fdbf7c782c55d8b2f1d4417e8ef7f397abc8e 100644 --- a/apps/user_ldap/user_proxy.php +++ b/apps/user_ldap/user_proxy.php @@ -23,6 +23,8 @@ namespace OCA\user_ldap; +use OCA\user_ldap\lib\ILDAPWrapper; + class User_Proxy extends lib\Proxy implements \OCP\UserInterface { private $backends = array(); private $refBackend = null; @@ -31,12 +33,11 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { * @brief Constructor * @param $serverConfigPrefixes array containing the config Prefixes */ - public function __construct($serverConfigPrefixes) { - parent::__construct(); + public function __construct($serverConfigPrefixes, ILDAPWrapper $ldap) { + parent::__construct($ldap); foreach($serverConfigPrefixes as $configPrefix) { - $this->backends[$configPrefix] = new \OCA\user_ldap\USER_LDAP(); - $connector = $this->getConnector($configPrefix); - $this->backends[$configPrefix]->setConnector($connector); + $this->backends[$configPrefix] = + new \OCA\user_ldap\USER_LDAP($this->getAccess($configPrefix)); if(is_null($this->refBackend)) { $this->refBackend = &$this->backends[$configPrefix]; } diff --git a/apps/user_webdavauth/l10n/hu_HU.php b/apps/user_webdavauth/l10n/hu_HU.php index 63fc084ff4cf7f2a73754d3f960d3db8f8eb9cdc..0b946e25e70fa212f198c9076bb835c42b1c02a0 100644 --- a/apps/user_webdavauth/l10n/hu_HU.php +++ b/apps/user_webdavauth/l10n/hu_HU.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "WebDAV hitelesítés" +"WebDAV Authentication" => "WebDAV hitelesítés", +"Address: " => "Címek:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "A felhasználói hitelesítő adatai el lesznek küldve erre a címre. Ez a bővítőmodul leellenőrzi a választ és ha a HTTP hibakód nem 401 vagy 403 azaz érvénytelen a hitelesítő adat, akkor minden más válasz érvényes lesz." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/autotest.sh b/autotest.sh index 83f184fa9c065fa12088d700536b4405d4b57182..3831e1812451577c1a020be83c90926743b2ba83 100755 --- a/autotest.sh +++ b/autotest.sh @@ -12,6 +12,16 @@ DATABASEUSER=oc_autotest$EXECUTOR_NUMBER ADMINLOGIN=admin$EXECUTOR_NUMBER BASEDIR=$PWD +if ! [ -w config -a -w config/config.php ]; then + echo "Please enable write permissions on config and config/config.php" >&2 + exit 1 +fi + +# Back up existing (dev) config if one exists +if [ -f config/config.php ]; then + mv config/config.php config/config-autotest-backup.php +fi + # use tmpfs for datadir - should speedup unit test execution if [ -d /dev/shm ]; then DATADIR=/dev/shm/data-autotest$EXECUTOR_NUMBER @@ -158,6 +168,13 @@ else execute_tests $1 $2 $3 fi +cd $BASEDIR + +# Restore existing config +if [ -f config/config-autotest-backup.php ]; then + mv config/config-autotest-backup.php config/config.php +fi + # # NOTES on mysql: # - CREATE DATABASE oc_autotest; diff --git a/core/ajax/share.php b/core/ajax/share.php index 648f0a71bd44da7c93fbaccb88388c7db92aac99..ed9cbfd109a3513a4b744252a19c2394939141ca 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -23,6 +23,8 @@ OC_JSON::checkLoggedIn(); OCP\JSON::callCheck(); OC_App::loadApps(); +$defaults = new \OCP\Defaults(); + if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSource'])) { switch ($_POST['action']) { case 'share': @@ -33,7 +35,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo if ($shareType === OCP\Share::SHARE_TYPE_LINK && $shareWith == '') { $shareWith = null; } - + $token = OCP\Share::shareItem( $_POST['itemType'], $_POST['itemSource'], @@ -41,7 +43,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo $shareWith, $_POST['permissions'] ); - + if (is_string($token)) { OC_JSON::success(array('data' => array('token' => $token))); } else { @@ -81,6 +83,104 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo ($return) ? OC_JSON::success() : OC_JSON::error(); } break; + case 'informRecipients': + + $l = OC_L10N::get('core'); + + $shareType = (int) $_POST['shareType']; + $itemType = $_POST['itemType']; + $itemSource = $_POST['itemSource']; + $recipient = $_POST['recipient']; + $ownerDisplayName = \OCP\User::getDisplayName(); + $from = \OCP\Util::getDefaultEmailAddress('sharing-noreply'); + + $noMail = array(); + $recipientList = array(); + + if($shareType === \OCP\Share::SHARE_TYPE_USER) { + $recipientList[] = $recipient; + } elseif ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { + $recipientList = \OC_Group::usersInGroup($recipient); + } + + // don't send a mail to the user who shared the file + $recipientList = array_diff($recipientList, [\OCP\User::getUser()]); + + // send mail to all recipients with an email address + foreach ($recipientList as $recipient) { + //get correct target folder name + $email = OC_Preferences::getValue($recipient, 'settings', 'email', ''); + + if ($email !== '') { + $displayName = \OCP\User::getDisplayName($recipient); + $items = \OCP\Share::getItemSharedWithUser($itemType, $itemSource, $recipient); + $filename = trim($items[0]['file_target'], '/'); + $subject = (string)$l->t('%s shared »%s« with you', array($ownerDisplayName, $filename)); + $expiration = null; + if (isset($items[0]['expiration'])) { + $date = new DateTime($items[0]['expiration']); + $expiration = $date->format('Y-m-d'); + } + + if ($itemType === 'folder') { + $foldername = "/Shared/" . $filename; + } else { + // if it is a file we can just link to the Shared folder, + // that's the place where the user will find the file + $foldername = "/Shared"; + } + + $link = \OCP\Util::linkToAbsolute('files', 'index.php', array("dir" => $foldername)); + + $content = new OC_Template("core", "mail", ""); + $content->assign('link', $link); + $content->assign('user_displayname', $ownerDisplayName); + $content->assign('filename', $filename); + $content->assign('expiration', $expiration); + $text = $content->fetchPage(); + + $content = new OC_Template("core", "altmail", ""); + $content->assign('link', $link); + $content->assign('user_displayname', $ownerDisplayName); + $content->assign('filename', $filename); + $content->assign('expiration', $expiration); + $alttext = $content->fetchPage(); + + $default_from = OCP\Util::getDefaultEmailAddress('sharing-noreply'); + $from = OCP\Config::getUserValue(\OCP\User::getUser(), 'settings', 'email', $default_from); + + // send it out now + try { + OCP\Util::sendMail($email, $displayName, $subject, $text, $from, $ownerDisplayName, 1, $alttext); + } catch (Exception $exception) { + $noMail[] = \OCP\User::getDisplayName($recipient); + } + } + } + + \OCP\Share::setSendMailStatus($itemType, $itemSource, $shareType, true); + + if (empty($noMail)) { + OCP\JSON::success(); + } else { + OCP\JSON::error(array( + 'data' => array( + 'message' => $l->t("Couldn't send mail to following users: %s ", + implode(', ', $noMail) + ) + ) + )); + } + break; + case 'informRecipientsDisabled': + $itemSource = $_POST['itemSource']; + $shareType = $_POST['shareType']; + $itemType = $_POST['itemType']; + $recipient = $_POST['recipient']; + \OCP\Share::setSendMailStatus($itemType, $itemSource, $shareType, false); + OCP\JSON::success(); + break; + case 'email': // read post variables $user = OCP\USER::getUser(); @@ -213,10 +313,10 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo } } $count = 0; - + // enable l10n support $l = OC_L10N::get('core'); - + foreach ($groups as $group) { if ($count < 15) { if (!isset($_GET['itemShares']) diff --git a/core/css/share.css b/core/css/share.css index 2d6849b4bb1361b1978906716ce0974fd7d1c643..2a21dc6edf66d1143febbb1db50ce217a44f8a96 100644 --- a/core/css/share.css +++ b/core/css/share.css @@ -2,95 +2,97 @@ This file is licensed under the Affero General Public License version 3 or later. See the COPYING-README file. */ - #dropdown { - background:#eee; - border-bottom-left-radius:1em; - border-bottom-right-radius:1em; - box-shadow:0 1px 1px #777; - display:block; - margin-right:7em; - position:absolute; - right:0; - width:19em; - z-index:500; - padding:1em; - } - - #shareWithList { - list-style-type:none; - padding:.5em; - } - - #shareWithList li { - padding-top:.1em; - } - - #shareWithList li:first-child { - white-space:normal; - } - - #shareWithList .cruds { - margin-left:-10px; - } +#dropdown { + background:#eee; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + box-shadow:0 1px 1px #777; + display:block; + margin-right:7em; + position:absolute; + right:0; + width:25em; + z-index:500; + padding:1em; +} + +#shareWithList { + list-style-type:none; + padding:.5em; +} + +#shareWithList li { + padding-top:.1em; +} + +#shareWithList li:first-child { + white-space:normal; +} + +#shareWithList .cruds { + margin-left:-10px; +} #shareWithList .unshare img, #shareWithList .showCruds img { vertical-align:text-bottom; /* properly align icons */ } - #dropdown label { - font-weight:400; - } +#dropdown label { + font-weight:400; +} - #dropdown input[type="checkbox"] { - margin:0 .2em 0 .5em; - } +#dropdown input[type="checkbox"] { + margin:0 .2em 0 .5em; +} - a.showCruds { - display:inline; - opacity:.5; - } +a.showCruds { + display:inline; + opacity:.5; +} - a.unshare { - display:inline; - float:right; - opacity:.5; - padding:.3em 0 0 .3em !important; +a.unshare { + display:inline; + float:right; + opacity:.5; + padding:.3em 0 0 .3em !important; margin-top:-5px; - } +} - #link { - border-top:1px solid #ddd; - padding-top:.5em; - } +#link { + border-top:1px solid #ddd; + padding-top:.5em; +} #dropdown input[type="text"],#dropdown input[type="password"] { - width:90%; + width:90%; } #dropdown form { - font-size: 100%; - margin-left: 0; - margin-right: 0; + font-size: 100%; + margin-left: 0; + margin-right: 0; } #linkText,#linkPass,#expiration { - display:none; - } + display:none; +} - #link #showPassword img { - padding-left:.3em; - width:12px; - } +#link #showPassword img { + padding-left:.3em; + width:12px; +} - .reshare,#link label,#expiration label { - padding-left:.5em; - } +.reshare,#link label,#expiration label { + padding-left:.5em; +} - a.showCruds:hover,a.unshare:hover { - opacity:1; - } +a.showCruds:hover,a.unshare:hover { + opacity:1; +} -.reshare { white-space:normal; } /* fix shared by text going out of box */ +.reshare { /* fix shared by text going out of box */ + white-space:normal; +} .ui-autocomplete { /* limit dropdown height to 4 1/2 entries */ max-height:103px; diff --git a/core/css/styles.css b/core/css/styles.css index dcdeda8a9c95d7aecf57db686a81bb23f23b8e4f..481fb6d5f39caec48e7c66bc890353eb3cd1bd65 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -19,9 +19,6 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari #body-user #header, #body-settings #header { position:fixed; top:0; left:0; right:0; z-index:100; height:45px; line-height:2.5em; background:#1d2d44 url('../img/noise.png') repeat; - -moz-box-shadow:0 0 10px rgba(0, 0, 0, .5); - -webkit-box-shadow:0 0 10px rgba(0, 0, 0, .5); - box-shadow:0 0 10px rgba(0, 0, 0, .5); } #body-login { @@ -46,6 +43,10 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari display: inline-block; } +#header .avatardiv img { + opacity: 1; +} + /* INPUTS */ input[type="text"], input[type="password"], input[type="search"], input[type="number"], input[type="email"], input[type="url"], textarea, select, @@ -155,23 +156,37 @@ input[type="submit"].enabled { background:#66f866; border:1px solid #5e5; -moz-b /* CONTENT ------------------------------------------------------------------ */ #controls { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; position: fixed; - height: 36px; + height: 44px; width: 100%; - padding: 0 75px 0 6px; + padding-right: 75px; margin: 0; background: #eee; border-bottom: 1px solid #e7e7e7; z-index: 50; - -moz-box-sizing: border-box; box-sizing: border-box; - -moz-box-shadow: 0 -3px 7px #000; -webkit-box-shadow: 0 -3px 7px #000; box-shadow: 0 -3px 7px #000; } -#controls .button { +#controls .button, +#controls button, +#controls input[type='submit'], +#controls input[type='text'], +#controls input[type='password'], +#controls select { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; display: inline-block; + height: 36px; + padding: 7px 10px } #content { position:relative; height:100%; width:100%; } -#content .hascontrols { position: relative; top: 2.9em; } +#content .hascontrols { + position: relative; + top: 45px; +} #content-wrapper { position:absolute; height:100%; width:100%; padding-top:3.5em; padding-left:80px; -moz-box-sizing:border-box; box-sizing:border-box; @@ -512,7 +527,6 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } z-index: 75; height: 100%; background:#383c43 url('../img/noise.png') repeat; - -moz-box-shadow:0 0 7px #000; -webkit-box-shadow:0 0 7px #000; box-shadow:0 0 7px #000; overflow:hidden; box-sizing:border-box; -moz-box-sizing:border-box; /* prevent ugly selection effect on accidental selection */ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; @@ -751,15 +765,38 @@ span.ui-icon {float: left; margin: 3px 7px 30px 0;} .arrow.left { left:-13px; bottom:1.2em; -webkit-transform:rotate(270deg); -moz-transform:rotate(270deg); -o-transform:rotate(270deg); -ms-transform:rotate(270deg); transform:rotate(270deg); } .arrow.up { top:-8px; right:2em; } .arrow.down { -webkit-transform:rotate(180deg); -moz-transform:rotate(180deg); -o-transform:rotate(180deg); -ms-transform:rotate(180deg); transform:rotate(180deg); } -.help-includes {overflow: hidden; width: 100%; height: 100%; -moz-box-sizing: border-box; box-sizing: border-box; padding-top: 2.8em; } +.help-includes { + overflow: hidden; + width: 100%; + height: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding-top: 44px; +} .help-iframe {width: 100%; height: 100%; margin: 0;padding: 0; border: 0; overflow: auto;} /* ---- BREADCRUMB ---- */ -div.crumb { float:left; display:block; background:url('../img/breadcrumb.svg') no-repeat right 0; padding:.75em 1.5em 0 1em; height:2.9em; -moz-box-sizing:border-box; box-sizing:border-box; } -div.crumb:first-child { padding:10px 20px 10px 5px; } -div.crumb.last { font-weight:bold; background:none; padding-right:10px; } -div.crumb a{ padding: 0.9em 0 0.7em 0; } +div.crumb { + float: left; + display: block; + background: url('../img/breadcrumb.svg') no-repeat right center; + height: 44px; +} +div.crumb a { + position: relative; + top: 12px; + padding: 14px 24px 14px 17px; + color: #555; +} +div.crumb:first-child a { + position: relative; + top: 13px; +} +div.crumb.last { + font-weight: bold; + margin-right: 10px; +} /* some feedback for hover/tap on breadcrumbs */ div.crumb:hover, diff --git a/core/img/breadcrumb-start.png b/core/img/breadcrumb-start.png deleted file mode 100644 index b0df5f44037637c322fb4eb867f90c18c6e8f613..0000000000000000000000000000000000000000 Binary files a/core/img/breadcrumb-start.png and /dev/null differ diff --git a/core/img/breadcrumb-start.svg b/core/img/breadcrumb-start.svg deleted file mode 100644 index 7f36231cdf8d370d8abc8ea1cb2ea50b21f0c657..0000000000000000000000000000000000000000 --- a/core/img/breadcrumb-start.svg +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="36" width="11" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> - <g transform="translate(0 -1016.4)"> - <path d="m0 0 11 18-11 18z" transform="translate(0 1016.4)" fill="#ddd"/> - </g> -</svg> diff --git a/core/img/breadcrumb.png b/core/img/breadcrumb.png index 84992be0d9350d7a94455cfe46dcea2fcc669e64..7e9593a36bf9a2fc123ee6237fdfc88c022df0a6 100644 Binary files a/core/img/breadcrumb.png and b/core/img/breadcrumb.png differ diff --git a/core/img/breadcrumb.svg b/core/img/breadcrumb.svg index 05a216e50a9eaec7a20be7274957dc6e8ae2f46f..f0b5c9218d50b5b05e9a7446519bad8743464440 100644 --- a/core/img/breadcrumb.svg +++ b/core/img/breadcrumb.svg @@ -1,6 +1,12 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="36" width="11" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> - <g transform="translate(0 -1016.4)"> - <path d="m0.5 0 10 18-10 18 10-18z" transform="translate(0 1016.4)" stroke="#ddd" stroke-linecap="round" stroke-miterlimit="31.2" stroke-width="0.9" fill="#ddd"/> - </g> +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="44" width="14" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:title/> + </cc:Work> + </rdf:RDF> + </metadata> + <path d="M0.54879,0.047777,12.744,22,0.54879,43.951,12.744,22z" stroke="#d7d7d7" stroke-linecap="round" stroke-miterlimit="31.20000076000000178" stroke-width="1.09758711000000009" fill="#F00"/> </svg> diff --git a/core/img/places/link.png b/core/img/places/link.png new file mode 100644 index 0000000000000000000000000000000000000000..44b7e199a7267e9c1d87f54ebdbf064e7fac0b45 Binary files /dev/null and b/core/img/places/link.png differ diff --git a/core/img/places/link.svg b/core/img/places/link.svg new file mode 100644 index 0000000000000000000000000000000000000000..8784ebc1456b6050f176baa85d3432f1375458f1 --- /dev/null +++ b/core/img/places/link.svg @@ -0,0 +1,12 @@ +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:title/> + </cc:Work> + </rdf:RDF> + </metadata> + <path fill="#333" d="M16,4c-6.6274,0-12,5.3726-12,12,0,6.627,5.3726,12,12,12,6.627,0,12-5.373,12-12,0-6.6274-5.373-12-12-12zm1.375,1.5313c2.059,0.0457,3.879,1.2826,5.719,2.0938l2.9691,4.1093-0.46971,1.7657,0.90686,0.56246-0.01543,2.0937c-0.02074,0.59892,0.0086,1.1986-0.0156,1.7969-0.28517,1.1355-0.94394,2.1713-1.5,3.2031-0.37695,0.18585,0.03437-1.2317-0.20313-1.6719,0.05486-1.0173-0.80743-0.97029-1.3903-0.40526-0.72172,0.42068-2.3074,0.54754-2.3589-0.59383-0.40972-1.3716-0.06-2.833,0.49886-4.1093l-0.921-1.125,0.327-2.891-1.469-1.4839,0.345-1.6252-1.719-0.9687c-0.339-0.2661-0.984-0.3713-1.125-0.7344,0.13954-0.00789,0.28457-0.018686,0.42189-0.0156zm-4.2187,0.015634c0.0539,0.00789,0.11999,0.045309,0.21874,0.125,0.57943,0.31834-0.14143,0.67954-0.31251,1.0157-0.92537,0.62589,0.28457,1.1385,0.68743,1.6406,0.64577-0.18549,1.2917-1.1086,2.2344-0.828,1.2058-0.37629,1.0137,1.0099,1.7031,1.625,0.08948,0.28954,1.5086,1.2317,0.65623,0.92177-0.702-0.54411-1.4827-0.50314-1.9845,0.28131-1.355,0.735-0.552-1.4144-1.202-1.9373-0.982-1.0957-0.57,0.8186-0.687,1.3907-0.639-0.0139-1.831-0.4913-2.485,0.2816l0.64046,1.0467,0.76577-1.1719c0.186-0.42411,0.41949,0.32966,0.62486,0.46886,0.24531,0.47297,1.4109,1.2744,0.53126,1.5-1.3039,0.72326-2.3295,1.8202-3.4375,2.7969-0.37371,0.78857-1.1366,0.6984-1.6094,0.0468-1.1438-0.70372-1.0589,1.1256-0.99994,1.8125l1.0013-0.626v1.0312c-0.028286,0.19509-0.00411,0.39806-0.0156,0.59383-0.70063,0.732-1.4069-1.0277-2.0157-1.422l-0.0468-2.5781c0.022114-0.72429-0.1308-1.4659,0.0156-2.1718,1.3779-1.4789,2.7775-3.0107,3.5935-4.891h1.3437c0.93909,0.45497,0.40406-1.0082,0.7812-0.95314zm-1.984,13.406c0.16303-0.01739,0.34848,0.01984,0.54688,0.12501,1.265,0.18106,2.2109,1.0987,3.2187,1.7969,0.80352,0.79632,2.5419,0.54134,2.7345,1.8907-0.29248,1.4636-1.7323,2.2495-3,2.7657-0.31646,0.17657-0.65657,0.31714-1.0157,0.37543-1.1753,0.29314-1.6834-0.912-1.9219-1.8137-0.53212-1.1143-1.8621-1.9577-1.6718-3.3274,0.0312-0.68057,0.40286-1.7373,1.1093-1.8125z"/> +</svg> diff --git a/core/js/avatar.js b/core/js/avatar.js index 57e6daa0930251fba4fa314bf36864e5209da8f2..c54c40687689259fb0ee4e04d4e48094ebac2856 100644 --- a/core/js/avatar.js +++ b/core/js/avatar.js @@ -1,6 +1,6 @@ $(document).ready(function(){ if (OC.currentUser) { - $('#header .avatardiv').avatar(OC.currentUser, 32); + $('#header .avatardiv').avatar(OC.currentUser, 32, undefined, true); // Personal settings $('#avatar .avatardiv').avatar(OC.currentUser, 128); } diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js index 88a4c25d1eecfc401f7a684d6228a086eb8df44a..0006810172668fb4bf9d34bce83707dc64155d37 100644 --- a/core/js/jquery.avatar.js +++ b/core/js/jquery.avatar.js @@ -15,7 +15,7 @@ * You may use this on any <div></div> * Here I'm using <div class="avatardiv"></div> as an example. * - * There are 4 ways to call this: + * There are 5 ways to call this: * * 1. $('.avatardiv').avatar('jdoe', 128); * This will make the div to jdoe's fitting avatar, with a size of 128px. @@ -34,10 +34,15 @@ * 4. $('.avatardiv').avatar('jdoe', 128, true); * This will behave like the first example, except it will also append random * hashes to the custom avatar images, to force image reloading in IE8. + * + * 5. $('.avatardiv').avatar('jdoe', 128, undefined, true); + * This will behave like the first example, but it will hide the avatardiv, if + * it will display the default placeholder. undefined is the ie8fix from + * example 4 and can be either true, or false/undefined, to be ignored. */ (function ($) { - $.fn.avatar = function(user, size, ie8fix) { + $.fn.avatar = function(user, size, ie8fix, hidedefault) { if (typeof(size) === 'undefined') { if (this.height() > 0) { size = this.height(); @@ -69,12 +74,17 @@ var url = OC.Router.generate('core_avatar_get', {user: user, size: size})+'?requesttoken='+oc_requesttoken; $.get(url, function(result) { if (typeof(result) === 'object') { - if (result.data && result.data.displayname) { - $div.placeholder(user, result.data.displayname); + if (!hidedefault) { + if (result.data && result.data.displayname) { + $div.placeholder(user, result.data.displayname); + } else { + $div.placeholder(user); + } } else { - $div.placeholder(user); + $div.hide(); } } else { + $div.show(); if (ie8fix === true) { $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">'); } else { diff --git a/core/js/share.js b/core/js/share.js index 82f5da0baea0f5f610b9f2ea1c4c8e6080981a91..8d14520cd74650934b691495dcdbc04b3ebadd64 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -114,6 +114,7 @@ OC.Share={ data = false; } }}); + return data; }, share:function(itemType, itemSource, shareType, shareWith, permissions, callback) { @@ -217,9 +218,9 @@ OC.Share={ OC.Share.showLink(share.token, share.share_with, itemSource); } else { if (share.collection) { - OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.collection); + OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, share.collection); } else { - OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, false); + OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, false); } } if (share.expiration != null) { @@ -301,7 +302,7 @@ OC.Share={ } }); }, - addShareWith:function(shareType, shareWith, shareWithDisplayName, permissions, possiblePermissions, collection) { + addShareWith:function(shareType, shareWith, shareWithDisplayName, permissions, possiblePermissions, mailSend, collection) { if (!OC.Share.itemShares[shareType]) { OC.Share.itemShares[shareType] = []; } @@ -343,6 +344,14 @@ OC.Share={ }else{ html += escapeHTML(shareWithDisplayName); } + var mailNotificationEnabled = $('input:hidden[name=mailNotificationEnabled]').val(); + if (mailNotificationEnabled === 'yes') { + var checked = ''; + if (mailSend === '1') { + checked = 'checked'; + } + html += '<input type="checkbox" name="mailNotification" class="mailNotification" ' + checked + ' />'+t('core', 'notify user by email')+'</label>'; + } if (possiblePermissions & OC.PERMISSION_CREATE || possiblePermissions & OC.PERMISSION_UPDATE || possiblePermissions & OC.PERMISSION_DELETE) { if (editChecked == '') { html += '<label style="display:none;">'; @@ -699,5 +708,27 @@ $(document).ready(function() { } }); + $(document).on('click', '#dropdown input[name=mailNotification]', function() { + var li = $(this).parent(); + var itemType = $('#dropdown').data('item-type'); + var itemSource = $('#dropdown').data('item-source'); + var action = ''; + if (this.checked) { + action = 'informRecipients'; + } else { + action = 'informRecipientsDisabled'; + } + + var shareType = $(li).data('share-type'); + var shareWith = $(li).data('share-with'); + + $.post(OC.filePath('core', 'ajax', 'share.php'), {action: action, recipient: shareWith, shareType: shareType, itemSource: itemSource, itemType: itemType}, function(result) { + if (result.status !== 'success') { + OC.dialogs.alert(t('core', result.data.message), t('core', 'Warning')); + } + }); + +}); + }); diff --git a/core/l10n/cs_CZ.php b/core/l10n/cs_CZ.php index abed4a0fdac5b6df80906b3e0cf4562c85857dcf..8b63079c87aeb39923919c7dac1517ebe991eb73 100644 --- a/core/l10n/cs_CZ.php +++ b/core/l10n/cs_CZ.php @@ -60,7 +60,9 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Chyba při nahrávání šablony zprávy: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("","",""), "One file conflict" => "Jeden konflikt souboru", +"Which files do you want to keep?" => "Které soubory chcete ponechat?", "Cancel" => "Zrušit", +"Continue" => "Pokračovat", "The object type is not specified." => "Není určen typ objektu.", "Error" => "Chyba", "The app name is not specified." => "Není určen název aplikace.", diff --git a/core/l10n/hu_HU.php b/core/l10n/hu_HU.php index d893269ee810f04c7e2560027855bb5eae36a458..107a5f04c05dd2a7dfb5fa2bead82dcd12622e89 100644 --- a/core/l10n/hu_HU.php +++ b/core/l10n/hu_HU.php @@ -2,6 +2,12 @@ $TRANSLATIONS = array( "%s shared »%s« with you" => "%s megosztotta Önnel ezt: »%s«", "group" => "csoport", +"Turned on maintenance mode" => "A karbantartási mód bekapcsolva", +"Turned off maintenance mode" => "A karbantartási mód kikapcsolva", +"Updated database" => "Frissítet adatbázis", +"Updating filecache, this may take really long..." => "A filecache frissítése folyamatban, ez a folyamat hosszabb ideig is eltarthat...", +"Updated filecache" => "Filecache frissítve", +"... %d%% done ..." => "... %d%% kész ...", "Category type not provided." => "Nincs megadva a kategória típusa.", "No category to add?" => "Nincs hozzáadandó kategória?", "This category already exists: %s" => "Ez a kategória már létezik: %s", @@ -10,6 +16,11 @@ $TRANSLATIONS = array( "Error adding %s to favorites." => "Nem sikerült a kedvencekhez adni ezt: %s", "No categories selected for deletion." => "Nincs törlésre jelölt kategória", "Error removing %s from favorites." => "Nem sikerült a kedvencekből törölni ezt: %s", +"No image or file provided" => "Nincs kép vagy file megadva", +"Unknown filetype" => "Ismeretlen file tipús", +"Invalid image" => "Hibás kép", +"No temporary profile picture available, try again" => "Az átmeneti profil kép nem elérhető, próbáld újra", +"No crop data provided" => "Vágáshoz nincs adat megadva", "Sunday" => "vasárnap", "Monday" => "hétfő", "Tuesday" => "kedd", @@ -42,11 +53,20 @@ $TRANSLATIONS = array( "last year" => "tavaly", "years ago" => "több éve", "Choose" => "Válasszon", +"Error loading file picker template: {error}" => "Nem sikerült betölteni a fájlkiválasztó sablont: {error}", "Yes" => "Igen", "No" => "Nem", "Ok" => "Ok", +"Error loading message template: {error}" => "Nem sikerült betölteni az üzenet sablont: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("",""), +"One file conflict" => "Egy file ütközik", +"Which files do you want to keep?" => "Melyik file-okat akarod megtartani?", +"If you select both versions, the copied file will have a number added to its name." => "Ha kiválasztod mindazokaz a verziókat, a másolt fileok neve sorszámozva lesz.", "Cancel" => "Mégsem", +"Continue" => "Folytatás", +"(all selected)" => "(all selected)", +"({count} selected)" => "({count} kiválasztva)", +"Error loading file exists template" => "Hiba a létező sablon betöltésekor", "The object type is not specified." => "Az objektum típusa nincs megadva.", "Error" => "Hiba", "The app name is not specified." => "Az alkalmazás neve nincs megadva.", @@ -85,6 +105,7 @@ $TRANSLATIONS = array( "Email sent" => "Az emailt elküldtük", "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "A frissítés nem sikerült. Kérem értesítse erről a problémáról az <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud közösséget</a>.", "The update was successful. Redirecting you to ownCloud now." => "A frissítés sikeres volt. Visszairányítjuk az ownCloud szolgáltatáshoz.", +"%s password reset" => "%s jelszó visszaállítás", "Use the following link to reset your password: {link}" => "Használja ezt a linket a jelszó ismételt beállításához: {link}", "The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Emailben fog kapni egy linket, amivel új jelszót tud majd beállítani magának. <br>Ha a levél nem jött meg, holott úgy érzi, hogy már meg kellett volna érkeznie, akkor ellenőrizze a spam/levélszemét mappáját. <br>Ha ott sincsen, akkor érdeklődjön a rendszergazdánál.", "Request failed!<br>Did you make sure your email/username was right?" => "A kérést nem sikerült teljesíteni! <br>Biztos, hogy jó emailcímet/felhasználónevet adott meg?", diff --git a/core/l10n/ja_JP.php b/core/l10n/ja_JP.php index 0baab441f956bd62c1536c1a53a1cf9e3cceac05..110e5b2120106280453aa1e8ca29e062de747649 100644 --- a/core/l10n/ja_JP.php +++ b/core/l10n/ja_JP.php @@ -20,6 +20,7 @@ $TRANSLATIONS = array( "Unknown filetype" => "不明なファイルタイプ", "Invalid image" => "無効な画像", "No temporary profile picture available, try again" => "一時的なプロファイル用画像が利用できません。もう一度試して下さい", +"No crop data provided" => "クロップデータは提供されません", "Sunday" => "日", "Monday" => "月", "Tuesday" => "火", @@ -57,8 +58,15 @@ $TRANSLATIONS = array( "No" => "いいえ", "Ok" => "OK", "Error loading message template: {error}" => "メッセージテンプレートの読み込みエラー: {error}", -"_{count} file conflict_::_{count} file conflicts_" => array(""), +"_{count} file conflict_::_{count} file conflicts_" => array("{count} ファイルが競合"), +"One file conflict" => "1ファイルが競合", +"Which files do you want to keep?" => "どちらのファイルを保持したいですか?", +"If you select both versions, the copied file will have a number added to its name." => "両方のバージョンを選択した場合は、ファイル名の後ろに数字を追加したファイルのコピーを作成します。", "Cancel" => "キャンセル", +"Continue" => "続ける", +"(all selected)" => "(全て選択)", +"({count} selected)" => "({count} 選択)", +"Error loading file exists template" => "既存ファイルのテンプレートの読み込みエラー", "The object type is not specified." => "オブジェクタイプが指定されていません。", "Error" => "エラー", "The app name is not specified." => "アプリ名がしていされていません。", diff --git a/core/l10n/lt_LT.php b/core/l10n/lt_LT.php index 492aee12c1d8a150202aa1462e0caa7dd87b71bc..610e7aeadebcfebe3a2b3184c97649b6c57ff39d 100644 --- a/core/l10n/lt_LT.php +++ b/core/l10n/lt_LT.php @@ -58,8 +58,15 @@ $TRANSLATIONS = array( "No" => "Ne", "Ok" => "Gerai", "Error loading message template: {error}" => "Klaida įkeliant žinutės ruošinį: {error}", -"_{count} file conflict_::_{count} file conflicts_" => array("","",""), +"_{count} file conflict_::_{count} file conflicts_" => array("{count} failas konfliktuoja","{count} failai konfliktuoja","{count} failų konfliktų"), +"One file conflict" => "Vienas failo konfliktas", +"Which files do you want to keep?" => "Kuriuos failus norite laikyti?", +"If you select both versions, the copied file will have a number added to its name." => "Jei pasirenkate abi versijas, nukopijuotas failas turės pridėtą numerį pavadinime.", "Cancel" => "Atšaukti", +"Continue" => "Tęsti", +"(all selected)" => "(visi pažymėti)", +"({count} selected)" => "({count} pažymėtų)", +"Error loading file exists template" => "Klaida įkeliant esančių failų ruošinį", "The object type is not specified." => "Objekto tipas nenurodytas.", "Error" => "Klaida", "The app name is not specified." => "Nenurodytas programos pavadinimas.", diff --git a/core/l10n/pl.php b/core/l10n/pl.php index 621038f79f7a2de7ec1de05ec5c822d5128e7a73..ad467fe100ea0198e5c1f38712662d9dad420b24 100644 --- a/core/l10n/pl.php +++ b/core/l10n/pl.php @@ -16,6 +16,8 @@ $TRANSLATIONS = array( "Error adding %s to favorites." => "Błąd podczas dodawania %s do ulubionych.", "No categories selected for deletion." => "Nie zaznaczono kategorii do usunięcia.", "Error removing %s from favorites." => "Błąd podczas usuwania %s z ulubionych.", +"Unknown filetype" => "Nieznany typ pliku", +"Invalid image" => "Nieprawidłowe zdjęcie", "Sunday" => "Niedziela", "Monday" => "Poniedziałek", "Tuesday" => "Wtorek", @@ -51,8 +53,12 @@ $TRANSLATIONS = array( "Yes" => "Tak", "No" => "Nie", "Ok" => "OK", -"_{count} file conflict_::_{count} file conflicts_" => array("","",""), +"_{count} file conflict_::_{count} file conflicts_" => array("{count} konfliktów plików","{count} konfliktów plików","{count} konfliktów plików"), +"One file conflict" => "Konflikt pliku", "Cancel" => "Anuluj", +"Continue" => "Kontynuuj ", +"(all selected)" => "(wszystkie zaznaczone)", +"({count} selected)" => "({count} zaznaczonych)", "The object type is not specified." => "Nie określono typu obiektu.", "Error" => "Błąd", "The app name is not specified." => "Nie określono nazwy aplikacji.", diff --git a/core/skeleton/welcome.txt b/core/skeleton/welcome.txt new file mode 100644 index 0000000000000000000000000000000000000000..c86eaf91bbea5395ffa76ee1c99ed4b2380be47b --- /dev/null +++ b/core/skeleton/welcome.txt @@ -0,0 +1,5 @@ +Welcome to your ownCloud account! + +This is just an example file for developers and git users. +The packaged and released versions will come with better examples. + diff --git a/core/templates/altmail.php b/core/templates/altmail.php index 2551473c6f0939364d95f3739201709281b08a41..00b67bee456e75783dc3fea8ccf9abf64eb04214 100644 --- a/core/templates/altmail.php +++ b/core/templates/altmail.php @@ -1,5 +1,9 @@ <?php -print_unescaped($l->t("Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\nCheers!", array($_['user_displayname'], $_['filename'], $_['link']))); +print_unescaped($l->t("Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n", array($_['user_displayname'], $_['filename'], $_['link']))); +if ( isset($_['expiration']) ) { + print_unescaped($l->t("The share will expire on %s.\n\n", array($_['expiration']))); +} +p($l->t("Cheers!")); ?> -- diff --git a/core/templates/login.php b/core/templates/login.php index ee761f0aa523d5378f8a345379613af19fe90a46..06f64d41e39e24e5efd9490eef5215b664f17cc9 100644 --- a/core/templates/login.php +++ b/core/templates/login.php @@ -32,9 +32,10 @@ <?php p($l->t('Lost your password?')); ?> </a> <?php endif; ?> - + <?php if ($_['rememberLoginAllowed'] === true) : ?> <input type="checkbox" name="remember_login" value="1" id="remember_login" checked /> <label for="remember_login"><?php p($l->t('remember')); ?></label> + <?php endif; ?> <input type="hidden" name="timezone-offset" id="timezone-offset"/> <input type="submit" id="submit" class="login primary" value="<?php p($l->t('Log in')); ?>"/> </fieldset> diff --git a/core/templates/mail.php b/core/templates/mail.php index de72b136b135149a73b09bf04b7dbb2b55b12cc4..40092f5491f88aa3f19156e975bb86b5ddecd1fd 100644 --- a/core/templates/mail.php +++ b/core/templates/mail.php @@ -12,7 +12,11 @@ <td bgcolor="#f8f8f8" width="20px"> </td> <td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;"> <?php -print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared »%s« with you.<br><a href="%s">View it!</a><br><br>Cheers!', array($_['user_displayname'], $_['filename'], $_['link']))); +print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared »%s« with you.<br><a href="%s">View it!</a><br><br>', array($_['user_displayname'], $_['filename'], $_['link']))); +if ( isset($_['expiration']) ) { + print_unescaped($l->t("The share will expire on %s.<br><br>", array($_['expiration']))); +} +p($l->t('Cheers!')); ?> </td> </tr> @@ -22,7 +26,8 @@ print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared » <td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br> <?php p($theme->getName()); ?> - <?php p($theme->getSlogan()); ?> -<br><a href="<?php print_unescaped($theme->getBaseUrl()); ?>"><?php print_unescaped($theme->getBaseUrl());?></a></td> +<br><a href="<?php print_unescaped($theme->getBaseUrl()); ?>"><?php print_unescaped($theme->getBaseUrl());?></a> +</td> </tr> <tr> <td bgcolor="#f8f8f8" colspan="2"> </td> diff --git a/db_structure.xml b/db_structure.xml index 86f9989e1c237e7c035c40157e01dddbd3ca7340..f9470dc86b359f3769a83df225b80190c0c50568 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -844,6 +844,14 @@ <length>32</length> </field> + <field> + <name>mail_send</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <length>1</length> + </field> + <index> <name>token_index</name> <field> diff --git a/index.php b/index.php index 90fd3efcc96e060e5f31875e6b7f12e03791e3f6..40063fa6e05b44305807b88926d331e6477b5bba 100755 --- a/index.php +++ b/index.php @@ -31,7 +31,7 @@ try { } catch (Exception $ex) { //show the user a detailed error page - OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR); \OCP\Util::writeLog('index', $ex->getMessage(), \OCP\Util::FATAL); + OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR); OC_Template::printExceptionErrorPage($ex); } diff --git a/l10n/cs_CZ/core.po b/l10n/cs_CZ/core.po index 40b693b988a4c3db0598d97b2e71ff808dd75e67..914c6bcc2079c4c5742d66ab20e77dc7b7f74e96 100644 --- a/l10n/cs_CZ/core.po +++ b/l10n/cs_CZ/core.po @@ -4,6 +4,7 @@ # # Translators: # janinko <janinko.g@gmail.com>, 2013 +# dibalaj <dibalaj@dibalaj.cz>, 2013 # Honza K. <honza889@gmail.com>, 2013 # Martin <fireball@atlas.cz>, 2013 # pstast <petr@stastny.eu>, 2013 @@ -12,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-27 00:01-0400\n" -"PO-Revision-Date: 2013-09-25 10:50+0000\n" -"Last-Translator: pstast <petr@stastny.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 16:57+0000\n" +"Last-Translator: dibalaj <dibalaj@dibalaj.cz>\n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -288,7 +289,7 @@ msgstr "Jeden konflikt souboru" #: js/oc-dialogs.js:367 msgid "Which files do you want to keep?" -msgstr "" +msgstr "Které soubory chcete ponechat?" #: js/oc-dialogs.js:368 msgid "" @@ -302,7 +303,7 @@ msgstr "Zrušit" #: js/oc-dialogs.js:386 msgid "Continue" -msgstr "" +msgstr "Pokračovat" #: js/oc-dialogs.js:433 js/oc-dialogs.js:446 msgid "(all selected)" diff --git a/l10n/cs_CZ/files.po b/l10n/cs_CZ/files.po index 7ce4b33052159b99a4626f186c2e6e49c9b6f9a3..5cff84e574f2a9e5345a690ac3bd63f6b67e503c 100644 --- a/l10n/cs_CZ/files.po +++ b/l10n/cs_CZ/files.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# dibalaj <dibalaj@dibalaj.cz>, 2013 # Honza K. <honza889@gmail.com>, 2013 # cvanca <mrs.jenkins.oh.yeah@gmail.com>, 2013 # pstast <petr@stastny.eu>, 2013 @@ -11,9 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:44-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-29 16:54+0000\n" +"Last-Translator: dibalaj <dibalaj@dibalaj.cz>\n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -90,7 +91,7 @@ msgstr "" msgid "Invalid directory." msgstr "Neplatný adresář" -#: appinfo/app.php:12 +#: appinfo/app.php:11 msgid "Files" msgstr "Soubory" @@ -228,7 +229,7 @@ msgstr "Vaše soubory ke stažení se připravují. Pokud jsou velké, může to #: js/files.js:507 js/files.js:545 msgid "Error moving file" -msgstr "" +msgstr "Chyba při přesunu souboru" #: js/files.js:558 templates/index.php:61 msgid "Name" diff --git a/l10n/hu_HU/core.po b/l10n/hu_HU/core.po index 7b484995d4b18d8aa196d60184637f122e60eb01..9a7a4428b56fd3083d20abeff75570e4543bb995 100644 --- a/l10n/hu_HU/core.po +++ b/l10n/hu_HU/core.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-22 12:55-0400\n" -"PO-Revision-Date: 2013-09-20 15:01+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 00:42+0000\n" +"Last-Translator: ebela <bela@dandre.hu>\n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -30,28 +30,28 @@ msgstr "csoport" #: ajax/update.php:11 msgid "Turned on maintenance mode" -msgstr "" +msgstr "A karbantartási mód bekapcsolva" #: ajax/update.php:14 msgid "Turned off maintenance mode" -msgstr "" +msgstr "A karbantartási mód kikapcsolva" #: ajax/update.php:17 msgid "Updated database" -msgstr "" +msgstr "Frissítet adatbázis" #: ajax/update.php:20 msgid "Updating filecache, this may take really long..." -msgstr "" +msgstr "A filecache frissítése folyamatban, ez a folyamat hosszabb ideig is eltarthat..." #: ajax/update.php:23 msgid "Updated filecache" -msgstr "" +msgstr "Filecache frissítve" #: ajax/update.php:26 #, php-format msgid "... %d%% done ..." -msgstr "" +msgstr "... %d%% kész ..." #: ajax/vcategories/add.php:26 ajax/vcategories/edit.php:25 msgid "Category type not provided." @@ -94,23 +94,23 @@ msgstr "Nem sikerült a kedvencekből törölni ezt: %s" #: avatar/controller.php:62 msgid "No image or file provided" -msgstr "" +msgstr "Nincs kép vagy file megadva" #: avatar/controller.php:81 msgid "Unknown filetype" -msgstr "" +msgstr "Ismeretlen file tipús" #: avatar/controller.php:85 msgid "Invalid image" -msgstr "" +msgstr "Hibás kép" #: avatar/controller.php:115 avatar/controller.php:142 msgid "No temporary profile picture available, try again" -msgstr "" +msgstr "Az átmeneti profil kép nem elérhető, próbáld újra" #: avatar/controller.php:135 msgid "No crop data provided" -msgstr "" +msgstr "Vágáshoz nincs adat megadva" #: js/config.php:32 msgid "Sunday" @@ -250,7 +250,7 @@ msgstr "Válasszon" #: js/oc-dialogs.js:146 msgid "Error loading file picker template: {error}" -msgstr "" +msgstr "Nem sikerült betölteni a fájlkiválasztó sablont: {error}" #: js/oc-dialogs.js:172 msgid "Yes" @@ -266,7 +266,7 @@ msgstr "Ok" #: js/oc-dialogs.js:219 msgid "Error loading message template: {error}" -msgstr "" +msgstr "Nem sikerült betölteni az üzenet sablont: {error}" #: js/oc-dialogs.js:347 msgid "{count} file conflict" @@ -276,17 +276,17 @@ msgstr[1] "" #: js/oc-dialogs.js:361 msgid "One file conflict" -msgstr "" +msgstr "Egy file ütközik" #: js/oc-dialogs.js:367 msgid "Which files do you want to keep?" -msgstr "" +msgstr "Melyik file-okat akarod megtartani?" #: js/oc-dialogs.js:368 msgid "" "If you select both versions, the copied file will have a number added to its" " name." -msgstr "" +msgstr "Ha kiválasztod mindazokaz a verziókat, a másolt fileok neve sorszámozva lesz." #: js/oc-dialogs.js:376 msgid "Cancel" @@ -294,19 +294,19 @@ msgstr "Mégsem" #: js/oc-dialogs.js:386 msgid "Continue" -msgstr "" +msgstr "Folytatás" #: js/oc-dialogs.js:433 js/oc-dialogs.js:446 msgid "(all selected)" -msgstr "" +msgstr "(all selected)" #: js/oc-dialogs.js:436 js/oc-dialogs.js:449 msgid "({count} selected)" -msgstr "" +msgstr "({count} kiválasztva)" #: js/oc-dialogs.js:457 msgid "Error loading file exists template" -msgstr "" +msgstr "Hiba a létező sablon betöltésekor" #: js/oc-vcategories.js:5 js/oc-vcategories.js:85 js/oc-vcategories.js:102 #: js/oc-vcategories.js:117 js/oc-vcategories.js:132 js/oc-vcategories.js:162 @@ -317,7 +317,7 @@ msgstr "Az objektum típusa nincs megadva." #: js/oc-vcategories.js:110 js/oc-vcategories.js:125 js/oc-vcategories.js:136 #: js/oc-vcategories.js:172 js/oc-vcategories.js:189 js/oc-vcategories.js:195 #: js/oc-vcategories.js:199 js/share.js:129 js/share.js:142 js/share.js:149 -#: js/share.js:645 js/share.js:657 +#: js/share.js:656 js/share.js:668 msgid "Error" msgstr "Hiba" @@ -337,7 +337,7 @@ msgstr "Megosztott" msgid "Share" msgstr "Megosztás" -#: js/share.js:131 js/share.js:685 +#: js/share.js:131 js/share.js:696 msgid "Error while sharing" msgstr "Nem sikerült létrehozni a megosztást" @@ -437,23 +437,23 @@ msgstr "töröl" msgid "share" msgstr "megoszt" -#: js/share.js:400 js/share.js:632 +#: js/share.js:400 js/share.js:643 msgid "Password protected" msgstr "Jelszóval van védve" -#: js/share.js:645 +#: js/share.js:656 msgid "Error unsetting expiration date" msgstr "Nem sikerült a lejárati időt törölni" -#: js/share.js:657 +#: js/share.js:668 msgid "Error setting expiration date" msgstr "Nem sikerült a lejárati időt beállítani" -#: js/share.js:672 +#: js/share.js:683 msgid "Sending ..." msgstr "Küldés ..." -#: js/share.js:683 +#: js/share.js:694 msgid "Email sent" msgstr "Az emailt elküldtük" @@ -471,7 +471,7 @@ msgstr "A frissítés sikeres volt. Visszairányítjuk az ownCloud szolgáltatá #: lostpassword/controller.php:62 #, php-format msgid "%s password reset" -msgstr "" +msgstr "%s jelszó visszaállítás" #: lostpassword/templates/email.php:2 msgid "Use the following link to reset your password: {link}" diff --git a/l10n/hu_HU/lib.po b/l10n/hu_HU/lib.po index 6cd771a902443ac431c2cc1658f1d86a2c459c74..57212087ee511580e5b71ff55212490c08bd491f 100644 --- a/l10n/hu_HU/lib.po +++ b/l10n/hu_HU/lib.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-16 11:33-0400\n" -"PO-Revision-Date: 2013-09-16 15:34+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 00:50+0000\n" +"Last-Translator: ebela <bela@dandre.hu>\n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,38 +19,38 @@ msgstr "" "Language: hu_HU\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: app.php:239 +#: app.php:237 #, php-format msgid "" "App \"%s\" can't be installed because it is not compatible with this version" " of ownCloud." msgstr "" -#: app.php:250 +#: app.php:248 msgid "No app name specified" -msgstr "" +msgstr "Nincs az alkalmazás név megadva." -#: app.php:361 +#: app.php:352 msgid "Help" msgstr "Súgó" -#: app.php:374 +#: app.php:365 msgid "Personal" msgstr "Személyes" -#: app.php:385 +#: app.php:376 msgid "Settings" msgstr "Beállítások" -#: app.php:397 +#: app.php:388 msgid "Users" msgstr "Felhasználók" -#: app.php:410 +#: app.php:401 msgid "Admin" msgstr "Adminsztráció" -#: app.php:839 +#: app.php:832 #, php-format msgid "Failed to upgrade \"%s\"." msgstr "Sikertelen Frissítés \"%s\"." @@ -61,11 +61,11 @@ msgstr "" #: avatar.php:64 msgid "Unknown filetype" -msgstr "" +msgstr "Ismeretlen file tipús" #: avatar.php:69 msgid "Invalid image" -msgstr "" +msgstr "Hibás kép" #: defaults.php:35 msgid "web services under your control" @@ -121,7 +121,7 @@ msgstr "" #: installer.php:125 msgid "App does not provide an info.xml file" -msgstr "" +msgstr "Az alkalmazás nem szolgáltatott info.xml file-t" #: installer.php:131 msgid "App can't be installed because of not allowed code in the App" @@ -131,7 +131,7 @@ msgstr "" msgid "" "App can't be installed because it is not compatible with this version of " "ownCloud" -msgstr "" +msgstr "Az alalmazás nem telepíthető, mert nem kompatibilis az ownClod ezzel a verziójával." #: installer.php:146 msgid "" @@ -147,12 +147,12 @@ msgstr "" #: installer.php:162 msgid "App directory already exists" -msgstr "" +msgstr "Az alkalmazás mappája már létezik" #: installer.php:175 #, php-format msgid "Can't create app folder. Please fix permissions. %s" -msgstr "" +msgstr "Nem lehetett létrehozni az alkalmzás mappáját. Kérlek ellenőrizd a jogosultásgokat. %s" #: json.php:28 msgid "Application is not enabled" @@ -166,15 +166,15 @@ msgstr "Azonosítási hiba" msgid "Token expired. Please reload page." msgstr "A token lejárt. Frissítse az oldalt." -#: search/provider/file.php:17 search/provider/file.php:35 +#: search/provider/file.php:18 search/provider/file.php:36 msgid "Files" msgstr "Fájlok" -#: search/provider/file.php:26 search/provider/file.php:33 +#: search/provider/file.php:27 search/provider/file.php:34 msgid "Text" msgstr "Szöveg" -#: search/provider/file.php:29 +#: search/provider/file.php:30 msgid "Images" msgstr "Képek" @@ -278,6 +278,11 @@ msgstr "Az Ön webkiszolgálója nincs megfelelően beállítva az állományok msgid "Please double check the <a href='%s'>installation guides</a>." msgstr "Kérjük tüzetesen tanulmányozza át a <a href='%s'>telepítési útmutatót</a>." +#: tags.php:194 +#, php-format +msgid "Could not find category \"%s\"" +msgstr "Ez a kategória nem található: \"%s\"" + #: template/functions.php:96 msgid "seconds ago" msgstr "pár másodperce" @@ -329,8 +334,3 @@ msgstr "több éve" #: template.php:297 msgid "Caused by:" msgstr "Okozta:" - -#: vcategories.php:188 vcategories.php:249 -#, php-format -msgid "Could not find category \"%s\"" -msgstr "Ez a kategória nem található: \"%s\"" diff --git a/l10n/hu_HU/settings.po b/l10n/hu_HU/settings.po index 7ef4a07d1aea0084180b2f83c757e3133feb1cd3..f1bb5c03cfe5311e98077ca85ca553401eecca5f 100644 --- a/l10n/hu_HU/settings.po +++ b/l10n/hu_HU/settings.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:45-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" +"PO-Revision-Date: 2013-09-30 00:21+0000\n" +"Last-Translator: ebela <bela@dandre.hu>\n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -89,42 +89,42 @@ msgstr "A program frissítése nem sikerült." #: changepassword/controller.php:20 msgid "Wrong password" -msgstr "" +msgstr "Hibás jelszó" #: changepassword/controller.php:42 msgid "No user supplied" -msgstr "" +msgstr "Nincs felhasználó által mellékelve" #: changepassword/controller.php:74 msgid "" "Please provide an admin recovery password, otherwise all user data will be " "lost" -msgstr "" +msgstr "Add meg az admin helyreállító jelszót, máskülönben az összes felhasználói adat elveszik." #: changepassword/controller.php:79 msgid "" "Wrong admin recovery password. Please check the password and try again." -msgstr "" +msgstr "Hibás admin helyreállítási jelszó. Ellenörizd a jelszót és próbáld újra." #: changepassword/controller.php:87 msgid "" "Back-end doesn't support password change, but the users encryption key was " "successfully updated." -msgstr "" +msgstr "A back-end nem támogatja a jelszó módosítást, de felhasználó titkosítási kulcsa sikeresen frissítve lett." #: changepassword/controller.php:92 changepassword/controller.php:103 msgid "Unable to change password" -msgstr "" +msgstr "Nem sikerült megváltoztatni a jelszót" #: js/apps.js:43 msgid "Update to {appversion}" msgstr "Frissítés erre a verzióra: {appversion}" -#: js/apps.js:49 js/apps.js:82 js/apps.js:108 +#: js/apps.js:49 js/apps.js:82 js/apps.js:110 msgid "Disable" msgstr "Letiltás" -#: js/apps.js:49 js/apps.js:89 js/apps.js:102 js/apps.js:117 +#: js/apps.js:49 js/apps.js:90 js/apps.js:103 js/apps.js:119 msgid "Enable" msgstr "engedélyezve" @@ -132,43 +132,43 @@ msgstr "engedélyezve" msgid "Please wait...." msgstr "Kérem várjon..." -#: js/apps.js:79 js/apps.js:80 js/apps.js:100 +#: js/apps.js:79 js/apps.js:80 js/apps.js:101 msgid "Error while disabling app" -msgstr "" +msgstr "Hiba az alkalmazás kikapcsolása közben" -#: js/apps.js:99 js/apps.js:112 js/apps.js:113 +#: js/apps.js:100 js/apps.js:114 js/apps.js:115 msgid "Error while enabling app" -msgstr "" +msgstr "Hiba az alalmazás engedélyezése közben" -#: js/apps.js:123 +#: js/apps.js:125 msgid "Updating...." msgstr "Frissítés folyamatban..." -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error while updating app" msgstr "Hiba történt a programfrissítés közben" -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error" msgstr "Hiba" -#: js/apps.js:127 templates/apps.php:43 +#: js/apps.js:129 templates/apps.php:43 msgid "Update" msgstr "Frissítés" -#: js/apps.js:130 +#: js/apps.js:132 msgid "Updated" msgstr "Frissítve" -#: js/personal.js:220 +#: js/personal.js:221 msgid "Select a profile picture" -msgstr "" +msgstr "Válassz profil képet" -#: js/personal.js:265 +#: js/personal.js:266 msgid "Decrypting files... Please wait, this can take some time." -msgstr "" +msgstr "File-ok kititkosítása folyamatban... Kérlek várj, ez hosszabb ideig is eltarthat ..." -#: js/personal.js:287 +#: js/personal.js:288 msgid "Saving..." msgstr "Mentés..." @@ -496,27 +496,27 @@ msgstr "Profilkép" #: templates/personal.php:90 msgid "Upload new" -msgstr "" +msgstr "Új feltöltése" #: templates/personal.php:92 msgid "Select new from Files" -msgstr "" +msgstr "Új kiválasztása Fileokból" #: templates/personal.php:93 msgid "Remove image" -msgstr "" +msgstr "Kép eltávolítása" #: templates/personal.php:94 msgid "Either png or jpg. Ideally square but you will be able to crop it." -msgstr "" +msgstr "Egyaránt png vagy jpg. Az ideális ha négyzet alaku, de késöbb még átszabható" #: templates/personal.php:97 msgid "Abort" -msgstr "" +msgstr "Megszakítás" #: templates/personal.php:98 msgid "Choose as profile image" -msgstr "" +msgstr "Válassz profil képet" #: templates/personal.php:106 templates/personal.php:107 msgid "Language" @@ -543,15 +543,15 @@ msgstr "Titkosítás" #: templates/personal.php:140 msgid "The encryption app is no longer enabled, decrypt all your file" -msgstr "" +msgstr "A titkosító alkalmzás a továbbiakban nincs engedélyezve, kititkosítja az összes fileodat" #: templates/personal.php:146 msgid "Log-in password" -msgstr "" +msgstr "Bejelentkezési jelszó" #: templates/personal.php:151 msgid "Decrypt all Files" -msgstr "" +msgstr "Kititkosítja az összes file-t" #: templates/users.php:21 msgid "Login Name" diff --git a/l10n/hu_HU/user_ldap.po b/l10n/hu_HU/user_ldap.po index 87a2b140468930d281477796924488f052316387..b1d5e5391c8ec1b7fa202118ceeeb8fd36fee781 100644 --- a/l10n/hu_HU/user_ldap.po +++ b/l10n/hu_HU/user_ldap.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-27 00:01-0400\n" -"PO-Revision-Date: 2013-09-24 19:00+0000\n" -"Last-Translator: Laszlo Tornoci <torlasz@gmail.com>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 00:22+0000\n" +"Last-Translator: ebela <bela@dandre.hu>\n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -348,7 +348,7 @@ msgid "" "behavior as before ownCloud 5 enter the user display name attribute in the " "following field. Leave it empty for default behavior. Changes will have " "effect only on newly mapped (added) LDAP users." -msgstr "" +msgstr "Alapértelmezetten a belső felhasználónév az UUID tulajdonságból jön létre. Ez biztosítja a felhasználónév egyediségét és hogy a nem kell konvertálni a karaktereket benne. A belső felhasználónévnél a megkötés az, hogy csak a következő karakterek engdélyezettek benne: [ a-zA-Z0-9_.@- ]. Ezeken a karaktereken kivül minden karakter le lesz cserélve az adott karakter ASCII kódtáblában használható párjára vagy ha ilyen nincs akkor egyszerűen ki lesz hagyva. Ha így mégis ütköznének a nevek akkor hozzá lesz füzve egy folyamatosan növekvő számláló rész. A belső felhasználónevet lehet használni a felhasználó azonosítására a programon belül. Illetve ez lesz az alapáértelmezett neve a felhasználó kezdő könyvtárának az ownCloud-ban. Illetve..............................." #: templates/settings.php:100 msgid "Internal Username Attribute:" diff --git a/l10n/hu_HU/user_webdavauth.po b/l10n/hu_HU/user_webdavauth.po index fd49829f9c598ac1c8caced3085c68eb23c32d69..35d7f6c9136ef78a6b357c1a3f36c10d77d5a142 100644 --- a/l10n/hu_HU/user_webdavauth.po +++ b/l10n/hu_HU/user_webdavauth.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-07-27 01:56-0400\n" -"PO-Revision-Date: 2013-07-27 05:57+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 00:32+0000\n" +"Last-Translator: ebela <bela@dandre.hu>\n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -25,11 +25,11 @@ msgstr "WebDAV hitelesítés" #: templates/settings.php:4 msgid "Address: " -msgstr "" +msgstr "Címek:" #: templates/settings.php:7 msgid "" "The user credentials will be sent to this address. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "A felhasználói hitelesítő adatai el lesznek küldve erre a címre. Ez a bővítőmodul leellenőrzi a választ és ha a HTTP hibakód nem 401 vagy 403 azaz érvénytelen a hitelesítő adat, akkor minden más válasz érvényes lesz." diff --git a/l10n/it/files.po b/l10n/it/files.po index 4711aa723a8fc7177aa443e5da5d1c033dc45739..3b8b0f65394b9c77b6b4902b41bedb771dbbbbeb 100644 --- a/l10n/it/files.po +++ b/l10n/it/files.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-22 12:51-0400\n" -"PO-Revision-Date: 2013-09-21 17:50+0000\n" -"Last-Translator: polxmod <paolo.velati@gmail.com>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-30 12:15+0000\n" +"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -78,11 +78,11 @@ msgstr "Spazio di archiviazione insufficiente" #: ajax/upload.php:120 ajax/upload.php:143 msgid "Upload failed. Could not get file info." -msgstr "Upload fallito. Impossibile ottenere informazioni sul file" +msgstr "Caricamento non riuscito. Impossibile ottenere informazioni sul file." #: ajax/upload.php:136 msgid "Upload failed. Could not find uploaded file" -msgstr "Upload fallit. Impossibile trovare file caricato" +msgstr "Caricamento non riuscito. Impossibile trovare il file caricato." #: ajax/upload.php:160 msgid "Invalid directory." @@ -94,7 +94,7 @@ msgstr "File" #: js/file-upload.js:244 msgid "Unable to upload {filename} as it is a directory or has 0 bytes" -msgstr "Impossibile caricare {filename} poiché è una cartella oppure è di 0 byte" +msgstr "Impossibile caricare {filename} poiché è una cartella oppure ha una dimensione di 0 byte." #: js/file-upload.js:255 msgid "Not enough space available" diff --git a/l10n/it/settings.po b/l10n/it/settings.po index 0e5f28a4d151641520d1ba2fb623a8a164e304b3..8248b45ef2445294ca1bcbb0d1c6773952ac36d8 100644 --- a/l10n/it/settings.po +++ b/l10n/it/settings.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:45-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" +"PO-Revision-Date: 2013-09-30 12:15+0000\n" +"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -121,11 +121,11 @@ msgstr "Impossibile cambiare la password" msgid "Update to {appversion}" msgstr "Aggiorna a {appversion}" -#: js/apps.js:49 js/apps.js:82 js/apps.js:108 +#: js/apps.js:49 js/apps.js:82 js/apps.js:110 msgid "Disable" msgstr "Disabilita" -#: js/apps.js:49 js/apps.js:89 js/apps.js:102 js/apps.js:117 +#: js/apps.js:49 js/apps.js:90 js/apps.js:103 js/apps.js:119 msgid "Enable" msgstr "Abilita" @@ -133,43 +133,43 @@ msgstr "Abilita" msgid "Please wait...." msgstr "Attendere..." -#: js/apps.js:79 js/apps.js:80 js/apps.js:100 +#: js/apps.js:79 js/apps.js:80 js/apps.js:101 msgid "Error while disabling app" msgstr "Errore durante la disattivazione" -#: js/apps.js:99 js/apps.js:112 js/apps.js:113 +#: js/apps.js:100 js/apps.js:114 js/apps.js:115 msgid "Error while enabling app" msgstr "Errore durante l'attivazione" -#: js/apps.js:123 +#: js/apps.js:125 msgid "Updating...." msgstr "Aggiornamento in corso..." -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error while updating app" msgstr "Errore durante l'aggiornamento" -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error" msgstr "Errore" -#: js/apps.js:127 templates/apps.php:43 +#: js/apps.js:129 templates/apps.php:43 msgid "Update" msgstr "Aggiorna" -#: js/apps.js:130 +#: js/apps.js:132 msgid "Updated" msgstr "Aggiornato" -#: js/personal.js:220 +#: js/personal.js:221 msgid "Select a profile picture" msgstr "Seleziona un'immagine del profilo" -#: js/personal.js:265 +#: js/personal.js:266 msgid "Decrypting files... Please wait, this can take some time." msgstr "Decifratura dei file in corso... Attendi, potrebbe richiedere del tempo." -#: js/personal.js:287 +#: js/personal.js:288 msgid "Saving..." msgstr "Salvataggio in corso..." diff --git a/l10n/ja_JP/core.po b/l10n/ja_JP/core.po index 0e8b19b17e312d2533ec78a819741644ecb4d510..73ad535aee2d066a2cb0b53b8bd97bee70ee36df 100644 --- a/l10n/ja_JP/core.po +++ b/l10n/ja_JP/core.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-22 12:55-0400\n" -"PO-Revision-Date: 2013-09-20 15:01+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 06:25+0000\n" +"Last-Translator: Daisuke Deguchi <ddeguchi@nagoya-u.jp>\n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -112,7 +112,7 @@ msgstr "一時的なプロファイル用画像が利用できません。もう #: avatar/controller.php:135 msgid "No crop data provided" -msgstr "" +msgstr "クロップデータは提供されません" #: js/config.php:32 msgid "Sunday" @@ -269,21 +269,21 @@ msgstr "メッセージテンプレートの読み込みエラー: {error}" #: js/oc-dialogs.js:347 msgid "{count} file conflict" msgid_plural "{count} file conflicts" -msgstr[0] "" +msgstr[0] "{count} ファイルが競合" #: js/oc-dialogs.js:361 msgid "One file conflict" -msgstr "" +msgstr "1ファイルが競合" #: js/oc-dialogs.js:367 msgid "Which files do you want to keep?" -msgstr "" +msgstr "どちらのファイルを保持したいですか?" #: js/oc-dialogs.js:368 msgid "" "If you select both versions, the copied file will have a number added to its" " name." -msgstr "" +msgstr "両方のバージョンを選択した場合は、ファイル名の後ろに数字を追加したファイルのコピーを作成します。" #: js/oc-dialogs.js:376 msgid "Cancel" @@ -291,19 +291,19 @@ msgstr "キャンセル" #: js/oc-dialogs.js:386 msgid "Continue" -msgstr "" +msgstr "続ける" #: js/oc-dialogs.js:433 js/oc-dialogs.js:446 msgid "(all selected)" -msgstr "" +msgstr "(全て選択)" #: js/oc-dialogs.js:436 js/oc-dialogs.js:449 msgid "({count} selected)" -msgstr "" +msgstr "({count} 選択)" #: js/oc-dialogs.js:457 msgid "Error loading file exists template" -msgstr "" +msgstr "既存ファイルのテンプレートの読み込みエラー" #: js/oc-vcategories.js:5 js/oc-vcategories.js:85 js/oc-vcategories.js:102 #: js/oc-vcategories.js:117 js/oc-vcategories.js:132 js/oc-vcategories.js:162 @@ -314,7 +314,7 @@ msgstr "オブジェクタイプが指定されていません。" #: js/oc-vcategories.js:110 js/oc-vcategories.js:125 js/oc-vcategories.js:136 #: js/oc-vcategories.js:172 js/oc-vcategories.js:189 js/oc-vcategories.js:195 #: js/oc-vcategories.js:199 js/share.js:129 js/share.js:142 js/share.js:149 -#: js/share.js:645 js/share.js:657 +#: js/share.js:656 js/share.js:668 msgid "Error" msgstr "エラー" @@ -334,7 +334,7 @@ msgstr "共有中" msgid "Share" msgstr "共有" -#: js/share.js:131 js/share.js:685 +#: js/share.js:131 js/share.js:696 msgid "Error while sharing" msgstr "共有でエラー発生" @@ -434,23 +434,23 @@ msgstr "削除" msgid "share" msgstr "共有" -#: js/share.js:400 js/share.js:632 +#: js/share.js:400 js/share.js:643 msgid "Password protected" msgstr "パスワード保護" -#: js/share.js:645 +#: js/share.js:656 msgid "Error unsetting expiration date" msgstr "有効期限の未設定エラー" -#: js/share.js:657 +#: js/share.js:668 msgid "Error setting expiration date" msgstr "有効期限の設定でエラー発生" -#: js/share.js:672 +#: js/share.js:683 msgid "Sending ..." msgstr "送信中..." -#: js/share.js:683 +#: js/share.js:694 msgid "Email sent" msgstr "メールを送信しました" diff --git a/l10n/ja_JP/files.po b/l10n/ja_JP/files.po index b712c8b95a9d2d506226485360c7ce5e9d8b68ba..23062b05965b6fe278adb748fd258b90a53271ad 100644 --- a/l10n/ja_JP/files.po +++ b/l10n/ja_JP/files.po @@ -12,9 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:44-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-30 06:27+0000\n" +"Last-Translator: Daisuke Deguchi <ddeguchi@nagoya-u.jp>\n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -81,23 +81,23 @@ msgstr "ストレージに十分な空き容量がありません" #: ajax/upload.php:120 ajax/upload.php:143 msgid "Upload failed. Could not get file info." -msgstr "" +msgstr "アップロードに失敗。ファイル情報を取得できませんでした。" #: ajax/upload.php:136 msgid "Upload failed. Could not find uploaded file" -msgstr "" +msgstr "アップロードに失敗。アップロード済みのファイルを見つけることができませんでした。" #: ajax/upload.php:160 msgid "Invalid directory." msgstr "無効なディレクトリです。" -#: appinfo/app.php:12 +#: appinfo/app.php:11 msgid "Files" msgstr "ファイル" #: js/file-upload.js:244 msgid "Unable to upload {filename} as it is a directory or has 0 bytes" -msgstr "" +msgstr "ディレクトリもしくは0バイトのため {filename} をアップロードできません" #: js/file-upload.js:255 msgid "Not enough space available" @@ -109,7 +109,7 @@ msgstr "アップロードはキャンセルされました。" #: js/file-upload.js:356 msgid "Could not get result from server." -msgstr "" +msgstr "サーバから結果を取得できませんでした。" #: js/file-upload.js:446 msgid "" @@ -223,7 +223,7 @@ msgstr "ダウンロードの準備中です。ファイルサイズが大きい #: js/files.js:507 js/files.js:545 msgid "Error moving file" -msgstr "" +msgstr "ファイルの移動エラー" #: js/files.js:558 templates/index.php:61 msgid "Name" diff --git a/l10n/ja_JP/settings.po b/l10n/ja_JP/settings.po index c9851b54dea5c54a55ea9fe780ed35aacbb7d7e3..9414aa1720c0e7f67532967b9a00b2b71e2682f4 100644 --- a/l10n/ja_JP/settings.po +++ b/l10n/ja_JP/settings.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:45-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" +"PO-Revision-Date: 2013-09-30 06:33+0000\n" +"Last-Translator: Daisuke Deguchi <ddeguchi@nagoya-u.jp>\n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -89,42 +89,42 @@ msgstr "アプリを更新出来ませんでした。" #: changepassword/controller.php:20 msgid "Wrong password" -msgstr "" +msgstr "無効なパスワード" #: changepassword/controller.php:42 msgid "No user supplied" -msgstr "" +msgstr "ユーザが指定されていません" #: changepassword/controller.php:74 msgid "" "Please provide an admin recovery password, otherwise all user data will be " "lost" -msgstr "" +msgstr "復元用の管理者パスワードを入力してください。そうでない場合は、全ユーザのデータが失われます。" #: changepassword/controller.php:79 msgid "" "Wrong admin recovery password. Please check the password and try again." -msgstr "" +msgstr "無効な復元用の管理者パスワード。パスワードを確認して再度実行してください。" #: changepassword/controller.php:87 msgid "" "Back-end doesn't support password change, but the users encryption key was " "successfully updated." -msgstr "" +msgstr "バックエンドはパスワード変更をサポートしていませんが、ユーザの暗号化キーは正常に更新されました。" #: changepassword/controller.php:92 changepassword/controller.php:103 msgid "Unable to change password" -msgstr "" +msgstr "パスワードを変更できません" #: js/apps.js:43 msgid "Update to {appversion}" msgstr "{appversion} に更新" -#: js/apps.js:49 js/apps.js:82 js/apps.js:108 +#: js/apps.js:49 js/apps.js:82 js/apps.js:110 msgid "Disable" msgstr "無効" -#: js/apps.js:49 js/apps.js:89 js/apps.js:102 js/apps.js:117 +#: js/apps.js:49 js/apps.js:90 js/apps.js:103 js/apps.js:119 msgid "Enable" msgstr "有効化" @@ -132,43 +132,43 @@ msgstr "有効化" msgid "Please wait...." msgstr "しばらくお待ちください。" -#: js/apps.js:79 js/apps.js:80 js/apps.js:100 +#: js/apps.js:79 js/apps.js:80 js/apps.js:101 msgid "Error while disabling app" msgstr "アプリ無効化中にエラーが発生" -#: js/apps.js:99 js/apps.js:112 js/apps.js:113 +#: js/apps.js:100 js/apps.js:114 js/apps.js:115 msgid "Error while enabling app" msgstr "アプリ有効化中にエラーが発生" -#: js/apps.js:123 +#: js/apps.js:125 msgid "Updating...." msgstr "更新中...." -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error while updating app" msgstr "アプリの更新中にエラーが発生" -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error" msgstr "エラー" -#: js/apps.js:127 templates/apps.php:43 +#: js/apps.js:129 templates/apps.php:43 msgid "Update" msgstr "更新" -#: js/apps.js:130 +#: js/apps.js:132 msgid "Updated" msgstr "更新済み" -#: js/personal.js:220 +#: js/personal.js:221 msgid "Select a profile picture" msgstr "プロファイル画像を選択" -#: js/personal.js:265 +#: js/personal.js:266 msgid "Decrypting files... Please wait, this can take some time." msgstr "ファイルを複合中... しばらくお待ちください、この処理には少し時間がかかるかもしれません。" -#: js/personal.js:287 +#: js/personal.js:288 msgid "Saving..." msgstr "保存中..." @@ -496,11 +496,11 @@ msgstr "プロフィール写真" #: templates/personal.php:90 msgid "Upload new" -msgstr "" +msgstr "新規にアップロード" #: templates/personal.php:92 msgid "Select new from Files" -msgstr "" +msgstr "ファイルから新規に選択" #: templates/personal.php:93 msgid "Remove image" @@ -508,7 +508,7 @@ msgstr "画像を削除" #: templates/personal.php:94 msgid "Either png or jpg. Ideally square but you will be able to crop it." -msgstr "" +msgstr "png と jpg のいずれか。正方形が理想ですが、切り取って加工することも可能です。" #: templates/personal.php:97 msgid "Abort" diff --git a/l10n/ko/files.po b/l10n/ko/files.po index b2497ad3499ca6e15a294bfe3c796d1b8f624729..d3f72518cc7ec8a6917fb91b37c826c348353391 100644 --- a/l10n/ko/files.po +++ b/l10n/ko/files.po @@ -5,13 +5,14 @@ # Translators: # ujuc Gang <potopro@gmail.com>, 2013 # ujuc Gang <potopro@gmail.com>, 2013 +# smallsnail <bjh13579@gmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:44-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-29 10:06+0000\n" +"Last-Translator: smallsnail <bjh13579@gmail.com>\n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -31,11 +32,11 @@ msgstr "%s 항목을 이딩시키지 못하였음" #: ajax/upload.php:16 ajax/upload.php:45 msgid "Unable to set upload directory." -msgstr "" +msgstr "업로드 디렉터리를 정할수 없습니다" #: ajax/upload.php:22 msgid "Invalid Token" -msgstr "" +msgstr "잘못된 토큰" #: ajax/upload.php:59 msgid "No file was uploaded. Unknown error" @@ -78,23 +79,23 @@ msgstr "저장소가 용량이 충분하지 않습니다." #: ajax/upload.php:120 ajax/upload.php:143 msgid "Upload failed. Could not get file info." -msgstr "" +msgstr "업로드에 실패했습니다. 파일 정보를 가져올수 없습니다." #: ajax/upload.php:136 msgid "Upload failed. Could not find uploaded file" -msgstr "" +msgstr "업로드에 실패했습니다. 업로드할 파일을 찾을수 없습니다" #: ajax/upload.php:160 msgid "Invalid directory." msgstr "올바르지 않은 디렉터리입니다." -#: appinfo/app.php:12 +#: appinfo/app.php:11 msgid "Files" msgstr "파일" #: js/file-upload.js:244 msgid "Unable to upload {filename} as it is a directory or has 0 bytes" -msgstr "" +msgstr "{filename}을 업로드 할수 없습니다. 폴더이거나 0 바이트 파일입니다." #: js/file-upload.js:255 msgid "Not enough space available" @@ -106,7 +107,7 @@ msgstr "업로드가 취소되었습니다." #: js/file-upload.js:356 msgid "Could not get result from server." -msgstr "" +msgstr "서버에서 결과를 가져올수 없습니다." #: js/file-upload.js:446 msgid "" @@ -119,7 +120,7 @@ msgstr "URL을 입력해야 합니다." #: js/file-upload.js:525 lib/app.php:53 msgid "Invalid folder name. Usage of 'Shared' is reserved by ownCloud" -msgstr "" +msgstr "유효하지 않은 폴더명입니다. \"Shared\" 이름의 사용은 OwnCloud 가 이미 예약하고 있습니다." #: js/file-upload.js:557 js/file-upload.js:573 js/files.js:507 js/files.js:545 msgid "Error" @@ -168,21 +169,21 @@ msgstr "되돌리기" #: js/filelist.js:533 js/filelist.js:599 js/files.js:576 msgid "%n folder" msgid_plural "%n folders" -msgstr[0] "" +msgstr[0] "폴더 %n" #: js/filelist.js:534 js/filelist.js:600 js/files.js:582 msgid "%n file" msgid_plural "%n files" -msgstr[0] "" +msgstr[0] "파일 %n 개" #: js/filelist.js:541 msgid "{dirs} and {files}" -msgstr "" +msgstr "{dirs} 그리고 {files}" #: js/filelist.js:731 js/filelist.js:769 msgid "Uploading %n file" msgid_plural "Uploading %n files" -msgstr[0] "" +msgstr[0] "%n 개의 파일을 업로드중" #: js/files.js:25 msgid "'.' is an invalid file name." @@ -210,7 +211,7 @@ msgstr "저장 공간이 거의 가득 찼습니다 ({usedSpacePercent}%)" msgid "" "Encryption was disabled but your files are still encrypted. Please go to " "your personal settings to decrypt your files." -msgstr "" +msgstr "암호화는 해제되어 있지만, 파일은 아직 암호화 되어 있습니다. 개인 설저에 가셔서 암호를 해제하십시오" #: js/files.js:296 msgid "" @@ -220,7 +221,7 @@ msgstr "다운로드가 준비 중입니다. 파일 크기가 크다면 시간 #: js/files.js:507 js/files.js:545 msgid "Error moving file" -msgstr "" +msgstr "파일 이동 오류" #: js/files.js:558 templates/index.php:61 msgid "Name" @@ -237,7 +238,7 @@ msgstr "수정됨" #: lib/app.php:73 #, php-format msgid "%s could not be renamed" -msgstr "" +msgstr "%s 의 이름을 변경할수 없습니다" #: lib/helper.php:11 templates/index.php:17 msgid "Upload" diff --git a/l10n/ko/files_sharing.po b/l10n/ko/files_sharing.po index 434e19ca27ab0b758565655fde5d552df077e9f8..da94ad321107391e1cd8d25755d00d873171900e 100644 --- a/l10n/ko/files_sharing.po +++ b/l10n/ko/files_sharing.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# smallsnail <bjh13579@gmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-13 21:46-0400\n" -"PO-Revision-Date: 2013-09-14 00:01+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 10:14+0000\n" +"Last-Translator: smallsnail <bjh13579@gmail.com>\n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,7 +20,7 @@ msgstr "" #: templates/authenticate.php:4 msgid "The password is wrong. Try again." -msgstr "" +msgstr "비밀번호가 틀립니다. 다시 입력해주세요." #: templates/authenticate.php:7 msgid "Password" @@ -31,27 +32,27 @@ msgstr "제출" #: templates/part.404.php:3 msgid "Sorry, this link doesn’t seem to work anymore." -msgstr "" +msgstr "죄송합니다만 이 링크는 더이상 작동되지 않습니다." #: templates/part.404.php:4 msgid "Reasons might be:" -msgstr "" +msgstr "이유는 다음과 같을 수 있습니다:" #: templates/part.404.php:6 msgid "the item was removed" -msgstr "" +msgstr "이 항목은 삭제되었습니다" #: templates/part.404.php:7 msgid "the link expired" -msgstr "" +msgstr "링크가 만료되었습니다" #: templates/part.404.php:8 msgid "sharing is disabled" -msgstr "" +msgstr "공유가 비활성되었습니다" #: templates/part.404.php:10 msgid "For more info, please ask the person who sent this link." -msgstr "" +msgstr "더 자세한 설명은 링크를 보내신 분에게 여쭤보십시오" #: templates/public.php:15 #, php-format diff --git a/l10n/ko/files_trashbin.po b/l10n/ko/files_trashbin.po index 3e48f534a18e85e32eea1c454e0f115b58a6bf52..4d39e2d9acdad8ebd099d633e836d9188057c233 100644 --- a/l10n/ko/files_trashbin.po +++ b/l10n/ko/files_trashbin.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# smallsnail <bjh13579@gmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-08-15 04:47-0400\n" -"PO-Revision-Date: 2013-08-15 08:48+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 07:38+0000\n" +"Last-Translator: smallsnail <bjh13579@gmail.com>\n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,63 +21,63 @@ msgstr "" #: ajax/delete.php:42 #, php-format msgid "Couldn't delete %s permanently" -msgstr "" +msgstr "%s를 영구적으로 삭제할수 없습니다" #: ajax/undelete.php:42 #, php-format msgid "Couldn't restore %s" -msgstr "" +msgstr "%s를 복원할수 없습니다" -#: js/trash.js:7 js/trash.js:100 +#: js/trash.js:7 js/trash.js:102 msgid "perform restore operation" -msgstr "" +msgstr "복원 작업중" -#: js/trash.js:20 js/trash.js:48 js/trash.js:118 js/trash.js:146 +#: js/trash.js:20 js/trash.js:49 js/trash.js:120 js/trash.js:148 msgid "Error" msgstr "오류" -#: js/trash.js:36 +#: js/trash.js:37 msgid "delete file permanently" -msgstr "" +msgstr "영구적으로 파일 삭제하기" -#: js/trash.js:127 +#: js/trash.js:129 msgid "Delete permanently" msgstr "영원히 삭제" -#: js/trash.js:182 templates/index.php:17 +#: js/trash.js:190 templates/index.php:21 msgid "Name" msgstr "이름" -#: js/trash.js:183 templates/index.php:27 +#: js/trash.js:191 templates/index.php:31 msgid "Deleted" -msgstr "" +msgstr "삭제됨" -#: js/trash.js:191 +#: js/trash.js:199 msgid "%n folder" msgid_plural "%n folders" -msgstr[0] "" +msgstr[0] "폴더 %n개" -#: js/trash.js:197 +#: js/trash.js:205 msgid "%n file" msgid_plural "%n files" -msgstr[0] "" +msgstr[0] "파일 %n개 " -#: lib/trash.php:819 lib/trash.php:821 +#: lib/trashbin.php:814 lib/trashbin.php:816 msgid "restored" -msgstr "" +msgstr "복원됨" #: templates/index.php:9 msgid "Nothing in here. Your trash bin is empty!" -msgstr "" +msgstr "현재 휴지통은 비어있습니다!" -#: templates/index.php:20 templates/index.php:22 +#: templates/index.php:24 templates/index.php:26 msgid "Restore" msgstr "복원" -#: templates/index.php:30 templates/index.php:31 +#: templates/index.php:34 templates/index.php:35 msgid "Delete" msgstr "삭제" #: templates/part.breadcrumb.php:9 msgid "Deleted Files" -msgstr "" +msgstr "삭제된 파일들" diff --git a/l10n/ko/files_versions.po b/l10n/ko/files_versions.po index 19ec188ee6c09997312cec52b88b40ba8f6485ca..1a9375ae40014933b127b5c1be3d1f6f144a0fb5 100644 --- a/l10n/ko/files_versions.po +++ b/l10n/ko/files_versions.po @@ -4,13 +4,14 @@ # # Translators: # Shinjo Park <kde@peremen.name>, 2013 +# smallsnail <bjh13579@gmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-07-28 01:56-0400\n" -"PO-Revision-Date: 2013-07-27 06:10+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 10:18+0000\n" +"Last-Translator: smallsnail <bjh13579@gmail.com>\n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -29,16 +30,16 @@ msgstr "버전" #: js/versions.js:53 msgid "Failed to revert {file} to revision {timestamp}." -msgstr "" +msgstr "{timestamp} 판의 {file}로 돌리는데 실패했습니다." #: js/versions.js:79 msgid "More versions..." -msgstr "" +msgstr "더 많은 버전들..." #: js/versions.js:116 msgid "No other versions available" -msgstr "" +msgstr "다른 버전을 사용할수 없습니다" -#: js/versions.js:149 +#: js/versions.js:145 msgid "Restore" msgstr "복원" diff --git a/l10n/ko/lib.po b/l10n/ko/lib.po index 06627a79781404151c67ad3b1dd239b2093ca7f5..ca05c5e13306f6aa14c116bf10e30dd63541f72d 100644 --- a/l10n/ko/lib.po +++ b/l10n/ko/lib.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-16 11:33-0400\n" -"PO-Revision-Date: 2013-09-16 15:34+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 07:46+0000\n" +"Last-Translator: smallsnail <bjh13579@gmail.com>\n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,53 +19,53 @@ msgstr "" "Language: ko\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: app.php:239 +#: app.php:237 #, php-format msgid "" "App \"%s\" can't be installed because it is not compatible with this version" " of ownCloud." msgstr "현재 ownCloud 버전과 호환되지 않기 때문에 \"%s\" 앱을 설치할 수 없습니다." -#: app.php:250 +#: app.php:248 msgid "No app name specified" msgstr "앱 이름이 지정되지 않았습니다." -#: app.php:361 +#: app.php:352 msgid "Help" msgstr "도움말" -#: app.php:374 +#: app.php:365 msgid "Personal" msgstr "개인" -#: app.php:385 +#: app.php:376 msgid "Settings" msgstr "설정" -#: app.php:397 +#: app.php:388 msgid "Users" msgstr "사용자" -#: app.php:410 +#: app.php:401 msgid "Admin" msgstr "관리자" -#: app.php:839 +#: app.php:832 #, php-format msgid "Failed to upgrade \"%s\"." msgstr "\"%s\" 업그레이드에 실패했습니다." #: avatar.php:56 msgid "Custom profile pictures don't work with encryption yet" -msgstr "" +msgstr "개개인의 프로필 사진은 아직은 암호화 되지 않습니다" #: avatar.php:64 msgid "Unknown filetype" -msgstr "" +msgstr "알수없는 파일형식" #: avatar.php:69 msgid "Invalid image" -msgstr "" +msgstr "잘못된 그림" #: defaults.php:35 msgid "web services under your control" @@ -96,7 +96,7 @@ msgstr "선택한 파일들은 ZIP 파일을 생성하기에 너무 큽니다." msgid "" "Download the files in smaller chunks, seperately or kindly ask your " "administrator." -msgstr "" +msgstr "작은 조각들 안에 들어있는 파일들을 받고자 하신다면, 나누어서 받으시거나 혹은 시스템 관리자에게 정중하게 물어보십시오" #: installer.php:63 msgid "No source specified when installing app" @@ -166,15 +166,15 @@ msgstr "인증 오류" msgid "Token expired. Please reload page." msgstr "토큰이 만료되었습니다. 페이지를 새로 고치십시오." -#: search/provider/file.php:17 search/provider/file.php:35 +#: search/provider/file.php:18 search/provider/file.php:36 msgid "Files" msgstr "파일" -#: search/provider/file.php:26 search/provider/file.php:33 +#: search/provider/file.php:27 search/provider/file.php:34 msgid "Text" msgstr "텍스트" -#: search/provider/file.php:29 +#: search/provider/file.php:30 msgid "Images" msgstr "그림" @@ -278,6 +278,11 @@ msgstr "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서 msgid "Please double check the <a href='%s'>installation guides</a>." msgstr "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오." +#: tags.php:194 +#, php-format +msgid "Could not find category \"%s\"" +msgstr "분류 \"%s\"을(를) 찾을 수 없습니다." + #: template/functions.php:96 msgid "seconds ago" msgstr "초 전" @@ -325,8 +330,3 @@ msgstr "년 전" #: template.php:297 msgid "Caused by:" msgstr "원인: " - -#: vcategories.php:188 vcategories.php:249 -#, php-format -msgid "Could not find category \"%s\"" -msgstr "분류 \"%s\"을(를) 찾을 수 없습니다." diff --git a/l10n/lt_LT/core.po b/l10n/lt_LT/core.po index f340c7a46db57a87bc630805c51b01c0faaf11ab..4a22a7c94823bb76f855c3d3c006813ab6dc4624 100644 --- a/l10n/lt_LT/core.po +++ b/l10n/lt_LT/core.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-22 12:55-0400\n" -"PO-Revision-Date: 2013-09-20 15:01+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-29 07:58+0000\n" +"Last-Translator: Liudas Ališauskas <liudas.alisauskas@gmail.com>\n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -277,23 +277,23 @@ msgstr "Klaida įkeliant žinutės ruošinį: {error}" #: js/oc-dialogs.js:347 msgid "{count} file conflict" msgid_plural "{count} file conflicts" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "{count} failas konfliktuoja" +msgstr[1] "{count} failai konfliktuoja" +msgstr[2] "{count} failų konfliktų" #: js/oc-dialogs.js:361 msgid "One file conflict" -msgstr "" +msgstr "Vienas failo konfliktas" #: js/oc-dialogs.js:367 msgid "Which files do you want to keep?" -msgstr "" +msgstr "Kuriuos failus norite laikyti?" #: js/oc-dialogs.js:368 msgid "" "If you select both versions, the copied file will have a number added to its" " name." -msgstr "" +msgstr "Jei pasirenkate abi versijas, nukopijuotas failas turės pridėtą numerį pavadinime." #: js/oc-dialogs.js:376 msgid "Cancel" @@ -301,19 +301,19 @@ msgstr "Atšaukti" #: js/oc-dialogs.js:386 msgid "Continue" -msgstr "" +msgstr "Tęsti" #: js/oc-dialogs.js:433 js/oc-dialogs.js:446 msgid "(all selected)" -msgstr "" +msgstr "(visi pažymėti)" #: js/oc-dialogs.js:436 js/oc-dialogs.js:449 msgid "({count} selected)" -msgstr "" +msgstr "({count} pažymėtų)" #: js/oc-dialogs.js:457 msgid "Error loading file exists template" -msgstr "" +msgstr "Klaida įkeliant esančių failų ruošinį" #: js/oc-vcategories.js:5 js/oc-vcategories.js:85 js/oc-vcategories.js:102 #: js/oc-vcategories.js:117 js/oc-vcategories.js:132 js/oc-vcategories.js:162 @@ -324,7 +324,7 @@ msgstr "Objekto tipas nenurodytas." #: js/oc-vcategories.js:110 js/oc-vcategories.js:125 js/oc-vcategories.js:136 #: js/oc-vcategories.js:172 js/oc-vcategories.js:189 js/oc-vcategories.js:195 #: js/oc-vcategories.js:199 js/share.js:129 js/share.js:142 js/share.js:149 -#: js/share.js:645 js/share.js:657 +#: js/share.js:656 js/share.js:668 msgid "Error" msgstr "Klaida" @@ -344,7 +344,7 @@ msgstr "Dalinamasi" msgid "Share" msgstr "Dalintis" -#: js/share.js:131 js/share.js:685 +#: js/share.js:131 js/share.js:696 msgid "Error while sharing" msgstr "Klaida, dalijimosi metu" @@ -444,23 +444,23 @@ msgstr "ištrinti" msgid "share" msgstr "dalintis" -#: js/share.js:400 js/share.js:632 +#: js/share.js:400 js/share.js:643 msgid "Password protected" msgstr "Apsaugota slaptažodžiu" -#: js/share.js:645 +#: js/share.js:656 msgid "Error unsetting expiration date" msgstr "Klaida nuimant galiojimo laiką" -#: js/share.js:657 +#: js/share.js:668 msgid "Error setting expiration date" msgstr "Klaida nustatant galiojimo laiką" -#: js/share.js:672 +#: js/share.js:683 msgid "Sending ..." msgstr "Siunčiama..." -#: js/share.js:683 +#: js/share.js:694 msgid "Email sent" msgstr "Laiškas išsiųstas" diff --git a/l10n/lt_LT/files.po b/l10n/lt_LT/files.po index da69b0a419bf11cc830235eae937fe76592b884b..829d61188a31a491a0179d017fce7f38ad3335cc 100644 --- a/l10n/lt_LT/files.po +++ b/l10n/lt_LT/files.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:44-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-29 08:46+0000\n" +"Last-Translator: Liudas Ališauskas <liudas.alisauskas@gmail.com>\n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -78,23 +78,23 @@ msgstr "Nepakanka vietos serveryje" #: ajax/upload.php:120 ajax/upload.php:143 msgid "Upload failed. Could not get file info." -msgstr "" +msgstr "Įkėlimas nepavyko. Nepavyko gauti failo informacijos." #: ajax/upload.php:136 msgid "Upload failed. Could not find uploaded file" -msgstr "" +msgstr "Įkėlimas nepavyko. Nepavyko rasti įkelto failo" #: ajax/upload.php:160 msgid "Invalid directory." msgstr "Neteisingas aplankas" -#: appinfo/app.php:12 +#: appinfo/app.php:11 msgid "Files" msgstr "Failai" #: js/file-upload.js:244 msgid "Unable to upload {filename} as it is a directory or has 0 bytes" -msgstr "" +msgstr "Nepavyksta įkelti {filename}, nes tai katalogas arba yra 0 baitų dydžio" #: js/file-upload.js:255 msgid "Not enough space available" @@ -106,7 +106,7 @@ msgstr "Įkėlimas atšauktas." #: js/file-upload.js:356 msgid "Could not get result from server." -msgstr "" +msgstr "Nepavyko gauti rezultato iš serverio." #: js/file-upload.js:446 msgid "" @@ -226,7 +226,7 @@ msgstr "Jūsų atsisiuntimas yra paruošiamas. tai gali užtrukti jei atsisiunč #: js/files.js:507 js/files.js:545 msgid "Error moving file" -msgstr "" +msgstr "Klaida perkeliant failą" #: js/files.js:558 templates/index.php:61 msgid "Name" diff --git a/l10n/lt_LT/settings.po b/l10n/lt_LT/settings.po index 14592409dd94e4985f636edf01acf7697458e37f..ff719fb19fe07ea24b1bbfd894bc8a43fe686e3d 100644 --- a/l10n/lt_LT/settings.po +++ b/l10n/lt_LT/settings.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:45-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" +"PO-Revision-Date: 2013-09-29 08:49+0000\n" +"Last-Translator: Liudas Ališauskas <liudas.alisauskas@gmail.com>\n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -90,42 +90,42 @@ msgstr "Nepavyko atnaujinti programos." #: changepassword/controller.php:20 msgid "Wrong password" -msgstr "" +msgstr "Neteisingas slaptažodis" #: changepassword/controller.php:42 msgid "No user supplied" -msgstr "" +msgstr "Nepateiktas naudotojas" #: changepassword/controller.php:74 msgid "" "Please provide an admin recovery password, otherwise all user data will be " "lost" -msgstr "" +msgstr "Prašome įvesti administratoriaus atkūrimo slaptažodį, kitaip visi naudotojo suomenys bus prarasti" #: changepassword/controller.php:79 msgid "" "Wrong admin recovery password. Please check the password and try again." -msgstr "" +msgstr "Netinkamas administratoriau atkūrimo slaptažodis. Prašome pasitikrinti ir bandyti vėl." #: changepassword/controller.php:87 msgid "" "Back-end doesn't support password change, but the users encryption key was " "successfully updated." -msgstr "" +msgstr "Sistema nepalaiko slaptažodžio keitimo, bet naudotojo šifravimo raktas buvo sėkmingai atnaujintas." #: changepassword/controller.php:92 changepassword/controller.php:103 msgid "Unable to change password" -msgstr "" +msgstr "Nepavyksta pakeisti slaptažodžio" #: js/apps.js:43 msgid "Update to {appversion}" msgstr "Atnaujinti iki {appversion}" -#: js/apps.js:49 js/apps.js:82 js/apps.js:108 +#: js/apps.js:49 js/apps.js:82 js/apps.js:110 msgid "Disable" msgstr "Išjungti" -#: js/apps.js:49 js/apps.js:89 js/apps.js:102 js/apps.js:117 +#: js/apps.js:49 js/apps.js:90 js/apps.js:103 js/apps.js:119 msgid "Enable" msgstr "Įjungti" @@ -133,43 +133,43 @@ msgstr "Įjungti" msgid "Please wait...." msgstr "Prašome palaukti..." -#: js/apps.js:79 js/apps.js:80 js/apps.js:100 +#: js/apps.js:79 js/apps.js:80 js/apps.js:101 msgid "Error while disabling app" msgstr "Klaida išjungiant programą" -#: js/apps.js:99 js/apps.js:112 js/apps.js:113 +#: js/apps.js:100 js/apps.js:114 js/apps.js:115 msgid "Error while enabling app" msgstr "Klaida įjungiant programą" -#: js/apps.js:123 +#: js/apps.js:125 msgid "Updating...." msgstr "Atnaujinama..." -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error while updating app" msgstr "Įvyko klaida atnaujinant programą" -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error" msgstr "Klaida" -#: js/apps.js:127 templates/apps.php:43 +#: js/apps.js:129 templates/apps.php:43 msgid "Update" msgstr "Atnaujinti" -#: js/apps.js:130 +#: js/apps.js:132 msgid "Updated" msgstr "Atnaujinta" -#: js/personal.js:220 +#: js/personal.js:221 msgid "Select a profile picture" msgstr "Pažymėkite profilio paveikslėlį" -#: js/personal.js:265 +#: js/personal.js:266 msgid "Decrypting files... Please wait, this can take some time." msgstr "Iššifruojami failai... Prašome palaukti, tai gali užtrukti." -#: js/personal.js:287 +#: js/personal.js:288 msgid "Saving..." msgstr "Saugoma..." diff --git a/l10n/pl/core.po b/l10n/pl/core.po index 3d7aae83baeb37eaa90d13be4f9588b73e918af4..d3f781b0e4da2e5c4433189b1094515be628dbd2 100644 --- a/l10n/pl/core.po +++ b/l10n/pl/core.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-22 12:55-0400\n" -"PO-Revision-Date: 2013-09-20 15:01+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 12:27+0000\n" +"Last-Translator: Cyryl Sochacki <cyrylsochacki@gmail.com>\n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -98,11 +98,11 @@ msgstr "" #: avatar/controller.php:81 msgid "Unknown filetype" -msgstr "" +msgstr "Nieznany typ pliku" #: avatar/controller.php:85 msgid "Invalid image" -msgstr "" +msgstr "Nieprawidłowe zdjęcie" #: avatar/controller.php:115 avatar/controller.php:142 msgid "No temporary profile picture available, try again" @@ -275,13 +275,13 @@ msgstr "" #: js/oc-dialogs.js:347 msgid "{count} file conflict" msgid_plural "{count} file conflicts" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" +msgstr[0] "{count} konfliktów plików" +msgstr[1] "{count} konfliktów plików" +msgstr[2] "{count} konfliktów plików" #: js/oc-dialogs.js:361 msgid "One file conflict" -msgstr "" +msgstr "Konflikt pliku" #: js/oc-dialogs.js:367 msgid "Which files do you want to keep?" @@ -299,15 +299,15 @@ msgstr "Anuluj" #: js/oc-dialogs.js:386 msgid "Continue" -msgstr "" +msgstr "Kontynuuj " #: js/oc-dialogs.js:433 js/oc-dialogs.js:446 msgid "(all selected)" -msgstr "" +msgstr "(wszystkie zaznaczone)" #: js/oc-dialogs.js:436 js/oc-dialogs.js:449 msgid "({count} selected)" -msgstr "" +msgstr "({count} zaznaczonych)" #: js/oc-dialogs.js:457 msgid "Error loading file exists template" @@ -322,7 +322,7 @@ msgstr "Nie określono typu obiektu." #: js/oc-vcategories.js:110 js/oc-vcategories.js:125 js/oc-vcategories.js:136 #: js/oc-vcategories.js:172 js/oc-vcategories.js:189 js/oc-vcategories.js:195 #: js/oc-vcategories.js:199 js/share.js:129 js/share.js:142 js/share.js:149 -#: js/share.js:645 js/share.js:657 +#: js/share.js:656 js/share.js:668 msgid "Error" msgstr "Błąd" @@ -342,7 +342,7 @@ msgstr "Udostępniono" msgid "Share" msgstr "Udostępnij" -#: js/share.js:131 js/share.js:685 +#: js/share.js:131 js/share.js:696 msgid "Error while sharing" msgstr "Błąd podczas współdzielenia" @@ -442,23 +442,23 @@ msgstr "usuń" msgid "share" msgstr "współdziel" -#: js/share.js:400 js/share.js:632 +#: js/share.js:400 js/share.js:643 msgid "Password protected" msgstr "Zabezpieczone hasłem" -#: js/share.js:645 +#: js/share.js:656 msgid "Error unsetting expiration date" msgstr "Błąd podczas usuwania daty wygaśnięcia" -#: js/share.js:657 +#: js/share.js:668 msgid "Error setting expiration date" msgstr "Błąd podczas ustawiania daty wygaśnięcia" -#: js/share.js:672 +#: js/share.js:683 msgid "Sending ..." msgstr "Wysyłanie..." -#: js/share.js:683 +#: js/share.js:694 msgid "Email sent" msgstr "E-mail wysłany" diff --git a/l10n/pl/files.po b/l10n/pl/files.po index b94335006bb021b959ebebc674d546b2916c7236..a88ee97ad7e89bf66341e6eb7e34aa273b5eb5cd 100644 --- a/l10n/pl/files.po +++ b/l10n/pl/files.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:44-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" +"PO-Revision-Date: 2013-09-30 12:24+0000\n" +"Last-Translator: Cyryl Sochacki <cyrylsochacki@gmail.com>\n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -79,23 +79,23 @@ msgstr "Za mało dostępnego miejsca" #: ajax/upload.php:120 ajax/upload.php:143 msgid "Upload failed. Could not get file info." -msgstr "" +msgstr "Nieudane przesłanie. Nie można pobrać informacji o pliku." #: ajax/upload.php:136 msgid "Upload failed. Could not find uploaded file" -msgstr "" +msgstr "Nieudane przesłanie. Nie można znaleźć przesyłanego pliku" #: ajax/upload.php:160 msgid "Invalid directory." msgstr "Zła ścieżka." -#: appinfo/app.php:12 +#: appinfo/app.php:11 msgid "Files" msgstr "Pliki" #: js/file-upload.js:244 msgid "Unable to upload {filename} as it is a directory or has 0 bytes" -msgstr "" +msgstr "Nie można przesłać {filename} być może jest katalogiem lub posiada 0 bajtów" #: js/file-upload.js:255 msgid "Not enough space available" @@ -107,7 +107,7 @@ msgstr "Wczytywanie anulowane." #: js/file-upload.js:356 msgid "Could not get result from server." -msgstr "" +msgstr "Nie można uzyskać wyniku z serwera." #: js/file-upload.js:446 msgid "" @@ -227,7 +227,7 @@ msgstr "Pobieranie jest przygotowywane. Może to zająć trochę czasu jeśli pl #: js/files.js:507 js/files.js:545 msgid "Error moving file" -msgstr "" +msgstr "Błąd prz przenoszeniu pliku" #: js/files.js:558 templates/index.php:61 msgid "Name" diff --git a/l10n/pl/lib.po b/l10n/pl/lib.po index beae34e58032bc7e70e077bf6d9a9983ee137da3..9e29c51c5a9e8a08335e00b55c5ea2955e1741f0 100644 --- a/l10n/pl/lib.po +++ b/l10n/pl/lib.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-16 11:33-0400\n" -"PO-Revision-Date: 2013-09-16 15:34+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" +"PO-Revision-Date: 2013-09-30 12:26+0000\n" +"Last-Translator: Cyryl Sochacki <cyrylsochacki@gmail.com>\n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,53 +18,53 @@ msgstr "" "Language: pl\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: app.php:239 +#: app.php:237 #, php-format msgid "" "App \"%s\" can't be installed because it is not compatible with this version" " of ownCloud." msgstr "Aplikacja \"%s\" nie może zostać zainstalowana, ponieważ nie jest zgodna z tą wersją ownCloud." -#: app.php:250 +#: app.php:248 msgid "No app name specified" msgstr "Nie określono nazwy aplikacji" -#: app.php:361 +#: app.php:352 msgid "Help" msgstr "Pomoc" -#: app.php:374 +#: app.php:365 msgid "Personal" msgstr "Osobiste" -#: app.php:385 +#: app.php:376 msgid "Settings" msgstr "Ustawienia" -#: app.php:397 +#: app.php:388 msgid "Users" msgstr "Użytkownicy" -#: app.php:410 +#: app.php:401 msgid "Admin" msgstr "Administrator" -#: app.php:839 +#: app.php:832 #, php-format msgid "Failed to upgrade \"%s\"." msgstr "Błąd przy aktualizacji \"%s\"." #: avatar.php:56 msgid "Custom profile pictures don't work with encryption yet" -msgstr "" +msgstr "Domyślny profil zdjęć nie działa z szyfrowaniem jeszcze" #: avatar.php:64 msgid "Unknown filetype" -msgstr "" +msgstr "Nieznany typ pliku" #: avatar.php:69 msgid "Invalid image" -msgstr "" +msgstr "Błędne zdjęcie" #: defaults.php:35 msgid "web services under your control" @@ -165,15 +165,15 @@ msgstr "Błąd uwierzytelniania" msgid "Token expired. Please reload page." msgstr "Token wygasł. Proszę ponownie załadować stronę." -#: search/provider/file.php:17 search/provider/file.php:35 +#: search/provider/file.php:18 search/provider/file.php:36 msgid "Files" msgstr "Pliki" -#: search/provider/file.php:26 search/provider/file.php:33 +#: search/provider/file.php:27 search/provider/file.php:34 msgid "Text" msgstr "Połączenie tekstowe" -#: search/provider/file.php:29 +#: search/provider/file.php:30 msgid "Images" msgstr "Obrazy" @@ -277,6 +277,11 @@ msgstr "Serwer internetowy nie jest jeszcze poprawnie skonfigurowany, aby umożl msgid "Please double check the <a href='%s'>installation guides</a>." msgstr "Sprawdź ponownie <a href='%s'>przewodniki instalacji</a>." +#: tags.php:194 +#, php-format +msgid "Could not find category \"%s\"" +msgstr "Nie można odnaleźć kategorii \"%s\"" + #: template/functions.php:96 msgid "seconds ago" msgstr "sekund temu" @@ -332,8 +337,3 @@ msgstr "lat temu" #: template.php:297 msgid "Caused by:" msgstr "Spowodowane przez:" - -#: vcategories.php:188 vcategories.php:249 -#, php-format -msgid "Could not find category \"%s\"" -msgstr "Nie można odnaleźć kategorii \"%s\"" diff --git a/l10n/pl/settings.po b/l10n/pl/settings.po index 5b5e435ef1cc589e02c57f455b25717a77e76aea..830b2045a3fdd06dfbf99fa8ce8904dda511b6e3 100644 --- a/l10n/pl/settings.po +++ b/l10n/pl/settings.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-09-20 10:45-0400\n" -"PO-Revision-Date: 2013-09-20 14:45+0000\n" -"Last-Translator: I Robot <owncloud-bot@tmit.eu>\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" +"PO-Revision-Date: 2013-09-30 12:15+0000\n" +"Last-Translator: Cyryl Sochacki <cyrylsochacki@gmail.com>\n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -88,7 +88,7 @@ msgstr "Nie można uaktualnić aplikacji." #: changepassword/controller.php:20 msgid "Wrong password" -msgstr "" +msgstr "Złe hasło" #: changepassword/controller.php:42 msgid "No user supplied" @@ -113,17 +113,17 @@ msgstr "" #: changepassword/controller.php:92 changepassword/controller.php:103 msgid "Unable to change password" -msgstr "" +msgstr "Nie można zmienić hasła" #: js/apps.js:43 msgid "Update to {appversion}" msgstr "Aktualizacja do {appversion}" -#: js/apps.js:49 js/apps.js:82 js/apps.js:108 +#: js/apps.js:49 js/apps.js:82 js/apps.js:110 msgid "Disable" msgstr "Wyłącz" -#: js/apps.js:49 js/apps.js:89 js/apps.js:102 js/apps.js:117 +#: js/apps.js:49 js/apps.js:90 js/apps.js:103 js/apps.js:119 msgid "Enable" msgstr "Włącz" @@ -131,43 +131,43 @@ msgstr "Włącz" msgid "Please wait...." msgstr "Proszę czekać..." -#: js/apps.js:79 js/apps.js:80 js/apps.js:100 +#: js/apps.js:79 js/apps.js:80 js/apps.js:101 msgid "Error while disabling app" msgstr "Błąd podczas wyłączania aplikacji" -#: js/apps.js:99 js/apps.js:112 js/apps.js:113 +#: js/apps.js:100 js/apps.js:114 js/apps.js:115 msgid "Error while enabling app" msgstr "Błąd podczas włączania aplikacji" -#: js/apps.js:123 +#: js/apps.js:125 msgid "Updating...." msgstr "Aktualizacja w toku..." -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error while updating app" msgstr "Błąd podczas aktualizacji aplikacji" -#: js/apps.js:126 +#: js/apps.js:128 msgid "Error" msgstr "Błąd" -#: js/apps.js:127 templates/apps.php:43 +#: js/apps.js:129 templates/apps.php:43 msgid "Update" msgstr "Aktualizuj" -#: js/apps.js:130 +#: js/apps.js:132 msgid "Updated" msgstr "Zaktualizowano" -#: js/personal.js:220 +#: js/personal.js:221 msgid "Select a profile picture" -msgstr "" +msgstr "Wybierz zdjęcie profilu" -#: js/personal.js:265 +#: js/personal.js:266 msgid "Decrypting files... Please wait, this can take some time." msgstr "Odszyfrowuje pliki... Proszę czekać, to może zająć jakiś czas." -#: js/personal.js:287 +#: js/personal.js:288 msgid "Saving..." msgstr "Zapisywanie..." @@ -495,15 +495,15 @@ msgstr "Zdjęcie profilu" #: templates/personal.php:90 msgid "Upload new" -msgstr "" +msgstr "Wczytaj nowe" #: templates/personal.php:92 msgid "Select new from Files" -msgstr "" +msgstr "Wybierz nowe z plików" #: templates/personal.php:93 msgid "Remove image" -msgstr "" +msgstr "Usuń zdjęcie" #: templates/personal.php:94 msgid "Either png or jpg. Ideally square but you will be able to crop it." @@ -515,7 +515,7 @@ msgstr "Anuluj" #: templates/personal.php:98 msgid "Choose as profile image" -msgstr "" +msgstr "Wybierz zdjęcie profilu" #: templates/personal.php:106 templates/personal.php:107 msgid "Language" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index afb3a410c4c0f7f6778aca15ef188011b0c8c1ce..687b168209c8d5070bd04c13b193d92345c73db8 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 1e72820c523fcb07ff6a509a005122e85e883ad6..5a5cf056beb95345b3f102aca16096d3c40f6617 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:14-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index aea2b2282e1eff4c997be34bb60ef1edb2e68295..312f7f29bb0e6b1072fd30fb41faf9d0844adbe5 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:15-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index ad32cfb2fcfe69230b8143676f49faf78fe3a5bb..0ec2c070912ef82fb275d28310360758cc17d338 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index e9a596f361cf46effc970905b6715036ba057bc3..77c296c9a7c49a3c554cef885caea5e5b0bdf409 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_trashbin.pot b/l10n/templates/files_trashbin.pot index 044fb375dfce5c1a0894a7dd93a493c018a410cb..b379edf9e9310d38f1a6affa8f582b368ab787cd 100644 --- a/l10n/templates/files_trashbin.pot +++ b/l10n/templates/files_trashbin.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index a61952105bd4a61febef8cf06ae835b51275c311..4d7bff6e8b69a372cec83c842b494d1bfd536ff8 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index 2f54bdc23353cf4425d5398f6863e06f497ece1d..cdaf465ab302912b24aea53c00e7da465514ed12 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -18,38 +18,38 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: app.php:239 +#: app.php:237 #, php-format msgid "" "App \"%s\" can't be installed because it is not compatible with this version " "of ownCloud." msgstr "" -#: app.php:250 +#: app.php:248 msgid "No app name specified" msgstr "" -#: app.php:361 +#: app.php:352 msgid "Help" msgstr "" -#: app.php:374 +#: app.php:365 msgid "Personal" msgstr "" -#: app.php:385 +#: app.php:376 msgid "Settings" msgstr "" -#: app.php:397 +#: app.php:388 msgid "Users" msgstr "" -#: app.php:410 +#: app.php:401 msgid "Admin" msgstr "" -#: app.php:839 +#: app.php:832 #, php-format msgid "Failed to upgrade \"%s\"." msgstr "" @@ -277,6 +277,11 @@ msgstr "" msgid "Please double check the <a href='%s'>installation guides</a>." msgstr "" +#: tags.php:194 +#, php-format +msgid "Could not find category \"%s\"" +msgstr "" + #: template/functions.php:96 msgid "seconds ago" msgstr "" @@ -328,8 +333,3 @@ msgstr "" #: template.php:297 msgid "Caused by:" msgstr "" - -#: vcategories.php:188 vcategories.php:249 -#, php-format -msgid "Could not find category \"%s\"" -msgstr "" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index a669dad822d9197b42f325910ef9b624c7f22c16..af2b7236802602fb44637ae239db1678b694dcf5 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:17-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index 0848d9935376129ef19d6c099fee1f8045d64b5d..ca738710f5cd80ee3485cdef0b33cde76b1202d5 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index ec5a60a6ecb6266df9fc10a6586bc6687647b120..d3a899a1fe57978a0223a9adf4a9b13077b839a3 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 5.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2013-09-29 00:02-0400\n" +"POT-Creation-Date: 2013-09-30 10:16-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/lib/autoloader.php b/lib/autoloader.php index 01841f831becb72a546c8787ce2400cc9d9c2b2f..b5b58918372f563e844851255254b8abc617eeba 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -73,9 +73,10 @@ class Autoloader { } } elseif (strpos($class, 'OC_') === 0) { // first check for legacy classes if underscores are used - $paths[] = 'legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php'); - $paths[] = strtolower(str_replace('_', '/', substr($class, 3)) . '.php'); + $paths[] = 'private/legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php'); + $paths[] = 'private/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php'); } elseif (strpos($class, 'OC\\') === 0) { + $paths[] = 'private/' . strtolower(str_replace('\\', '/', substr($class, 3)) . '.php'); $paths[] = strtolower(str_replace('\\', '/', substr($class, 3)) . '.php'); } elseif (strpos($class, 'OCP\\') === 0) { $paths[] = 'public/' . strtolower(str_replace('\\', '/', substr($class, 4)) . '.php'); @@ -117,7 +118,11 @@ class Autoloader { // Does this PHP have an in-memory cache? We cache the paths there if ($this->constructingMemoryCache && !$this->memoryCache) { $this->constructingMemoryCache = false; - $this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader'); + try { + $this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader'); + } catch(\Exception $ex) { + // no caching then - fine with me + } } if ($this->memoryCache) { $pathsToRequire = $this->memoryCache->get($class); diff --git a/lib/base.php b/lib/base.php index 395d8486a5eaaa5c2844fd25b8f871d5b389a78a..42182c21fb04950ee7bc8a29e8728c30edb9bb38 100644 --- a/lib/base.php +++ b/lib/base.php @@ -84,6 +84,11 @@ class OC { */ public static $loader = null; + /** + * @var \OC\Server + */ + public static $server = null; + public static function initPaths() { // calculate the root directories OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4)); @@ -159,7 +164,7 @@ class OC { // set the right include path set_include_path( - OC::$SERVERROOT . '/lib' . PATH_SEPARATOR . + OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR . OC::$SERVERROOT . '/config' . PATH_SEPARATOR . OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR . implode($paths, PATH_SEPARATOR) . PATH_SEPARATOR . @@ -451,6 +456,9 @@ class OC { stream_wrapper_register('quota', 'OC\Files\Stream\Quota'); stream_wrapper_register('oc', 'OC\Files\Stream\OC'); + // setup the basic server + self::$server = new \OC\Server(); + self::initTemplateEngine(); if (!self::$CLI) { self::initSession(); @@ -557,11 +565,13 @@ class OC { if (OC_Config::getValue('installed', false)) { //don't try to do this before we are properly setup // register cache cleanup jobs try { //if this is executed before the upgrade to the new backgroundjob system is completed it will throw an exception - \OCP\BackgroundJob::registerJob('OC_Cache_FileGlobalGC'); + \OCP\BackgroundJob::registerJob('OC\Cache\FileGlobalGC'); } catch (Exception $e) { } - OC_Hook::connect('OC_User', 'post_login', 'OC_Cache_File', 'loginListener'); + // NOTE: This will be replaced to use OCP + $userSession = \OC_User::getUserSession(); + $userSession->listen('postLogin', '\OC\Cache\File', 'loginListener'); } } @@ -760,6 +770,7 @@ class OC { || !isset($_COOKIE["oc_token"]) || !isset($_COOKIE["oc_username"]) || !$_COOKIE["oc_remember_login"] + || !OC_Util::rememberLoginAllowed() ) { return false; } diff --git a/lib/cache/fileglobalgc.php b/lib/cache/fileglobalgc.php deleted file mode 100644 index a29c31f9063087a49dd9d0d3c498d1e1fe23e68d..0000000000000000000000000000000000000000 --- a/lib/cache/fileglobalgc.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - - -class OC_Cache_FileGlobalGC extends \OC\BackgroundJob\Job{ - public function run($argument){ - OC_Cache_FileGlobal::gc(); - } -} diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php new file mode 100644 index 0000000000000000000000000000000000000000..72aabf60793b8caf84cdd93e5760a022ce0de9b4 --- /dev/null +++ b/lib/private/allconfig.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC; + +/** + * Class to combine all the configuration options ownCloud offers + */ +class AllConfig implements \OCP\IConfig { + /** + * Sets a new system wide value + * @param string $key the key of the value, under which will be saved + * @param string $value the value that should be stored + * @todo need a use case for this + */ +// public function setSystemValue($key, $value) { +// \OCP\Config::setSystemValue($key, $value); +// } + + /** + * Looks up a system wide defined value + * @param string $key the key of the value, under which it was saved + * @return string the saved value + */ + public function getSystemValue($key) { + return \OCP\Config::getSystemValue($key, ''); + } + + + /** + * Writes a new app wide value + * @param string $appName the appName that we want to store the value under + * @param string $key the key of the value, under which will be saved + * @param string $value the value that should be stored + */ + public function setAppValue($appName, $key, $value) { + \OCP\Config::setAppValue($appName, $key, $value); + } + + /** + * Looks up an app wide defined value + * @param string $appName the appName that we stored the value under + * @param string $key the key of the value, under which it was saved + * @return string the saved value + */ + public function getAppValue($appName, $key) { + return \OCP\Config::getAppValue($appName, $key, ''); + } + + + /** + * Set a user defined value + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we want to store the value under + * @param string $key the key under which the value is being stored + * @param string $value the value that you want to store + */ + public function setUserValue($userId, $appName, $key, $value) { + \OCP\Config::setUserValue($userId, $appName, $key, $value); + } + + /** + * Shortcut for getting a user defined value + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we stored the value under + * @param string $key the key under which the value is being stored + */ + public function getUserValue($userId, $appName, $key){ + return \OCP\Config::getUserValue($userId, $appName, $key); + } +} diff --git a/lib/api.php b/lib/private/api.php similarity index 100% rename from lib/api.php rename to lib/private/api.php diff --git a/lib/app.php b/lib/private/app.php similarity index 97% rename from lib/app.php rename to lib/private/app.php index d98af2dc29688956d2a531a5851973b2ccd65299..0ab1ee57f631654cffcde66de4040b78ac23550e 100644 --- a/lib/app.php +++ b/lib/private/app.php @@ -27,8 +27,6 @@ * upgrading and removing apps. */ class OC_App{ - static private $activeapp = ''; - static private $navigation = array(); static private $settingsForms = array(); static private $adminForms = array(); static private $personalForms = array(); @@ -271,7 +269,7 @@ class OC_App{ /** * @brief adds an entry to the navigation - * @param string $data array containing the data + * @param array $data array containing the data * @return bool * * This function adds a new entry to the navigation visible to users. $data @@ -287,11 +285,7 @@ class OC_App{ * the navigation. Lower values come first. */ public static function addNavigationEntry( $data ) { - $data['active']=false; - if(!isset($data['icon'])) { - $data['icon']=''; - } - OC_App::$navigation[] = $data; + OC::$server->getNavigationManager()->add($data); return true; } @@ -305,9 +299,7 @@ class OC_App{ * highlighting the current position of the user. */ public static function setActiveNavigationEntry( $id ) { - // load all the apps, to make sure we have all the navigation entries - self::loadApps(); - self::$activeapp = $id; + OC::$server->getNavigationManager()->setActiveEntry($id); return true; } @@ -315,15 +307,14 @@ class OC_App{ * @brief Get the navigation entries for the $app * @param string $app app * @return array of the $data added with addNavigationEntry + * + * Warning: destroys the existing entries */ public static function getAppNavigationEntries($app) { if(is_file(self::getAppPath($app).'/appinfo/app.php')) { - $save = self::$navigation; - self::$navigation = array(); + OC::$server->getNavigationManager()->clear(); require $app.'/appinfo/app.php'; - $app_entries = self::$navigation; - self::$navigation = $save; - return $app_entries; + return OC::$server->getNavigationManager()->getAll(); } return array(); } @@ -336,7 +327,7 @@ class OC_App{ * setActiveNavigationEntry */ public static function getActiveNavigationEntry() { - return self::$activeapp; + return OC::$server->getNavigationManager()->getActiveEntry(); } /** @@ -419,8 +410,9 @@ class OC_App{ // This is private as well. It simply works, so don't ask for more details private static function proceedNavigation( $list ) { + $activeapp = OC::$server->getNavigationManager()->getActiveEntry(); foreach( $list as &$naventry ) { - if( $naventry['id'] == self::$activeapp ) { + if( $naventry['id'] == $activeapp ) { $naventry['active'] = true; } else{ @@ -572,7 +564,8 @@ class OC_App{ * - active: boolean, signals if the user is on this navigation entry */ public static function getNavigation() { - $navigation = self::proceedNavigation( self::$navigation ); + $entries = OC::$server->getNavigationManager()->getAll(); + $navigation = self::proceedNavigation( $entries ); return $navigation; } diff --git a/lib/appconfig.php b/lib/private/appconfig.php similarity index 100% rename from lib/appconfig.php rename to lib/private/appconfig.php diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php new file mode 100644 index 0000000000000000000000000000000000000000..7ff55bb809d1ddcfeef1142547878a8fcf3e1805 --- /dev/null +++ b/lib/private/appframework/app.php @@ -0,0 +1,98 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework; + +use OC\AppFramework\DependencyInjection\DIContainer; +use OCP\AppFramework\IAppContainer; + + +/** + * Entry point for every request in your app. You can consider this as your + * public static void main() method + * + * Handles all the dependency injection, controllers and output flow + */ +class App { + + + /** + * Shortcut for calling a controller method and printing the result + * @param string $controllerName the name of the controller under which it is + * stored in the DI container + * @param string $methodName the method that you want to call + * @param array $urlParams an array with variables extracted from the routes + * @param DIContainer $container an instance of a pimple container. + */ + public static function main($controllerName, $methodName, array $urlParams, + IAppContainer $container) { + $container['urlParams'] = $urlParams; + $controller = $container[$controllerName]; + + // initialize the dispatcher and run all the middleware before the controller + $dispatcher = $container['Dispatcher']; + + list($httpHeaders, $responseHeaders, $output) = + $dispatcher->dispatch($controller, $methodName); + + if(!is_null($httpHeaders)) { + header($httpHeaders); + } + + foreach($responseHeaders as $name => $value) { + header($name . ': ' . $value); + } + + if(!is_null($output)) { + header('Content-Length: ' . strlen($output)); + print($output); + } + + } + + /** + * Shortcut for calling a controller method and printing the result. + * Similar to App:main except that no headers will be sent. + * This should be used for example when registering sections via + * \OC\AppFramework\Core\API::registerAdmin() + * + * @param string $controllerName the name of the controller under which it is + * stored in the DI container + * @param string $methodName the method that you want to call + * @param array $urlParams an array with variables extracted from the routes + * @param DIContainer $container an instance of a pimple container. + */ + public static function part($controllerName, $methodName, array $urlParams, + DIContainer $container){ + + $container['urlParams'] = $urlParams; + $controller = $container[$controllerName]; + + $dispatcher = $container['Dispatcher']; + + list(, , $output) = $dispatcher->dispatch($controller, $methodName); + return $output; + } + +} diff --git a/lib/private/appframework/controller/controller.php b/lib/private/appframework/controller/controller.php new file mode 100644 index 0000000000000000000000000000000000000000..0ea0a38cc090e36906de3a9782edc603a8567481 --- /dev/null +++ b/lib/private/appframework/controller/controller.php @@ -0,0 +1,142 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Controller; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Core\API; +use OCP\AppFramework\Http\TemplateResponse; + + +/** + * Base class to inherit your controllers from + */ +abstract class Controller { + + /** + * @var API instance of the api layer + */ + protected $api; + + protected $request; + + /** + * @param API $api an api wrapper instance + * @param Request $request an instance of the request + */ + public function __construct(API $api, Request $request){ + $this->api = $api; + $this->request = $request; + } + + + /** + * Lets you access post and get parameters by the index + * @param string $key the key which you want to access in the URL Parameter + * placeholder, $_POST or $_GET array. + * The priority how they're returned is the following: + * 1. URL parameters + * 2. POST parameters + * 3. GET parameters + * @param mixed $default If the key is not found, this value will be returned + * @return mixed the content of the array + */ + public function params($key, $default=null){ + return $this->request->getParam($key, $default); + } + + + /** + * Returns all params that were received, be it from the request + * (as GET or POST) or throuh the URL by the route + * @return array the array with all parameters + */ + public function getParams() { + return $this->request->getParams(); + } + + + /** + * Returns the method of the request + * @return string the method of the request (POST, GET, etc) + */ + public function method() { + return $this->request->getMethod(); + } + + + /** + * Shortcut for accessing an uploaded file through the $_FILES array + * @param string $key the key that will be taken from the $_FILES array + * @return array the file in the $_FILES element + */ + public function getUploadedFile($key) { + return $this->request->getUploadedFile($key); + } + + + /** + * Shortcut for getting env variables + * @param string $key the key that will be taken from the $_ENV array + * @return array the value in the $_ENV element + */ + public function env($key) { + return $this->request->getEnv($key); + } + + + /** + * Shortcut for getting cookie variables + * @param string $key the key that will be taken from the $_COOKIE array + * @return array the value in the $_COOKIE element + */ + public function cookie($key) { + return $this->request->getCookie($key); + } + + + /** + * Shortcut for rendering a template + * @param string $templateName the name of the template + * @param array $params the template parameters in key => value structure + * @param string $renderAs user renders a full page, blank only your template + * admin an entry in the admin settings + * @param array $headers set additional headers in name/value pairs + * @return \OCP\AppFramework\Http\TemplateResponse containing the page + */ + public function render($templateName, array $params=array(), + $renderAs='user', array $headers=array()){ + $response = new TemplateResponse($this->api, $templateName); + $response->setParams($params); + $response->renderAs($renderAs); + + foreach($headers as $name => $value){ + $response->addHeader($name, $value); + } + + return $response; + } + + +} diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php new file mode 100644 index 0000000000000000000000000000000000000000..39522ee3dd5ce2e4ab6add7a8808206ee2faf5d7 --- /dev/null +++ b/lib/private/appframework/core/api.php @@ -0,0 +1,348 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Core; +use OCP\AppFramework\IApi; + + +/** + * This is used to wrap the owncloud static api calls into an object to make the + * code better abstractable for use in the dependency injection container + * + * Should you find yourself in need for more methods, simply inherit from this + * class and add your methods + */ +class API implements IApi{ + + private $appName; + + /** + * constructor + * @param string $appName the name of your application + */ + public function __construct($appName){ + $this->appName = $appName; + } + + + /** + * Gets the userid of the current user + * @return string the user id of the current user + */ + public function getUserId(){ + return \OCP\User::getUser(); + } + + + /** + * Adds a new javascript file + * @param string $scriptName the name of the javascript in js/ without the suffix + * @param string $appName the name of the app, defaults to the current one + */ + public function addScript($scriptName, $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + \OCP\Util::addScript($appName, $scriptName); + } + + + /** + * Adds a new css file + * @param string $styleName the name of the css file in css/without the suffix + * @param string $appName the name of the app, defaults to the current one + */ + public function addStyle($styleName, $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + \OCP\Util::addStyle($appName, $styleName); + } + + + /** + * shorthand for addScript for files in the 3rdparty directory + * @param string $name the name of the file without the suffix + */ + public function add3rdPartyScript($name){ + \OCP\Util::addScript($this->appName . '/3rdparty', $name); + } + + + /** + * shorthand for addStyle for files in the 3rdparty directory + * @param string $name the name of the file without the suffix + */ + public function add3rdPartyStyle($name){ + \OCP\Util::addStyle($this->appName . '/3rdparty', $name); + } + + + /** + * Returns the translation object + * @return \OC_L10N the translation object + */ + public function getTrans(){ + # TODO: use public api + return \OC_L10N::get($this->appName); + } + + + /** + * Returns the URL for a route + * @param string $routeName the name of the route + * @param array $arguments an array with arguments which will be filled into the url + * @return string the url + */ + public function linkToRoute($routeName, $arguments=array()){ + return \OCP\Util::linkToRoute($routeName, $arguments); + } + + + /** + * Returns an URL for an image or file + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + */ + public function linkTo($file, $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + return \OCP\Util::linkTo($appName, $file); + } + + + /** + * Returns the link to an image, like link to but only with prepending img/ + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + */ + public function imagePath($file, $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + return \OCP\Util::imagePath($appName, $file); + } + + + /** + * Makes an URL absolute + * @param string $url the url + * @return string the absolute url + */ + public function getAbsoluteURL($url){ + # TODO: use public api + return \OC_Helper::makeURLAbsolute($url); + } + + + /** + * links to a file + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + * @deprecated replaced with linkToRoute() + * @return string the url + */ + public function linkToAbsolute($file, $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + return \OCP\Util::linkToAbsolute($appName, $file); + } + + + /** + * Checks if the CSRF check was correct + * @return bool true if CSRF check passed + */ + public function passesCSRFCheck(){ + # TODO: use public api + return \OC_Util::isCallRegistered(); + } + + + /** + * Checks if an app is enabled + * @param string $appName the name of an app + * @return bool true if app is enabled + */ + public function isAppEnabled($appName){ + return \OCP\App::isEnabled($appName); + } + + + /** + * Writes a function into the error log + * @param string $msg the error message to be logged + * @param int $level the error level + */ + public function log($msg, $level=null){ + switch($level){ + case 'debug': + $level = \OCP\Util::DEBUG; + break; + case 'info': + $level = \OCP\Util::INFO; + break; + case 'warn': + $level = \OCP\Util::WARN; + break; + case 'fatal': + $level = \OCP\Util::FATAL; + break; + default: + $level = \OCP\Util::ERROR; + break; + } + \OCP\Util::writeLog($this->appName, $msg, $level); + } + + + /** + * turns an owncloud path into a path on the filesystem + * @param string path the path to the file on the oc filesystem + * @return string the filepath in the filesystem + */ + public function getLocalFilePath($path){ + # TODO: use public api + return \OC_Filesystem::getLocalFile($path); + } + + + /** + * used to return and open a new eventsource + * @return \OC_EventSource a new open EventSource class + */ + public function openEventSource(){ + # TODO: use public api + return new \OC_EventSource(); + } + + /** + * @brief connects a function to a hook + * @param string $signalClass class name of emitter + * @param string $signalName name of signal + * @param string $slotClass class name of slot + * @param string $slotName name of slot, in another word, this is the + * name of the method that will be called when registered + * signal is emitted. + * @return bool, always true + */ + public function connectHook($signalClass, $signalName, $slotClass, $slotName) { + return \OCP\Util::connectHook($signalClass, $signalName, $slotClass, $slotName); + } + + /** + * @brief Emits a signal. To get data from the slot use references! + * @param string $signalClass class name of emitter + * @param string $signalName name of signal + * @param array $params defautl: array() array with additional data + * @return bool, true if slots exists or false if not + */ + public function emitHook($signalClass, $signalName, $params = array()) { + return \OCP\Util::emitHook($signalClass, $signalName, $params); + } + + /** + * @brief clear hooks + * @param string $signalClass + * @param string $signalName + */ + public function clearHook($signalClass=false, $signalName=false) { + if ($signalClass) { + \OC_Hook::clear($signalClass, $signalName); + } + } + + /** + * Gets the content of an URL by using CURL or a fallback if it is not + * installed + * @param string $url the url that should be fetched + * @return string the content of the webpage + */ + public function getUrlContent($url) { + return \OC_Util::getUrlContent($url); + } + + /** + * Register a backgroundjob task + * @param string $className full namespace and class name of the class + * @param string $methodName the name of the static method that should be + * called + */ + public function addRegularTask($className, $methodName) { + \OCP\Backgroundjob::addRegularTask($className, $methodName); + } + + /** + * Returns a template + * @param string $templateName the name of the template + * @param string $renderAs how it should be rendered + * @param string $appName the name of the app + * @return \OCP\Template a new template + */ + public function getTemplate($templateName, $renderAs='user', $appName=null){ + if($appName === null){ + $appName = $this->appName; + } + + if($renderAs === 'blank'){ + return new \OCP\Template($appName, $templateName); + } else { + return new \OCP\Template($appName, $templateName, $renderAs); + } + } + + + /** + * Tells ownCloud to include a template in the admin overview + * @param string $mainPath the path to the main php file without the php + * suffix, relative to your apps directory! not the template directory + * @param string $appName the name of the app, defaults to the current one + */ + public function registerAdmin($mainPath, $appName=null) { + if($appName === null){ + $appName = $this->appName; + } + + \OCP\App::registerAdmin($appName, $mainPath); + } + + + /** + * get the filesystem info + * + * @param string $path + * @return array with the following keys: + * - size + * - mtime + * - mimetype + * - encrypted + * - versioned + */ + public function getFileInfo($path) { + return \OC\Files\Filesystem::getFileInfo($path); + } + +} diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php new file mode 100644 index 0000000000000000000000000000000000000000..3755d45fa092dd1b44f8dfc62f9f3eafee23c536 --- /dev/null +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -0,0 +1,146 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\DependencyInjection; + +use OC\AppFramework\Http\Http; +use OC\AppFramework\Http\Request; +use OC\AppFramework\Http\Dispatcher; +use OC\AppFramework\Core\API; +use OC\AppFramework\Middleware\MiddlewareDispatcher; +use OC\AppFramework\Middleware\Security\SecurityMiddleware; +use OC\AppFramework\Utility\SimpleContainer; +use OC\AppFramework\Utility\TimeFactory; +use OCP\AppFramework\IApi; +use OCP\AppFramework\IAppContainer; +use OCP\AppFramework\IMiddleWare; +use OCP\IServerContainer; + + +class DIContainer extends SimpleContainer implements IAppContainer{ + + /** + * @var array + */ + private $middleWares = array(); + + /** + * Put your class dependencies in here + * @param string $appName the name of the app + */ + public function __construct($appName){ + + $this['AppName'] = $appName; + + $this->registerParameter('ServerContainer', \OC::$server); + + $this['API'] = $this->share(function($c){ + return new API($c['AppName']); + }); + + /** + * Http + */ + $this['Request'] = $this->share(function($c) { + /** @var $c SimpleContainer */ + /** @var $server IServerContainer */ + $server = $c->query('ServerContainer'); + return $server->getRequest(); + }); + + $this['Protocol'] = $this->share(function($c){ + if(isset($_SERVER['SERVER_PROTOCOL'])) { + return new Http($_SERVER, $_SERVER['SERVER_PROTOCOL']); + } else { + return new Http($_SERVER); + } + }); + + $this['Dispatcher'] = $this->share(function($c) { + return new Dispatcher($c['Protocol'], $c['MiddlewareDispatcher']); + }); + + + /** + * Middleware + */ + $this['SecurityMiddleware'] = $this->share(function($c){ + return new SecurityMiddleware($c['API'], $c['Request']); + }); + + $this['MiddlewareDispatcher'] = $this->share(function($c){ + $dispatcher = new MiddlewareDispatcher(); + $dispatcher->registerMiddleware($c['SecurityMiddleware']); + + foreach($this->middleWares as $middleWare) { + $dispatcher->registerMiddleware($middleWare); + } + + return $dispatcher; + }); + + + /** + * Utilities + */ + $this['TimeFactory'] = $this->share(function($c){ + return new TimeFactory(); + }); + + + } + + + /** + * @return IApi + */ + function getCoreApi() + { + return $this->query('API'); + } + + /** + * @return \OCP\IServerContainer + */ + function getServer() + { + return $this->query('ServerContainer'); + } + + /** + * @param IMiddleWare $middleWare + * @return boolean + */ + function registerMiddleWare(IMiddleWare $middleWare) { + array_push($this->middleWares, $middleWare); + } + + /** + * used to return the appname of the set application + * @return string the name of your application + */ + function getAppName() { + return $this->query('AppName'); + } +} diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php new file mode 100644 index 0000000000000000000000000000000000000000..ea57a6860cc27ea4fa4b3c9c8f8ba0a8a8db7666 --- /dev/null +++ b/lib/private/appframework/http/dispatcher.php @@ -0,0 +1,100 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + +use \OC\AppFramework\Controller\Controller; +use \OC\AppFramework\Middleware\MiddlewareDispatcher; + + +/** + * Class to dispatch the request to the middleware dispatcher + */ +class Dispatcher { + + private $middlewareDispatcher; + private $protocol; + + + /** + * @param Http $protocol the http protocol with contains all status headers + * @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which + * runs the middleware + */ + public function __construct(Http $protocol, + MiddlewareDispatcher $middlewareDispatcher) { + $this->protocol = $protocol; + $this->middlewareDispatcher = $middlewareDispatcher; + } + + + /** + * Handles a request and calls the dispatcher on the controller + * @param Controller $controller the controller which will be called + * @param string $methodName the method name which will be called on + * the controller + * @return array $array[0] contains a string with the http main header, + * $array[1] contains headers in the form: $key => value, $array[2] contains + * the response output + */ + public function dispatch(Controller $controller, $methodName) { + $out = array(null, array(), null); + + try { + + $this->middlewareDispatcher->beforeController($controller, + $methodName); + $response = $controller->$methodName(); + + // if an exception appears, the middleware checks if it can handle the + // exception and creates a response. If no response is created, it is + // assumed that theres no middleware who can handle it and the error is + // thrown again + } catch(\Exception $exception){ + $response = $this->middlewareDispatcher->afterException( + $controller, $methodName, $exception); + if (is_null($response)) { + throw $exception; + } + } + + $response = $this->middlewareDispatcher->afterController( + $controller, $methodName, $response); + + // get the output which should be printed and run the after output + // middleware to modify the response + $output = $response->render(); + $out[2] = $this->middlewareDispatcher->beforeOutput( + $controller, $methodName, $output); + + // depending on the cache object the headers need to be changed + $out[0] = $this->protocol->getStatusHeader($response->getStatus(), + $response->getLastModified(), $response->getETag()); + $out[1] = $response->getHeaders(); + + return $out; + } + + +} diff --git a/lib/private/appframework/http/downloadresponse.php b/lib/private/appframework/http/downloadresponse.php new file mode 100644 index 0000000000000000000000000000000000000000..67b9542dba6956dc9ef919b809edf5195917a6e7 --- /dev/null +++ b/lib/private/appframework/http/downloadresponse.php @@ -0,0 +1,50 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +/** + * Prompts the user to download the a file + */ +class DownloadResponse extends \OCP\AppFramework\Http\Response { + + private $filename; + private $contentType; + + /** + * Creates a response that prompts the user to download the file + * @param string $filename the name that the downloaded file should have + * @param string $contentType the mimetype that the downloaded file should have + */ + public function __construct($filename, $contentType) { + $this->filename = $filename; + $this->contentType = $contentType; + + $this->addHeader('Content-Disposition', 'attachment; filename="' . $filename . '"'); + $this->addHeader('Content-Type', $contentType); + } + + +} diff --git a/lib/private/appframework/http/http.php b/lib/private/appframework/http/http.php new file mode 100644 index 0000000000000000000000000000000000000000..e00dc9cdc4a2514a34e13e958cd904fd8e858952 --- /dev/null +++ b/lib/private/appframework/http/http.php @@ -0,0 +1,148 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +class Http extends \OCP\AppFramework\Http\Http{ + + private $server; + private $protocolVersion; + protected $headers; + + /** + * @param $_SERVER $server + * @param string $protocolVersion the http version to use defaults to HTTP/1.1 + */ + public function __construct($server, $protocolVersion='HTTP/1.1') { + $this->server = $server; + $this->protocolVersion = $protocolVersion; + + $this->headers = array( + self::STATUS_CONTINUE => 'Continue', + self::STATUS_SWITCHING_PROTOCOLS => 'Switching Protocols', + self::STATUS_PROCESSING => 'Processing', + self::STATUS_OK => 'OK', + self::STATUS_CREATED => 'Created', + self::STATUS_ACCEPTED => 'Accepted', + self::STATUS_NON_AUTHORATIVE_INFORMATION => 'Non-Authorative Information', + self::STATUS_NO_CONTENT => 'No Content', + self::STATUS_RESET_CONTENT => 'Reset Content', + self::STATUS_PARTIAL_CONTENT => 'Partial Content', + self::STATUS_MULTI_STATUS => 'Multi-Status', // RFC 4918 + self::STATUS_ALREADY_REPORTED => 'Already Reported', // RFC 5842 + self::STATUS_IM_USED => 'IM Used', // RFC 3229 + self::STATUS_MULTIPLE_CHOICES => 'Multiple Choices', + self::STATUS_MOVED_PERMANENTLY => 'Moved Permanently', + self::STATUS_FOUND => 'Found', + self::STATUS_SEE_OTHER => 'See Other', + self::STATUS_NOT_MODIFIED => 'Not Modified', + self::STATUS_USE_PROXY => 'Use Proxy', + self::STATUS_RESERVED => 'Reserved', + self::STATUS_TEMPORARY_REDIRECT => 'Temporary Redirect', + self::STATUS_BAD_REQUEST => 'Bad request', + self::STATUS_UNAUTHORIZED => 'Unauthorized', + self::STATUS_PAYMENT_REQUIRED => 'Payment Required', + self::STATUS_FORBIDDEN => 'Forbidden', + self::STATUS_NOT_FOUND => 'Not Found', + self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed', + self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable', + self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required', + self::STATUS_REQUEST_TIMEOUT => 'Request Timeout', + self::STATUS_CONFLICT => 'Conflict', + self::STATUS_GONE => 'Gone', + self::STATUS_LENGTH_REQUIRED => 'Length Required', + self::STATUS_PRECONDITION_FAILED => 'Precondition failed', + self::STATUS_REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large', + self::STATUS_REQUEST_URI_TOO_LONG => 'Request-URI Too Long', + self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type', + self::STATUS_REQUEST_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable', + self::STATUS_EXPECTATION_FAILED => 'Expectation Failed', + self::STATUS_IM_A_TEAPOT => 'I\'m a teapot', // RFC 2324 + self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', // RFC 4918 + self::STATUS_LOCKED => 'Locked', // RFC 4918 + self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency', // RFC 4918 + self::STATUS_UPGRADE_REQUIRED => 'Upgrade required', + self::STATUS_PRECONDITION_REQUIRED => 'Precondition required', // draft-nottingham-http-new-status + self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests', // draft-nottingham-http-new-status + self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', // draft-nottingham-http-new-status + self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error', + self::STATUS_NOT_IMPLEMENTED => 'Not Implemented', + self::STATUS_BAD_GATEWAY => 'Bad Gateway', + self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable', + self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout', + self::STATUS_HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported', + self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates', + self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage', // RFC 4918 + self::STATUS_LOOP_DETECTED => 'Loop Detected', // RFC 5842 + self::STATUS_BANDWIDTH_LIMIT_EXCEEDED => 'Bandwidth Limit Exceeded', // non-standard + self::STATUS_NOT_EXTENDED => 'Not extended', + self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', // draft-nottingham-http-new-status + ); + } + + + /** + * Gets the correct header + * @param Http::CONSTANT $status the constant from the Http class + * @param \DateTime $lastModified formatted last modified date + * @param string $Etag the etag + */ + public function getStatusHeader($status, \DateTime $lastModified=null, + $ETag=null) { + + if(!is_null($lastModified)) { + $lastModified = $lastModified->format(\DateTime::RFC2822); + } + + // if etag or lastmodified have not changed, return a not modified + if ((isset($this->server['HTTP_IF_NONE_MATCH']) + && trim($this->server['HTTP_IF_NONE_MATCH']) === $ETag) + + || + + (isset($this->server['HTTP_IF_MODIFIED_SINCE']) + && trim($this->server['HTTP_IF_MODIFIED_SINCE']) === + $lastModified)) { + + $status = self::STATUS_NOT_MODIFIED; + } + + // we have one change currently for the http 1.0 header that differs + // from 1.1: STATUS_TEMPORARY_REDIRECT should be STATUS_FOUND + // if this differs any more, we want to create childclasses for this + if($status === self::STATUS_TEMPORARY_REDIRECT + && $this->protocolVersion === 'HTTP/1.0') { + + $status = self::STATUS_FOUND; + } + + return $this->protocolVersion . ' ' . $status . ' ' . + $this->headers[$status]; + } + + +} + + diff --git a/lib/private/appframework/http/redirectresponse.php b/lib/private/appframework/http/redirectresponse.php new file mode 100644 index 0000000000000000000000000000000000000000..688447f16180c2943a704cad0c95009d1d627841 --- /dev/null +++ b/lib/private/appframework/http/redirectresponse.php @@ -0,0 +1,56 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + +use OCP\AppFramework\Http\Response; + + +/** + * Redirects to a different URL + */ +class RedirectResponse extends Response { + + private $redirectURL; + + /** + * Creates a response that redirects to a url + * @param string $redirectURL the url to redirect to + */ + public function __construct($redirectURL) { + $this->redirectURL = $redirectURL; + $this->setStatus(Http::STATUS_TEMPORARY_REDIRECT); + $this->addHeader('Location', $redirectURL); + } + + + /** + * @return string the url to redirect + */ + public function getRedirectURL() { + return $this->redirectURL; + } + + +} diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php new file mode 100644 index 0000000000000000000000000000000000000000..34605acdfead8b7073f19702fd6965799e1b776c --- /dev/null +++ b/lib/private/appframework/http/request.php @@ -0,0 +1,307 @@ +<?php +/** + * ownCloud - Request + * + * @author Thomas Tanghus + * @copyright 2013 Thomas Tanghus (thomas@tanghus.net) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\AppFramework\Http; + +use OCP\IRequest; + +/** + * Class for accessing variables in the request. + * This class provides an immutable object with request variables. + */ + +class Request implements \ArrayAccess, \Countable, IRequest { + + protected $items = array(); + protected $allowedKeys = array( + 'get', + 'post', + 'files', + 'server', + 'env', + 'cookies', + 'urlParams', + 'params', + 'parameters', + 'method' + ); + + /** + * @param array $vars An associative array with the following optional values: + * @param array 'params' the parsed json array + * @param array 'urlParams' the parameters which were matched from the URL + * @param array 'get' the $_GET array + * @param array 'post' the $_POST array + * @param array 'files' the $_FILES array + * @param array 'server' the $_SERVER array + * @param array 'env' the $_ENV array + * @param array 'session' the $_SESSION array + * @param array 'cookies' the $_COOKIE array + * @param string 'method' the request method (GET, POST etc) + * @see http://www.php.net/manual/en/reserved.variables.php + */ + public function __construct(array $vars=array()) { + + foreach($this->allowedKeys as $name) { + $this->items[$name] = isset($vars[$name]) + ? $vars[$name] + : array(); + } + + $this->items['parameters'] = array_merge( + $this->items['params'], + $this->items['get'], + $this->items['post'], + $this->items['urlParams'] + ); + + } + + // Countable method. + public function count() { + return count(array_keys($this->items['parameters'])); + } + + /** + * ArrayAccess methods + * + * Gives access to the combined GET, POST and urlParams arrays + * + * Examples: + * + * $var = $request['myvar']; + * + * or + * + * if(!isset($request['myvar']) { + * // Do something + * } + * + * $request['myvar'] = 'something'; // This throws an exception. + * + * @param string $offset The key to lookup + * @return string|null + */ + public function offsetExists($offset) { + return isset($this->items['parameters'][$offset]); + } + + /** + * @see offsetExists + */ + public function offsetGet($offset) { + return isset($this->items['parameters'][$offset]) + ? $this->items['parameters'][$offset] + : null; + } + + /** + * @see offsetExists + */ + public function offsetSet($offset, $value) { + throw new \RuntimeException('You cannot change the contents of the request object'); + } + + /** + * @see offsetExists + */ + public function offsetUnset($offset) { + throw new \RuntimeException('You cannot change the contents of the request object'); + } + + // Magic property accessors + public function __set($name, $value) { + throw new \RuntimeException('You cannot change the contents of the request object'); + } + + /** + * Access request variables by method and name. + * Examples: + * + * $request->post['myvar']; // Only look for POST variables + * $request->myvar; or $request->{'myvar'}; or $request->{$myvar} + * Looks in the combined GET, POST and urlParams array. + * + * if($request->method !== 'POST') { + * throw new Exception('This function can only be invoked using POST'); + * } + * + * @param string $name The key to look for. + * @return mixed|null + */ + public function __get($name) { + switch($name) { + case 'get': + case 'post': + case 'files': + case 'server': + case 'env': + case 'cookies': + case 'parameters': + case 'params': + case 'urlParams': + return isset($this->items[$name]) + ? $this->items[$name] + : null; + break; + case 'method': + return $this->items['method']; + break; + default; + return isset($this[$name]) + ? $this[$name] + : null; + break; + } + } + + + public function __isset($name) { + return isset($this->items['parameters'][$name]); + } + + + public function __unset($id) { + throw new \RunTimeException('You cannot change the contents of the request object'); + } + + /** + * Returns the value for a specific http header. + * + * This method returns null if the header did not exist. + * + * @param string $name + * @return string + */ + public function getHeader($name) { + + $name = strtoupper(str_replace(array('-'),array('_'),$name)); + if (isset($this->server['HTTP_' . $name])) { + return $this->server['HTTP_' . $name]; + } + + // There's a few headers that seem to end up in the top-level + // server array. + switch($name) { + case 'CONTENT_TYPE' : + case 'CONTENT_LENGTH' : + if (isset($this->server[$name])) { + return $this->server[$name]; + } + break; + + } + + return null; + } + + /** + * Lets you access post and get parameters by the index + * In case of json requests the encoded json body is accessed + * + * @param string $key the key which you want to access in the URL Parameter + * placeholder, $_POST or $_GET array. + * The priority how they're returned is the following: + * 1. URL parameters + * 2. POST parameters + * 3. GET parameters + * @param mixed $default If the key is not found, this value will be returned + * @return mixed the content of the array + */ + public function getParam($key, $default = null) { + return isset($this->parameters[$key]) + ? $this->parameters[$key] + : $default; + } + + /** + * Returns all params that were received, be it from the request + * (as GET or POST) or throuh the URL by the route + * @return array the array with all parameters + */ + public function getParams() { + return $this->parameters; + } + + /** + * Returns the method of the request + * @return string the method of the request (POST, GET, etc) + */ + public function getMethod() { + return $this->method; + } + + /** + * Shortcut for accessing an uploaded file through the $_FILES array + * @param string $key the key that will be taken from the $_FILES array + * @return array the file in the $_FILES element + */ + public function getUploadedFile($key) { + return isset($this->files[$key]) ? $this->files[$key] : null; + } + + /** + * Shortcut for getting env variables + * @param string $key the key that will be taken from the $_ENV array + * @return array the value in the $_ENV element + */ + public function getEnv($key) { + return isset($this->env[$key]) ? $this->env[$key] : null; + } + + /** + * Shortcut for getting cookie variables + * @param string $key the key that will be taken from the $_COOKIE array + * @return array the value in the $_COOKIE element + */ + function getCookie($key) { + return isset($this->cookies[$key]) ? $this->cookies[$key] : null; + } + + /** + * Returns the request body content. + * + * @param Boolean $asResource If true, a resource will be returned + * + * @return string|resource The request body content or a resource to read the body stream. + * + * @throws \LogicException + */ + function getContent($asResource = false) { + return null; +// if (false === $this->content || (true === $asResource && null !== $this->content)) { +// throw new \LogicException('getContent() can only be called once when using the resource return type.'); +// } +// +// if (true === $asResource) { +// $this->content = false; +// +// return fopen('php://input', 'rb'); +// } +// +// if (null === $this->content) { +// $this->content = file_get_contents('php://input'); +// } +// +// return $this->content; + } +} diff --git a/lib/private/appframework/middleware/middleware.php b/lib/private/appframework/middleware/middleware.php new file mode 100644 index 0000000000000000000000000000000000000000..b12c03c3eb8da3627077f148679bc5d8aa8dd09e --- /dev/null +++ b/lib/private/appframework/middleware/middleware.php @@ -0,0 +1,100 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Middleware; + +use OCP\AppFramework\Http\Response; + + +/** + * Middleware is used to provide hooks before or after controller methods and + * deal with possible exceptions raised in the controller methods. + * They're modeled after Django's middleware system: + * https://docs.djangoproject.com/en/dev/topics/http/middleware/ + */ +abstract class Middleware { + + + /** + * This is being run in normal order before the controller is being + * called which allows several modifications and checks + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + */ + public function beforeController($controller, $methodName){ + + } + + + /** + * This is being run when either the beforeController method or the + * controller method itself is throwing an exception. The middleware is + * asked in reverse order to handle the exception and to return a response. + * If the response is null, it is assumed that the exception could not be + * handled and the error will be thrown again + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @throws \Exception the passed in exception if it cant handle it + * @return Response a Response object in case that the exception was handled + */ + public function afterException($controller, $methodName, \Exception $exception){ + throw $exception; + } + + + /** + * This is being run after a successful controllermethod call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + public function afterController($controller, $methodName, Response $response){ + return $response; + } + + + /** + * This is being run after the response object has been rendered and + * allows the manipulation of the output. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param string $output the generated output from a response + * @return string the output that should be printed + */ + public function beforeOutput($controller, $methodName, $output){ + return $output; + } + +} diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php new file mode 100644 index 0000000000000000000000000000000000000000..70ab108e6b884d8404504a2db5bc246c3c2aa578 --- /dev/null +++ b/lib/private/appframework/middleware/middlewaredispatcher.php @@ -0,0 +1,159 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Middleware; + +use OC\AppFramework\Controller\Controller; +use OCP\AppFramework\Http\Response; + + +/** + * This class is used to store and run all the middleware in correct order + */ +class MiddlewareDispatcher { + + /** + * @var array array containing all the middlewares + */ + private $middlewares; + + /** + * @var int counter which tells us what middlware was executed once an + * exception occurs + */ + private $middlewareCounter; + + + /** + * Constructor + */ + public function __construct(){ + $this->middlewares = array(); + $this->middlewareCounter = 0; + } + + + /** + * Adds a new middleware + * @param Middleware $middleware the middleware which will be added + */ + public function registerMiddleware(Middleware $middleWare){ + array_push($this->middlewares, $middleWare); + } + + + /** + * returns an array with all middleware elements + * @return array the middlewares + */ + public function getMiddlewares(){ + return $this->middlewares; + } + + + /** + * This is being run in normal order before the controller is being + * called which allows several modifications and checks + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + */ + public function beforeController(Controller $controller, $methodName){ + // we need to count so that we know which middlewares we have to ask in + // case theres an exception + for($i=0; $i<count($this->middlewares); $i++){ + $this->middlewareCounter++; + $middleware = $this->middlewares[$i]; + $middleware->beforeController($controller, $methodName); + } + } + + + /** + * This is being run when either the beforeController method or the + * controller method itself is throwing an exception. The middleware is asked + * in reverse order to handle the exception and to return a response. + * If the response is null, it is assumed that the exception could not be + * handled and the error will be thrown again + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @return Response a Response object if the middleware can handle the + * exception + * @throws \Exception the passed in exception if it cant handle it + */ + public function afterException(Controller $controller, $methodName, \Exception $exception){ + for($i=$this->middlewareCounter-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + try { + return $middleware->afterException($controller, $methodName, $exception); + } catch(\Exception $exception){ + continue; + } + } + throw $exception; + } + + + /** + * This is being run after a successful controllermethod call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + public function afterController(Controller $controller, $methodName, Response $response){ + for($i=count($this->middlewares)-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + $response = $middleware->afterController($controller, $methodName, $response); + } + return $response; + } + + + /** + * This is being run after the response object has been rendered and + * allows the manipulation of the output. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param string $output the generated output from a response + * @return string the output that should be printed + */ + public function beforeOutput(Controller $controller, $methodName, $output){ + for($i=count($this->middlewares)-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + $output = $middleware->beforeOutput($controller, $methodName, $output); + } + return $output; + } + +} diff --git a/lib/private/appframework/middleware/security/securityexception.php b/lib/private/appframework/middleware/security/securityexception.php new file mode 100644 index 0000000000000000000000000000000000000000..b32a2769ff5c3975e2ee5545fccceaad8d61215b --- /dev/null +++ b/lib/private/appframework/middleware/security/securityexception.php @@ -0,0 +1,41 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Middleware\Security; + + +/** + * Thrown when the security middleware encounters a security problem + */ +class SecurityException extends \Exception { + + /** + * @param string $msg the security error message + * @param bool $ajax true if it resulted because of an ajax request + */ + public function __construct($msg, $code = 0) { + parent::__construct($msg, $code); + } + +} diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php new file mode 100644 index 0000000000000000000000000000000000000000..4f1447e1afba11ffea26f40792be80c392b053b3 --- /dev/null +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -0,0 +1,136 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Controller\Controller; +use OC\AppFramework\Http\Http; +use OC\AppFramework\Http\Request; +use OC\AppFramework\Http\RedirectResponse; +use OC\AppFramework\Utility\MethodAnnotationReader; +use OC\AppFramework\Middleware\Middleware; +use OC\AppFramework\Core\API; +use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\JSONResponse; + + +/** + * Used to do all the authentication and checking stuff for a controller method + * It reads out the annotations of a controller method and checks which if + * security things should be checked and also handles errors in case a security + * check fails + */ +class SecurityMiddleware extends Middleware { + + private $api; + + /** + * @var \OC\AppFramework\Http\Request + */ + private $request; + + /** + * @param API $api an instance of the api + */ + public function __construct(API $api, Request $request){ + $this->api = $api; + $this->request = $request; + } + + + /** + * This runs all the security checks before a method call. The + * security checks are determined by inspecting the controller method + * annotations + * @param string/Controller $controller the controllername or string + * @param string $methodName the name of the method + * @throws SecurityException when a security check fails + */ + public function beforeController($controller, $methodName){ + + // get annotations from comments + $annotationReader = new MethodAnnotationReader($controller, $methodName); + + // this will set the current navigation entry of the app, use this only + // for normal HTML requests and not for AJAX requests + $this->api->activateNavigationEntry(); + + // security checks + $isPublicPage = $annotationReader->hasAnnotation('PublicPage'); + if(!$isPublicPage) { + if(!$this->api->isLoggedIn()) { + throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); + } + + if(!$annotationReader->hasAnnotation('NoAdminRequired')) { + if(!$this->api->isAdminUser($this->api->getUserId())) { + throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); + } + } + } + + if(!$annotationReader->hasAnnotation('NoCSRFRequired')) { + if(!$this->api->passesCSRFCheck()) { + throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); + } + } + + } + + + /** + * If an SecurityException is being caught, ajax requests return a JSON error + * response and non ajax requests redirect to the index + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @throws \Exception the passed in exception if it cant handle it + * @return Response a Response object or null in case that the exception could not be handled + */ + public function afterException($controller, $methodName, \Exception $exception){ + if($exception instanceof SecurityException){ + + if (stripos($this->request->getHeader('Accept'),'html')===false) { + + $response = new JSONResponse( + array('message' => $exception->getMessage()), + $exception->getCode() + ); + $this->api->log($exception->getMessage(), 'debug'); + } else { + + $url = $this->api->linkToAbsolute('index.php', ''); // TODO: replace with link to route + $response = new RedirectResponse($url); + $this->api->log($exception->getMessage(), 'debug'); + } + + return $response; + + } + + throw $exception; + } + +} diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/appframework/routing/routeactionhandler.php new file mode 100644 index 0000000000000000000000000000000000000000..7fb56f14eab7db7395b0bd4dcd70ed1812f32a44 --- /dev/null +++ b/lib/private/appframework/routing/routeactionhandler.php @@ -0,0 +1,42 @@ +<?php +/** + * ownCloud - App Framework + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\AppFramework\routing; + +use \OC\AppFramework\App; +use \OC\AppFramework\DependencyInjection\DIContainer; + +class RouteActionHandler { + private $controllerName; + private $actionName; + private $container; + + public function __construct(DIContainer $container, $controllerName, $actionName) { + $this->controllerName = $controllerName; + $this->actionName = $actionName; + $this->container = $container; + } + + public function __invoke($params) { + App::main($this->controllerName, $this->actionName, $params, $this->container); + } +} diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php new file mode 100644 index 0000000000000000000000000000000000000000..53ab11bf2f599770d0d8f2bce8a0a97400fb4d24 --- /dev/null +++ b/lib/private/appframework/routing/routeconfig.php @@ -0,0 +1,186 @@ +<?php +/** + * ownCloud - App Framework + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\AppFramework\routing; + +use OC\AppFramework\DependencyInjection\DIContainer; + +/** + * Class RouteConfig + * @package OC\AppFramework\routing + */ +class RouteConfig { + private $container; + private $router; + private $routes; + private $appName; + + /** + * @param \OC\AppFramework\DependencyInjection\DIContainer $container + * @param \OC_Router $router + * @param string $pathToYml + * @internal param $appName + */ + public function __construct(DIContainer $container, \OC_Router $router, $routes) { + $this->routes = $routes; + $this->container = $container; + $this->router = $router; + $this->appName = $container['AppName']; + } + + /** + * The routes and resource will be registered to the \OC_Router + */ + public function register() { + + // parse simple + $this->processSimpleRoutes($this->routes); + + // parse resources + $this->processResources($this->routes); + } + + /** + * Creates one route base on the give configuration + * @param $routes + * @throws \UnexpectedValueException + */ + private function processSimpleRoutes($routes) + { + $simpleRoutes = isset($routes['routes']) ? $routes['routes'] : array(); + foreach ($simpleRoutes as $simpleRoute) { + $name = $simpleRoute['name']; + $url = $simpleRoute['url']; + $verb = isset($simpleRoute['verb']) ? strtoupper($simpleRoute['verb']) : 'GET'; + + $split = explode('#', $name, 2); + if (count($split) != 2) { + throw new \UnexpectedValueException('Invalid route name'); + } + $controller = $split[0]; + $action = $split[1]; + + $controllerName = $this->buildControllerName($controller); + $actionName = $this->buildActionName($action); + + // register the route + $handler = new RouteActionHandler($this->container, $controllerName, $actionName); + $this->router->create($this->appName.'.'.$controller.'.'.$action, $url)->method($verb)->action($handler); + } + } + + /** + * For a given name and url restful routes are created: + * - index + * - show + * - new + * - create + * - update + * - destroy + * + * @param $routes + */ + private function processResources($routes) + { + // declaration of all restful actions + $actions = array( + array('name' => 'index', 'verb' => 'GET', 'on-collection' => true), + array('name' => 'show', 'verb' => 'GET'), + array('name' => 'create', 'verb' => 'POST', 'on-collection' => true), + array('name' => 'update', 'verb' => 'PUT'), + array('name' => 'destroy', 'verb' => 'DELETE'), + ); + + $resources = isset($routes['resources']) ? $routes['resources'] : array(); + foreach ($resources as $resource => $config) { + + // the url parameter used as id to the resource + $resourceId = $this->buildResourceId($resource); + foreach($actions as $action) { + $url = $config['url']; + $method = $action['name']; + $verb = isset($action['verb']) ? strtoupper($action['verb']) : 'GET'; + $collectionAction = isset($action['on-collection']) ? $action['on-collection'] : false; + if (!$collectionAction) { + $url = $url . '/' . $resourceId; + } + if (isset($action['url-postfix'])) { + $url = $url . '/' . $action['url-postfix']; + } + + $controller = $resource; + + $controllerName = $this->buildControllerName($controller); + $actionName = $this->buildActionName($method); + + $routeName = $this->appName . '.' . strtolower($resource) . '.' . strtolower($method); + + $this->router->create($routeName, $url)->method($verb)->action( + new RouteActionHandler($this->container, $controllerName, $actionName) + ); + } + } + } + + /** + * Based on a given route name the controller name is generated + * @param $controller + * @return string + */ + private function buildControllerName($controller) + { + return $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller'; + } + + /** + * Based on the action part of the route name the controller method name is generated + * @param $action + * @return string + */ + private function buildActionName($action) { + return $this->underScoreToCamelCase($action); + } + + /** + * Generates the id used in the url part o the route url + * @param $resource + * @return string + */ + private function buildResourceId($resource) { + return '{'.$this->underScoreToCamelCase(rtrim($resource, 's')).'Id}'; + } + + /** + * Underscored strings are converted to camel case strings + * @param $str string + * @return string + */ + private function underScoreToCamelCase($str) { + $pattern = "/_[a-z]?/"; + return preg_replace_callback( + $pattern, + function ($matches) { + return strtoupper(ltrim($matches[0], "_")); + }, + $str); + } +} diff --git a/lib/private/appframework/utility/methodannotationreader.php b/lib/private/appframework/utility/methodannotationreader.php new file mode 100644 index 0000000000000000000000000000000000000000..42060a0852987206de1d023df0b51654149022ca --- /dev/null +++ b/lib/private/appframework/utility/methodannotationreader.php @@ -0,0 +1,61 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Utility; + + +/** + * Reads and parses annotations from doc comments + */ +class MethodAnnotationReader { + + private $annotations; + + /** + * @param object $object an object or classname + * @param string $method the method which we want to inspect for annotations + */ + public function __construct($object, $method){ + $this->annotations = array(); + + $reflection = new \ReflectionMethod($object, $method); + $docs = $reflection->getDocComment(); + + // extract everything prefixed by @ and first letter uppercase + preg_match_all('/@([A-Z]\w+)/', $docs, $matches); + $this->annotations = $matches[1]; + } + + + /** + * Check if a method contains an annotation + * @param string $name the name of the annotation + * @return bool true if the annotation is found + */ + public function hasAnnotation($name){ + return in_array($name, $this->annotations); + } + + +} diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php new file mode 100644 index 0000000000000000000000000000000000000000..7e4db63bde58b5c76e8b79295d19a9f9829e9224 --- /dev/null +++ b/lib/private/appframework/utility/simplecontainer.php @@ -0,0 +1,44 @@ +<?php + +namespace OC\AppFramework\Utility; + +// register 3rdparty autoloaders +require_once __DIR__ . '/../../../../3rdparty/Pimple/Pimple.php'; + +/** + * Class SimpleContainer + * + * SimpleContainer is a simple implementation of IContainer on basis of \Pimple + */ +class SimpleContainer extends \Pimple implements \OCP\IContainer { + + /** + * @param string $name name of the service to query for + * @return object registered service for the given $name + */ + public function query($name) { + return $this->offsetGet($name); + } + + function registerParameter($name, $value) + { + $this[$name] = $value; + } + + /** + * The given closure is call the first time the given service is queried. + * The closure has to return the instance for the given service. + * Created instance will be cached in case $shared is true. + * + * @param string $name name of the service to register another backend for + * @param callable $closure the closure to be called on service creation + */ + function registerService($name, \Closure $closure, $shared = true) + { + if ($shared) { + $this[$name] = \Pimple::share($closure); + } else { + $this[$name] = $closure; + } + } +} diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/appframework/utility/timefactory.php new file mode 100644 index 0000000000000000000000000000000000000000..2c3dd6cf5e3182e7c73a01964241b55b1edeb134 --- /dev/null +++ b/lib/private/appframework/utility/timefactory.php @@ -0,0 +1,42 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Utility; + + +/** + * Needed to mock calls to time() + */ +class TimeFactory { + + + /** + * @return int the result of a call to time() + */ + public function getTime() { + return time(); + } + + +} diff --git a/lib/archive.php b/lib/private/archive.php similarity index 100% rename from lib/archive.php rename to lib/private/archive.php diff --git a/lib/archive/tar.php b/lib/private/archive/tar.php similarity index 100% rename from lib/archive/tar.php rename to lib/private/archive/tar.php diff --git a/lib/archive/zip.php b/lib/private/archive/zip.php similarity index 100% rename from lib/archive/zip.php rename to lib/private/archive/zip.php diff --git a/lib/arrayparser.php b/lib/private/arrayparser.php similarity index 100% rename from lib/arrayparser.php rename to lib/private/arrayparser.php diff --git a/lib/avatar.php b/lib/private/avatar.php similarity index 100% rename from lib/avatar.php rename to lib/private/avatar.php diff --git a/lib/backgroundjob.php b/lib/private/backgroundjob.php similarity index 100% rename from lib/backgroundjob.php rename to lib/private/backgroundjob.php diff --git a/lib/backgroundjob/job.php b/lib/private/backgroundjob/job.php similarity index 100% rename from lib/backgroundjob/job.php rename to lib/private/backgroundjob/job.php diff --git a/lib/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php similarity index 100% rename from lib/backgroundjob/joblist.php rename to lib/private/backgroundjob/joblist.php diff --git a/lib/backgroundjob/legacy/queuedjob.php b/lib/private/backgroundjob/legacy/queuedjob.php similarity index 100% rename from lib/backgroundjob/legacy/queuedjob.php rename to lib/private/backgroundjob/legacy/queuedjob.php diff --git a/lib/backgroundjob/legacy/regularjob.php b/lib/private/backgroundjob/legacy/regularjob.php similarity index 100% rename from lib/backgroundjob/legacy/regularjob.php rename to lib/private/backgroundjob/legacy/regularjob.php diff --git a/lib/backgroundjob/queuedjob.php b/lib/private/backgroundjob/queuedjob.php similarity index 100% rename from lib/backgroundjob/queuedjob.php rename to lib/private/backgroundjob/queuedjob.php diff --git a/lib/backgroundjob/timedjob.php b/lib/private/backgroundjob/timedjob.php similarity index 100% rename from lib/backgroundjob/timedjob.php rename to lib/private/backgroundjob/timedjob.php diff --git a/lib/cache.php b/lib/private/cache.php similarity index 84% rename from lib/cache.php rename to lib/private/cache.php index 48b9964ba9d19dd0713f3b5d188e0daa9b20e4e0..a311f10a00fa4736136ab6a1e6bf3c5e3b7166d9 100644 --- a/lib/cache.php +++ b/lib/private/cache.php @@ -6,34 +6,36 @@ * See the COPYING-README file. */ -class OC_Cache { +namespace OC; + +class Cache { /** - * @var OC_Cache $user_cache + * @var Cache $user_cache */ static protected $user_cache; /** - * @var OC_Cache $global_cache + * @var Cache $global_cache */ static protected $global_cache; /** * get the global cache - * @return OC_Cache + * @return Cache */ static public function getGlobalCache() { if (!self::$global_cache) { - self::$global_cache = new OC_Cache_FileGlobal(); + self::$global_cache = new Cache\FileGlobal(); } return self::$global_cache; } /** * get the user cache - * @return OC_Cache + * @return Cache */ static public function getUserCache() { if (!self::$user_cache) { - self::$user_cache = new OC_Cache_File(); + self::$user_cache = new Cache\File(); } return self::$user_cache; } @@ -85,7 +87,7 @@ class OC_Cache { /** * clear the user cache of all entries starting with a prefix - * @param string prefix (optional) + * @param string $prefix (optional) * @return bool */ static public function clear($prefix='') { @@ -93,6 +95,11 @@ class OC_Cache { return $user_cache->clear($prefix); } + /** + * creates cache key based on the files given + * @param $files + * @return string + */ static public function generateCacheKeyFromFiles($files) { $key = ''; sort($files); diff --git a/lib/cache/broker.php b/lib/private/cache/broker.php similarity index 92% rename from lib/cache/broker.php rename to lib/private/cache/broker.php index a161dbfa3bb1c2664b9eb4ab25c0ddf57da90633..9b7e837e1bc96f4c4fbb32e2f607142438c23d8b 100644 --- a/lib/cache/broker.php +++ b/lib/private/cache/broker.php @@ -6,8 +6,18 @@ * See the COPYING-README file. */ -class OC_Cache_Broker { +namespace OC\Cache; + +class Broker { + + /** + * @var \OC\Cache + */ protected $fast_cache; + + /** + * @var \OC\Cache + */ protected $slow_cache; public function __construct($fast_cache, $slow_cache) { diff --git a/lib/cache/file.php b/lib/private/cache/file.php similarity index 87% rename from lib/cache/file.php rename to lib/private/cache/file.php index 361138e47362138295c67873ca611aa26c12fd55..2ab914d17b891b421fd573a1ad98edc233d52a99 100644 --- a/lib/cache/file.php +++ b/lib/private/cache/file.php @@ -6,24 +6,25 @@ * See the COPYING-README file. */ +namespace OC\Cache; -class OC_Cache_File{ +class File { protected $storage; protected function getStorage() { if (isset($this->storage)) { return $this->storage; } - if(OC_User::isLoggedIn()) { - \OC\Files\Filesystem::initMountPoints(OC_User::getUser()); + if(\OC_User::isLoggedIn()) { + \OC\Files\Filesystem::initMountPoints(\OC_User::getUser()); $subdir = 'cache'; - $view = new \OC\Files\View('/'.OC_User::getUser()); + $view = new \OC\Files\View('/' . \OC_User::getUser()); if(!$view->file_exists($subdir)) { $view->mkdir($subdir); } - $this->storage = new \OC\Files\View('/'.OC_User::getUser().'/'.$subdir); + $this->storage = new \OC\Files\View('/' . \OC_User::getUser().'/'.$subdir); return $this->storage; }else{ - OC_Log::write('core', 'Can\'t get cache storage, user not logged in', OC_Log::ERROR); + \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR); return false; } } diff --git a/lib/cache/fileglobal.php b/lib/private/cache/fileglobal.php similarity index 89% rename from lib/cache/fileglobal.php rename to lib/private/cache/fileglobal.php index c0bd8e45f39a67729a37baf60ee7073599baa076..bd049bba4d0a5ebc2c0bb56bc807cce26fb2e2c4 100644 --- a/lib/cache/fileglobal.php +++ b/lib/private/cache/fileglobal.php @@ -6,10 +6,11 @@ * See the COPYING-README file. */ +namespace OC\Cache; -class OC_Cache_FileGlobal{ +class FileGlobal { static protected function getCacheDir() { - $cache_dir = get_temp_dir().'/owncloud-'.OC_Util::getInstanceId().'/'; + $cache_dir = get_temp_dir().'/owncloud-' . \OC_Util::getInstanceId().'/'; if (!is_dir($cache_dir)) { mkdir($cache_dir); } @@ -80,13 +81,13 @@ class OC_Cache_FileGlobal{ } static public function gc() { - $last_run = OC_AppConfig::getValue('core', 'global_cache_gc_lastrun', 0); + $last_run = \OC_AppConfig::getValue('core', 'global_cache_gc_lastrun', 0); $now = time(); if (($now - $last_run) < 300) { // only do cleanup every 5 minutes return; } - OC_AppConfig::setValue('core', 'global_cache_gc_lastrun', $now); + \OC_AppConfig::setValue('core', 'global_cache_gc_lastrun', $now); $cache_dir = self::getCacheDir(); if($cache_dir and is_dir($cache_dir)) { $dh=opendir($cache_dir); diff --git a/lib/private/cache/fileglobalgc.php b/lib/private/cache/fileglobalgc.php new file mode 100644 index 0000000000000000000000000000000000000000..399dd5e6f9468f5595596fd9d64a87d988628779 --- /dev/null +++ b/lib/private/cache/fileglobalgc.php @@ -0,0 +1,9 @@ +<?php + +namespace OC\Cache; + +class FileGlobalGC extends \OC\BackgroundJob\Job{ + public function run($argument){ + FileGlobal::gc(); + } +} diff --git a/lib/private/cache/usercache.php b/lib/private/cache/usercache.php new file mode 100644 index 0000000000000000000000000000000000000000..baa8820700b9c652e0ed0e39bf4b1f008c61d26b --- /dev/null +++ b/lib/private/cache/usercache.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OC\Cache; + +/** + * This interface defines method for accessing the file based user cache. + */ +class UserCache implements \OCP\ICache { + + /** + * @var \OC\Cache\File $userCache + */ + protected $userCache; + + public function __construct() { + $this->userCache = new File(); + } + + /** + * Get a value from the user cache + * + * @param string $key + * @return mixed + */ + public function get($key) { + return $this->userCache->get($key); + } + + /** + * Set a value in the user cache + * + * @param string $key + * @param mixed $value + * @param int $ttl Time To Live in seconds. Defaults to 60*60*24 + * @return bool + */ + public function set($key, $value, $ttl = 0) { + if (empty($key)) { + return false; + } + return $this->userCache->set($key, $value, $ttl); + } + + /** + * Check if a value is set in the user cache + * + * @param string $key + * @return bool + */ + public function hasKey($key) { + return $this->userCache->hasKey($key); + } + + /** + * Remove an item from the user cache + * + * @param string $key + * @return bool + */ + public function remove($key) { + return $this->userCache->remove($key); + } + + /** + * clear the user cache of all entries starting with a prefix + * @param string $prefix (optional) + * @return bool + */ + public function clear($prefix = '') { + return $this->userCache->clear($prefix); + } +} diff --git a/lib/config.php b/lib/private/config.php similarity index 100% rename from lib/config.php rename to lib/private/config.php diff --git a/lib/connector/sabre/ServiceUnavailable.php b/lib/private/connector/sabre/ServiceUnavailable.php similarity index 100% rename from lib/connector/sabre/ServiceUnavailable.php rename to lib/private/connector/sabre/ServiceUnavailable.php diff --git a/lib/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php similarity index 100% rename from lib/connector/sabre/aborteduploaddetectionplugin.php rename to lib/private/connector/sabre/aborteduploaddetectionplugin.php diff --git a/lib/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php similarity index 100% rename from lib/connector/sabre/auth.php rename to lib/private/connector/sabre/auth.php diff --git a/lib/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php similarity index 100% rename from lib/connector/sabre/directory.php rename to lib/private/connector/sabre/directory.php diff --git a/lib/connector/sabre/file.php b/lib/private/connector/sabre/file.php similarity index 100% rename from lib/connector/sabre/file.php rename to lib/private/connector/sabre/file.php diff --git a/lib/connector/sabre/locks.php b/lib/private/connector/sabre/locks.php similarity index 100% rename from lib/connector/sabre/locks.php rename to lib/private/connector/sabre/locks.php diff --git a/lib/connector/sabre/maintenanceplugin.php b/lib/private/connector/sabre/maintenanceplugin.php similarity index 100% rename from lib/connector/sabre/maintenanceplugin.php rename to lib/private/connector/sabre/maintenanceplugin.php diff --git a/lib/connector/sabre/node.php b/lib/private/connector/sabre/node.php similarity index 95% rename from lib/connector/sabre/node.php rename to lib/private/connector/sabre/node.php index ee864ce7b51f592f78b76655c4b5dcb1e6c457b0..fa27abb381ab48297b65dcaae36a33537afdad14 100644 --- a/lib/connector/sabre/node.php +++ b/lib/private/connector/sabre/node.php @@ -214,7 +214,14 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr while( $row = $result->fetchRow()) { $this->property_cache[$row['propertyname']] = $row['propertyvalue']; } - $this->property_cache[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path); + + // Don't call the static getETagPropertyForPath, its result is not cached + $this->getFileinfoCache(); + if ($this->fileinfo_cache['etag']) { + $this->property_cache[self::GETETAG_PROPERTYNAME] = '"'.$this->fileinfo_cache['etag'].'"'; + } else { + $this->property_cache[self::GETETAG_PROPERTYNAME] = null; + } } // if the array was empty, we need to return everything diff --git a/lib/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php similarity index 100% rename from lib/connector/sabre/objecttree.php rename to lib/private/connector/sabre/objecttree.php diff --git a/lib/connector/sabre/principal.php b/lib/private/connector/sabre/principal.php similarity index 100% rename from lib/connector/sabre/principal.php rename to lib/private/connector/sabre/principal.php diff --git a/lib/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php similarity index 100% rename from lib/connector/sabre/quotaplugin.php rename to lib/private/connector/sabre/quotaplugin.php diff --git a/lib/connector/sabre/request.php b/lib/private/connector/sabre/request.php similarity index 100% rename from lib/connector/sabre/request.php rename to lib/private/connector/sabre/request.php diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php new file mode 100644 index 0000000000000000000000000000000000000000..fc6745b450506b063afe027cb8f3578d2e53093d --- /dev/null +++ b/lib/private/contactsmanager.php @@ -0,0 +1,145 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC { + + class ContactsManager implements \OCP\Contacts\IManager { + + /** + * This function is used to search and find contacts within the users address books. + * In case $pattern is empty all contacts will be returned. + * + * @param string $pattern which should match within the $searchProperties + * @param array $searchProperties defines the properties within the query pattern should match + * @param array $options - for future use. One should always have options! + * @return array of contacts which are arrays of key-value-pairs + */ + public function search($pattern, $searchProperties = array(), $options = array()) { + $result = array(); + foreach($this->address_books as $address_book) { + $r = $address_book->search($pattern, $searchProperties, $options); + $result = array_merge($result, $r); + } + + return $result; + } + + /** + * This function can be used to delete the contact identified by the given id + * + * @param object $id the unique identifier to a contact + * @param $address_book_key + * @return bool successful or not + */ + public function delete($id, $address_book_key) { + if (!array_key_exists($address_book_key, $this->address_books)) + return null; + + $address_book = $this->address_books[$address_book_key]; + if ($address_book->getPermissions() & \OCP\PERMISSION_DELETE) + return null; + + return $address_book->delete($id); + } + + /** + * This function is used to create a new contact if 'id' is not given or not present. + * Otherwise the contact will be updated by replacing the entire data set. + * + * @param array $properties this array if key-value-pairs defines a contact + * @param $address_book_key string to identify the address book in which the contact shall be created or updated + * @return array representing the contact just created or updated + */ + public function createOrUpdate($properties, $address_book_key) { + + if (!array_key_exists($address_book_key, $this->address_books)) + return null; + + $address_book = $this->address_books[$address_book_key]; + if ($address_book->getPermissions() & \OCP\PERMISSION_CREATE) + return null; + + return $address_book->createOrUpdate($properties); + } + + /** + * Check if contacts are available (e.g. contacts app enabled) + * + * @return bool true if enabled, false if not + */ + public function isEnabled() { + return !empty($this->address_books); + } + + /** + * @param \OCP\IAddressBook $address_book + */ + public function registerAddressBook(\OCP\IAddressBook $address_book) { + $this->address_books[$address_book->getKey()] = $address_book; + } + + /** + * @param \OCP\IAddressBook $address_book + */ + public function unregisterAddressBook(\OCP\IAddressBook $address_book) { + unset($this->address_books[$address_book->getKey()]); + } + + /** + * @return array + */ + public function getAddressBooks() { + $result = array(); + foreach($this->address_books as $address_book) { + $result[$address_book->getKey()] = $address_book->getDisplayName(); + } + + return $result; + } + + /** + * removes all registered address book instances + */ + public function clear() { + $this->address_books = array(); + } + + /** + * @var \OCP\IAddressBook[] which holds all registered address books + */ + private $address_books = array(); + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * address books are actually requested + * + * @param string $key + * @param \Closure $callable + */ + function register($key, \Closure $callable) + { + // + //TODO: implement me + // + } + } +} diff --git a/lib/db.php b/lib/private/db.php similarity index 100% rename from lib/db.php rename to lib/private/db.php diff --git a/lib/db/adapter.php b/lib/private/db/adapter.php similarity index 100% rename from lib/db/adapter.php rename to lib/private/db/adapter.php diff --git a/lib/db/adapteroci8.php b/lib/private/db/adapteroci8.php similarity index 100% rename from lib/db/adapteroci8.php rename to lib/private/db/adapteroci8.php diff --git a/lib/db/adapterpgsql.php b/lib/private/db/adapterpgsql.php similarity index 100% rename from lib/db/adapterpgsql.php rename to lib/private/db/adapterpgsql.php diff --git a/lib/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php similarity index 100% rename from lib/db/adaptersqlite.php rename to lib/private/db/adaptersqlite.php diff --git a/lib/db/adaptersqlsrv.php b/lib/private/db/adaptersqlsrv.php similarity index 100% rename from lib/db/adaptersqlsrv.php rename to lib/private/db/adaptersqlsrv.php diff --git a/lib/db/connection.php b/lib/private/db/connection.php similarity index 98% rename from lib/db/connection.php rename to lib/private/db/connection.php index 2581969dbd0a34a7a1ab3d61e381f49810943095..2d3193a148a46fa84cd38b31879612f22d64a708 100644 --- a/lib/db/connection.php +++ b/lib/private/db/connection.php @@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\Common\EventManager; -class Connection extends \Doctrine\DBAL\Connection { +class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection { /** * @var string $tablePrefix */ diff --git a/lib/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php similarity index 100% rename from lib/db/mdb2schemamanager.php rename to lib/private/db/mdb2schemamanager.php diff --git a/lib/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php similarity index 100% rename from lib/db/mdb2schemareader.php rename to lib/private/db/mdb2schemareader.php diff --git a/lib/db/mdb2schemawriter.php b/lib/private/db/mdb2schemawriter.php similarity index 100% rename from lib/db/mdb2schemawriter.php rename to lib/private/db/mdb2schemawriter.php diff --git a/lib/db/oracleconnection.php b/lib/private/db/oracleconnection.php similarity index 100% rename from lib/db/oracleconnection.php rename to lib/private/db/oracleconnection.php diff --git a/lib/db/statementwrapper.php b/lib/private/db/statementwrapper.php similarity index 100% rename from lib/db/statementwrapper.php rename to lib/private/db/statementwrapper.php diff --git a/lib/defaults.php b/lib/private/defaults.php similarity index 96% rename from lib/defaults.php rename to lib/private/defaults.php index 10813a3e8d88d3eba151bb95f06f671c110374d4..4951c6f50aebc90b75a13f1a39df29c4db012ac3 100644 --- a/lib/defaults.php +++ b/lib/private/defaults.php @@ -13,6 +13,7 @@ if (file_exists(OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults. class OC_Defaults { private $theme; + private $l; private $defaultEntity; private $defaultName; @@ -24,7 +25,7 @@ class OC_Defaults { private $defaultLogoClaim; function __construct() { - $l = OC_L10N::get('core'); + $this->l = OC_L10N::get('core'); $this->defaultEntity = "ownCloud"; /* e.g. company name, used for footers and copyright notices */ $this->defaultName = "ownCloud"; /* short name, used when referring to the software */ @@ -32,7 +33,7 @@ class OC_Defaults { $this->defaultBaseUrl = "http://owncloud.org"; $this->defaultSyncClientUrl = " http://owncloud.org/sync-clients/"; $this->defaultDocBaseUrl = "http://doc.owncloud.org"; - $this->defaultSlogan = $l->t("web services under your control"); + $this->defaultSlogan = $this->l->t("web services under your control"); $this->defaultLogoClaim = ""; if (class_exists("OC_Theme")) { diff --git a/lib/eventsource.php b/lib/private/eventsource.php similarity index 100% rename from lib/eventsource.php rename to lib/private/eventsource.php diff --git a/lib/filechunking.php b/lib/private/filechunking.php similarity index 98% rename from lib/filechunking.php rename to lib/private/filechunking.php index e6d69273a44a6e08e4ad1bcf728c6cea78808ea2..313a6ee87d2975d6139b2a3a8691a63d6994784e 100644 --- a/lib/filechunking.php +++ b/lib/private/filechunking.php @@ -29,7 +29,7 @@ class OC_FileChunking { protected function getCache() { if (!isset($this->cache)) { - $this->cache = new OC_Cache_File(); + $this->cache = new \OC\Cache\File(); } return $this->cache; } diff --git a/lib/fileproxy.php b/lib/private/fileproxy.php similarity index 100% rename from lib/fileproxy.php rename to lib/private/fileproxy.php diff --git a/lib/fileproxy/fileoperations.php b/lib/private/fileproxy/fileoperations.php similarity index 100% rename from lib/fileproxy/fileoperations.php rename to lib/private/fileproxy/fileoperations.php diff --git a/lib/files.php b/lib/private/files.php similarity index 100% rename from lib/files.php rename to lib/private/files.php diff --git a/lib/files/cache/backgroundwatcher.php b/lib/private/files/cache/backgroundwatcher.php similarity index 100% rename from lib/files/cache/backgroundwatcher.php rename to lib/private/files/cache/backgroundwatcher.php diff --git a/lib/files/cache/cache.php b/lib/private/files/cache/cache.php similarity index 100% rename from lib/files/cache/cache.php rename to lib/private/files/cache/cache.php diff --git a/lib/files/cache/legacy.php b/lib/private/files/cache/legacy.php similarity index 100% rename from lib/files/cache/legacy.php rename to lib/private/files/cache/legacy.php diff --git a/lib/files/cache/permissions.php b/lib/private/files/cache/permissions.php similarity index 100% rename from lib/files/cache/permissions.php rename to lib/private/files/cache/permissions.php diff --git a/lib/files/cache/scanner.php b/lib/private/files/cache/scanner.php similarity index 100% rename from lib/files/cache/scanner.php rename to lib/private/files/cache/scanner.php diff --git a/lib/files/cache/storage.php b/lib/private/files/cache/storage.php similarity index 100% rename from lib/files/cache/storage.php rename to lib/private/files/cache/storage.php diff --git a/lib/files/cache/updater.php b/lib/private/files/cache/updater.php similarity index 100% rename from lib/files/cache/updater.php rename to lib/private/files/cache/updater.php diff --git a/lib/files/cache/upgrade.php b/lib/private/files/cache/upgrade.php similarity index 97% rename from lib/files/cache/upgrade.php rename to lib/private/files/cache/upgrade.php index cfb9a1173113fffd6f278acb780a05e87879001d..e3a46896cbfa49a18f26d0d2446346a170a61a9f 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/private/files/cache/upgrade.php @@ -192,7 +192,15 @@ class Upgrade { */ static function needUpgrade($user) { $cacheVersion = (int)\OCP\Config::getUserValue($user, 'files', 'cache_version', 4); - return $cacheVersion < 5; + if ($cacheVersion < 5) { + $legacy = new \OC\Files\Cache\Legacy($user); + if ($legacy->hasItems()) { + return true; + } + self::upgradeDone($user); + } + + return false; } /** diff --git a/lib/files/cache/watcher.php b/lib/private/files/cache/watcher.php similarity index 100% rename from lib/files/cache/watcher.php rename to lib/private/files/cache/watcher.php diff --git a/lib/files/filesystem.php b/lib/private/files/filesystem.php similarity index 100% rename from lib/files/filesystem.php rename to lib/private/files/filesystem.php diff --git a/lib/files/mapper.php b/lib/private/files/mapper.php similarity index 100% rename from lib/files/mapper.php rename to lib/private/files/mapper.php diff --git a/lib/files/mount/manager.php b/lib/private/files/mount/manager.php similarity index 100% rename from lib/files/mount/manager.php rename to lib/private/files/mount/manager.php diff --git a/lib/files/mount/mount.php b/lib/private/files/mount/mount.php similarity index 100% rename from lib/files/mount/mount.php rename to lib/private/files/mount/mount.php diff --git a/lib/files/node/file.php b/lib/private/files/node/file.php similarity index 100% rename from lib/files/node/file.php rename to lib/private/files/node/file.php diff --git a/lib/files/node/folder.php b/lib/private/files/node/folder.php similarity index 100% rename from lib/files/node/folder.php rename to lib/private/files/node/folder.php diff --git a/lib/files/node/node.php b/lib/private/files/node/node.php similarity index 100% rename from lib/files/node/node.php rename to lib/private/files/node/node.php diff --git a/lib/files/node/nonexistingfile.php b/lib/private/files/node/nonexistingfile.php similarity index 100% rename from lib/files/node/nonexistingfile.php rename to lib/private/files/node/nonexistingfile.php diff --git a/lib/files/node/nonexistingfolder.php b/lib/private/files/node/nonexistingfolder.php similarity index 100% rename from lib/files/node/nonexistingfolder.php rename to lib/private/files/node/nonexistingfolder.php diff --git a/lib/files/node/root.php b/lib/private/files/node/root.php similarity index 100% rename from lib/files/node/root.php rename to lib/private/files/node/root.php diff --git a/lib/files/storage/common.php b/lib/private/files/storage/common.php similarity index 100% rename from lib/files/storage/common.php rename to lib/private/files/storage/common.php diff --git a/lib/files/storage/commontest.php b/lib/private/files/storage/commontest.php similarity index 100% rename from lib/files/storage/commontest.php rename to lib/private/files/storage/commontest.php diff --git a/lib/files/storage/loader.php b/lib/private/files/storage/loader.php similarity index 100% rename from lib/files/storage/loader.php rename to lib/private/files/storage/loader.php diff --git a/lib/files/storage/local.php b/lib/private/files/storage/local.php similarity index 100% rename from lib/files/storage/local.php rename to lib/private/files/storage/local.php diff --git a/lib/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php similarity index 100% rename from lib/files/storage/mappedlocal.php rename to lib/private/files/storage/mappedlocal.php diff --git a/lib/files/storage/storage.php b/lib/private/files/storage/storage.php similarity index 100% rename from lib/files/storage/storage.php rename to lib/private/files/storage/storage.php diff --git a/lib/files/storage/temporary.php b/lib/private/files/storage/temporary.php similarity index 100% rename from lib/files/storage/temporary.php rename to lib/private/files/storage/temporary.php diff --git a/lib/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php similarity index 100% rename from lib/files/storage/wrapper/quota.php rename to lib/private/files/storage/wrapper/quota.php diff --git a/lib/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php similarity index 100% rename from lib/files/storage/wrapper/wrapper.php rename to lib/private/files/storage/wrapper/wrapper.php diff --git a/lib/files/stream/close.php b/lib/private/files/stream/close.php similarity index 100% rename from lib/files/stream/close.php rename to lib/private/files/stream/close.php diff --git a/lib/files/stream/dir.php b/lib/private/files/stream/dir.php similarity index 100% rename from lib/files/stream/dir.php rename to lib/private/files/stream/dir.php diff --git a/lib/files/stream/oc.php b/lib/private/files/stream/oc.php similarity index 100% rename from lib/files/stream/oc.php rename to lib/private/files/stream/oc.php diff --git a/lib/files/stream/quota.php b/lib/private/files/stream/quota.php similarity index 100% rename from lib/files/stream/quota.php rename to lib/private/files/stream/quota.php diff --git a/lib/files/stream/staticstream.php b/lib/private/files/stream/staticstream.php similarity index 100% rename from lib/files/stream/staticstream.php rename to lib/private/files/stream/staticstream.php diff --git a/lib/files/type/detection.php b/lib/private/files/type/detection.php similarity index 100% rename from lib/files/type/detection.php rename to lib/private/files/type/detection.php diff --git a/lib/files/type/templatemanager.php b/lib/private/files/type/templatemanager.php similarity index 100% rename from lib/files/type/templatemanager.php rename to lib/private/files/type/templatemanager.php diff --git a/lib/files/utils/scanner.php b/lib/private/files/utils/scanner.php similarity index 100% rename from lib/files/utils/scanner.php rename to lib/private/files/utils/scanner.php diff --git a/lib/files/view.php b/lib/private/files/view.php similarity index 100% rename from lib/files/view.php rename to lib/private/files/view.php diff --git a/lib/geo.php b/lib/private/geo.php similarity index 100% rename from lib/geo.php rename to lib/private/geo.php diff --git a/lib/group.php b/lib/private/group.php similarity index 100% rename from lib/group.php rename to lib/private/group.php diff --git a/lib/group/backend.php b/lib/private/group/backend.php similarity index 100% rename from lib/group/backend.php rename to lib/private/group/backend.php diff --git a/lib/group/database.php b/lib/private/group/database.php similarity index 100% rename from lib/group/database.php rename to lib/private/group/database.php diff --git a/lib/group/dummy.php b/lib/private/group/dummy.php similarity index 100% rename from lib/group/dummy.php rename to lib/private/group/dummy.php diff --git a/lib/group/example.php b/lib/private/group/example.php similarity index 100% rename from lib/group/example.php rename to lib/private/group/example.php diff --git a/lib/group/group.php b/lib/private/group/group.php similarity index 100% rename from lib/group/group.php rename to lib/private/group/group.php diff --git a/lib/group/interface.php b/lib/private/group/interface.php similarity index 100% rename from lib/group/interface.php rename to lib/private/group/interface.php diff --git a/lib/group/manager.php b/lib/private/group/manager.php similarity index 100% rename from lib/group/manager.php rename to lib/private/group/manager.php diff --git a/lib/helper.php b/lib/private/helper.php similarity index 100% rename from lib/helper.php rename to lib/private/helper.php diff --git a/lib/hintexception.php b/lib/private/hintexception.php similarity index 100% rename from lib/hintexception.php rename to lib/private/hintexception.php diff --git a/lib/hook.php b/lib/private/hook.php similarity index 100% rename from lib/hook.php rename to lib/private/hook.php diff --git a/lib/hooks/basicemitter.php b/lib/private/hooks/basicemitter.php similarity index 100% rename from lib/hooks/basicemitter.php rename to lib/private/hooks/basicemitter.php diff --git a/lib/hooks/emitter.php b/lib/private/hooks/emitter.php similarity index 100% rename from lib/hooks/emitter.php rename to lib/private/hooks/emitter.php diff --git a/lib/hooks/forwardingemitter.php b/lib/private/hooks/forwardingemitter.php similarity index 100% rename from lib/hooks/forwardingemitter.php rename to lib/private/hooks/forwardingemitter.php diff --git a/lib/hooks/legacyemitter.php b/lib/private/hooks/legacyemitter.php similarity index 100% rename from lib/hooks/legacyemitter.php rename to lib/private/hooks/legacyemitter.php diff --git a/lib/hooks/publicemitter.php b/lib/private/hooks/publicemitter.php similarity index 100% rename from lib/hooks/publicemitter.php rename to lib/private/hooks/publicemitter.php diff --git a/lib/image.php b/lib/private/image.php similarity index 100% rename from lib/image.php rename to lib/private/image.php diff --git a/lib/installer.php b/lib/private/installer.php similarity index 100% rename from lib/installer.php rename to lib/private/installer.php diff --git a/lib/json.php b/lib/private/json.php similarity index 100% rename from lib/json.php rename to lib/private/json.php diff --git a/lib/l10n.php b/lib/private/l10n.php similarity index 100% rename from lib/l10n.php rename to lib/private/l10n.php diff --git a/lib/l10n/ach.php b/lib/private/l10n/ach.php similarity index 100% rename from lib/l10n/ach.php rename to lib/private/l10n/ach.php diff --git a/lib/l10n/af_ZA.php b/lib/private/l10n/af_ZA.php similarity index 100% rename from lib/l10n/af_ZA.php rename to lib/private/l10n/af_ZA.php diff --git a/lib/l10n/ar.php b/lib/private/l10n/ar.php similarity index 100% rename from lib/l10n/ar.php rename to lib/private/l10n/ar.php diff --git a/lib/l10n/be.php b/lib/private/l10n/be.php similarity index 100% rename from lib/l10n/be.php rename to lib/private/l10n/be.php diff --git a/lib/l10n/bg_BG.php b/lib/private/l10n/bg_BG.php similarity index 100% rename from lib/l10n/bg_BG.php rename to lib/private/l10n/bg_BG.php diff --git a/lib/l10n/bn_BD.php b/lib/private/l10n/bn_BD.php similarity index 100% rename from lib/l10n/bn_BD.php rename to lib/private/l10n/bn_BD.php diff --git a/lib/l10n/bs.php b/lib/private/l10n/bs.php similarity index 100% rename from lib/l10n/bs.php rename to lib/private/l10n/bs.php diff --git a/lib/l10n/ca.php b/lib/private/l10n/ca.php similarity index 100% rename from lib/l10n/ca.php rename to lib/private/l10n/ca.php diff --git a/lib/l10n/cs_CZ.php b/lib/private/l10n/cs_CZ.php similarity index 100% rename from lib/l10n/cs_CZ.php rename to lib/private/l10n/cs_CZ.php diff --git a/lib/l10n/cy_GB.php b/lib/private/l10n/cy_GB.php similarity index 100% rename from lib/l10n/cy_GB.php rename to lib/private/l10n/cy_GB.php diff --git a/lib/l10n/da.php b/lib/private/l10n/da.php similarity index 100% rename from lib/l10n/da.php rename to lib/private/l10n/da.php diff --git a/lib/l10n/de.php b/lib/private/l10n/de.php similarity index 100% rename from lib/l10n/de.php rename to lib/private/l10n/de.php diff --git a/lib/l10n/de_AT.php b/lib/private/l10n/de_AT.php similarity index 100% rename from lib/l10n/de_AT.php rename to lib/private/l10n/de_AT.php diff --git a/lib/l10n/de_CH.php b/lib/private/l10n/de_CH.php similarity index 100% rename from lib/l10n/de_CH.php rename to lib/private/l10n/de_CH.php diff --git a/lib/l10n/de_DE.php b/lib/private/l10n/de_DE.php similarity index 100% rename from lib/l10n/de_DE.php rename to lib/private/l10n/de_DE.php diff --git a/lib/l10n/el.php b/lib/private/l10n/el.php similarity index 100% rename from lib/l10n/el.php rename to lib/private/l10n/el.php diff --git a/lib/l10n/en@pirate.php b/lib/private/l10n/en@pirate.php similarity index 100% rename from lib/l10n/en@pirate.php rename to lib/private/l10n/en@pirate.php diff --git a/lib/l10n/en_GB.php b/lib/private/l10n/en_GB.php similarity index 100% rename from lib/l10n/en_GB.php rename to lib/private/l10n/en_GB.php diff --git a/lib/l10n/eo.php b/lib/private/l10n/eo.php similarity index 100% rename from lib/l10n/eo.php rename to lib/private/l10n/eo.php diff --git a/lib/l10n/es.php b/lib/private/l10n/es.php similarity index 100% rename from lib/l10n/es.php rename to lib/private/l10n/es.php diff --git a/lib/l10n/es_AR.php b/lib/private/l10n/es_AR.php similarity index 100% rename from lib/l10n/es_AR.php rename to lib/private/l10n/es_AR.php diff --git a/lib/l10n/es_MX.php b/lib/private/l10n/es_MX.php similarity index 100% rename from lib/l10n/es_MX.php rename to lib/private/l10n/es_MX.php diff --git a/lib/l10n/et_EE.php b/lib/private/l10n/et_EE.php similarity index 100% rename from lib/l10n/et_EE.php rename to lib/private/l10n/et_EE.php diff --git a/lib/l10n/eu.php b/lib/private/l10n/eu.php similarity index 100% rename from lib/l10n/eu.php rename to lib/private/l10n/eu.php diff --git a/lib/l10n/fa.php b/lib/private/l10n/fa.php similarity index 100% rename from lib/l10n/fa.php rename to lib/private/l10n/fa.php diff --git a/lib/l10n/fi.php b/lib/private/l10n/fi.php similarity index 100% rename from lib/l10n/fi.php rename to lib/private/l10n/fi.php diff --git a/lib/l10n/fi_FI.php b/lib/private/l10n/fi_FI.php similarity index 100% rename from lib/l10n/fi_FI.php rename to lib/private/l10n/fi_FI.php diff --git a/lib/l10n/fr.php b/lib/private/l10n/fr.php similarity index 100% rename from lib/l10n/fr.php rename to lib/private/l10n/fr.php diff --git a/lib/l10n/gl.php b/lib/private/l10n/gl.php similarity index 100% rename from lib/l10n/gl.php rename to lib/private/l10n/gl.php diff --git a/lib/l10n/he.php b/lib/private/l10n/he.php similarity index 100% rename from lib/l10n/he.php rename to lib/private/l10n/he.php diff --git a/lib/l10n/hi.php b/lib/private/l10n/hi.php similarity index 100% rename from lib/l10n/hi.php rename to lib/private/l10n/hi.php diff --git a/lib/l10n/hr.php b/lib/private/l10n/hr.php similarity index 100% rename from lib/l10n/hr.php rename to lib/private/l10n/hr.php diff --git a/lib/l10n/hu_HU.php b/lib/private/l10n/hu_HU.php similarity index 84% rename from lib/l10n/hu_HU.php rename to lib/private/l10n/hu_HU.php index 7ec7621a6553c24efd9495baee9755f88389439a..e944291caee069b4c43bef8958a376ae85a95345 100644 --- a/lib/l10n/hu_HU.php +++ b/lib/private/l10n/hu_HU.php @@ -1,11 +1,14 @@ <?php $TRANSLATIONS = array( +"No app name specified" => "Nincs az alkalmazás név megadva.", "Help" => "Súgó", "Personal" => "Személyes", "Settings" => "Beállítások", "Users" => "Felhasználók", "Admin" => "Adminsztráció", "Failed to upgrade \"%s\"." => "Sikertelen Frissítés \"%s\".", +"Unknown filetype" => "Ismeretlen file tipús", +"Invalid image" => "Hibás kép", "web services under your control" => "webszolgáltatások saját kézben", "cannot open \"%s\"" => "nem sikerült megnyitni \"%s\"", "ZIP download is turned off." => "A ZIP-letöltés nincs engedélyezve.", @@ -13,6 +16,10 @@ $TRANSLATIONS = array( "Back to Files" => "Vissza a Fájlokhoz", "Selected files too large to generate zip file." => "A kiválasztott fájlok túl nagyok a zip tömörítéshez.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Tölts le a fileokat kisebb chunkokban, kölün vagy kérj segitséget a rendszergazdádtól.", +"App does not provide an info.xml file" => "Az alkalmazás nem szolgáltatott info.xml file-t", +"App can't be installed because it is not compatible with this version of ownCloud" => "Az alalmazás nem telepíthető, mert nem kompatibilis az ownClod ezzel a verziójával.", +"App directory already exists" => "Az alkalmazás mappája már létezik", +"Can't create app folder. Please fix permissions. %s" => "Nem lehetett létrehozni az alkalmzás mappáját. Kérlek ellenőrizd a jogosultásgokat. %s", "Application is not enabled" => "Az alkalmazás nincs engedélyezve", "Authentication error" => "Azonosítási hiba", "Token expired. Please reload page." => "A token lejárt. Frissítse az oldalt.", @@ -39,6 +46,7 @@ $TRANSLATIONS = array( "Set an admin password." => "Állítson be egy jelszót az adminisztrációhoz.", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Az Ön webkiszolgálója nincs megfelelően beállítva az állományok szinkronizálásához, mert a WebDAV-elérés úgy tűnik, nem működik.", "Please double check the <a href='%s'>installation guides</a>." => "Kérjük tüzetesen tanulmányozza át a <a href='%s'>telepítési útmutatót</a>.", +"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\"", "seconds ago" => "pár másodperce", "_%n minute ago_::_%n minutes ago_" => array("",""), "_%n hour ago_::_%n hours ago_" => array("",""), @@ -49,7 +57,6 @@ $TRANSLATIONS = array( "_%n month ago_::_%n months ago_" => array("",""), "last year" => "tavaly", "years ago" => "több éve", -"Caused by:" => "Okozta:", -"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\"" +"Caused by:" => "Okozta:" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/l10n/hy.php b/lib/private/l10n/hy.php similarity index 100% rename from lib/l10n/hy.php rename to lib/private/l10n/hy.php diff --git a/lib/l10n/ia.php b/lib/private/l10n/ia.php similarity index 100% rename from lib/l10n/ia.php rename to lib/private/l10n/ia.php diff --git a/lib/l10n/id.php b/lib/private/l10n/id.php similarity index 100% rename from lib/l10n/id.php rename to lib/private/l10n/id.php diff --git a/lib/l10n/is.php b/lib/private/l10n/is.php similarity index 100% rename from lib/l10n/is.php rename to lib/private/l10n/is.php diff --git a/lib/l10n/it.php b/lib/private/l10n/it.php similarity index 100% rename from lib/l10n/it.php rename to lib/private/l10n/it.php diff --git a/lib/l10n/ja_JP.php b/lib/private/l10n/ja_JP.php similarity index 100% rename from lib/l10n/ja_JP.php rename to lib/private/l10n/ja_JP.php diff --git a/lib/l10n/ka.php b/lib/private/l10n/ka.php similarity index 100% rename from lib/l10n/ka.php rename to lib/private/l10n/ka.php diff --git a/lib/l10n/ka_GE.php b/lib/private/l10n/ka_GE.php similarity index 100% rename from lib/l10n/ka_GE.php rename to lib/private/l10n/ka_GE.php diff --git a/lib/l10n/km.php b/lib/private/l10n/km.php similarity index 100% rename from lib/l10n/km.php rename to lib/private/l10n/km.php diff --git a/lib/l10n/kn.php b/lib/private/l10n/kn.php similarity index 100% rename from lib/l10n/kn.php rename to lib/private/l10n/kn.php diff --git a/lib/l10n/ko.php b/lib/private/l10n/ko.php similarity index 91% rename from lib/l10n/ko.php rename to lib/private/l10n/ko.php index eec5be65abd5d4a48974f3688a99c4781587aea1..3ef39fefa602d3e1f2da40eb3c65ca9967aea6e1 100644 --- a/lib/l10n/ko.php +++ b/lib/private/l10n/ko.php @@ -8,12 +8,16 @@ $TRANSLATIONS = array( "Users" => "사용자", "Admin" => "관리자", "Failed to upgrade \"%s\"." => "\"%s\" 업그레이드에 실패했습니다.", +"Custom profile pictures don't work with encryption yet" => "개개인의 프로필 사진은 아직은 암호화 되지 않습니다", +"Unknown filetype" => "알수없는 파일형식", +"Invalid image" => "잘못된 그림", "web services under your control" => "내가 관리하는 웹 서비스", "cannot open \"%s\"" => "\"%s\"을(를) 열 수 없습니다.", "ZIP download is turned off." => "ZIP 다운로드가 비활성화되었습니다.", "Files need to be downloaded one by one." => "파일을 개별적으로 다운로드해야 합니다.", "Back to Files" => "파일로 돌아가기", "Selected files too large to generate zip file." => "선택한 파일들은 ZIP 파일을 생성하기에 너무 큽니다.", +"Download the files in smaller chunks, seperately or kindly ask your administrator." => "작은 조각들 안에 들어있는 파일들을 받고자 하신다면, 나누어서 받으시거나 혹은 시스템 관리자에게 정중하게 물어보십시오", "No source specified when installing app" => "앱을 설치할 때 소스가 지정되지 않았습니다.", "No href specified when installing app from http" => "http에서 앱을 설치할 대 href가 지정되지 않았습니다.", "No path specified when installing app from local file" => "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", @@ -52,6 +56,7 @@ $TRANSLATIONS = array( "Set an admin password." => "관리자 비밀번호 설정", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서버에서 파일 동기화를 사용할 수 있도록 설정이 제대로 되지 않은 것 같습니다.", "Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오.", +"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다.", "seconds ago" => "초 전", "_%n minute ago_::_%n minutes ago_" => array("%n분 전 "), "_%n hour ago_::_%n hours ago_" => array("%n시간 전 "), @@ -62,7 +67,6 @@ $TRANSLATIONS = array( "_%n month ago_::_%n months ago_" => array("%n달 전 "), "last year" => "작년", "years ago" => "년 전", -"Caused by:" => "원인: ", -"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다." +"Caused by:" => "원인: " ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/l10n/ku_IQ.php b/lib/private/l10n/ku_IQ.php similarity index 100% rename from lib/l10n/ku_IQ.php rename to lib/private/l10n/ku_IQ.php diff --git a/lib/l10n/lb.php b/lib/private/l10n/lb.php similarity index 100% rename from lib/l10n/lb.php rename to lib/private/l10n/lb.php diff --git a/lib/l10n/lt_LT.php b/lib/private/l10n/lt_LT.php similarity index 100% rename from lib/l10n/lt_LT.php rename to lib/private/l10n/lt_LT.php diff --git a/lib/l10n/lv.php b/lib/private/l10n/lv.php similarity index 100% rename from lib/l10n/lv.php rename to lib/private/l10n/lv.php diff --git a/lib/l10n/mk.php b/lib/private/l10n/mk.php similarity index 100% rename from lib/l10n/mk.php rename to lib/private/l10n/mk.php diff --git a/lib/l10n/ml_IN.php b/lib/private/l10n/ml_IN.php similarity index 100% rename from lib/l10n/ml_IN.php rename to lib/private/l10n/ml_IN.php diff --git a/lib/l10n/ms_MY.php b/lib/private/l10n/ms_MY.php similarity index 100% rename from lib/l10n/ms_MY.php rename to lib/private/l10n/ms_MY.php diff --git a/lib/l10n/my_MM.php b/lib/private/l10n/my_MM.php similarity index 100% rename from lib/l10n/my_MM.php rename to lib/private/l10n/my_MM.php diff --git a/lib/l10n/nb_NO.php b/lib/private/l10n/nb_NO.php similarity index 100% rename from lib/l10n/nb_NO.php rename to lib/private/l10n/nb_NO.php diff --git a/lib/l10n/ne.php b/lib/private/l10n/ne.php similarity index 100% rename from lib/l10n/ne.php rename to lib/private/l10n/ne.php diff --git a/lib/l10n/nl.php b/lib/private/l10n/nl.php similarity index 100% rename from lib/l10n/nl.php rename to lib/private/l10n/nl.php diff --git a/lib/l10n/nn_NO.php b/lib/private/l10n/nn_NO.php similarity index 100% rename from lib/l10n/nn_NO.php rename to lib/private/l10n/nn_NO.php diff --git a/lib/l10n/nqo.php b/lib/private/l10n/nqo.php similarity index 100% rename from lib/l10n/nqo.php rename to lib/private/l10n/nqo.php diff --git a/lib/l10n/oc.php b/lib/private/l10n/oc.php similarity index 100% rename from lib/l10n/oc.php rename to lib/private/l10n/oc.php diff --git a/lib/l10n/pa.php b/lib/private/l10n/pa.php similarity index 100% rename from lib/l10n/pa.php rename to lib/private/l10n/pa.php diff --git a/lib/l10n/pl.php b/lib/private/l10n/pl.php similarity index 95% rename from lib/l10n/pl.php rename to lib/private/l10n/pl.php index 4acd735d692161c470719b7098b5ce6317727446..270559b4e5067cef01a25103a5b8a32f971d0058 100644 --- a/lib/l10n/pl.php +++ b/lib/private/l10n/pl.php @@ -8,6 +8,9 @@ $TRANSLATIONS = array( "Users" => "Użytkownicy", "Admin" => "Administrator", "Failed to upgrade \"%s\"." => "Błąd przy aktualizacji \"%s\".", +"Custom profile pictures don't work with encryption yet" => "Domyślny profil zdjęć nie działa z szyfrowaniem jeszcze", +"Unknown filetype" => "Nieznany typ pliku", +"Invalid image" => "Błędne zdjęcie", "web services under your control" => "Kontrolowane serwisy", "cannot open \"%s\"" => "Nie można otworzyć \"%s\"", "ZIP download is turned off." => "Pobieranie ZIP jest wyłączone.", @@ -53,6 +56,7 @@ $TRANSLATIONS = array( "Set an admin password." => "Ustaw hasło administratora.", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serwer internetowy nie jest jeszcze poprawnie skonfigurowany, aby umożliwić synchronizację plików, ponieważ interfejs WebDAV wydaje się być uszkodzony.", "Please double check the <a href='%s'>installation guides</a>." => "Sprawdź ponownie <a href='%s'>przewodniki instalacji</a>.", +"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\"", "seconds ago" => "sekund temu", "_%n minute ago_::_%n minutes ago_" => array("%n minute temu","%n minut temu","%n minut temu"), "_%n hour ago_::_%n hours ago_" => array("%n godzinę temu","%n godzin temu","%n godzin temu"), @@ -63,7 +67,6 @@ $TRANSLATIONS = array( "_%n month ago_::_%n months ago_" => array("%n miesiąc temu","%n miesięcy temu","%n miesięcy temu"), "last year" => "w zeszłym roku", "years ago" => "lat temu", -"Caused by:" => "Spowodowane przez:", -"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\"" +"Caused by:" => "Spowodowane przez:" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/lib/l10n/pl_PL.php b/lib/private/l10n/pl_PL.php similarity index 100% rename from lib/l10n/pl_PL.php rename to lib/private/l10n/pl_PL.php diff --git a/lib/l10n/pt_BR.php b/lib/private/l10n/pt_BR.php similarity index 100% rename from lib/l10n/pt_BR.php rename to lib/private/l10n/pt_BR.php diff --git a/lib/l10n/pt_PT.php b/lib/private/l10n/pt_PT.php similarity index 100% rename from lib/l10n/pt_PT.php rename to lib/private/l10n/pt_PT.php diff --git a/lib/l10n/ro.php b/lib/private/l10n/ro.php similarity index 100% rename from lib/l10n/ro.php rename to lib/private/l10n/ro.php diff --git a/lib/l10n/ru.php b/lib/private/l10n/ru.php similarity index 100% rename from lib/l10n/ru.php rename to lib/private/l10n/ru.php diff --git a/lib/l10n/si_LK.php b/lib/private/l10n/si_LK.php similarity index 100% rename from lib/l10n/si_LK.php rename to lib/private/l10n/si_LK.php diff --git a/lib/l10n/sk.php b/lib/private/l10n/sk.php similarity index 100% rename from lib/l10n/sk.php rename to lib/private/l10n/sk.php diff --git a/lib/l10n/sk_SK.php b/lib/private/l10n/sk_SK.php similarity index 100% rename from lib/l10n/sk_SK.php rename to lib/private/l10n/sk_SK.php diff --git a/lib/l10n/sl.php b/lib/private/l10n/sl.php similarity index 100% rename from lib/l10n/sl.php rename to lib/private/l10n/sl.php diff --git a/lib/l10n/sq.php b/lib/private/l10n/sq.php similarity index 100% rename from lib/l10n/sq.php rename to lib/private/l10n/sq.php diff --git a/lib/l10n/sr.php b/lib/private/l10n/sr.php similarity index 100% rename from lib/l10n/sr.php rename to lib/private/l10n/sr.php diff --git a/lib/l10n/sr@latin.php b/lib/private/l10n/sr@latin.php similarity index 100% rename from lib/l10n/sr@latin.php rename to lib/private/l10n/sr@latin.php diff --git a/lib/l10n/string.php b/lib/private/l10n/string.php similarity index 100% rename from lib/l10n/string.php rename to lib/private/l10n/string.php diff --git a/lib/l10n/sv.php b/lib/private/l10n/sv.php similarity index 100% rename from lib/l10n/sv.php rename to lib/private/l10n/sv.php diff --git a/lib/l10n/sw_KE.php b/lib/private/l10n/sw_KE.php similarity index 100% rename from lib/l10n/sw_KE.php rename to lib/private/l10n/sw_KE.php diff --git a/lib/l10n/ta_LK.php b/lib/private/l10n/ta_LK.php similarity index 100% rename from lib/l10n/ta_LK.php rename to lib/private/l10n/ta_LK.php diff --git a/lib/l10n/te.php b/lib/private/l10n/te.php similarity index 100% rename from lib/l10n/te.php rename to lib/private/l10n/te.php diff --git a/lib/l10n/th_TH.php b/lib/private/l10n/th_TH.php similarity index 100% rename from lib/l10n/th_TH.php rename to lib/private/l10n/th_TH.php diff --git a/lib/l10n/tr.php b/lib/private/l10n/tr.php similarity index 100% rename from lib/l10n/tr.php rename to lib/private/l10n/tr.php diff --git a/lib/l10n/ug.php b/lib/private/l10n/ug.php similarity index 100% rename from lib/l10n/ug.php rename to lib/private/l10n/ug.php diff --git a/lib/l10n/uk.php b/lib/private/l10n/uk.php similarity index 100% rename from lib/l10n/uk.php rename to lib/private/l10n/uk.php diff --git a/lib/l10n/ur_PK.php b/lib/private/l10n/ur_PK.php similarity index 100% rename from lib/l10n/ur_PK.php rename to lib/private/l10n/ur_PK.php diff --git a/lib/l10n/vi.php b/lib/private/l10n/vi.php similarity index 100% rename from lib/l10n/vi.php rename to lib/private/l10n/vi.php diff --git a/lib/l10n/zh_CN.php b/lib/private/l10n/zh_CN.php similarity index 100% rename from lib/l10n/zh_CN.php rename to lib/private/l10n/zh_CN.php diff --git a/lib/l10n/zh_HK.php b/lib/private/l10n/zh_HK.php similarity index 100% rename from lib/l10n/zh_HK.php rename to lib/private/l10n/zh_HK.php diff --git a/lib/l10n/zh_TW.php b/lib/private/l10n/zh_TW.php similarity index 100% rename from lib/l10n/zh_TW.php rename to lib/private/l10n/zh_TW.php diff --git a/lib/private/legacy/cache.php b/lib/private/legacy/cache.php new file mode 100644 index 0000000000000000000000000000000000000000..f915eb516b1e538c5db80b91b5fc17f1382426f2 --- /dev/null +++ b/lib/private/legacy/cache.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class OC_Cache extends \OC\Cache { +} \ No newline at end of file diff --git a/lib/legacy/config.php b/lib/private/legacy/config.php similarity index 100% rename from lib/legacy/config.php rename to lib/private/legacy/config.php diff --git a/lib/legacy/filesystem.php b/lib/private/legacy/filesystem.php similarity index 100% rename from lib/legacy/filesystem.php rename to lib/private/legacy/filesystem.php diff --git a/lib/legacy/filesystemview.php b/lib/private/legacy/filesystemview.php similarity index 100% rename from lib/legacy/filesystemview.php rename to lib/private/legacy/filesystemview.php diff --git a/lib/legacy/log.php b/lib/private/legacy/log.php similarity index 100% rename from lib/legacy/log.php rename to lib/private/legacy/log.php diff --git a/lib/legacy/preferences.php b/lib/private/legacy/preferences.php similarity index 100% rename from lib/legacy/preferences.php rename to lib/private/legacy/preferences.php diff --git a/lib/legacy/updater.php b/lib/private/legacy/updater.php similarity index 100% rename from lib/legacy/updater.php rename to lib/private/legacy/updater.php diff --git a/lib/log.php b/lib/private/log.php similarity index 100% rename from lib/log.php rename to lib/private/log.php diff --git a/lib/log/errorhandler.php b/lib/private/log/errorhandler.php similarity index 100% rename from lib/log/errorhandler.php rename to lib/private/log/errorhandler.php diff --git a/lib/log/owncloud.php b/lib/private/log/owncloud.php similarity index 100% rename from lib/log/owncloud.php rename to lib/private/log/owncloud.php diff --git a/lib/log/rotate.php b/lib/private/log/rotate.php similarity index 100% rename from lib/log/rotate.php rename to lib/private/log/rotate.php diff --git a/lib/log/syslog.php b/lib/private/log/syslog.php similarity index 100% rename from lib/log/syslog.php rename to lib/private/log/syslog.php diff --git a/lib/mail.php b/lib/private/mail.php similarity index 100% rename from lib/mail.php rename to lib/private/mail.php diff --git a/lib/memcache/apc.php b/lib/private/memcache/apc.php similarity index 100% rename from lib/memcache/apc.php rename to lib/private/memcache/apc.php diff --git a/lib/memcache/apcu.php b/lib/private/memcache/apcu.php similarity index 100% rename from lib/memcache/apcu.php rename to lib/private/memcache/apcu.php diff --git a/lib/memcache/cache.php b/lib/private/memcache/cache.php similarity index 100% rename from lib/memcache/cache.php rename to lib/private/memcache/cache.php diff --git a/lib/memcache/factory.php b/lib/private/memcache/factory.php similarity index 100% rename from lib/memcache/factory.php rename to lib/private/memcache/factory.php diff --git a/lib/memcache/memcached.php b/lib/private/memcache/memcached.php similarity index 100% rename from lib/memcache/memcached.php rename to lib/private/memcache/memcached.php diff --git a/lib/memcache/xcache.php b/lib/private/memcache/xcache.php similarity index 100% rename from lib/memcache/xcache.php rename to lib/private/memcache/xcache.php diff --git a/lib/migrate.php b/lib/private/migrate.php similarity index 100% rename from lib/migrate.php rename to lib/private/migrate.php diff --git a/lib/migration/content.php b/lib/private/migration/content.php similarity index 100% rename from lib/migration/content.php rename to lib/private/migration/content.php diff --git a/lib/migration/provider.php b/lib/private/migration/provider.php similarity index 100% rename from lib/migration/provider.php rename to lib/private/migration/provider.php diff --git a/lib/mimetypes.list.php b/lib/private/mimetypes.list.php similarity index 100% rename from lib/mimetypes.list.php rename to lib/private/mimetypes.list.php diff --git a/lib/minimizer.php b/lib/private/minimizer.php similarity index 100% rename from lib/minimizer.php rename to lib/private/minimizer.php diff --git a/lib/minimizer/css.php b/lib/private/minimizer/css.php similarity index 100% rename from lib/minimizer/css.php rename to lib/private/minimizer/css.php diff --git a/lib/minimizer/js.php b/lib/private/minimizer/js.php similarity index 100% rename from lib/minimizer/js.php rename to lib/private/minimizer/js.php diff --git a/lib/private/navigationmanager.php b/lib/private/navigationmanager.php new file mode 100644 index 0000000000000000000000000000000000000000..1f657b9ad80fd8b47edf0c381efd09132dd1ae15 --- /dev/null +++ b/lib/private/navigationmanager.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC; + +/** + * Manages the ownCloud navigation + */ +class NavigationManager implements \OCP\INavigationManager { + protected $entries = array(); + protected $activeEntry; + + /** + * Creates a new navigation entry + * @param array $entry containing: id, name, order, icon and href key + */ + public function add(array $entry) { + $entry['active'] = false; + if(!isset($entry['icon'])) { + $entry['icon'] = ''; + } + $this->entries[] = $entry; + } + + /** + * @brief returns all the added Menu entries + * @return array of the added entries + */ + public function getAll() { + return $this->entries; + } + + /** + * @brief removes all the entries + */ + public function clear() { + $this->entries = array(); + } + + /** + * Sets the current navigation entry of the currently running app + * @param string $id of the app entry to activate (from added $entry) + */ + public function setActiveEntry($id) { + $this->activeEntry = $id; + } + + /** + * @brief gets the active Menu entry + * @return string id or empty string + * + * This function returns the id of the active navigation entry (set by + * setActiveEntry + */ + public function getActiveEntry() { + return $this->activeEntry; + } +} diff --git a/lib/notsquareexception.php b/lib/private/notsquareexception.php similarity index 100% rename from lib/notsquareexception.php rename to lib/private/notsquareexception.php diff --git a/lib/ocs.php b/lib/private/ocs.php similarity index 100% rename from lib/ocs.php rename to lib/private/ocs.php diff --git a/lib/ocs/cloud.php b/lib/private/ocs/cloud.php similarity index 100% rename from lib/ocs/cloud.php rename to lib/private/ocs/cloud.php diff --git a/lib/ocs/config.php b/lib/private/ocs/config.php similarity index 100% rename from lib/ocs/config.php rename to lib/private/ocs/config.php diff --git a/lib/ocs/person.php b/lib/private/ocs/person.php similarity index 100% rename from lib/ocs/person.php rename to lib/private/ocs/person.php diff --git a/lib/ocs/privatedata.php b/lib/private/ocs/privatedata.php similarity index 100% rename from lib/ocs/privatedata.php rename to lib/private/ocs/privatedata.php diff --git a/lib/ocs/result.php b/lib/private/ocs/result.php similarity index 100% rename from lib/ocs/result.php rename to lib/private/ocs/result.php diff --git a/lib/ocsclient.php b/lib/private/ocsclient.php similarity index 97% rename from lib/ocsclient.php rename to lib/private/ocsclient.php index 58636f806be694d361c66628295233e72e491cd7..e35556d92b80abc253ca7ed884c08a8dae13a3f6 100644 --- a/lib/ocsclient.php +++ b/lib/private/ocsclient.php @@ -36,7 +36,12 @@ class OC_OCSClient{ * to set it in the config file or it will fallback to the default */ private static function getAppStoreURL() { - $url = OC_Config::getValue('appstoreurl', 'http://api.apps.owncloud.com/v1'); + if(OC_Util::getEditionString()===''){ + $default='http://api.apps.owncloud.com/v1'; + }else{ + $default=''; + } + $url = OC_Config::getValue('appstoreurl', $default); return($url); } diff --git a/lib/preferences.php b/lib/private/preferences.php similarity index 100% rename from lib/preferences.php rename to lib/private/preferences.php diff --git a/lib/preview.php b/lib/private/preview.php similarity index 99% rename from lib/preview.php rename to lib/private/preview.php index b40ba191fbae27eb1b36444bc29eea543038568d..266f7795f12f420402c9809b67cbcc376e51444e 100755 --- a/lib/preview.php +++ b/lib/private/preview.php @@ -42,6 +42,9 @@ class Preview { private $scalingup; //preview images object + /** + * @var \OC_Image + */ private $preview; //preview providers @@ -624,4 +627,4 @@ class Preview { } return false; } -} \ No newline at end of file +} diff --git a/lib/preview/image.php b/lib/private/preview/image.php similarity index 100% rename from lib/preview/image.php rename to lib/private/preview/image.php diff --git a/lib/preview/movies.php b/lib/private/preview/movies.php similarity index 100% rename from lib/preview/movies.php rename to lib/private/preview/movies.php diff --git a/lib/preview/mp3.php b/lib/private/preview/mp3.php similarity index 100% rename from lib/preview/mp3.php rename to lib/private/preview/mp3.php diff --git a/lib/preview/office-cl.php b/lib/private/preview/office-cl.php similarity index 100% rename from lib/preview/office-cl.php rename to lib/private/preview/office-cl.php diff --git a/lib/preview/office-fallback.php b/lib/private/preview/office-fallback.php similarity index 100% rename from lib/preview/office-fallback.php rename to lib/private/preview/office-fallback.php diff --git a/lib/preview/office.php b/lib/private/preview/office.php similarity index 100% rename from lib/preview/office.php rename to lib/private/preview/office.php diff --git a/lib/preview/pdf.php b/lib/private/preview/pdf.php similarity index 100% rename from lib/preview/pdf.php rename to lib/private/preview/pdf.php diff --git a/lib/preview/provider.php b/lib/private/preview/provider.php similarity index 100% rename from lib/preview/provider.php rename to lib/private/preview/provider.php diff --git a/lib/preview/svg.php b/lib/private/preview/svg.php similarity index 100% rename from lib/preview/svg.php rename to lib/private/preview/svg.php diff --git a/lib/preview/txt.php b/lib/private/preview/txt.php similarity index 100% rename from lib/preview/txt.php rename to lib/private/preview/txt.php diff --git a/lib/preview/unknown.php b/lib/private/preview/unknown.php similarity index 100% rename from lib/preview/unknown.php rename to lib/private/preview/unknown.php diff --git a/lib/private/previewmanager.php b/lib/private/previewmanager.php new file mode 100755 index 0000000000000000000000000000000000000000..ac9a866a75b71d04f86afe114df11e4dbe58d89d --- /dev/null +++ b/lib/private/previewmanager.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright (c) 2013 Thomas Müller thomas.mueller@tmit.eu + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ +namespace OC; + +use OCP\image; +use OCP\IPreview; + +class PreviewManager implements IPreview { + /** + * @brief return a preview of a file + * @param string $file The path to the file where you want a thumbnail from + * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image + * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image + * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly + * @return \OCP\Image + */ + function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) + { + $preview = new \OC\Preview('', '/', $file, $maxX, $maxY, $scaleUp); + return $preview->getPreview(); + } + + /** + * @brief returns true if the passed mime type is supported + * @param string $mimeType + * @return boolean + */ + function isMimeSupported($mimeType = '*') + { + return \OC\Preview::isMimeSupported($mimeType); + } +} diff --git a/lib/request.php b/lib/private/request.php similarity index 100% rename from lib/request.php rename to lib/private/request.php diff --git a/lib/response.php b/lib/private/response.php similarity index 100% rename from lib/response.php rename to lib/private/response.php diff --git a/lib/route.php b/lib/private/route.php similarity index 100% rename from lib/route.php rename to lib/private/route.php diff --git a/lib/router.php b/lib/private/router.php similarity index 100% rename from lib/router.php rename to lib/private/router.php diff --git a/lib/search.php b/lib/private/search.php similarity index 100% rename from lib/search.php rename to lib/private/search.php diff --git a/lib/search/provider.php b/lib/private/search/provider.php similarity index 100% rename from lib/search/provider.php rename to lib/private/search/provider.php diff --git a/lib/search/provider/file.php b/lib/private/search/provider/file.php similarity index 100% rename from lib/search/provider/file.php rename to lib/private/search/provider/file.php diff --git a/lib/search/result.php b/lib/private/search/result.php similarity index 100% rename from lib/search/result.php rename to lib/private/search/result.php diff --git a/lib/private/server.php b/lib/private/server.php new file mode 100644 index 0000000000000000000000000000000000000000..cabb15324ec36169ff0d950211bf95af008ae3a4 --- /dev/null +++ b/lib/private/server.php @@ -0,0 +1,255 @@ +<?php + +namespace OC; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Utility\SimpleContainer; +use OC\Cache\UserCache; +use OC\Files\Node\Root; +use OC\Files\View; +use OCP\IServerContainer; + +/** + * Class Server + * @package OC + * + * TODO: hookup all manager classes + */ +class Server extends SimpleContainer implements IServerContainer { + + function __construct() { + $this->registerService('ContactsManager', function($c) { + return new ContactsManager(); + }); + $this->registerService('Request', function($c) { + $params = array(); + + // we json decode the body only in case of content type json + if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') !== false ) { + $params = json_decode(file_get_contents('php://input'), true); + $params = is_array($params) ? $params: array(); + } + + return new Request( + array( + 'get' => $_GET, + 'post' => $_POST, + 'files' => $_FILES, + 'server' => $_SERVER, + 'env' => $_ENV, + 'cookies' => $_COOKIE, + 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD'])) + ? $_SERVER['REQUEST_METHOD'] + : null, + 'params' => $params, + 'urlParams' => $c['urlParams'] + ) + ); + }); + $this->registerService('PreviewManager', function($c) { + return new PreviewManager(); + }); + $this->registerService('TagManager', function($c) { + $user = \OC_User::getUser(); + return new TagManager($user); + }); + $this->registerService('RootFolder', function($c) { + // TODO: get user and user manager from container as well + $user = \OC_User::getUser(); + /** @var $c SimpleContainer */ + $userManager = $c->query('UserManager'); + $user = $userManager->get($user); + $manager = \OC\Files\Filesystem::getMountManager(); + $view = new View(); + return new Root($manager, $view, $user); + }); + $this->registerService('UserManager', function($c) { + return new \OC\User\Manager(); + }); + $this->registerService('UserSession', function($c) { + /** @var $c SimpleContainer */ + $manager = $c->query('UserManager'); + $userSession = new \OC\User\Session($manager, \OC::$session); + $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { + \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password)); + }); + $userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password)); + }); + $userSession->listen('\OC\User', 'preDelete', function ($user) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID())); + }); + $userSession->listen('\OC\User', 'postDelete', function ($user) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID())); + }); + $userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); + }); + $userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); + }); + $userSession->listen('\OC\User', 'preLogin', function ($uid, $password) { + \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password)); + }); + $userSession->listen('\OC\User', 'postLogin', function ($user, $password) { + /** @var $user \OC\User\User */ + \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password)); + }); + $userSession->listen('\OC\User', 'logout', function () { + \OC_Hook::emit('OC_User', 'logout', array()); + }); + return $userSession; + }); + $this->registerService('NavigationManager', function($c) { + return new \OC\NavigationManager(); + }); + $this->registerService('AllConfig', function($c) { + return new \OC\AllConfig(); + }); + $this->registerService('UserCache', function($c) { + return new UserCache(); + }); + } + + /** + * @return \OCP\Contacts\IManager + */ + function getContactsManager() { + return $this->query('ContactsManager'); + } + + /** + * The current request object holding all information about the request + * currently being processed is returned from this method. + * In case the current execution was not initiated by a web request null is returned + * + * @return \OCP\IRequest|null + */ + function getRequest() { + return $this->query('Request'); + } + + /** + * Returns the preview manager which can create preview images for a given file + * + * @return \OCP\IPreview + */ + function getPreviewManager() { + return $this->query('PreviewManager'); + } + + /** + * Returns the tag manager which can get and set tags for different object types + * + * @see \OCP\ITagManager::load() + * @return \OCP\ITagManager + */ + function getTagManager() { + return $this->query('TagManager'); + } + + /** + * Returns the root folder of ownCloud's data directory + * + * @return \OCP\Files\Folder + */ + function getRootFolder() { + return $this->query('RootFolder'); + } + + /** + * Returns a view to ownCloud's files folder + * + * @return \OCP\Files\Folder + */ + function getUserFolder() { + + $dir = '/files'; + $root = $this->getRootFolder(); + $folder = null; + if(!$root->nodeExists($dir)) { + $folder = $root->newFolder($dir); + } else { + $folder = $root->get($dir); + } + return $folder; + } + + /** + * Returns an app-specific view in ownClouds data directory + * + * @return \OCP\Files\Folder + */ + function getAppFolder() { + + $dir = '/' . \OC_App::getCurrentApp(); + $root = $this->getRootFolder(); + $folder = null; + if(!$root->nodeExists($dir)) { + $folder = $root->newFolder($dir); + } else { + $folder = $root->get($dir); + } + return $folder; + } + + /** + * @return \OC\User\Manager + */ + function getUserManager() { + return $this->query('UserManager'); + } + + /** + * @return \OC\User\Session + */ + function getUserSession() { + return $this->query('UserSession'); + } + + /** + * @return \OC\NavigationManager + */ + function getNavigationManager() { + return $this->query('NavigationManager'); + } + + /** + * @return \OC\Config + */ + function getConfig() { + return $this->query('AllConfig'); + } + + /** + * Returns an ICache instance + * + * @return \OCP\ICache + */ + function getCache() { + return $this->query('UserCache'); + } + + /** + * Returns the current session + * + * @return \OCP\ISession + */ + function getSession() { + return \OC::$session; + } + + /** + * Returns the current session + * + * @return \OCP\IDBConnection + */ + function getDatabaseConnection() { + return \OC_DB::getConnection(); + } +} diff --git a/lib/session/internal.php b/lib/private/session/internal.php similarity index 100% rename from lib/session/internal.php rename to lib/private/session/internal.php diff --git a/lib/session/memory.php b/lib/private/session/memory.php similarity index 100% rename from lib/session/memory.php rename to lib/private/session/memory.php diff --git a/lib/session/session.php b/lib/private/session/session.php similarity index 95% rename from lib/session/session.php rename to lib/private/session/session.php index 55515f57a87d186adb11c407655b50f943350eda..c55001eccaca570e9381679646be0526855580ee 100644 --- a/lib/session/session.php +++ b/lib/private/session/session.php @@ -8,7 +8,7 @@ namespace OC\Session; -abstract class Session implements \ArrayAccess { +abstract class Session implements \ArrayAccess, \OCP\ISession { /** * $name serves as a namespace for the session keys * diff --git a/lib/setup.php b/lib/private/setup.php similarity index 100% rename from lib/setup.php rename to lib/private/setup.php diff --git a/lib/setup/abstractdatabase.php b/lib/private/setup/abstractdatabase.php similarity index 100% rename from lib/setup/abstractdatabase.php rename to lib/private/setup/abstractdatabase.php diff --git a/lib/setup/mssql.php b/lib/private/setup/mssql.php similarity index 100% rename from lib/setup/mssql.php rename to lib/private/setup/mssql.php diff --git a/lib/setup/mysql.php b/lib/private/setup/mysql.php similarity index 100% rename from lib/setup/mysql.php rename to lib/private/setup/mysql.php diff --git a/lib/setup/oci.php b/lib/private/setup/oci.php similarity index 100% rename from lib/setup/oci.php rename to lib/private/setup/oci.php diff --git a/lib/setup/postgresql.php b/lib/private/setup/postgresql.php similarity index 100% rename from lib/setup/postgresql.php rename to lib/private/setup/postgresql.php diff --git a/lib/setup/sqlite.php b/lib/private/setup/sqlite.php similarity index 100% rename from lib/setup/sqlite.php rename to lib/private/setup/sqlite.php diff --git a/lib/subadmin.php b/lib/private/subadmin.php similarity index 100% rename from lib/subadmin.php rename to lib/private/subadmin.php diff --git a/lib/private/tagmanager.php b/lib/private/tagmanager.php new file mode 100644 index 0000000000000000000000000000000000000000..9a371a11253f524c7148336a22df896f4b60514a --- /dev/null +++ b/lib/private/tagmanager.php @@ -0,0 +1,68 @@ +<?php +/** +* ownCloud +* +* @author Thomas Tanghus +* @copyright 2013 Thomas Tanghus <thomas@tanghus.net> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * Factory class creating instances of \OCP\ITags + * + * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or + * anything else that is either parsed from a vobject or that the user chooses + * to add. + * Tag names are not case-sensitive, but will be saved with the case they + * are entered in. If a user already has a tag 'family' for a type, and + * tries to add a tag named 'Family' it will be silently ignored. + */ + +namespace OC; + +class TagManager implements \OCP\ITagManager { + + /** + * User + * + * @var string + */ + private $user = null; + + /** + * Constructor. + * + * @param string $user The user whos data the object will operate on. + */ + public function __construct($user) { + + $this->user = $user; + + } + + /** + * Create a new \OCP\ITags instance and load tags from db. + * + * @see \OCP\ITags + * @param string $type The type identifier e.g. 'contact' or 'event'. + * @param array $defaultTags An array of default tags to be used if none are stored. + * @return \OCP\ITags + */ + public function load($type, $defaultTags=array()) { + return new Tags($this->user, $type, $defaultTags); + } + +} \ No newline at end of file diff --git a/lib/private/tags.php b/lib/private/tags.php new file mode 100644 index 0000000000000000000000000000000000000000..9fdb35a7d6e54c0021db3ba9c693756cceb8e8a9 --- /dev/null +++ b/lib/private/tags.php @@ -0,0 +1,642 @@ +<?php +/** +* ownCloud +* +* @author Thomas Tanghus +* @copyright 2012-2013 Thomas Tanghus <thomas@tanghus.net> +* @copyright 2012 Bart Visscher bartv@thisnet.nl +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * Class for easily tagging objects by their id + * + * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or + * anything else that is either parsed from a vobject or that the user chooses + * to add. + * Tag names are not case-sensitive, but will be saved with the case they + * are entered in. If a user already has a tag 'family' for a type, and + * tries to add a tag named 'Family' it will be silently ignored. + */ + +namespace OC; + +class Tags implements \OCP\ITags { + + /** + * Tags + * + * @var array + */ + private $tags = array(); + + /** + * Used for storing objectid/categoryname pairs while rescanning. + * + * @var array + */ + private static $relations = array(); + + /** + * Type + * + * @var string + */ + private $type = null; + + /** + * User + * + * @var string + */ + private $user = null; + + const TAG_TABLE = '*PREFIX*vcategory'; + const RELATION_TABLE = '*PREFIX*vcategory_to_object'; + + const TAG_FAVORITE = '_$!<Favorite>!$_'; + + /** + * Constructor. + * + * @param string $user The user whos data the object will operate on. + */ + public function __construct($user, $type, $defaultTags = array()) { + $this->user = $user; + $this->type = $type; + $this->loadTags($defaultTags); + } + + /** + * Load tags from db. + * + * @param string $type The type identifier e.g. 'contact' or 'event'. + * @param array $defaultTags An array of default tags to be used if none are stored. + */ + protected function loadTags($defaultTags=array()) { + $this->tags = array(); + $result = null; + $sql = 'SELECT `id`, `category` FROM `' . self::TAG_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`'; + try { + $stmt = \OCP\DB::prepare($sql); + $result = $stmt->execute(array($this->user, $this->type)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + + if(!is_null($result)) { + while( $row = $result->fetchRow()) { + $this->tags[$row['id']] = $row['category']; + } + } + + if(count($defaultTags) > 0 && count($this->tags) === 0) { + $this->addMultiple($defaultTags, true); + } + \OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true), + \OCP\Util::DEBUG); + + } + + /** + * Check if any tags are saved for this type and user. + * + * @return boolean. + */ + public function isEmpty() { + $sql = 'SELECT COUNT(*) FROM `' . self::TAG_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ?'; + try { + $stmt = \OCP\DB::prepare($sql); + $result = $stmt->execute(array($this->user, $this->type)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + return false; + } + return ((int)$result->fetchOne() === 0); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + } + + /** + * Get the tags for a specific user. + * + * This returns an array with id/name maps: + * [ + * ['id' => 0, 'name' = 'First tag'], + * ['id' => 1, 'name' = 'Second tag'], + * ] + * + * @return array + */ + public function getTags() { + if(!count($this->tags)) { + return array(); + } + + $tags = array_values($this->tags); + uasort($tags, 'strnatcasecmp'); + $tagMap = array(); + + foreach($tags as $tag) { + if($tag !== self::TAG_FAVORITE) { + $tagMap[] = array( + 'id' => $this->array_searchi($tag, $this->tags), + 'name' => $tag + ); + } + } + return $tagMap; + + } + + /** + * Get the a list if items tagged with $tag. + * + * Throws an exception if the tag could not be found. + * + * @param string|integer $tag Tag id or name. + * @return array An array of object ids or false on error. + */ + public function getIdsForTag($tag) { + $result = null; + if(is_numeric($tag)) { + $tagId = $tag; + } elseif(is_string($tag)) { + $tag = trim($tag); + $tagId = $this->array_searchi($tag, $this->tags); + } + + if($tagId === false) { + $l10n = \OC_L10N::get('core'); + throw new \Exception( + $l10n->t('Could not find category "%s"', $tag) + ); + } + + $ids = array(); + $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE + . '` WHERE `categoryid` = ?'; + + try { + $stmt = \OCP\DB::prepare($sql); + $result = $stmt->execute(array($tagId)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + return false; + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + + if(!is_null($result)) { + while( $row = $result->fetchRow()) { + $ids[] = (int)$row['objid']; + } + } + + return $ids; + } + + /** + * Checks whether a tag is already saved. + * + * @param string $name The name to check for. + * @return bool + */ + public function hasTag($name) { + return $this->in_arrayi($name, $this->tags); + } + + /** + * Add a new tag. + * + * @param string $name A string with a name of the tag + * @return int the id of the added tag or false if it already exists. + */ + public function add($name) { + $name = trim($name); + + if($this->hasTag($name)) { + \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG); + return false; + } + try { + $result = \OCP\DB::insertIfNotExist( + self::TAG_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $name, + ) + ); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + return false; + } elseif((int)$result === 0) { + \OCP\Util::writeLog('core', __METHOD__.', Tag already exists: ' . $name, \OCP\Util::DEBUG); + return false; + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + $id = \OCP\DB::insertid(self::TAG_TABLE); + \OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, \OCP\Util::DEBUG); + $this->tags[$id] = $name; + return $id; + } + + /** + * Rename tag. + * + * @param string $from The name of the existing tag + * @param string $to The new name of the tag. + * @return bool + */ + public function rename($from, $to) { + $from = trim($from); + $to = trim($to); + $id = $this->array_searchi($from, $this->tags); + if($id === false) { + \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG); + return false; + } + + $sql = 'UPDATE `' . self::TAG_TABLE . '` SET `category` = ? ' + . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?'; + try { + $stmt = \OCP\DB::prepare($sql); + $result = $stmt->execute(array($to, $this->user, $this->type, $id)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + return false; + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + $this->tags[$id] = $to; + return true; + } + + /** + * Add a list of new tags. + * + * @param string[] $names A string with a name or an array of strings containing + * the name(s) of the to add. + * @param bool $sync When true, save the tags + * @param int|null $id int Optional object id to add to this|these tag(s) + * @return bool Returns false on error. + */ + public function addMultiple($names, $sync=false, $id = null) { + if(!is_array($names)) { + $names = array($names); + } + $names = array_map('trim', $names); + $newones = array(); + foreach($names as $name) { + if(($this->in_arrayi( + $name, $this->tags) == false) && $name !== '') { + $newones[] = $name; + } + if(!is_null($id) ) { + // Insert $objectid, $categoryid pairs if not exist. + self::$relations[] = array('objid' => $id, 'tag' => $name); + } + } + $this->tags = array_merge($this->tags, $newones); + if($sync === true) { + $this->save(); + } + + return true; + } + + /** + * Save the list of tags and their object relations + */ + protected function save() { + if(is_array($this->tags)) { + foreach($this->tags as $tag) { + try { + \OCP\DB::insertIfNotExist(self::TAG_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $tag, + )); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + } + // reload tags to get the proper ids. + $this->loadTags(); + // Loop through temporarily cached objectid/tagname pairs + // and save relations. + $tags = $this->tags; + // For some reason this is needed or array_search(i) will return 0..? + ksort($tags); + foreach(self::$relations as $relation) { + $tagId = $this->array_searchi($relation['tag'], $tags); + \OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG); + if($tagId) { + try { + \OCP\DB::insertIfNotExist(self::RELATION_TABLE, + array( + 'objid' => $relation['objid'], + 'categoryid' => $tagId, + 'type' => $this->type, + )); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + } + } + self::$relations = array(); // reset + } else { + \OCP\Util::writeLog('core', __METHOD__.', $this->tags is not an array! ' + . print_r($this->tags, true), \OCP\Util::ERROR); + } + } + + /** + * Delete tags and tag/object relations for a user. + * + * For hooking up on post_deleteUser + * + * @param array + */ + public static function post_deleteUser($arguments) { + // Find all objectid/tagId pairs. + $result = null; + try { + $stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` ' + . 'WHERE `uid` = ?'); + $result = $stmt->execute(array($arguments['uid'])); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + + if(!is_null($result)) { + try { + $stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `categoryid` = ?'); + while( $row = $result->fetchRow()) { + try { + $stmt->execute(array($row['id'])); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + } + } + try { + $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` ' + . 'WHERE `uid` = ?'); + $result = $stmt->execute(array($arguments['uid'])); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__ . ', exception: ' + . $e->getMessage(), \OCP\Util::ERROR); + } + } + + /** + * Delete tag/object relations from the db + * + * @param array $ids The ids of the objects + * @return boolean Returns false on error. + */ + public function purgeObjects(array $ids) { + if(count($ids) === 0) { + // job done ;) + return true; + } + $updates = $ids; + try { + $query = 'DELETE FROM `' . self::RELATION_TABLE . '` '; + $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) '; + $query .= 'AND `type`= ?'; + $updates[] = $this->type; + $stmt = \OCP\DB::prepare($query); + $result = $stmt->execute($updates); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + return false; + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(), + \OCP\Util::ERROR); + return false; + } + return true; + } + + /** + * Get favorites for an object type + * + * @return array An array of object ids. + */ + public function getFavorites() { + try { + return $this->getIdsForTag(self::TAG_FAVORITE); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(), + \OCP\Util::ERROR); + return array(); + } + } + + /** + * Add an object to favorites + * + * @param int $objid The id of the object + * @return boolean + */ + public function addToFavorites($objid) { + if(!$this->hasTag(self::TAG_FAVORITE)) { + $this->add(self::TAG_FAVORITE, true); + } + return $this->tagAs($objid, self::TAG_FAVORITE, $this->type); + } + + /** + * Remove an object from favorites + * + * @param int $objid The id of the object + * @return boolean + */ + public function removeFromFavorites($objid) { + return $this->unTag($objid, self::TAG_FAVORITE, $this->type); + } + + /** + * Creates a tag/object relation. + * + * @param int $objid The id of the object + * @param int|string $tag The id or name of the tag + * @return boolean Returns false on database error. + */ + public function tagAs($objid, $tag) { + if(is_string($tag) && !is_numeric($tag)) { + $tag = trim($tag); + if(!$this->hasTag($tag)) { + $this->add($tag, true); + } + $tagId = $this->array_searchi($tag, $this->tags); + } else { + $tagId = $tag; + } + try { + \OCP\DB::insertIfNotExist(self::RELATION_TABLE, + array( + 'objid' => $objid, + 'categoryid' => $tagId, + 'type' => $this->type, + )); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + return true; + } + + /** + * Delete single tag/object relation from the db + * + * @param int $objid The id of the object + * @param int|string $tag The id or name of the tag + * @return boolean + */ + public function unTag($objid, $tag) { + if(is_string($tag) && !is_numeric($tag)) { + $tag = trim($tag); + $tagId = $this->array_searchi($tag, $this->tags); + } else { + $tagId = $tag; + } + + try { + $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?'; + $stmt = \OCP\DB::prepare($sql); + $stmt->execute(array($objid, $tagId, $this->type)); + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + return true; + } + + /** + * Delete tags from the + * + * @param string[] $names An array of tags to delete + * @return bool Returns false on error + */ + public function delete($names) { + if(!is_array($names)) { + $names = array($names); + } + + $names = array_map('trim', $names); + + \OCP\Util::writeLog('core', __METHOD__ . ', before: ' + . print_r($this->tags, true), \OCP\Util::DEBUG); + foreach($names as $name) { + $id = null; + + if($this->hasTag($name)) { + $id = $this->array_searchi($name, $this->tags); + unset($this->tags[$id]); + } + try { + $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` WHERE ' + . '`uid` = ? AND `type` = ? AND `category` = ?'); + $result = $stmt->execute(array($this->user, $this->type, $name)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__ . ', exception: ' + . $e->getMessage(), \OCP\Util::ERROR); + return false; + } + if(!is_null($id) && $id !== false) { + try { + $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `categoryid` = ?'; + $stmt = \OCP\DB::prepare($sql); + $result = $stmt->execute(array($id)); + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('core', + __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), + \OCP\Util::ERROR); + return false; + } + } catch(\Exception $e) { + \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + \OCP\Util::ERROR); + return false; + } + } + } + return true; + } + + // case-insensitive in_array + private function in_arrayi($needle, $haystack) { + if(!is_array($haystack)) { + return false; + } + return in_array(strtolower($needle), array_map('strtolower', $haystack)); + } + + // case-insensitive array_search + private function array_searchi($needle, $haystack) { + if(!is_array($haystack)) { + return false; + } + return array_search(strtolower($needle), array_map('strtolower', $haystack)); + } +} diff --git a/lib/template.php b/lib/private/template.php similarity index 100% rename from lib/template.php rename to lib/private/template.php diff --git a/lib/template/base.php b/lib/private/template/base.php similarity index 100% rename from lib/template/base.php rename to lib/private/template/base.php diff --git a/lib/template/cssresourcelocator.php b/lib/private/template/cssresourcelocator.php similarity index 100% rename from lib/template/cssresourcelocator.php rename to lib/private/template/cssresourcelocator.php diff --git a/lib/template/functions.php b/lib/private/template/functions.php similarity index 100% rename from lib/template/functions.php rename to lib/private/template/functions.php diff --git a/lib/template/jsresourcelocator.php b/lib/private/template/jsresourcelocator.php similarity index 100% rename from lib/template/jsresourcelocator.php rename to lib/private/template/jsresourcelocator.php diff --git a/lib/template/resourcelocator.php b/lib/private/template/resourcelocator.php similarity index 100% rename from lib/template/resourcelocator.php rename to lib/private/template/resourcelocator.php diff --git a/lib/template/templatefilelocator.php b/lib/private/template/templatefilelocator.php similarity index 100% rename from lib/template/templatefilelocator.php rename to lib/private/template/templatefilelocator.php diff --git a/lib/templatelayout.php b/lib/private/templatelayout.php similarity index 100% rename from lib/templatelayout.php rename to lib/private/templatelayout.php diff --git a/lib/updater.php b/lib/private/updater.php similarity index 98% rename from lib/updater.php rename to lib/private/updater.php index df7332a96a97c24e79f72246d5477f0bae8ce89c..9827d8a8c12d7084e5f9eab3e10a63c560a0184c 100644 --- a/lib/updater.php +++ b/lib/private/updater.php @@ -56,7 +56,7 @@ class Updater extends BasicEmitter { $version = \OC_Util::getVersion(); $version['installed'] = \OC_Appconfig::getValue('core', 'installedat'); $version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat'); - $version['updatechannel'] = 'stable'; + $version['updatechannel'] = \OC_Util::getChannel(); $version['edition'] = \OC_Util::getEditionString(); $versionString = implode('x', $version); diff --git a/lib/user.php b/lib/private/user.php similarity index 84% rename from lib/user.php rename to lib/private/user.php index ed75b0bc17cf5e9bff602bc03eaa4bca6aa9e5dd..15e807088b4c8e731116d978f94f74ee4217c65a 100644 --- a/lib/user.php +++ b/lib/private/user.php @@ -37,54 +37,15 @@ * logout() */ class OC_User { - public static $userSession = null; - public static function getUserSession() { - if (!self::$userSession) { - $manager = new \OC\User\Manager(); - self::$userSession = new \OC\User\Session($manager, \OC::$session); - self::$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { - \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password)); - }); - self::$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password)); - }); - self::$userSession->listen('\OC\User', 'preDelete', function ($user) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID())); - }); - self::$userSession->listen('\OC\User', 'postDelete', function ($user) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID())); - }); - self::$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) { - /** @var $user \OC\User\User */ - OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); - }); - self::$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) { - /** @var $user \OC\User\User */ - OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); - }); - self::$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) { - \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password)); - }); - self::$userSession->listen('\OC\User', 'postLogin', function ($user, $password) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password)); - }); - self::$userSession->listen('\OC\User', 'logout', function () { - \OC_Hook::emit('OC_User', 'logout', array()); - }); - } - return self::$userSession; + return OC::$server->getUserSession(); } /** * @return \OC\User\Manager */ public static function getManager() { - return self::getUserSession()->getManager(); + return OC::$server->getUserManager(); } private static $_backends = array(); diff --git a/lib/user/backend.php b/lib/private/user/backend.php similarity index 100% rename from lib/user/backend.php rename to lib/private/user/backend.php diff --git a/lib/user/database.php b/lib/private/user/database.php similarity index 100% rename from lib/user/database.php rename to lib/private/user/database.php diff --git a/lib/user/dummy.php b/lib/private/user/dummy.php similarity index 100% rename from lib/user/dummy.php rename to lib/private/user/dummy.php diff --git a/lib/user/example.php b/lib/private/user/example.php similarity index 100% rename from lib/user/example.php rename to lib/private/user/example.php diff --git a/lib/user/http.php b/lib/private/user/http.php similarity index 100% rename from lib/user/http.php rename to lib/private/user/http.php diff --git a/lib/user/interface.php b/lib/private/user/interface.php similarity index 100% rename from lib/user/interface.php rename to lib/private/user/interface.php diff --git a/lib/user/manager.php b/lib/private/user/manager.php similarity index 100% rename from lib/user/manager.php rename to lib/private/user/manager.php diff --git a/lib/user/session.php b/lib/private/user/session.php similarity index 98% rename from lib/user/session.php rename to lib/private/user/session.php index b5e9385234d3750cc1cd010564caef96bf76e34a..525c65ab8a15e3b86af5bacb0c704f368c7840db 100644 --- a/lib/user/session.php +++ b/lib/private/user/session.php @@ -27,7 +27,7 @@ use OC\Hooks\Emitter; * * @package OC\User */ -class Session implements Emitter { +class Session implements Emitter, \OCP\IUserSession { /** * @var \OC\User\Manager $manager */ diff --git a/lib/user/user.php b/lib/private/user/user.php similarity index 100% rename from lib/user/user.php rename to lib/private/user/user.php diff --git a/lib/util.php b/lib/private/util.php similarity index 90% rename from lib/util.php rename to lib/private/util.php index d4f4eed1ca77c6398d9f0170ac8397e7e3727934..ae9aef69b4cd1fce4efb6a85e4571cdf46042cb0 100755 --- a/lib/util.php +++ b/lib/private/util.php @@ -68,6 +68,7 @@ class OC_Util { $userDirectory = $userRoot . '/files'; if( !is_dir( $userDirectory )) { mkdir( $userDirectory, 0755, true ); + OC_Util::copySkeleton($userDirectory); } //jail the user into his "home" directory \OC\Files\Filesystem::init($user, $userDir); @@ -92,6 +93,35 @@ class OC_Util { } } + /** + * @brief copies the user skeleton files into the fresh user home files + * @param string $userDirectory + */ + public static function copySkeleton($userDirectory) { + OC_Util::copyr(\OC::$SERVERROOT.'/core/skeleton' , $userDirectory); + } + + /** + * @brief copies a directory recursively + * @param string $source + * @param string $target + * @return void + */ + public static function copyr($source,$target) { + $dir = opendir($source); + @mkdir($target); + while(false !== ( $file = readdir($dir)) ) { + if ( !\OC\Files\Filesystem::isIgnoredDir($file) ) { + if ( is_dir($source . '/' . $file) ) { + OC_Util::copyr($source . '/' . $file , $target . '/' . $file); + } else { + copy($source . '/' . $file,$target . '/' . $file); + } + } + } + closedir($dir); + } + /** * @return void */ @@ -106,9 +136,8 @@ class OC_Util { * @return array */ public static function getVersion() { - // hint: We only can count up. Reset minor/patchlevel when - // updating major/minor version number. - return array(5, 80, 07); + OC_Util::loadVersion(); + return \OC::$server->getSession()->get('OC_Version'); } /** @@ -116,7 +145,8 @@ class OC_Util { * @return string */ public static function getVersionString() { - return '6.0 pre alpha'; + OC_Util::loadVersion(); + return \OC::$server->getSession()->get('OC_VersionString'); } /** @@ -126,7 +156,46 @@ class OC_Util { * @return string */ public static function getEditionString() { - return ''; + OC_Util::loadVersion(); + return \OC::$server->getSession()->get('OC_Edition'); + } + + /** + * @description get the update channel of the current installed of ownCloud. + * @return string + */ + public static function getChannel() { + OC_Util::loadVersion(); + return \OC::$server->getSession()->get('OC_Channel'); + } + + /** + * @description get the build number of the current installed of ownCloud. + * @return string + */ + public static function getBuild() { + OC_Util::loadVersion(); + return \OC::$server->getSession()->get('OC_Build'); + } + + /** + * @description load the version.php into the session as cache + */ + private static function loadVersion() { + if(!\OC::$server->getSession()->exists('OC_Version')) { + require 'version.php'; + $session = \OC::$server->getSession(); + /** @var $OC_Version string */ + $session->set('OC_Version', $OC_Version); + /** @var $OC_VersionString string */ + $session->set('OC_VersionString', $OC_VersionString); + /** @var $OC_Edition string */ + $session->set('OC_Edition', $OC_Edition); + /** @var $OC_Channel string */ + $session->set('OC_Channel', $OC_Channel); + /** @var $OC_Build string */ + $session->set('OC_Build', $OC_Build); + } } /** @@ -410,14 +479,18 @@ class OC_Util { $encryptedFiles = false; if (OC_App::isEnabled('files_encryption') === false) { $view = new OC\Files\View('/' . OCP\User::getUser()); - if ($view->file_exists('/files_encryption/keyfiles')) { - $encryptedFiles = true; + $keyfilePath = '/files_encryption/keyfiles'; + if ($view->is_dir($keyfilePath)) { + $dircontent = $view->getDirectoryContent($keyfilePath); + if (!empty($dircontent)) { + $encryptedFiles = true; + } } } - + return $encryptedFiles; } - + /** * @brief Check for correct file permissions of data directory * @paran string $dataDirectory @@ -467,6 +540,7 @@ class OC_Util { } $parameters['alt_login'] = OC_App::getAlternativeLogIns(); + $parameters['rememberLoginAllowed'] = self::rememberLoginAllowed(); OC_Template::printGuestPage("", "login", $parameters); } @@ -508,6 +582,27 @@ class OC_Util { } } + /** + * Check if it is allowed to remember login. + * + * @note Every app can set 'rememberlogin' to 'false' to disable the remember login feature + * + * @return bool + */ + public static function rememberLoginAllowed() { + + $apps = OC_App::getEnabledApps(); + + foreach ($apps as $app) { + $appInfo = OC_App::getAppInfo($app); + if (isset($appInfo['rememberlogin']) && $appInfo['rememberlogin'] === 'false') { + return false; + } + + } + return true; + } + /** * @brief Check if the user is a subadmin, redirects to home if not * @return array $groups where the current user is subadmin @@ -552,7 +647,7 @@ class OC_Util { if(is_null($id)) { // We need to guarantee at least one letter in instanceid so it can be used as the session_name $id = 'oc' . self::generateRandomBytes(10); - OC_Config::setValue('instanceid', $id); + OC_Config::$object->setValue('instanceid', $id); } return $id; } @@ -654,16 +749,16 @@ class OC_Util { } return $value; } - + /** * @brief Public function to encode url parameters * * This function is used to encode path to file before output. * Encoding is done according to RFC 3986 with one exception: - * Character '/' is preserved as is. + * Character '/' is preserved as is. * * @param string $component part of URI to encode - * @return string + * @return string */ public static function encodePath($component) { $encoded = rawurlencode($component); @@ -801,7 +896,7 @@ class OC_Util { } } } - + /** * @brief Check if the connection to the internet is disabled on purpose * @return bool diff --git a/lib/vobject.php b/lib/private/vobject.php similarity index 100% rename from lib/vobject.php rename to lib/private/vobject.php diff --git a/lib/vobject/compoundproperty.php b/lib/private/vobject/compoundproperty.php similarity index 100% rename from lib/vobject/compoundproperty.php rename to lib/private/vobject/compoundproperty.php diff --git a/lib/vobject/stringproperty.php b/lib/private/vobject/stringproperty.php similarity index 100% rename from lib/vobject/stringproperty.php rename to lib/private/vobject/stringproperty.php diff --git a/lib/public/app.php b/lib/public/app.php index a1ecf524cc84110440378a9452aad77b05068a49..0a5721b334e090413c7c9429795fa35d0c566b22 100644 --- a/lib/public/app.php +++ b/lib/public/app.php @@ -35,10 +35,10 @@ namespace OCP; */ class App { /** - * @brief Makes owncloud aware of this app + * @brief Makes ownCloud aware of this app * @brief This call is deprecated and not necessary to use. * @param $data array with all information - * @returns true/false + * @returns boolean * * @deprecated this method is deprecated * Do not call it anymore @@ -52,7 +52,7 @@ class App { /** * @brief adds an entry to the navigation * @param $data array containing the data - * @returns true/false + * @returns boolean * * This function adds a new entry to the navigation visible to users. $data * is an associative array. @@ -72,8 +72,8 @@ class App { /** * @brief marks a navigation entry as active - * @param $id id of the entry - * @returns true/false + * @param $id string id of the entry + * @returns boolean * * This function sets a navigation entry as active and removes the 'active' * property from all other entries. The templates can use this for @@ -104,7 +104,7 @@ class App { /** * @brief Read app metadata from the info.xml file * @param string $app id of the app or the path of the info.xml file - * @param boolean path (optional) + * @param boolean $path (optional) * @returns array */ public static function getAppInfo( $app, $path=false ) { @@ -114,7 +114,7 @@ class App { /** * @brief checks whether or not an app is enabled * @param $app app - * @returns true/false + * @returns boolean * * This function checks whether or not an app is enabled. */ @@ -133,7 +133,7 @@ class App { /** * @brief Get the last version of the app, either from appinfo/version or from appinfo/info.xml * @param $app app - * @returns true/false + * @returns boolean */ public static function getAppVersion( $app ) { return \OC_App::getAppVersion( $app ); diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php new file mode 100644 index 0000000000000000000000000000000000000000..d97c5c81848861b6b6aea43ea23bddfdcdc3f32b --- /dev/null +++ b/lib/public/appframework/app.php @@ -0,0 +1,81 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller deepdiver@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\AppFramework; + + +/** + * Class App + * @package OCP\AppFramework + * + * Any application must inherit this call - all controller instances to be used are + * to be registered using IContainer::registerService + */ +class App { + public function __construct($appName) { + $this->container = new \OC\AppFramework\DependencyInjection\DIContainer($appName); + } + + private $container; + + /** + * @return IAppContainer + */ + public function getContainer() { + return $this->container; + } + + /** + * This function is called by the routing component to fire up the frameworks dispatch mechanism. + * + * Example code in routes.php of the task app: + * $this->create('tasks_index', '/')->get()->action( + * function($params){ + * $app = new TaskApp(); + * $app->dispatch('PageController', 'index', $params); + * } + * ); + * + * + * Example for for TaskApp implementation: + * class TaskApp extends \OCP\AppFramework\App { + * + * public function __construct(){ + * parent::__construct('tasks'); + * + * $this->getContainer()->registerService('PageController', function(IAppContainer $c){ + * $a = $c->query('API'); + * $r = $c->query('Request'); + * return new PageController($a, $r); + * }); + * } + * } + * + * @param string $controllerName the name of the controller under which it is + * stored in the DI container + * @param string $methodName the method that you want to call + * @param array $urlParams an array with variables extracted from the routes + */ + public function dispatch($controllerName, $methodName, array $urlParams) { + \OC\AppFramework\App::main($controllerName, $methodName, $urlParams, $this->container); + } +} diff --git a/lib/public/appframework/http/http.php b/lib/public/appframework/http/http.php new file mode 100644 index 0000000000000000000000000000000000000000..9eafe782726ac58d78042a7dc90a439eb30b51aa --- /dev/null +++ b/lib/public/appframework/http/http.php @@ -0,0 +1,89 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework\Http; + + +class Http { + + const STATUS_CONTINUE = 100; + const STATUS_SWITCHING_PROTOCOLS = 101; + const STATUS_PROCESSING = 102; + const STATUS_OK = 200; + const STATUS_CREATED = 201; + const STATUS_ACCEPTED = 202; + const STATUS_NON_AUTHORATIVE_INFORMATION = 203; + const STATUS_NO_CONTENT = 204; + const STATUS_RESET_CONTENT = 205; + const STATUS_PARTIAL_CONTENT = 206; + const STATUS_MULTI_STATUS = 207; + const STATUS_ALREADY_REPORTED = 208; + const STATUS_IM_USED = 226; + const STATUS_MULTIPLE_CHOICES = 300; + const STATUS_MOVED_PERMANENTLY = 301; + const STATUS_FOUND = 302; + const STATUS_SEE_OTHER = 303; + const STATUS_NOT_MODIFIED = 304; + const STATUS_USE_PROXY = 305; + const STATUS_RESERVED = 306; + const STATUS_TEMPORARY_REDIRECT = 307; + const STATUS_BAD_REQUEST = 400; + const STATUS_UNAUTHORIZED = 401; + const STATUS_PAYMENT_REQUIRED = 402; + const STATUS_FORBIDDEN = 403; + const STATUS_NOT_FOUND = 404; + const STATUS_METHOD_NOT_ALLOWED = 405; + const STATUS_NOT_ACCEPTABLE = 406; + const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407; + const STATUS_REQUEST_TIMEOUT = 408; + const STATUS_CONFLICT = 409; + const STATUS_GONE = 410; + const STATUS_LENGTH_REQUIRED = 411; + const STATUS_PRECONDITION_FAILED = 412; + const STATUS_REQUEST_ENTITY_TOO_LARGE = 413; + const STATUS_REQUEST_URI_TOO_LONG = 414; + const STATUS_UNSUPPORTED_MEDIA_TYPE = 415; + const STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416; + const STATUS_EXPECTATION_FAILED = 417; + const STATUS_IM_A_TEAPOT = 418; + const STATUS_UNPROCESSABLE_ENTITY = 422; + const STATUS_LOCKED = 423; + const STATUS_FAILED_DEPENDENCY = 424; + const STATUS_UPGRADE_REQUIRED = 426; + const STATUS_PRECONDITION_REQUIRED = 428; + const STATUS_TOO_MANY_REQUESTS = 429; + const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; + const STATUS_INTERNAL_SERVER_ERROR = 500; + const STATUS_NOT_IMPLEMENTED = 501; + const STATUS_BAD_GATEWAY = 502; + const STATUS_SERVICE_UNAVAILABLE = 503; + const STATUS_GATEWAY_TIMEOUT = 504; + const STATUS_HTTP_VERSION_NOT_SUPPORTED = 505; + const STATUS_VARIANT_ALSO_NEGOTIATES = 506; + const STATUS_INSUFFICIENT_STORAGE = 507; + const STATUS_LOOP_DETECTED = 508; + const STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509; + const STATUS_NOT_EXTENDED = 510; + const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511; +} diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php new file mode 100644 index 0000000000000000000000000000000000000000..085fdbed2f9da300aa400bae218d35dde4176873 --- /dev/null +++ b/lib/public/appframework/http/jsonresponse.php @@ -0,0 +1,74 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework\Http; + + +/** + * A renderer for JSON calls + */ +class JSONResponse extends Response { + + protected $data; + + + /** + * @param array|object $data the object or array that should be transformed + * @param int $statusCode the Http status code, defaults to 200 + */ + public function __construct($data=array(), $statusCode=Http::STATUS_OK) { + $this->data = $data; + $this->setStatus($statusCode); + $this->addHeader('X-Content-Type-Options', 'nosniff'); + $this->addHeader('Content-type', 'application/json; charset=utf-8'); + } + + + /** + * Returns the rendered json + * @return string the rendered json + */ + public function render(){ + return json_encode($this->data); + } + + /** + * Sets values in the data json array + * @param array|object $params an array or object which will be transformed + * to JSON + */ + public function setData($data){ + $this->data = $data; + } + + + /** + * Used to get the set parameters + * @return array the data + */ + public function getData(){ + return $this->data; + } + +} diff --git a/lib/public/appframework/http/response.php b/lib/public/appframework/http/response.php new file mode 100644 index 0000000000000000000000000000000000000000..644772589484e1e1a0236e38ccb151f6ba4344ee --- /dev/null +++ b/lib/public/appframework/http/response.php @@ -0,0 +1,169 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework\Http; + + +/** + * Base class for responses. Also used to just send headers + */ +class Response { + + /** + * @var array default headers + */ + private $headers = array( + 'Cache-Control' => 'no-cache, must-revalidate' + ); + + + /** + * @var string + */ + private $status = Http::STATUS_OK; + + + /** + * @var \DateTime + */ + private $lastModified; + + + /** + * @var string + */ + private $ETag; + + + /** + * Caches the response + * @param int $cacheSeconds the amount of seconds that should be cached + * if 0 then caching will be disabled + */ + public function cacheFor($cacheSeconds) { + + if($cacheSeconds > 0) { + $this->addHeader('Cache-Control', 'max-age=' . $cacheSeconds . + ', must-revalidate'); + } else { + $this->addHeader('Cache-Control', 'no-cache, must-revalidate'); + } + + } + + + /** + * Adds a new header to the response that will be called before the render + * function + * @param string $name The name of the HTTP header + * @param string $value The value, null will delete it + */ + public function addHeader($name, $value) { + if(is_null($value)) { + unset($this->headers[$name]); + } else { + $this->headers[$name] = $value; + } + } + + + /** + * Returns the set headers + * @return array the headers + */ + public function getHeaders() { + $mergeWith = array(); + + if($this->lastModified) { + $mergeWith['Last-Modified'] = + $this->lastModified->format(\DateTime::RFC2822); + } + + if($this->ETag) { + $mergeWith['ETag'] = '"' . $this->ETag . '"'; + } + + return array_merge($mergeWith, $this->headers); + } + + + /** + * By default renders no output + * @return null + */ + public function render() { + return null; + } + + + /** + * Set response status + * @param int $status a HTTP status code, see also the STATUS constants + */ + public function setStatus($status) { + $this->status = $status; + } + + + /** + * Get response status + */ + public function getStatus() { + return $this->status; + } + + + /** + * @return string the etag + */ + public function getETag() { + return $this->ETag; + } + + + /** + * @return string RFC2822 formatted last modified date + */ + public function getLastModified() { + return $this->lastModified; + } + + + /** + * @param string $ETag + */ + public function setETag($ETag) { + $this->ETag = $ETag; + } + + + /** + * @param \DateTime $lastModified + */ + public function setLastModified($lastModified) { + $this->lastModified = $lastModified; + } + + +} diff --git a/lib/public/appframework/http/templateresponse.php b/lib/public/appframework/http/templateresponse.php new file mode 100644 index 0000000000000000000000000000000000000000..97678c96cbaffb6cc592516fe6b3c2b0e3235350 --- /dev/null +++ b/lib/public/appframework/http/templateresponse.php @@ -0,0 +1,126 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework\Http; + +use OC\AppFramework\Core\API; + + +/** + * Response for a normal template + */ +class TemplateResponse extends Response { + + protected $templateName; + protected $params; + protected $api; + protected $renderAs; + protected $appName; + + /** + * @param API $api an API instance + * @param string $templateName the name of the template + * @param string $appName optional if you want to include a template from + * a different app + */ + public function __construct(API $api, $templateName, $appName=null) { + $this->templateName = $templateName; + $this->appName = $appName; + $this->api = $api; + $this->params = array(); + $this->renderAs = 'user'; + } + + + /** + * Sets template parameters + * @param array $params an array with key => value structure which sets template + * variables + */ + public function setParams(array $params){ + $this->params = $params; + } + + + /** + * Used for accessing the set parameters + * @return array the params + */ + public function getParams(){ + return $this->params; + } + + + /** + * Used for accessing the name of the set template + * @return string the name of the used template + */ + public function getTemplateName(){ + return $this->templateName; + } + + + /** + * Sets the template page + * @param string $renderAs admin, user or blank. Admin also prints the admin + * settings header and footer, user renders the normal + * normal page including footer and header and blank + * just renders the plain template + */ + public function renderAs($renderAs){ + $this->renderAs = $renderAs; + } + + + /** + * Returns the set renderAs + * @return string the renderAs value + */ + public function getRenderAs(){ + return $this->renderAs; + } + + + /** + * Returns the rendered html + * @return string the rendered html + */ + public function render(){ + + if($this->appName !== null){ + $appName = $this->appName; + } else { + $appName = $this->api->getAppName(); + } + + $template = $this->api->getTemplate($this->templateName, $this->renderAs, $appName); + + foreach($this->params as $key => $value){ + $template->assign($key, $value); + } + + return $template->fetchPage(); + } + +} diff --git a/lib/public/appframework/iapi.php b/lib/public/appframework/iapi.php new file mode 100644 index 0000000000000000000000000000000000000000..fa6af5f596593c6ba1d6b3e42c20f89a063c9d92 --- /dev/null +++ b/lib/public/appframework/iapi.php @@ -0,0 +1,151 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework; + + +/** + * A few very basic and frequently used API functions are combined in here + */ +interface IApi { + + + /** + * Gets the userid of the current user + * @return string the user id of the current user + */ + function getUserId(); + + + /** + * Adds a new javascript file + * @param string $scriptName the name of the javascript in js/ without the suffix + * @param string $appName the name of the app, defaults to the current one + */ + function addScript($scriptName, $appName = null); + + + /** + * Adds a new css file + * @param string $styleName the name of the css file in css/without the suffix + * @param string $appName the name of the app, defaults to the current one + */ + function addStyle($styleName, $appName = null); + + + /** + * shorthand for addScript for files in the 3rdparty directory + * @param string $name the name of the file without the suffix + */ + function add3rdPartyScript($name); + + + /** + * shorthand for addStyle for files in the 3rdparty directory + * @param string $name the name of the file without the suffix + */ + function add3rdPartyStyle($name); + + /** + * Returns the translation object + * @return \OC_L10N the translation object + * + * FIXME: returns private object / should be retrieved from teh ServerContainer + */ + function getTrans(); + + + /** + * Returns the URL for a route + * @param string $routeName the name of the route + * @param array $arguments an array with arguments which will be filled into the url + * @return string the url + */ + function linkToRoute($routeName, $arguments=array()); + + + /** + * Returns an URL for an image or file + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + */ + function linkTo($file, $appName=null); + + + /** + * Returns the link to an image, like link to but only with prepending img/ + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + */ + function imagePath($file, $appName = null); + + + /** + * Makes an URL absolute + * @param string $url the url + * @return string the absolute url + * + * FIXME: function should live in Request / Response + */ + function getAbsoluteURL($url); + + + /** + * links to a file + * @param string $file the name of the file + * @param string $appName the name of the app, defaults to the current one + * @deprecated replaced with linkToRoute() + * @return string the url + */ + function linkToAbsolute($file, $appName = null); + + + /** + * Checks if an app is enabled + * @param string $appName the name of an app + * @return bool true if app is enabled + */ + public function isAppEnabled($appName); + + + /** + * Writes a function into the error log + * @param string $msg the error message to be logged + * @param int $level the error level + * + * FIXME: add logger instance to ServerContainer + */ + function log($msg, $level = null); + + + /** + * Returns a template + * @param string $templateName the name of the template + * @param string $renderAs how it should be rendered + * @param string $appName the name of the app + * @return \OCP\Template a new template + */ + function getTemplate($templateName, $renderAs='user', $appName=null); + +} diff --git a/lib/public/appframework/iappcontainer.php b/lib/public/appframework/iappcontainer.php new file mode 100644 index 0000000000000000000000000000000000000000..7d3b4b3bac7587331ff003322369f205830d6a20 --- /dev/null +++ b/lib/public/appframework/iappcontainer.php @@ -0,0 +1,57 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller deepdiver@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\AppFramework; + +use OCP\AppFramework\IApi; +use OCP\IContainer; + +/** + * Class IAppContainer + * @package OCP\AppFramework + * + * This container interface provides short cuts for app developers to access predefined app service. + */ +interface IAppContainer extends IContainer{ + + /** + * used to return the appname of the set application + * @return string the name of your application + */ + function getAppName(); + + /** + * @return IApi + */ + function getCoreApi(); + + /** + * @return \OCP\IServerContainer + */ + function getServer(); + + /** + * @param IMiddleWare $middleWare + * @return boolean + */ + function registerMiddleWare(IMiddleWare $middleWare); +} diff --git a/lib/public/appframework/imiddleware.php b/lib/public/appframework/imiddleware.php new file mode 100644 index 0000000000000000000000000000000000000000..1e76d3bbe499d75e2541360fdad3422bf5b3a922 --- /dev/null +++ b/lib/public/appframework/imiddleware.php @@ -0,0 +1,88 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\AppFramework; +use OCP\AppFramework\Http\Response; + + +/** + * Middleware is used to provide hooks before or after controller methods and + * deal with possible exceptions raised in the controller methods. + * They're modeled after Django's middleware system: + * https://docs.djangoproject.com/en/dev/topics/http/middleware/ + */ +interface IMiddleWare { + + + /** + * This is being run in normal order before the controller is being + * called which allows several modifications and checks + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + */ + function beforeController($controller, $methodName); + + + /** + * This is being run when either the beforeController method or the + * controller method itself is throwing an exception. The middleware is + * asked in reverse order to handle the exception and to return a response. + * If the response is null, it is assumed that the exception could not be + * handled and the error will be thrown again + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @throws \Exception the passed in exception if it cant handle it + * @return Response a Response object in case that the exception was handled + */ + function afterException($controller, $methodName, \Exception $exception); + + /** + * This is being run after a successful controller method call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + function afterController($controller, $methodName, Response $response); + + /** + * This is being run after the response object has been rendered and + * allows the manipulation of the output. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param string $output the generated output from a response + * @return string the output that should be printed + */ + function beforeOutput($controller, $methodName, $output); +} diff --git a/lib/public/contacts.php b/lib/public/contacts.php index 88d812e735a857b79e47cb85b712ab9801836711..1b61d7aa4ff22b6201a8bfe407eaec0b7f8ddf9b 100644 --- a/lib/public/contacts.php +++ b/lib/public/contacts.php @@ -90,13 +90,8 @@ namespace OCP { * @return array of contacts which are arrays of key-value-pairs */ public static function search($pattern, $searchProperties = array(), $options = array()) { - $result = array(); - foreach(self::$address_books as $address_book) { - $r = $address_book->search($pattern, $searchProperties, $options); - $result = array_merge($result, $r); - } - - return $result; + $cm = \OC::$server->getContactsManager(); + return $cm->search($pattern, $searchProperties, $options); } /** @@ -107,14 +102,8 @@ namespace OCP { * @return bool successful or not */ public static function delete($id, $address_book_key) { - if (!array_key_exists($address_book_key, self::$address_books)) - return null; - - $address_book = self::$address_books[$address_book_key]; - if ($address_book->getPermissions() & \OCP\PERMISSION_DELETE) - return null; - - return $address_book->delete($id); + $cm = \OC::$server->getContactsManager(); + return $cm->delete($id, $address_book_key); } /** @@ -126,15 +115,8 @@ namespace OCP { * @return array representing the contact just created or updated */ public static function createOrUpdate($properties, $address_book_key) { - - if (!array_key_exists($address_book_key, self::$address_books)) - return null; - - $address_book = self::$address_books[$address_book_key]; - if ($address_book->getPermissions() & \OCP\PERMISSION_CREATE) - return null; - - return $address_book->createOrUpdate($properties); + $cm = \OC::$server->getContactsManager(); + return $cm->search($properties, $address_book_key); } /** @@ -143,45 +125,40 @@ namespace OCP { * @return bool true if enabled, false if not */ public static function isEnabled() { - return !empty(self::$address_books); + $cm = \OC::$server->getContactsManager(); + return $cm->isEnabled(); } /** * @param \OCP\IAddressBook $address_book */ public static function registerAddressBook(\OCP\IAddressBook $address_book) { - self::$address_books[$address_book->getKey()] = $address_book; + $cm = \OC::$server->getContactsManager(); + return $cm->registerAddressBook($address_book); } /** * @param \OCP\IAddressBook $address_book */ public static function unregisterAddressBook(\OCP\IAddressBook $address_book) { - unset(self::$address_books[$address_book->getKey()]); + $cm = \OC::$server->getContactsManager(); + return $cm->unregisterAddressBook($address_book); } /** * @return array */ public static function getAddressBooks() { - $result = array(); - foreach(self::$address_books as $address_book) { - $result[$address_book->getKey()] = $address_book->getDisplayName(); - } - - return $result; + $cm = \OC::$server->getContactsManager(); + return $cm->getAddressBooks(); } /** * removes all registered address book instances */ public static function clear() { - self::$address_books = array(); + $cm = \OC::$server->getContactsManager(); + $cm->clear(); } - - /** - * @var \OCP\IAddressBook[] which holds all registered address books - */ - private static $address_books = array(); } } diff --git a/lib/public/contacts/imanager.php b/lib/public/contacts/imanager.php new file mode 100644 index 0000000000000000000000000000000000000000..3bfbca7be501ecee5b502277a3ae74294e2c6315 --- /dev/null +++ b/lib/public/contacts/imanager.php @@ -0,0 +1,150 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * Public interface of ownCloud for apps to use. + * Contacts Class + * + */ + +// use OCP namespace for all classes that are considered public. +// This means that they should be used by apps instead of the internal ownCloud classes +namespace OCP\Contacts { + + /** + * This class provides access to the contacts app. Use this class exclusively if you want to access contacts. + * + * Contacts in general will be expressed as an array of key-value-pairs. + * The keys will match the property names defined in https://tools.ietf.org/html/rfc2426#section-1 + * + * Proposed workflow for working with contacts: + * - search for the contacts + * - manipulate the results array + * - createOrUpdate will save the given contacts overwriting the existing data + * + * For updating it is mandatory to keep the id. + * Without an id a new contact will be created. + * + */ + interface IManager { + + /** + * This function is used to search and find contacts within the users address books. + * In case $pattern is empty all contacts will be returned. + * + * Example: + * Following function shows how to search for contacts for the name and the email address. + * + * public static function getMatchingRecipient($term) { + * $cm = \OC::$server->getContactsManager(); + * // The API is not active -> nothing to do + * if (!$cm->isEnabled()) { + * return array(); + * } + * + * $result = $cm->search($term, array('FN', 'EMAIL')); + * $receivers = array(); + * foreach ($result as $r) { + * $id = $r['id']; + * $fn = $r['FN']; + * $email = $r['EMAIL']; + * if (!is_array($email)) { + * $email = array($email); + * } + * + * // loop through all email addresses of this contact + * foreach ($email as $e) { + * $displayName = $fn . " <$e>"; + * $receivers[] = array( + * 'id' => $id, + * 'label' => $displayName, + * 'value' => $displayName); + * } + * } + * + * return $receivers; + * } + * + * + * @param string $pattern which should match within the $searchProperties + * @param array $searchProperties defines the properties within the query pattern should match + * @param array $options - for future use. One should always have options! + * @return array of contacts which are arrays of key-value-pairs + */ + function search($pattern, $searchProperties = array(), $options = array()); + + /** + * This function can be used to delete the contact identified by the given id + * + * @param object $id the unique identifier to a contact + * @param $address_book_key + * @return bool successful or not + */ + function delete($id, $address_book_key); + + /** + * This function is used to create a new contact if 'id' is not given or not present. + * Otherwise the contact will be updated by replacing the entire data set. + * + * @param array $properties this array if key-value-pairs defines a contact + * @param $address_book_key string to identify the address book in which the contact shall be created or updated + * @return array representing the contact just created or updated + */ + function createOrUpdate($properties, $address_book_key); + + /** + * Check if contacts are available (e.g. contacts app enabled) + * + * @return bool true if enabled, false if not + */ + function isEnabled(); + + /** + * @param \OCP\IAddressBook $address_book + */ + function registerAddressBook(\OCP\IAddressBook $address_book); + + /** + * @param \OCP\IAddressBook $address_book + */ + function unregisterAddressBook(\OCP\IAddressBook $address_book); + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * address books are actually requested + * + * @param string $key + * @param \Closure $callable + */ + function register($key, \Closure $callable); + + /** + * @return array + */ + function getAddressBooks(); + + /** + * removes all registered address book instances + */ + function clear(); + } +} diff --git a/lib/public/icache.php b/lib/public/icache.php new file mode 100644 index 0000000000000000000000000000000000000000..436ee71b2b99e511fe239bda82d5c7d9bce50a6b --- /dev/null +++ b/lib/public/icache.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP; + +/** + * This interface defines method for accessing the file based user cache. + */ +interface ICache { + + /** + * Get a value from the user cache + * + * @param string $key + * @return mixed + */ + public function get($key); + + /** + * Set a value in the user cache + * + * @param string $key + * @param mixed $value + * @param int $ttl Time To Live in seconds. Defaults to 60*60*24 + * @return bool + */ + public function set($key, $value, $ttl = 0); + + /** + * Check if a value is set in the user cache + * + * @param string $key + * @return bool + */ + public function hasKey($key); + + /** + * Remove an item from the user cache + * + * @param string $key + * @return bool + */ + public function remove($key); + + /** + * clear the user cache of all entries starting with a prefix + * @param string $prefix (optional) + * @return bool + */ + public function clear($prefix = ''); +} diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php new file mode 100644 index 0000000000000000000000000000000000000000..850bddf6935fce77b22c71b597481f77fb67c8bb --- /dev/null +++ b/lib/public/iconfig.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * Access to all the configuration options ownCloud offers + */ +interface IConfig { + /** + * Sets a new system wide value + * @param string $key the key of the value, under which will be saved + * @param string $value the value that should be stored + * @todo need a use case for this + */ +// public function setSystemValue($key, $value); + + /** + * Looks up a system wide defined value + * @param string $key the key of the value, under which it was saved + * @return string the saved value + */ + public function getSystemValue($key); + + + /** + * Writes a new app wide value + * @param string $appName the appName that we want to store the value under + * @param string $key the key of the value, under which will be saved + * @param string $value the value that should be stored + */ + public function setAppValue($appName, $key, $value); + + /** + * Looks up an app wide defined value + * @param string $appName the appName that we stored the value under + * @param string $key the key of the value, under which it was saved + * @return string the saved value + */ + public function getAppValue($appName, $key); + + + /** + * Set a user defined value + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we want to store the value under + * @param string $key the key under which the value is being stored + * @param string $value the value that you want to store + */ + public function setUserValue($userId, $appName, $key, $value); + + /** + * Shortcut for getting a user defined value + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we stored the value under + * @param string $key the key under which the value is being stored + */ + public function getUserValue($userId, $appName, $key); +} diff --git a/lib/public/icontainer.php b/lib/public/icontainer.php new file mode 100644 index 0000000000000000000000000000000000000000..d43c1c90f11dbca405f259a442a3d829cfbae509 --- /dev/null +++ b/lib/public/icontainer.php @@ -0,0 +1,64 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller deepdiver@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP; + +/** + * Class IContainer + * + * IContainer is the basic interface to be used for any internal dependency injection mechanism + * + * @package OCP + */ +interface IContainer { + + /** + * Look up a service for a given name in the container. + * + * @param string $name + * @return mixed + */ + function query($name); + + /** + * A value is stored in the container with it's corresponding name + * + * @param string $name + * @param mixed $value + * @return void + */ + function registerParameter($name, $value); + + /** + * A service is registered in the container where a closure is passed in which will actually + * create the service on demand. + * In case the parameter $shared is set to true (the default usage) the once created service will remain in + * memory and be reused on subsequent calls. + * In case the parameter is false the service will be recreated on every call. + * + * @param string $name + * @param callable $closure + * @param bool $shared + * @return void + */ + function registerService($name, \Closure $closure, $shared = true); +} diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php new file mode 100644 index 0000000000000000000000000000000000000000..c741a0f061ac19d49614c1bd547759e1e366ba87 --- /dev/null +++ b/lib/public/idbconnection.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * TODO: Description + */ +interface IDBConnection { + /** + * Used to abstract the owncloud database access away + * @param string $sql the sql query with ? placeholder for params + * @param int $limit the maximum number of rows + * @param int $offset from which row we want to start + * @return \Doctrine\DBAL\Driver\Statement The prepared statement. + */ + public function prepare($sql, $limit=null, $offset=null); + + /** + * Used to get the id of the just inserted element + * @param string $tableName the name of the table where we inserted the item + * @return int the id of the inserted element + */ + public function lastInsertId($table = null); + + /** + * @brief Insert a row if a matching row doesn't exists. + * @param $table string The table name (will replace *PREFIX*) to perform the replace on. + * @param $input array + * + * The input array if in the form: + * + * array ( 'id' => array ( 'value' => 6, + * 'key' => true + * ), + * 'name' => array ('value' => 'Stoyan'), + * 'family' => array ('value' => 'Stefanov'), + * 'birth_date' => array ('value' => '1975-06-20') + * ); + * @return bool + * + */ + public function insertIfNotExist($table, $input); + + /** + * @brief Start a transaction + * @return bool TRUE on success or FALSE on failure + */ + public function beginTransaction(); + + /** + * @brief Commit the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function commit(); + + /** + * @brief Rollback the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function rollBack(); + + /** + * returns the error code and message as a string for logging + * @return string + */ + public function getError(); +} diff --git a/lib/public/inavigationmanager.php b/lib/public/inavigationmanager.php new file mode 100644 index 0000000000000000000000000000000000000000..f89e790c1d0f6bbf70f8cf51db8a12c194781a83 --- /dev/null +++ b/lib/public/inavigationmanager.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * Manages the ownCloud navigation + */ +interface INavigationManager { + /** + * Creates a new navigation entry + * @param array $entry containing: id, name, order, icon and href key + */ + public function add(array $entry); + + /** + * Sets the current navigation entry of the currently running app + * @param string $appId id of the app entry to activate (from added $entry) + */ + public function setActiveEntry($appId); +} diff --git a/lib/public/ipreview.php b/lib/public/ipreview.php new file mode 100644 index 0000000000000000000000000000000000000000..b01e7f5b539918f7cee5549af7233080511daabe --- /dev/null +++ b/lib/public/ipreview.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * Copyright (c) 2013 Georg Ehrke georg@ownCloud.com + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP; + +/** + * This class provides functions to render and show thumbnails and previews of files + */ +interface IPreview +{ + + /** + * @brief return a preview of a file + * @param string $file The path to the file where you want a thumbnail from + * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image + * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image + * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly + * @return \OCP\Image + */ + function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); + + + /** + * @brief returns true if the passed mime type is supported + * @param string $mimeType + * @return boolean + */ + function isMimeSupported($mimeType = '*'); + +} diff --git a/lib/public/irequest.php b/lib/public/irequest.php new file mode 100644 index 0000000000000000000000000000000000000000..9f335b06f2ac85093f6ff92f6749d8dbd48d2129 --- /dev/null +++ b/lib/public/irequest.php @@ -0,0 +1,96 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller deepdiver@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP; + + +interface IRequest { + + function getHeader($name); + + /** + * Lets you access post and get parameters by the index + * In case of json requests the encoded json body is accessed + * + * @param string $key the key which you want to access in the URL Parameter + * placeholder, $_POST or $_GET array. + * The priority how they're returned is the following: + * 1. URL parameters + * 2. POST parameters + * 3. GET parameters + * @param mixed $default If the key is not found, this value will be returned + * @return mixed the content of the array + */ + public function getParam($key, $default = null); + + + /** + * Returns all params that were received, be it from the request + * + * (as GET or POST) or through the URL by the route + * @return array the array with all parameters + */ + public function getParams(); + + /** + * Returns the method of the request + * + * @return string the method of the request (POST, GET, etc) + */ + public function getMethod(); + + /** + * Shortcut for accessing an uploaded file through the $_FILES array + * + * @param string $key the key that will be taken from the $_FILES array + * @return array the file in the $_FILES element + */ + public function getUploadedFile($key); + + + /** + * Shortcut for getting env variables + * + * @param string $key the key that will be taken from the $_ENV array + * @return array the value in the $_ENV element + */ + public function getEnv($key); + + + /** + * Shortcut for getting cookie variables + * + * @param string $key the key that will be taken from the $_COOKIE array + * @return array the value in the $_COOKIE element + */ + function getCookie($key); + + + /** + * Returns the request body content. + * + * @param Boolean $asResource If true, a resource will be returned + * @return string|resource The request body content or a resource to read the body stream. + * @throws \LogicException + */ + function getContent($asResource = false); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php new file mode 100644 index 0000000000000000000000000000000000000000..f4045faefeff98ed52343d0b63b86a02b055b473 --- /dev/null +++ b/lib/public/iservercontainer.php @@ -0,0 +1,125 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller deepdiver@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP; + + +/** + * Class IServerContainer + * @package OCP + * + * This container holds all ownCloud services + */ +interface IServerContainer { + + /** + * The contacts manager will act as a broker between consumers for contacts information and + * providers which actual deliver the contact information. + * + * @return \OCP\Contacts\IManager + */ + function getContactsManager(); + + /** + * The current request object holding all information about the request currently being processed + * is returned from this method. + * In case the current execution was not initiated by a web request null is returned + * + * @return \OCP\IRequest|null + */ + function getRequest(); + + /** + * Returns the preview manager which can create preview images for a given file + * + * @return \OCP\IPreview + */ + function getPreviewManager(); + + /** + * Returns the tag manager which can get and set tags for different object types + * + * @see \OCP\ITagManager::load() + * @return \OCP\ITagManager + */ + function getTagManager(); + + /** + * Returns the root folder of ownCloud's data directory + * + * @return \OCP\Files\Folder + */ + function getRootFolder(); + + /** + * Returns a view to ownCloud's files folder + * + * @return \OCP\Files\Folder + */ + function getUserFolder(); + + /** + * Returns an app-specific view in ownClouds data directory + * + * @return \OCP\Files\Folder + */ + function getAppFolder(); + + /** + * Returns the user session + * + * @return \OCP\IUserSession + */ + function getUserSession(); + + /** + * @return \OCP\INavigationManager + */ + function getNavigationManager(); + + /** + * @return \OCP\IConfig + */ + function getConfig(); + + /** + * Returns an ICache instance + * + * @return \OCP\ICache + */ + function getCache(); + + /** + * Returns the current session + * + * @return \OCP\ISession + */ + function getSession(); + + /** + * Returns the current session + * + * @return \OCP\IDBConnection + */ + function getDatabaseConnection(); + +} diff --git a/lib/public/isession.php b/lib/public/isession.php new file mode 100644 index 0000000000000000000000000000000000000000..0a77b0c823b042cef5d840bc66723bcf4adc2bea --- /dev/null +++ b/lib/public/isession.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) + * @author Thomas Tanghus + * @author Robin Appelman + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +/** + * Interface ISession + * + * wrap PHP's internal session handling into the ISession interface + */ +interface ISession { + + /** + * Set a value in the session + * + * @param string $key + * @param mixed $value + */ + public function set($key, $value); + + /** + * Get a value from the session + * + * @param string $key + * @return mixed should return null if $key does not exist + */ + public function get($key); + + /** + * Check if a named key exists in the session + * + * @param string $key + * @return bool + */ + public function exists($key); + + /** + * Remove a $key/$value pair from the session + * + * @param string $key + */ + public function remove($key); + + /** + * Reset and recreate the session + */ + public function clear(); + +} diff --git a/lib/public/itagmanager.php b/lib/public/itagmanager.php new file mode 100644 index 0000000000000000000000000000000000000000..07e1d12fc0f53ee132d3b546d89534b72e7d0743 --- /dev/null +++ b/lib/public/itagmanager.php @@ -0,0 +1,48 @@ +<?php +/** +* ownCloud +* +* @author Thomas Tanghus +* @copyright 2013 Thomas Tanghus <thomas@tanghus.net> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * Factory class creating instances of \OCP\ITags + * + * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or + * anything else that is either parsed from a vobject or that the user chooses + * to add. + * Tag names are not case-sensitive, but will be saved with the case they + * are entered in. If a user already has a tag 'family' for a type, and + * tries to add a tag named 'Family' it will be silently ignored. + */ + +namespace OCP; + +interface ITagManager { + + /** + * Create a new \OCP\ITags instance and load tags from db. + * + * @see \OCP\ITags + * @param string $type The type identifier e.g. 'contact' or 'event'. + * @param array $defaultTags An array of default tags to be used if none are stored. + * @return \OCP\ITags + */ + public function load($type, $defaultTags=array()); + +} \ No newline at end of file diff --git a/lib/public/itags.php b/lib/public/itags.php new file mode 100644 index 0000000000000000000000000000000000000000..5b1ebd189da25e4fb11ea168eb7a614a9930f5fd --- /dev/null +++ b/lib/public/itags.php @@ -0,0 +1,164 @@ +<?php +/** +* ownCloud +* +* @author Thomas Tanghus +* @copyright 2013 Thomas Tanghus <thomas@tanghus.net> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +namespace OCP; + +// FIXME: Where should I put this? Or should it be implemented as a Listener? +\OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Tags', 'post_deleteUser'); + +/** + * Class for easily tagging objects by their id + * + * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or + * anything else that is either parsed from a vobject or that the user chooses + * to add. + * Tag names are not case-sensitive, but will be saved with the case they + * are entered in. If a user already has a tag 'family' for a type, and + * tries to add a tag named 'Family' it will be silently ignored. + */ + +interface ITags { + + /** + * Check if any tags are saved for this type and user. + * + * @return boolean. + */ + public function isEmpty(); + + /** + * Get the tags for a specific user. + * + * This returns an array with id/name maps: + * [ + * ['id' => 0, 'name' = 'First tag'], + * ['id' => 1, 'name' = 'Second tag'], + * ] + * + * @returns array + */ + public function getTags(); + + /** + * Get the a list if items tagged with $tag. + * + * Throws an exception if the tag could not be found. + * + * @param string|integer $tag Tag id or name. + * @return array An array of object ids or false on error. + */ + public function getIdsForTag($tag); + + /** + * Checks whether a tag is already saved. + * + * @param string $name The name to check for. + * @return bool + */ + public function hasTag($name); + + /** + * Add a new tag. + * + * @param string $name A string with a name of the tag + * @return int the id of the added tag or false if it already exists. + */ + public function add($name); + + /** + * Rename tag. + * + * @param string $from The name of the existing tag + * @param string $to The new name of the tag. + * @return bool + */ + public function rename($from, $to); + + /** + * Add a list of new tags. + * + * @param string[] $names A string with a name or an array of strings containing + * the name(s) of the to add. + * @param bool $sync When true, save the tags + * @param int|null $id int Optional object id to add to this|these tag(s) + * @return bool Returns false on error. + */ + public function addMultiple($names, $sync=false, $id = null); + + /** + * Delete tag/object relations from the db + * + * @param array $ids The ids of the objects + * @return boolean Returns false on error. + */ + public function purgeObjects(array $ids); + + /** + * Get favorites for an object type + * + * @return array An array of object ids. + */ + public function getFavorites(); + + /** + * Add an object to favorites + * + * @param int $objid The id of the object + * @return boolean + */ + public function addToFavorites($objid); + + /** + * Remove an object from favorites + * + * @param int $objid The id of the object + * @return boolean + */ + public function removeFromFavorites($objid); + + /** + * Creates a tag/object relation. + * + * @param int $objid The id of the object + * @param int|string $tag The id or name of the tag + * @return boolean Returns false on database error. + */ + public function tagAs($objid, $tag); + + /** + * Delete single tag/object relation from the db + * + * @param int $objid The id of the object + * @param int|string $tag The id or name of the tag + * @return boolean + */ + public function unTag($objid, $tag); + + /** + * Delete tags from the + * + * @param string[] $names An array of tags to delete + * @return bool Returns false on error + */ + public function delete($names); + +} \ No newline at end of file diff --git a/lib/public/iusersession.php b/lib/public/iusersession.php new file mode 100644 index 0000000000000000000000000000000000000000..5dc1ecf71e647b14dba6676f5f6d59d2853e2687 --- /dev/null +++ b/lib/public/iusersession.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * User session + */ +interface IUserSession { + /** + * Do a user login + * @param string $user the username + * @param string $password the password + * @return bool true if successful + */ + public function login($user, $password); + + /** + * @brief Logs the user out including all the session data + * Logout, destroys session + */ + public function logout(); + +} diff --git a/lib/public/preview.php b/lib/public/preview.php deleted file mode 100644 index 7588347eccb76d88822b9d7babbcf6d39153c2c2..0000000000000000000000000000000000000000 --- a/lib/public/preview.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org - * Copyright (c) 2013 Georg Ehrke georg@ownCloud.com - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ -namespace OCP; - -/** - * This class provides functions to render and show thumbnails and previews of files - */ -class Preview { - - /** - * @brief return a preview of a file - * @param $file The path to the file where you want a thumbnail from - * @param $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image - * @param $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image - * @param $scaleup Scale smaller images up to the thumbnail size or not. Might look ugly - * @return image - */ - public static function show($file,$maxX=100,$maxY=75,$scaleup=false) { - return(\OC\Preview::show($file,$maxX,$maxY,$scaleup)); - } - - - - public static function isMimeSupported($mimetype='*') { - return \OC\Preview::isMimeSupported($mimetype); - } - -} diff --git a/lib/public/share.php b/lib/public/share.php index 6c5783f1179014c8897514a5df4c3008d2d25171..e6a74117aa21b012cf9cb6ca33b6a388c30eb2ec 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -246,9 +246,9 @@ class Share { /** * @brief Get the item of item type shared with the current user - * @param string Item type - * @param string Item target - * @param int Format (optional) Format type must be defined by the backend + * @param string $itemType + * @param string $ItemTarget + * @param int $format (optional) Format type must be defined by the backend * @return Return depends on format */ public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, @@ -257,6 +257,55 @@ class Share { $parameters, 1, $includeCollections); } + /** + * @brief Get the item of item type shared with a given user by source + * @param string $ItemType + * @param string $ItemSource + * @param string $user User user to whom the item was shared + * @return array Return list of items with file_target, permissions and expiration + */ + public static function getItemSharedWithUser($itemType, $itemSource, $user) { + + $shares = array(); + + // first check if there is a db entry for the specific user + $query = \OC_DB::prepare( + 'SELECT `file_target`, `permissions`, `expiration` + FROM + `*PREFIX*share` + WHERE + `item_source` = ? AND `item_type` = ? AND `share_with` = ?' + ); + + $result = \OC_DB::executeAudited($query, array($itemSource, $itemType, $user)); + + while ($row = $result->fetchRow()) { + $shares[] = $row; + } + + //if didn't found a result than let's look for a group share. + if(empty($shares)) { + $groups = \OC_Group::getUserGroups($user); + + $query = \OC_DB::prepare( + 'SELECT `file_target`, `permissions`, `expiration` + FROM + `*PREFIX*share` + WHERE + `item_source` = ? AND `item_type` = ? AND `share_with` in (?)' + ); + + $result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups))); + + while ($row = $result->fetchRow()) { + $shares[] = $row; + } + } + + return $shares; + + } + /** * @brief Get the item of item type shared with the current user by source * @param string Item type @@ -653,6 +702,29 @@ class Share { } return false; } + /** + * @brief sent status if users got informed by mail about share + * @param string $itemType + * @param string $itemSource + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK + * @param bool $status + */ + public static function setSendMailStatus($itemType, $itemSource, $shareType, $status) { + $status = $status ? 1 : 0; + + $query = \OC_DB::prepare( + 'UPDATE `*PREFIX*share` + SET `mail_send` = ? + WHERE `item_type` = ? AND `item_source` = ? AND `share_type` = ?'); + + $result = $query->execute(array($status, $itemType, $itemSource, $shareType)); + + if($result === false) { + \OC_Log::write('OCP\Share', 'Couldn\'t set send mail status', \OC_Log::ERROR); + } + + + } /** * @brief Set the permissions of an item for a specific user or group @@ -983,19 +1055,19 @@ class Share { if ($format == self::FORMAT_STATUSES) { if ($itemType == 'file' || $itemType == 'folder') { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`,' - .' `share_type`, `file_source`, `path`, `expiration`, `storage`'; + .' `share_type`, `file_source`, `path`, `expiration`, `storage`, `mail_send`'; } else { - $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `expiration`'; + $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `expiration`, `mail_send`'; } } else { if (isset($uidOwner)) { if ($itemType == 'file' || $itemType == 'folder') { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`,' .' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,' - .' `expiration`, `token`, `storage`'; + .' `expiration`, `token`, `storage`, `mail_send`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,' - .' `stime`, `file_source`, `expiration`, `token`'; + .' `stime`, `file_source`, `expiration`, `token`, `mail_send`'; } } else { if ($fileDependent) { @@ -1006,11 +1078,11 @@ class Share { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, ' .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' .'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' - .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`'; + .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, - `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`'; + `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`'; } } else { $select = '*'; diff --git a/lib/vcategories.php b/lib/vcategories.php deleted file mode 100644 index 8403695835973d7b73e1c381d66c604c8fe0e6c2..0000000000000000000000000000000000000000 --- a/lib/vcategories.php +++ /dev/null @@ -1,821 +0,0 @@ -<?php -/** -* ownCloud -* -* @author Thomas Tanghus -* @copyright 2012 Thomas Tanghus <thomas@tanghus.net> -* @copyright 2012 Bart Visscher bartv@thisnet.nl -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_VCategories', 'post_deleteUser'); - -/** - * Class for easy access to categories in VCARD, VEVENT, VTODO and VJOURNAL. - * A Category can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or - * anything else that is either parsed from a vobject or that the user chooses - * to add. - * Category names are not case-sensitive, but will be saved with the case they - * are entered in. If a user already has a category 'family' for a type, and - * tries to add a category named 'Family' it will be silently ignored. - */ -class OC_VCategories { - - /** - * Categories - */ - private $categories = array(); - - /** - * Used for storing objectid/categoryname pairs while rescanning. - */ - private static $relations = array(); - - private $type = null; - private $user = null; - - const CATEGORY_TABLE = '*PREFIX*vcategory'; - const RELATION_TABLE = '*PREFIX*vcategory_to_object'; - - const CATEGORY_FAVORITE = '_$!<Favorite>!$_'; - - const FORMAT_LIST = 0; - const FORMAT_MAP = 1; - - /** - * @brief Constructor. - * @param $type The type identifier e.g. 'contact' or 'event'. - * @param $user The user whos data the object will operate on. This - * parameter should normally be omitted but to make an app able to - * update categories for all users it is made possible to provide it. - * @param $defcategories An array of default categories to be used if none is stored. - */ - public function __construct($type, $user=null, $defcategories=array()) { - $this->type = $type; - $this->user = is_null($user) ? OC_User::getUser() : $user; - - $this->loadCategories(); - OCP\Util::writeLog('core', __METHOD__ . ', categories: ' - . print_r($this->categories, true), - OCP\Util::DEBUG - ); - - if($defcategories && count($this->categories) === 0) { - $this->addMulti($defcategories, true); - } - } - - /** - * @brief Load categories from db. - */ - private function loadCategories() { - $this->categories = array(); - $result = null; - $sql = 'SELECT `id`, `category` FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`'; - try { - $stmt = OCP\DB::prepare($sql); - $result = $stmt->execute(array($this->user, $this->type)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - - if(!is_null($result)) { - while( $row = $result->fetchRow()) { - // The keys are prefixed because array_search wouldn't work otherwise :-/ - $this->categories[$row['id']] = $row['category']; - } - } - OCP\Util::writeLog('core', __METHOD__.', categories: ' . print_r($this->categories, true), - OCP\Util::DEBUG); - } - - - /** - * @brief Check if any categories are saved for this type and user. - * @returns boolean. - * @param $type The type identifier e.g. 'contact' or 'event'. - * @param $user The user whos categories will be checked. If not set current user will be used. - */ - public static function isEmpty($type, $user = null) { - $user = is_null($user) ? OC_User::getUser() : $user; - $sql = 'SELECT COUNT(*) FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ?'; - try { - $stmt = OCP\DB::prepare($sql); - $result = $stmt->execute(array($user, $type)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - return ($result->numRows() === 0); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - } - - /** - * @brief Get the categories for a specific user. - * @param - * @returns array containing the categories as strings. - */ - public function categories($format = null) { - if(!$this->categories) { - return array(); - } - $categories = array_values($this->categories); - uasort($categories, 'strnatcasecmp'); - if($format == self::FORMAT_MAP) { - $catmap = array(); - foreach($categories as $category) { - if($category !== self::CATEGORY_FAVORITE) { - $catmap[] = array( - 'id' => $this->array_searchi($category, $this->categories), - 'name' => $category - ); - } - } - return $catmap; - } - - // Don't add favorites to normal categories. - $favpos = array_search(self::CATEGORY_FAVORITE, $categories); - if($favpos !== false) { - return array_splice($categories, $favpos); - } else { - return $categories; - } - } - - /** - * Get the a list if items belonging to $category. - * - * Throws an exception if the category could not be found. - * - * @param string|integer $category Category id or name. - * @returns array An array of object ids or false on error. - */ - public function idsForCategory($category) { - $result = null; - if(is_numeric($category)) { - $catid = $category; - } elseif(is_string($category)) { - $catid = $this->array_searchi($category, $this->categories); - } - OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG); - if($catid === false) { - $l10n = OC_L10N::get('core'); - throw new Exception( - $l10n->t('Could not find category "%s"', $category) - ); - } - - $ids = array(); - $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE - . '` WHERE `categoryid` = ?'; - - try { - $stmt = OCP\DB::prepare($sql); - $result = $stmt->execute(array($catid)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - - if(!is_null($result)) { - while( $row = $result->fetchRow()) { - $ids[] = (int)$row['objid']; - } - } - - return $ids; - } - - /** - * Get the a list if items belonging to $category. - * - * Throws an exception if the category could not be found. - * - * @param string|integer $category Category id or name. - * @param array $tableinfo Array in the form {'tablename' => table, 'fields' => ['field1', 'field2']} - * @param int $limit - * @param int $offset - * - * This generic method queries a table assuming that the id - * field is called 'id' and the table name provided is in - * the form '*PREFIX*table_name'. - * - * If the category name cannot be resolved an exception is thrown. - * - * TODO: Maybe add the getting permissions for objects? - * - * @returns array containing the resulting items or false on error. - */ - public function itemsForCategory($category, $tableinfo, $limit = null, $offset = null) { - $result = null; - if(is_numeric($category)) { - $catid = $category; - } elseif(is_string($category)) { - $catid = $this->array_searchi($category, $this->categories); - } - OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG); - if($catid === false) { - $l10n = OC_L10N::get('core'); - throw new Exception( - $l10n->t('Could not find category "%s"', $category) - ); - } - $fields = ''; - foreach($tableinfo['fields'] as $field) { - $fields .= '`' . $tableinfo['tablename'] . '`.`' . $field . '`,'; - } - $fields = substr($fields, 0, -1); - - $items = array(); - $sql = 'SELECT `' . self::RELATION_TABLE . '`.`categoryid`, ' . $fields - . ' FROM `' . $tableinfo['tablename'] . '` JOIN `' - . self::RELATION_TABLE . '` ON `' . $tableinfo['tablename'] - . '`.`id` = `' . self::RELATION_TABLE . '`.`objid` WHERE `' - . self::RELATION_TABLE . '`.`categoryid` = ?'; - - try { - $stmt = OCP\DB::prepare($sql, $limit, $offset); - $result = $stmt->execute(array($catid)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - - if(!is_null($result)) { - while( $row = $result->fetchRow()) { - $items[] = $row; - } - } - //OCP\Util::writeLog('core', __METHOD__.', count: ' . count($items), OCP\Util::DEBUG); - //OCP\Util::writeLog('core', __METHOD__.', sql: ' . $sql, OCP\Util::DEBUG); - - return $items; - } - - /** - * @brief Checks whether a category is already saved. - * @param $name The name to check for. - * @returns bool - */ - public function hasCategory($name) { - return $this->in_arrayi($name, $this->categories); - } - - /** - * @brief Add a new category. - * @param $name A string with a name of the category - * @returns int the id of the added category or false if it already exists. - */ - public function add($name) { - OCP\Util::writeLog('core', __METHOD__.', name: ' . $name, OCP\Util::DEBUG); - if($this->hasCategory($name)) { - OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', OCP\Util::DEBUG); - return false; - } - try { - OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, - array( - 'uid' => $this->user, - 'type' => $this->type, - 'category' => $name, - )); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - $id = OCP\DB::insertid(self::CATEGORY_TABLE); - OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, OCP\Util::DEBUG); - $this->categories[$id] = $name; - return $id; - } - - /** - * @brief Rename category. - * @param string $from The name of the existing category - * @param string $to The new name of the category. - * @returns bool - */ - public function rename($from, $to) { - $id = $this->array_searchi($from, $this->categories); - if($id === false) { - OCP\Util::writeLog('core', __METHOD__.', category: ' . $from. ' does not exist', OCP\Util::DEBUG); - return false; - } - - $sql = 'UPDATE `' . self::CATEGORY_TABLE . '` SET `category` = ? ' - . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?'; - try { - $stmt = OCP\DB::prepare($sql); - $result = $stmt->execute(array($to, $this->user, $this->type, $id)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - $this->categories[$id] = $to; - return true; - } - - /** - * @brief Add a new category. - * @param $names A string with a name or an array of strings containing - * the name(s) of the categor(y|ies) to add. - * @param $sync bool When true, save the categories - * @param $id int Optional object id to add to this|these categor(y|ies) - * @returns bool Returns false on error. - */ - public function addMulti($names, $sync=false, $id = null) { - if(!is_array($names)) { - $names = array($names); - } - $names = array_map('trim', $names); - $newones = array(); - foreach($names as $name) { - if(($this->in_arrayi( - $name, $this->categories) == false) && $name != '') { - $newones[] = $name; - } - if(!is_null($id) ) { - // Insert $objectid, $categoryid pairs if not exist. - self::$relations[] = array('objid' => $id, 'category' => $name); - } - } - $this->categories = array_merge($this->categories, $newones); - if($sync === true) { - $this->save(); - } - - return true; - } - - /** - * @brief Extracts categories from a vobject and add the ones not already present. - * @param $vobject The instance of OC_VObject to load the categories from. - */ - public function loadFromVObject($id, $vobject, $sync=false) { - $this->addMulti($vobject->getAsArray('CATEGORIES'), $sync, $id); - } - - /** - * @brief Reset saved categories and rescan supplied vobjects for categories. - * @param $objects An array of vobjects (as text). - * To get the object array, do something like: - * // For Addressbook: - * $categories = new OC_VCategories('contacts'); - * $stmt = OC_DB::prepare( 'SELECT `carddata` FROM `*PREFIX*contacts_cards`' ); - * $result = $stmt->execute(); - * $objects = array(); - * if(!is_null($result)) { - * while( $row = $result->fetchRow()){ - * $objects[] = array($row['id'], $row['carddata']); - * } - * } - * $categories->rescan($objects); - */ - public function rescan($objects, $sync=true, $reset=true) { - - if($reset === true) { - $result = null; - // Find all objectid/categoryid pairs. - try { - $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ?'); - $result = $stmt->execute(array($this->user, $this->type)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - - // And delete them. - if(!is_null($result)) { - $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' - . 'WHERE `categoryid` = ? AND `type`= ?'); - while( $row = $result->fetchRow()) { - $stmt->execute(array($row['id'], $this->type)); - } - } - try { - $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ?'); - $result = $stmt->execute(array($this->user, $this->type)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__ . ', exception: ' - . $e->getMessage(), OCP\Util::ERROR); - return; - } - $this->categories = array(); - } - // Parse all the VObjects - foreach($objects as $object) { - $vobject = OC_VObject::parse($object[1]); - if(!is_null($vobject)) { - // Load the categories - $this->loadFromVObject($object[0], $vobject, $sync); - } else { - OC_Log::write('core', __METHOD__ . ', unable to parse. ID: ' . ', ' - . substr($object, 0, 100) . '(...)', OC_Log::DEBUG); - } - } - $this->save(); - } - - /** - * @brief Save the list with categories - */ - private function save() { - if(is_array($this->categories)) { - foreach($this->categories as $category) { - try { - OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, - array( - 'uid' => $this->user, - 'type' => $this->type, - 'category' => $category, - )); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - } - // reload categories to get the proper ids. - $this->loadCategories(); - // Loop through temporarily cached objectid/categoryname pairs - // and save relations. - $categories = $this->categories; - // For some reason this is needed or array_search(i) will return 0..? - ksort($categories); - foreach(self::$relations as $relation) { - $catid = $this->array_searchi($relation['category'], $categories); - OC_Log::write('core', __METHOD__ . 'catid, ' . $relation['category'] . ' ' . $catid, OC_Log::DEBUG); - if($catid) { - try { - OCP\DB::insertIfNotExist(self::RELATION_TABLE, - array( - 'objid' => $relation['objid'], - 'categoryid' => $catid, - 'type' => $this->type, - )); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - } - } - self::$relations = array(); // reset - } else { - OC_Log::write('core', __METHOD__.', $this->categories is not an array! ' - . print_r($this->categories, true), OC_Log::ERROR); - } - } - - /** - * @brief Delete categories and category/object relations for a user. - * For hooking up on post_deleteUser - * @param string $uid The user id for which entries should be purged. - */ - public static function post_deleteUser($arguments) { - // Find all objectid/categoryid pairs. - $result = null; - try { - $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ?'); - $result = $stmt->execute(array($arguments['uid'])); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - - if(!is_null($result)) { - try { - $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' - . 'WHERE `categoryid` = ?'); - while( $row = $result->fetchRow()) { - try { - $stmt->execute(array($row['id'])); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - } - } - try { - $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ?'); - $result = $stmt->execute(array($arguments['uid'])); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__ . ', exception: ' - . $e->getMessage(), OCP\Util::ERROR); - } - } - - /** - * @brief Delete category/object relations from the db - * @param array $ids The ids of the objects - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns boolean Returns false on error. - */ - public function purgeObjects(array $ids, $type = null) { - $type = is_null($type) ? $this->type : $type; - if(count($ids) === 0) { - // job done ;) - return true; - } - $updates = $ids; - try { - $query = 'DELETE FROM `' . self::RELATION_TABLE . '` '; - $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) '; - $query .= 'AND `type`= ?'; - $updates[] = $type; - $stmt = OCP\DB::prepare($query); - $result = $stmt->execute($updates); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(), - OCP\Util::ERROR); - return false; - } - return true; - } - - /** - * Get favorites for an object type - * - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns array An array of object ids. - */ - public function getFavorites($type = null) { - $type = is_null($type) ? $this->type : $type; - - try { - return $this->idsForCategory(self::CATEGORY_FAVORITE); - } catch(Exception $e) { - // No favorites - return array(); - } - } - - /** - * Add an object to favorites - * - * @param int $objid The id of the object - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns boolean - */ - public function addToFavorites($objid, $type = null) { - $type = is_null($type) ? $this->type : $type; - if(!$this->hasCategory(self::CATEGORY_FAVORITE)) { - $this->add(self::CATEGORY_FAVORITE, true); - } - return $this->addToCategory($objid, self::CATEGORY_FAVORITE, $type); - } - - /** - * Remove an object from favorites - * - * @param int $objid The id of the object - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns boolean - */ - public function removeFromFavorites($objid, $type = null) { - $type = is_null($type) ? $this->type : $type; - return $this->removeFromCategory($objid, self::CATEGORY_FAVORITE, $type); - } - - /** - * @brief Creates a category/object relation. - * @param int $objid The id of the object - * @param int|string $category The id or name of the category - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns boolean Returns false on database error. - */ - public function addToCategory($objid, $category, $type = null) { - $type = is_null($type) ? $this->type : $type; - if(is_string($category) && !is_numeric($category)) { - if(!$this->hasCategory($category)) { - $this->add($category, true); - } - $categoryid = $this->array_searchi($category, $this->categories); - } else { - $categoryid = $category; - } - try { - OCP\DB::insertIfNotExist(self::RELATION_TABLE, - array( - 'objid' => $objid, - 'categoryid' => $categoryid, - 'type' => $type, - )); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - return true; - } - - /** - * @brief Delete single category/object relation from the db - * @param int $objid The id of the object - * @param int|string $category The id or name of the category - * @param string $type The type of object (event/contact/task/journal). - * Defaults to the type set in the instance - * @returns boolean - */ - public function removeFromCategory($objid, $category, $type = null) { - $type = is_null($type) ? $this->type : $type; - $categoryid = (is_string($category) && !is_numeric($category)) - ? $this->array_searchi($category, $this->categories) - : $category; - try { - $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' - . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?'; - OCP\Util::writeLog('core', __METHOD__.', sql: ' . $objid . ' ' . $categoryid . ' ' . $type, - OCP\Util::DEBUG); - $stmt = OCP\DB::prepare($sql); - $stmt->execute(array($objid, $categoryid, $type)); - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - return true; - } - - /** - * @brief Delete categories from the db and from all the vobject supplied - * @param $names An array of categories to delete - * @param $objects An array of arrays with [id,vobject] (as text) pairs suitable for updating the apps object table. - */ - public function delete($names, array &$objects=null) { - if(!is_array($names)) { - $names = array($names); - } - - OC_Log::write('core', __METHOD__ . ', before: ' - . print_r($this->categories, true), OC_Log::DEBUG); - foreach($names as $name) { - $id = null; - OC_Log::write('core', __METHOD__.', '.$name, OC_Log::DEBUG); - if($this->hasCategory($name)) { - $id = $this->array_searchi($name, $this->categories); - unset($this->categories[$id]); - } - try { - $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` WHERE ' - . '`uid` = ? AND `type` = ? AND `category` = ?'); - $result = $stmt->execute(array($this->user, $this->type, $name)); - if (OC_DB::isError($result)) { - OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__ . ', exception: ' - . $e->getMessage(), OCP\Util::ERROR); - } - if(!is_null($id) && $id !== false) { - try { - $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' - . 'WHERE `categoryid` = ?'; - $stmt = OCP\DB::prepare($sql); - $result = $stmt->execute(array($id)); - if (OC_DB::isError($result)) { - OC_Log::write('core', - __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), - OC_Log::ERROR); - } - } catch(Exception $e) { - OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - OCP\Util::ERROR); - return false; - } - } - } - OC_Log::write('core', __METHOD__.', after: ' - . print_r($this->categories, true), OC_Log::DEBUG); - if(!is_null($objects)) { - foreach($objects as $key=>&$value) { - $vobject = OC_VObject::parse($value[1]); - if(!is_null($vobject)) { - $object = null; - $componentname = ''; - if (isset($vobject->VEVENT)) { - $object = $vobject->VEVENT; - $componentname = 'VEVENT'; - } else - if (isset($vobject->VTODO)) { - $object = $vobject->VTODO; - $componentname = 'VTODO'; - } else - if (isset($vobject->VJOURNAL)) { - $object = $vobject->VJOURNAL; - $componentname = 'VJOURNAL'; - } else { - $object = $vobject; - } - $categories = $object->getAsArray('CATEGORIES'); - foreach($names as $name) { - $idx = $this->array_searchi($name, $categories); - if($idx !== false) { - OC_Log::write('core', __METHOD__ - .', unsetting: ' - . $categories[$this->array_searchi($name, $categories)], - OC_Log::DEBUG); - unset($categories[$this->array_searchi($name, $categories)]); - } - } - - $object->setString('CATEGORIES', implode(',', $categories)); - if($vobject !== $object) { - $vobject[$componentname] = $object; - } - $value[1] = $vobject->serialize(); - $objects[$key] = $value; - } else { - OC_Log::write('core', __METHOD__ - .', unable to parse. ID: ' . $value[0] . ', ' - . substr($value[1], 0, 50) . '(...)', OC_Log::DEBUG); - } - } - } - } - - // case-insensitive in_array - private function in_arrayi($needle, $haystack) { - if(!is_array($haystack)) { - return false; - } - return in_array(strtolower($needle), array_map('strtolower', $haystack)); - } - - // case-insensitive array_search - private function array_searchi($needle, $haystack) { - if(!is_array($haystack)) { - return false; - } - return array_search(strtolower($needle), array_map('strtolower', $haystack)); - } -} diff --git a/settings/admin.php b/settings/admin.php index dd36790907df7621733938c032479ce648cba290..120f15bec19b0d59249359051810cd1bfbdaaeb5 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -33,16 +33,17 @@ $tmpl->assign('shareAPIEnabled', OC_Appconfig::getValue('core', 'shareapi_enable // Check if connected using HTTPS if (OC_Request::serverProtocol() === 'https') { - $connectedHTTPS = true; + $connectedHTTPS = true; } else { $connectedHTTPS = false; -} +} $tmpl->assign('isConnectedViaHTTPS', $connectedHTTPS); $tmpl->assign('enforceHTTPSEnabled', OC_Config::getValue( "forcessl", false)); $tmpl->assign('allowLinks', OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes')); $tmpl->assign('allowPublicUpload', OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes')); $tmpl->assign('allowResharing', OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes')); +$tmpl->assign('allowMailNotification', OC_Appconfig::getValue('core', 'shareapi_allow_mail_notification', 'yes')); $tmpl->assign('sharePolicy', OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global')); $tmpl->assign('forms', array()); foreach($forms as $form) { diff --git a/settings/css/settings.css b/settings/css/settings.css index 57a43180a43a5e9b5f2e2d54ecb6add952ab24bf..0afdd9edbfaef15627d0512d24f5e1621a71c5f3 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -47,18 +47,37 @@ tr:hover>td.remove>a { float:right; } li.selected { background-color:#ddd; } table:not(.nostyle) { width:100%; } #rightcontent { padding-left: 1em; } -div.quota { float:right; display:block; position:absolute; right:25em; top:-1px; } +div.quota { + float: right; + display: block; + position: absolute; + right: 216px; + top: 0; +} div.quota-select-wrapper { position: relative; } div.recoveryPassword { left:50em; display:block; position:absolute; top:-1px; } input#recoveryPassword {width:15em;} select.quota { position:absolute; left:0; top:0; width:10em; } select.quota-user { position:relative; left:0; top:0; width:10em; } -div.quota>span { position:absolute; right:0; white-space:nowrap; top:.7em; color:#888; text-shadow:0 1px 0 #fff; } +div.quota>span { + position: absolute; + right: 0; + white-space: nowrap; + top: 12px; + color: #888; + text-shadow: 0 1px 0 #fff; +} select.quota.active { background: #fff; } /* positioning fixes */ -#newuser { position:relative; top:-3px; } -#newuser .multiselect { top:1px; } +#newuser .multiselect { + min-width: 150px !important; +} +#newuser .multiselect, +#newusergroups + input[type='submit'] { + position: relative; + top: 1px; +} #headerGroups, #headerSubAdmins, #headerQuota { padding-left:18px; } .ie8 table.hascontrols{border-collapse:collapse;width: 100%;} diff --git a/settings/js/personal.js b/settings/js/personal.js index a923b47573145e16d2c8dca45b1cef76734afc5a..3fdc2907c4604ed48bc4b965fd53176ed1544116 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -45,12 +45,16 @@ function changeDisplayName(){ } } -function updateAvatar () { +function updateAvatar (hidedefault) { $headerdiv = $('#header .avatardiv'); $displaydiv = $('#displayavatar .avatardiv'); - $headerdiv.css({'background-color': ''}); - $headerdiv.avatar(OC.currentUser, 32, true); + if(hidedefault) { + $headerdiv.hide(); + } else { + $headerdiv.css({'background-color': ''}); + $headerdiv.avatar(OC.currentUser, 32, true); + } $displaydiv.css({'background-color': ''}); $displaydiv.avatar(OC.currentUser, 128, true); } @@ -232,7 +236,7 @@ $(document).ready(function(){ type: 'DELETE', url: OC.Router.generate('core_avatar_delete'), success: function(msg) { - updateAvatar(); + updateAvatar(true); } }); }); diff --git a/settings/l10n/hu_HU.php b/settings/l10n/hu_HU.php index f31826c149f5ef99ac61dac205a5ebf721eb4b4f..cba844e7818ac60793a625757065bd8c57d74a3d 100644 --- a/settings/l10n/hu_HU.php +++ b/settings/l10n/hu_HU.php @@ -16,15 +16,25 @@ $TRANSLATIONS = array( "Unable to add user to group %s" => "A felhasználó nem adható hozzá ehhez a csoporthoz: %s", "Unable to remove user from group %s" => "A felhasználó nem távolítható el ebből a csoportból: %s", "Couldn't update app." => "A program frissítése nem sikerült.", +"Wrong password" => "Hibás jelszó", +"No user supplied" => "Nincs felhasználó által mellékelve", +"Please provide an admin recovery password, otherwise all user data will be lost" => "Add meg az admin helyreállító jelszót, máskülönben az összes felhasználói adat elveszik.", +"Wrong admin recovery password. Please check the password and try again." => "Hibás admin helyreállítási jelszó. Ellenörizd a jelszót és próbáld újra.", +"Back-end doesn't support password change, but the users encryption key was successfully updated." => "A back-end nem támogatja a jelszó módosítást, de felhasználó titkosítási kulcsa sikeresen frissítve lett.", +"Unable to change password" => "Nem sikerült megváltoztatni a jelszót", "Update to {appversion}" => "Frissítés erre a verzióra: {appversion}", "Disable" => "Letiltás", "Enable" => "engedélyezve", "Please wait...." => "Kérem várjon...", +"Error while disabling app" => "Hiba az alkalmazás kikapcsolása közben", +"Error while enabling app" => "Hiba az alalmazás engedélyezése közben", "Updating...." => "Frissítés folyamatban...", "Error while updating app" => "Hiba történt a programfrissítés közben", "Error" => "Hiba", "Update" => "Frissítés", "Updated" => "Frissítve", +"Select a profile picture" => "Válassz profil képet", +"Decrypting files... Please wait, this can take some time." => "File-ok kititkosítása folyamatban... Kérlek várj, ez hosszabb ideig is eltarthat ...", "Saving..." => "Mentés...", "deleted" => "törölve", "undo" => "visszavonás", @@ -98,11 +108,20 @@ $TRANSLATIONS = array( "Your email address" => "Az Ön email címe", "Fill in an email address to enable password recovery" => "Adja meg az email címét, hogy jelszó-emlékeztetőt kérhessen, ha elfelejtette a jelszavát!", "Profile picture" => "Profilkép", +"Upload new" => "Új feltöltése", +"Select new from Files" => "Új kiválasztása Fileokból", +"Remove image" => "Kép eltávolítása", +"Either png or jpg. Ideally square but you will be able to crop it." => "Egyaránt png vagy jpg. Az ideális ha négyzet alaku, de késöbb még átszabható", +"Abort" => "Megszakítás", +"Choose as profile image" => "Válassz profil képet", "Language" => "Nyelv", "Help translate" => "Segítsen a fordításban!", "WebDAV" => "WebDAV", "Use this address to <a href=\"%s/server/5.0/user_manual/files/files.html\" target=\"_blank\">access your Files via WebDAV</a>" => "Ezt a címet használja, ha <a href=\"%s/server/5.0/user_manual/files/files.html\" target=\"_blank\">WebDAV-on keresztül szeretné elérni az állományait</a>", "Encryption" => "Titkosítás", +"The encryption app is no longer enabled, decrypt all your file" => "A titkosító alkalmzás a továbbiakban nincs engedélyezve, kititkosítja az összes fileodat", +"Log-in password" => "Bejelentkezési jelszó", +"Decrypt all Files" => "Kititkosítja az összes file-t", "Login Name" => "Bejelentkezési név", "Create" => "Létrehozás", "Admin Recovery Password" => "A jelszóvisszaállítás adminisztrációja", diff --git a/settings/l10n/ja_JP.php b/settings/l10n/ja_JP.php index 12784e3f5379841b85e1d0c776905fad75a77fd2..bfaa9827b21f36cca1a2550c819803f3c79c86ee 100644 --- a/settings/l10n/ja_JP.php +++ b/settings/l10n/ja_JP.php @@ -16,6 +16,12 @@ $TRANSLATIONS = array( "Unable to add user to group %s" => "ユーザをグループ %s に追加できません", "Unable to remove user from group %s" => "ユーザをグループ %s から削除できません", "Couldn't update app." => "アプリを更新出来ませんでした。", +"Wrong password" => "無効なパスワード", +"No user supplied" => "ユーザが指定されていません", +"Please provide an admin recovery password, otherwise all user data will be lost" => "復元用の管理者パスワードを入力してください。そうでない場合は、全ユーザのデータが失われます。", +"Wrong admin recovery password. Please check the password and try again." => "無効な復元用の管理者パスワード。パスワードを確認して再度実行してください。", +"Back-end doesn't support password change, but the users encryption key was successfully updated." => "バックエンドはパスワード変更をサポートしていませんが、ユーザの暗号化キーは正常に更新されました。", +"Unable to change password" => "パスワードを変更できません", "Update to {appversion}" => "{appversion} に更新", "Disable" => "無効", "Enable" => "有効化", @@ -102,7 +108,10 @@ $TRANSLATIONS = array( "Your email address" => "あなたのメールアドレス", "Fill in an email address to enable password recovery" => "※パスワード回復を有効にするにはメールアドレスの入力が必要です", "Profile picture" => "プロフィール写真", +"Upload new" => "新規にアップロード", +"Select new from Files" => "ファイルから新規に選択", "Remove image" => "画像を削除", +"Either png or jpg. Ideally square but you will be able to crop it." => "png と jpg のいずれか。正方形が理想ですが、切り取って加工することも可能です。", "Abort" => "中止", "Choose as profile image" => "プロファイル画像として選択", "Language" => "言語", diff --git a/settings/l10n/lt_LT.php b/settings/l10n/lt_LT.php index a23d21ed7f7bee21e58b2cf1b4421ddeb9da9477..df0247fc27e3511d1400054899cd38abe7cb4fdd 100644 --- a/settings/l10n/lt_LT.php +++ b/settings/l10n/lt_LT.php @@ -16,6 +16,12 @@ $TRANSLATIONS = array( "Unable to add user to group %s" => "Nepavyko pridėti vartotojo prie grupės %s", "Unable to remove user from group %s" => "Nepavyko ištrinti vartotojo iš grupės %s", "Couldn't update app." => "Nepavyko atnaujinti programos.", +"Wrong password" => "Neteisingas slaptažodis", +"No user supplied" => "Nepateiktas naudotojas", +"Please provide an admin recovery password, otherwise all user data will be lost" => "Prašome įvesti administratoriaus atkūrimo slaptažodį, kitaip visi naudotojo suomenys bus prarasti", +"Wrong admin recovery password. Please check the password and try again." => "Netinkamas administratoriau atkūrimo slaptažodis. Prašome pasitikrinti ir bandyti vėl.", +"Back-end doesn't support password change, but the users encryption key was successfully updated." => "Sistema nepalaiko slaptažodžio keitimo, bet naudotojo šifravimo raktas buvo sėkmingai atnaujintas.", +"Unable to change password" => "Nepavyksta pakeisti slaptažodžio", "Update to {appversion}" => "Atnaujinti iki {appversion}", "Disable" => "Išjungti", "Enable" => "Įjungti", diff --git a/settings/l10n/pl.php b/settings/l10n/pl.php index d07d1f7a4d22e30f6fb44795fdf1f290dfce4e88..6cce72df4b6d64847ea3c17fdea04aea1cba4189 100644 --- a/settings/l10n/pl.php +++ b/settings/l10n/pl.php @@ -16,6 +16,8 @@ $TRANSLATIONS = array( "Unable to add user to group %s" => "Nie można dodać użytkownika do grupy %s", "Unable to remove user from group %s" => "Nie można usunąć użytkownika z grupy %s", "Couldn't update app." => "Nie można uaktualnić aplikacji.", +"Wrong password" => "Złe hasło", +"Unable to change password" => "Nie można zmienić hasła", "Update to {appversion}" => "Aktualizacja do {appversion}", "Disable" => "Wyłącz", "Enable" => "Włącz", @@ -27,6 +29,7 @@ $TRANSLATIONS = array( "Error" => "Błąd", "Update" => "Aktualizuj", "Updated" => "Zaktualizowano", +"Select a profile picture" => "Wybierz zdjęcie profilu", "Decrypting files... Please wait, this can take some time." => "Odszyfrowuje pliki... Proszę czekać, to może zająć jakiś czas.", "Saving..." => "Zapisywanie...", "deleted" => "usunięto", @@ -101,7 +104,11 @@ $TRANSLATIONS = array( "Your email address" => "Twój adres e-mail", "Fill in an email address to enable password recovery" => "Podaj adres e-mail, aby uzyskać możliwość odzyskania hasła", "Profile picture" => "Zdjęcie profilu", +"Upload new" => "Wczytaj nowe", +"Select new from Files" => "Wybierz nowe z plików", +"Remove image" => "Usuń zdjęcie", "Abort" => "Anuluj", +"Choose as profile image" => "Wybierz zdjęcie profilu", "Language" => "Język", "Help translate" => "Pomóż w tłumaczeniu", "WebDAV" => "WebDAV", diff --git a/settings/templates/admin.php b/settings/templates/admin.php index e54586b80dfa15f4c91ff7a897aa433be745a942..72e93e78dac74c5d5a4b10bbbc1cd04cb40d6178 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -128,7 +128,7 @@ if (!$_['internetconnectionworking']) { </td> </tr> <tr> - <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('style="display:none"');?>> + <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('class="hidden"');?>> <input type="checkbox" name="shareapi_allow_links" id="allowLinks" value="1" <?php if ($_['allowLinks'] === 'yes') print_unescaped('checked="checked"'); ?> /> <label for="allowLinks"><?php p($l->t('Allow links'));?></label><br/> @@ -137,7 +137,7 @@ if (!$_['internetconnectionworking']) { </tr> <?php if (!\OCP\App::isEnabled('files_encryption')) { ?> <tr> - <td <?php if ($_['shareAPIEnabled'] == 'no') print_unescaped('style="display:none"');?>> + <td <?php if ($_['shareAPIEnabled'] == 'no') print_unescaped('class="hidden"');?>> <input type="checkbox" name="shareapi_allow_public_upload" id="allowPublicUpload" value="1" <?php if ($_['allowPublicUpload'] == 'yes') print_unescaped('checked="checked"'); ?> /> <label for="allowPublicUpload"><?php p($l->t('Allow public uploads'));?></label><br/> @@ -146,7 +146,7 @@ if (!$_['internetconnectionworking']) { </tr> <?php } ?> <tr> - <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('style="display:none"');?>> + <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('class="hidden"');?>> <input type="checkbox" name="shareapi_allow_resharing" id="allowResharing" value="1" <?php if ($_['allowResharing'] === 'yes') print_unescaped('checked="checked"'); ?> /> <label for="allowResharing"><?php p($l->t('Allow resharing'));?></label><br/> @@ -154,7 +154,7 @@ if (!$_['internetconnectionworking']) { </td> </tr> <tr> - <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('style="display:none"');?>> + <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('class="hidden"');?>> <input type="radio" name="shareapi_share_policy" id="sharePolicyGlobal" value="global" <?php if ($_['sharePolicy'] === 'global') print_unescaped('checked="checked"'); ?> /> <label for="sharePolicyGlobal"><?php p($l->t('Allow users to share with anyone')); ?></label><br/> @@ -163,6 +163,14 @@ if (!$_['internetconnectionworking']) { <label for="sharePolicyGroupsOnly"><?php p($l->t('Allow users to only share with users in their groups'));?></label><br/> </td> </tr> + <tr> + <td <?php if ($_['shareAPIEnabled'] === 'no') print_unescaped('class="hidden"');?>> + <input type="checkbox" name="shareapi_allow_mail_notification" id="allowMailNotification" + value="1" <?php if ($_['allowMailNotification'] === 'yes') print_unescaped('checked="checked"'); ?> /> + <label for="allowMailNotification"><?php p($l->t('Allow mail notification'));?></label><br/> + <em><?php p($l->t('Allow user to send mail notification for shared files')); ?></em> + </td> + </tr> </table> </fieldset> @@ -223,7 +231,7 @@ endfor;?> </td> <td> <?php if(is_int($entry->time)){ - p(OC_Util::formatDate($entry->time)); + p(OC_Util::formatDate($entry->time)); } else { p($entry->time); }?> diff --git a/tests/lib/appframework/AppTest.php b/tests/lib/appframework/AppTest.php new file mode 100644 index 0000000000000000000000000000000000000000..80abaefc43b0a4e285a982facc079b61d6a1e6d5 --- /dev/null +++ b/tests/lib/appframework/AppTest.php @@ -0,0 +1,99 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework; + + +class AppTest extends \PHPUnit_Framework_TestCase { + + private $container; + private $api; + private $controller; + private $dispatcher; + private $params; + private $headers; + private $output; + private $controllerName; + private $controllerMethod; + + protected function setUp() { + $this->container = new \OC\AppFramework\DependencyInjection\DIContainer('test'); + $this->controller = $this->getMockBuilder( + 'OC\AppFramework\Controller\Controller') + ->disableOriginalConstructor() + ->getMock(); + $this->dispatcher = $this->getMockBuilder( + 'OC\AppFramework\Http\Dispatcher') + ->disableOriginalConstructor() + ->getMock(); + + + $this->headers = array('key' => 'value'); + $this->output = 'hi'; + $this->controllerName = 'Controller'; + $this->controllerMethod = 'method'; + + $this->container[$this->controllerName] = $this->controller; + $this->container['Dispatcher'] = $this->dispatcher; + } + + + public function testControllerNameAndMethodAreBeingPassed(){ + $return = array(null, array(), null); + $this->dispatcher->expects($this->once()) + ->method('dispatch') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod)) + ->will($this->returnValue($return)); + + $this->expectOutputString(''); + + App::main($this->controllerName, $this->controllerMethod, array(), + $this->container); + } + + + /* + FIXME: this complains about shit headers which are already sent because + of the content length. Would be cool if someone could fix this + + public function testOutputIsPrinted(){ + $return = array(null, array(), $this->output); + $this->dispatcher->expects($this->once()) + ->method('dispatch') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod)) + ->will($this->returnValue($return)); + + $this->expectOutputString($this->output); + + App::main($this->controllerName, $this->controllerMethod, array(), + $this->container); + } + */ + + // FIXME: if someone manages to test the headers output, I'd be grateful + + +} diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4441bddfca9f4685385744aafa29671592222843 --- /dev/null +++ b/tests/lib/appframework/controller/ControllerTest.php @@ -0,0 +1,155 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace Test\AppFramework\Controller; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Controller\Controller; +use OCP\AppFramework\Http\TemplateResponse; + + +//require_once __DIR__ . "/../classloader.php"; + + +class ChildController extends Controller {}; + +class ControllerTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Controller + */ + private $controller; + private $api; + + protected function setUp(){ + $request = new Request( + array( + 'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'), + 'post' => array('name' => 'Jane Doe', 'nickname' => 'Janey'), + 'urlParams' => array('name' => 'Johnny Weissmüller'), + 'files' => array('file' => 'filevalue'), + 'env' => array('PATH' => 'daheim'), + 'session' => array('sezession' => 'kein'), + 'method' => 'hi', + ) + ); + + $this->api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName'), array('test')); + $this->api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('apptemplate_advanced')); + + $this->controller = new ChildController($this->api, $request); + } + + + public function testParamsGet(){ + $this->assertEquals('Johnny Weissmüller', $this->controller->params('name', 'Tarzan')); + } + + + public function testParamsGetDefault(){ + $this->assertEquals('Tarzan', $this->controller->params('Ape Man', 'Tarzan')); + } + + + public function testParamsFile(){ + $this->assertEquals('filevalue', $this->controller->params('file', 'filevalue')); + } + + + public function testGetUploadedFile(){ + $this->assertEquals('filevalue', $this->controller->getUploadedFile('file')); + } + + + + public function testGetUploadedFileDefault(){ + $this->assertEquals('default', $this->controller->params('files', 'default')); + } + + + public function testGetParams(){ + $params = array( + 'name' => 'Johnny Weissmüller', + 'nickname' => 'Janey', + ); + + $this->assertEquals($params, $this->controller->getParams()); + } + + + public function testRender(){ + $this->assertTrue($this->controller->render('') instanceof TemplateResponse); + } + + + public function testSetParams(){ + $params = array('john' => 'foo'); + $response = $this->controller->render('home', $params); + + $this->assertEquals($params, $response->getParams()); + } + + + public function testRenderRenderAs(){ + $ocTpl = $this->getMock('Template', array('fetchPage')); + $ocTpl->expects($this->once()) + ->method('fetchPage'); + + $api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName', 'getTemplate'), array('app')); + $api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + $api->expects($this->once()) + ->method('getTemplate') + ->with($this->equalTo('home'), $this->equalTo('admin'), $this->equalTo('app')) + ->will($this->returnValue($ocTpl)); + + $this->controller = new ChildController($api, new Request()); + $this->controller->render('home', array(), 'admin')->render(); + } + + + public function testRenderHeaders(){ + $headers = array('one', 'two'); + $response = $this->controller->render('', array(), '', $headers); + + $this->assertTrue(in_array($headers[0], $response->getHeaders())); + $this->assertTrue(in_array($headers[1], $response->getHeaders())); + } + + + public function testGetRequestMethod(){ + $this->assertEquals('hi', $this->controller->method()); + } + + + public function testGetEnvVariable(){ + $this->assertEquals('daheim', $this->controller->env('PATH')); + } + +} diff --git a/tests/lib/appframework/dependencyinjection/DIContainerTest.php b/tests/lib/appframework/dependencyinjection/DIContainerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..25fdd202839340ad233dff21caff16b8bb01e3b8 --- /dev/null +++ b/tests/lib/appframework/dependencyinjection/DIContainerTest.php @@ -0,0 +1,98 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @author Morris Jobke + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\DependencyInjection; + +use \OC\AppFramework\Http\Request; + + +//require_once(__DIR__ . "/../classloader.php"); + + +class DIContainerTest extends \PHPUnit_Framework_TestCase { + + private $container; + + protected function setUp(){ + $this->container = new DIContainer('name'); + $this->api = $this->getMock('OC\AppFramework\Core\API', array('getTrans'), array('hi')); + } + + private function exchangeAPI(){ + $this->api->expects($this->any()) + ->method('getTrans') + ->will($this->returnValue('yo')); + $this->container['API'] = $this->api; + } + + public function testProvidesAPI(){ + $this->assertTrue(isset($this->container['API'])); + } + + + public function testProvidesRequest(){ + $this->assertTrue(isset($this->container['Request'])); + } + + + public function testProvidesSecurityMiddleware(){ + $this->assertTrue(isset($this->container['SecurityMiddleware'])); + } + + + public function testProvidesMiddlewareDispatcher(){ + $this->assertTrue(isset($this->container['MiddlewareDispatcher'])); + } + + + public function testProvidesAppName(){ + $this->assertTrue(isset($this->container['AppName'])); + } + + + public function testAppNameIsSetCorrectly(){ + $this->assertEquals('name', $this->container['AppName']); + } + + + public function testMiddlewareDispatcherIncludesSecurityMiddleware(){ + $this->container['Request'] = new Request(); + $security = $this->container['SecurityMiddleware']; + $dispatcher = $this->container['MiddlewareDispatcher']; + + $this->assertContains($security, $dispatcher->getMiddlewares()); + } + + + public function testMiddlewareDispatcherDoesNotIncludeTwigWhenTplDirectoryNotSet(){ + $this->container['Request'] = new Request(); + $this->exchangeAPI(); + $dispatcher = $this->container['MiddlewareDispatcher']; + + $this->assertEquals(1, count($dispatcher->getMiddlewares())); + } + +} diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php new file mode 100644 index 0000000000000000000000000000000000000000..849b0ca97a68dcb1bb0456c0c87e1750427065cd --- /dev/null +++ b/tests/lib/appframework/http/DispatcherTest.php @@ -0,0 +1,218 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + +use OC\AppFramework\Core\API; +use OC\AppFramework\Middleware\MiddlewareDispatcher; + +//require_once(__DIR__ . "/../classloader.php"); + + +class DispatcherTest extends \PHPUnit_Framework_TestCase { + + + private $middlewareDispatcher; + private $dispatcher; + private $controllerMethod; + private $response; + private $lastModified; + private $etag; + private $http; + + protected function setUp() { + $this->controllerMethod = 'test'; + + $api = $this->getMockBuilder( + '\OC\AppFramework\Core\API') + ->disableOriginalConstructor() + ->getMock(); + $request = $this->getMockBuilder( + '\OC\AppFramework\Http\Request') + ->disableOriginalConstructor() + ->getMock(); + $this->http = $this->getMockBuilder( + '\OC\AppFramework\Http\Http') + ->disableOriginalConstructor() + ->getMock(); + + $this->middlewareDispatcher = $this->getMockBuilder( + '\OC\AppFramework\Middleware\MiddlewareDispatcher') + ->disableOriginalConstructor() + ->getMock(); + $this->controller = $this->getMock( + '\OC\AppFramework\Controller\Controller', + array($this->controllerMethod), array($api, $request)); + + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher); + + $this->response = $this->getMockBuilder( + '\OCP\AppFramework\Http\Response') + ->disableOriginalConstructor() + ->getMock(); + + $this->lastModified = new \DateTime(null, new \DateTimeZone('GMT')); + $this->etag = 'hi'; + } + + + private function setMiddlewareExpections($out=null, + $httpHeaders=null, $responseHeaders=array(), + $ex=false, $catchEx=true) { + + if($ex) { + $exception = new \Exception(); + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeController') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod)) + ->will($this->throwException($exception)); + if($catchEx) { + $this->middlewareDispatcher->expects($this->once()) + ->method('afterException') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod), + $this->equalTo($exception)) + ->will($this->returnValue($this->response)); + } else { + $this->middlewareDispatcher->expects($this->once()) + ->method('afterException') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod), + $this->equalTo($exception)) + ->will($this->returnValue(null)); + return; + } + } else { + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeController') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod)); + $this->controller->expects($this->once()) + ->method($this->controllerMethod) + ->will($this->returnValue($this->response)); + } + + $this->response->expects($this->once()) + ->method('render') + ->will($this->returnValue($out)); + $this->response->expects($this->once()) + ->method('getStatus') + ->will($this->returnValue(Http::STATUS_OK)); + $this->response->expects($this->once()) + ->method('getLastModified') + ->will($this->returnValue($this->lastModified)); + $this->response->expects($this->once()) + ->method('getETag') + ->will($this->returnValue($this->etag)); + $this->response->expects($this->once()) + ->method('getHeaders') + ->will($this->returnValue($responseHeaders)); + $this->http->expects($this->once()) + ->method('getStatusHeader') + ->with($this->equalTo(Http::STATUS_OK), + $this->equalTo($this->lastModified), + $this->equalTo($this->etag)) + ->will($this->returnValue($httpHeaders)); + + $this->middlewareDispatcher->expects($this->once()) + ->method('afterController') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod), + $this->equalTo($this->response)) + ->will($this->returnValue($this->response)); + + $this->middlewareDispatcher->expects($this->once()) + ->method('afterController') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod), + $this->equalTo($this->response)) + ->will($this->returnValue($this->response)); + + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeOutput') + ->with($this->equalTo($this->controller), + $this->equalTo($this->controllerMethod), + $this->equalTo($out)) + ->will($this->returnValue($out)); + + + } + + + public function testDispatcherReturnsArrayWith2Entries() { + $this->setMiddlewareExpections(); + + $response = $this->dispatcher->dispatch($this->controller, + $this->controllerMethod); + $this->assertNull($response[0]); + $this->assertEquals(array(), $response[1]); + $this->assertNull($response[2]); + } + + + public function testHeadersAndOutputAreReturned(){ + $out = 'yo'; + $httpHeaders = 'Http'; + $responseHeaders = array('hell' => 'yeah'); + $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders); + + $response = $this->dispatcher->dispatch($this->controller, + $this->controllerMethod); + + $this->assertEquals($httpHeaders, $response[0]); + $this->assertEquals($responseHeaders, $response[1]); + $this->assertEquals($out, $response[2]); + } + + + public function testExceptionCallsAfterException() { + $out = 'yo'; + $httpHeaders = 'Http'; + $responseHeaders = array('hell' => 'yeah'); + $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true); + + $response = $this->dispatcher->dispatch($this->controller, + $this->controllerMethod); + + $this->assertEquals($httpHeaders, $response[0]); + $this->assertEquals($responseHeaders, $response[1]); + $this->assertEquals($out, $response[2]); + } + + + public function testExceptionThrowsIfCanNotBeHandledByAfterException() { + $out = 'yo'; + $httpHeaders = 'Http'; + $responseHeaders = array('hell' => 'yeah'); + $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true, false); + + $this->setExpectedException('\Exception'); + $response = $this->dispatcher->dispatch($this->controller, + $this->controllerMethod); + + } + +} diff --git a/tests/lib/appframework/http/DownloadResponseTest.php b/tests/lib/appframework/http/DownloadResponseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..64fe7992b6a83d8f50d345ab61d79e1805ac8b9f --- /dev/null +++ b/tests/lib/appframework/http/DownloadResponseTest.php @@ -0,0 +1,51 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +//require_once(__DIR__ . "/../classloader.php"); + + +class ChildDownloadResponse extends DownloadResponse {}; + + +class DownloadResponseTest extends \PHPUnit_Framework_TestCase { + + protected $response; + + protected function setUp(){ + $this->response = new ChildDownloadResponse('file', 'content'); + } + + + public function testHeaders() { + $headers = $this->response->getHeaders(); + + $this->assertContains('attachment; filename="file"', $headers['Content-Disposition']); + $this->assertContains('content', $headers['Content-Type']); + } + + +} diff --git a/tests/lib/appframework/http/HttpTest.php b/tests/lib/appframework/http/HttpTest.php new file mode 100644 index 0000000000000000000000000000000000000000..382d511b116449aa0ecda0047db07110ebbd93ad --- /dev/null +++ b/tests/lib/appframework/http/HttpTest.php @@ -0,0 +1,87 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +//require_once(__DIR__ . "/../classloader.php"); + + + +class HttpTest extends \PHPUnit_Framework_TestCase { + + private $server; + private $http; + + protected function setUp(){ + $this->server = array(); + $this->http = new Http($this->server); + } + + + public function testProtocol() { + $header = $this->http->getStatusHeader(Http::STATUS_TEMPORARY_REDIRECT); + $this->assertEquals('HTTP/1.1 307 Temporary Redirect', $header); + } + + + public function testProtocol10() { + $this->http = new Http($this->server, 'HTTP/1.0'); + $header = $this->http->getStatusHeader(Http::STATUS_OK); + $this->assertEquals('HTTP/1.0 200 OK', $header); + } + + + public function testEtagMatchReturnsNotModified() { + $http = new Http(array('HTTP_IF_NONE_MATCH' => 'hi')); + + $header = $http->getStatusHeader(Http::STATUS_OK, null, 'hi'); + $this->assertEquals('HTTP/1.1 304 Not Modified', $header); + } + + + public function testLastModifiedMatchReturnsNotModified() { + $dateTime = new \DateTime(null, new \DateTimeZone('GMT')); + $dateTime->setTimestamp('12'); + + $http = new Http( + array( + 'HTTP_IF_MODIFIED_SINCE' => 'Thu, 01 Jan 1970 00:00:12 +0000') + ); + + $header = $http->getStatusHeader(Http::STATUS_OK, $dateTime); + $this->assertEquals('HTTP/1.1 304 Not Modified', $header); + } + + + + public function testTempRedirectBecomesFoundInHttp10() { + $http = new Http(array(), 'HTTP/1.0'); + + $header = $http->getStatusHeader(Http::STATUS_TEMPORARY_REDIRECT); + $this->assertEquals('HTTP/1.0 302 Found', $header); + } + // TODO: write unittests for http codes + +} diff --git a/tests/lib/appframework/http/JSONResponseTest.php b/tests/lib/appframework/http/JSONResponseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..534c54cbcee726f473c1b55d59162d95b20e01bb --- /dev/null +++ b/tests/lib/appframework/http/JSONResponseTest.php @@ -0,0 +1,98 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @author Morris Jobke + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +use OCP\AppFramework\Http\JSONResponse; + +//require_once(__DIR__ . "/../classloader.php"); + + + +class JSONResponseTest extends \PHPUnit_Framework_TestCase { + + /** + * @var JSONResponse + */ + private $json; + + protected function setUp() { + $this->json = new JSONResponse(); + } + + + public function testHeader() { + $headers = $this->json->getHeaders(); + $this->assertEquals('application/json; charset=utf-8', $headers['Content-type']); + } + + + public function testSetData() { + $params = array('hi', 'yo'); + $this->json->setData($params); + + $this->assertEquals(array('hi', 'yo'), $this->json->getData()); + } + + + public function testSetRender() { + $params = array('test' => 'hi'); + $this->json->setData($params); + + $expected = '{"test":"hi"}'; + + $this->assertEquals($expected, $this->json->render()); + } + + + public function testRender() { + $params = array('test' => 'hi'); + $this->json->setData($params); + + $expected = '{"test":"hi"}'; + + $this->assertEquals($expected, $this->json->render()); + } + + + public function testShouldHaveXContentHeaderByDefault() { + $headers = $this->json->getHeaders(); + $this->assertEquals('nosniff', $headers['X-Content-Type-Options']); + } + + + public function testConstructorAllowsToSetData() { + $data = array('hi'); + $code = 300; + $response = new JSONResponse($data, $code); + + $expected = '["hi"]'; + $this->assertEquals($expected, $response->render()); + $this->assertEquals($code, $response->getStatus()); + } + +} diff --git a/tests/lib/appframework/http/RedirectResponseTest.php b/tests/lib/appframework/http/RedirectResponseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1946655b0fa54ea6c95ab9cdb3fff6e0fbefe2a9 --- /dev/null +++ b/tests/lib/appframework/http/RedirectResponseTest.php @@ -0,0 +1,55 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +//require_once(__DIR__ . "/../classloader.php"); + + + +class RedirectResponseTest extends \PHPUnit_Framework_TestCase { + + + protected $response; + + protected function setUp(){ + $this->response = new RedirectResponse('/url'); + } + + + public function testHeaders() { + $headers = $this->response->getHeaders(); + $this->assertEquals('/url', $headers['Location']); + $this->assertEquals(Http::STATUS_TEMPORARY_REDIRECT, + $this->response->getStatus()); + } + + + public function testGetRedirectUrl(){ + $this->assertEquals('/url', $this->response->getRedirectUrl()); + } + + +} diff --git a/tests/lib/appframework/http/RequestTest.php b/tests/lib/appframework/http/RequestTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0371c870cf292682b70a35a35fac70d3020f2468 --- /dev/null +++ b/tests/lib/appframework/http/RequestTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\AppFramework\Http; + + +class RequestTest extends \PHPUnit_Framework_TestCase { + + public function testRequestAccessors() { + $vars = array( + 'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'), + ); + + $request = new Request($vars); + + // Countable + $this->assertEquals(2, count($request)); + // Array access + $this->assertEquals('Joey', $request['nickname']); + // "Magic" accessors + $this->assertEquals('Joey', $request->{'nickname'}); + $this->assertTrue(isset($request['nickname'])); + $this->assertTrue(isset($request->{'nickname'})); + $this->assertEquals(false, isset($request->{'flickname'})); + // Only testing 'get', but same approach for post, files etc. + $this->assertEquals('Joey', $request->get['nickname']); + // Always returns null if variable not set. + $this->assertEquals(null, $request->{'flickname'}); + } + + // urlParams has precedence over POST which has precedence over GET + public function testPrecedence() { + $vars = array( + 'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'), + 'post' => array('name' => 'Jane Doe', 'nickname' => 'Janey'), + 'urlParams' => array('user' => 'jw', 'name' => 'Johnny Weissmüller'), + ); + + $request = new Request($vars); + + $this->assertEquals(3, count($request)); + $this->assertEquals('Janey', $request->{'nickname'}); + $this->assertEquals('Johnny Weissmüller', $request->{'name'}); + } + + + /** + * @expectedException RuntimeException + */ + public function testImmutableArrayAccess() { + $vars = array( + 'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'), + ); + + $request = new Request($vars); + $request['nickname'] = 'Janey'; + } + + /** + * @expectedException RuntimeException + */ + public function testImmutableMagicAccess() { + $vars = array( + 'get' => array('name' => 'John Q. Public', 'nickname' => 'Joey'), + ); + + $request = new Request($vars); + $request->{'nickname'} = 'Janey'; + } + +} diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7e09086f80172d3f4bd0a9245434560347b47363 --- /dev/null +++ b/tests/lib/appframework/http/ResponseTest.php @@ -0,0 +1,120 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + + +use OCP\AppFramework\Http\Response; + + +class ResponseTest extends \PHPUnit_Framework_TestCase { + + /** + * @var \OCP\AppFramework\Http\Response + */ + private $childResponse; + + protected function setUp(){ + $this->childResponse = new Response(); + } + + + public function testAddHeader(){ + $this->childResponse->addHeader('hello', 'world'); + $headers = $this->childResponse->getHeaders(); + $this->assertEquals('world', $headers['hello']); + } + + + public function testAddHeaderValueNullDeletesIt(){ + $this->childResponse->addHeader('hello', 'world'); + $this->childResponse->addHeader('hello', null); + $this->assertEquals(1, count($this->childResponse->getHeaders())); + } + + + public function testCacheHeadersAreDisabledByDefault(){ + $headers = $this->childResponse->getHeaders(); + $this->assertEquals('no-cache, must-revalidate', $headers['Cache-Control']); + } + + + public function testRenderReturnNullByDefault(){ + $this->assertEquals(null, $this->childResponse->render()); + } + + + public function testGetStatus() { + $default = $this->childResponse->getStatus(); + + $this->childResponse->setStatus(Http::STATUS_NOT_FOUND); + + $this->assertEquals(Http::STATUS_OK, $default); + $this->assertEquals(Http::STATUS_NOT_FOUND, $this->childResponse->getStatus()); + } + + + public function testGetEtag() { + $this->childResponse->setEtag('hi'); + $this->assertEquals('hi', $this->childResponse->getEtag()); + } + + + public function testGetLastModified() { + $lastModified = new \DateTime(null, new \DateTimeZone('GMT')); + $lastModified->setTimestamp(1); + $this->childResponse->setLastModified($lastModified); + $this->assertEquals($lastModified, $this->childResponse->getLastModified()); + } + + + + public function testCacheSecondsZero() { + $this->childResponse->cacheFor(0); + + $headers = $this->childResponse->getHeaders(); + $this->assertEquals('no-cache, must-revalidate', $headers['Cache-Control']); + } + + + public function testCacheSeconds() { + $this->childResponse->cacheFor(33); + + $headers = $this->childResponse->getHeaders(); + $this->assertEquals('max-age=33, must-revalidate', + $headers['Cache-Control']); + } + + + + public function testEtagLastModifiedHeaders() { + $lastModified = new \DateTime(null, new \DateTimeZone('GMT')); + $lastModified->setTimestamp(1); + $this->childResponse->setLastModified($lastModified); + $headers = $this->childResponse->getHeaders(); + $this->assertEquals('Thu, 01 Jan 1970 00:00:01 +0000', $headers['Last-Modified']); + } + + +} diff --git a/tests/lib/appframework/http/TemplateResponseTest.php b/tests/lib/appframework/http/TemplateResponseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3c6d29cd3392bfcb1a7c9b07923a1578a7abe212 --- /dev/null +++ b/tests/lib/appframework/http/TemplateResponseTest.php @@ -0,0 +1,161 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Http; + +use OCP\AppFramework\Http\TemplateResponse; + + +class TemplateResponseTest extends \PHPUnit_Framework_TestCase { + + /** + * @var \OCP\AppFramework\Http\TemplateResponse + */ + private $tpl; + + /** + * @var \OCP\AppFramework\IApi + */ + private $api; + + protected function setUp() { + $this->api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName'), array('test')); + $this->api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + + $this->tpl = new TemplateResponse($this->api, 'home'); + } + + + public function testSetParams(){ + $params = array('hi' => 'yo'); + $this->tpl->setParams($params); + + $this->assertEquals(array('hi' => 'yo'), $this->tpl->getParams()); + } + + + public function testGetTemplateName(){ + $this->assertEquals('home', $this->tpl->getTemplateName()); + } + + + public function testRender(){ + $ocTpl = $this->getMock('Template', array('fetchPage')); + $ocTpl->expects($this->once()) + ->method('fetchPage'); + + $api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName', 'getTemplate'), array('app')); + $api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + $api->expects($this->once()) + ->method('getTemplate') + ->with($this->equalTo('home'), $this->equalTo('user'), $this->equalTo('app')) + ->will($this->returnValue($ocTpl)); + + $tpl = new TemplateResponse($api, 'home'); + + $tpl->render(); + } + + + public function testRenderAssignsParams(){ + $params = array('john' => 'doe'); + + $ocTpl = $this->getMock('Template', array('assign', 'fetchPage')); + $ocTpl->expects($this->once()) + ->method('assign') + ->with($this->equalTo('john'), $this->equalTo('doe')); + + $api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName', 'getTemplate'), array('app')); + $api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + $api->expects($this->once()) + ->method('getTemplate') + ->with($this->equalTo('home'), $this->equalTo('user'), $this->equalTo('app')) + ->will($this->returnValue($ocTpl)); + + $tpl = new TemplateResponse($api, 'home'); + $tpl->setParams($params); + + $tpl->render(); + } + + + public function testRenderDifferentApp(){ + $ocTpl = $this->getMock('Template', array('fetchPage')); + $ocTpl->expects($this->once()) + ->method('fetchPage'); + + $api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName', 'getTemplate'), array('app')); + $api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + $api->expects($this->once()) + ->method('getTemplate') + ->with($this->equalTo('home'), $this->equalTo('user'), $this->equalTo('app2')) + ->will($this->returnValue($ocTpl)); + + $tpl = new TemplateResponse($api, 'home', 'app2'); + + $tpl->render(); + } + + + public function testRenderDifferentRenderAs(){ + $ocTpl = $this->getMock('Template', array('fetchPage')); + $ocTpl->expects($this->once()) + ->method('fetchPage'); + + $api = $this->getMock('OC\AppFramework\Core\API', + array('getAppName', 'getTemplate'), array('app')); + $api->expects($this->any()) + ->method('getAppName') + ->will($this->returnValue('app')); + $api->expects($this->once()) + ->method('getTemplate') + ->with($this->equalTo('home'), $this->equalTo('admin'), $this->equalTo('app')) + ->will($this->returnValue($ocTpl)); + + $tpl = new TemplateResponse($api, 'home'); + $tpl->renderAs('admin'); + + $tpl->render(); + } + + + public function testGetRenderAs(){ + $render = 'myrender'; + $this->tpl->renderAs($render); + $this->assertEquals($render, $this->tpl->getRenderAs()); + } + +} diff --git a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php new file mode 100644 index 0000000000000000000000000000000000000000..43727846dcf3863af85aa4b14f272d060b805ec6 --- /dev/null +++ b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php @@ -0,0 +1,285 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Middleware\Middleware; +use OC\AppFramework\Middleware\MiddlewareDispatcher; +use OCP\AppFramework\Http\Response; + + +// needed to test ordering +class TestMiddleware extends Middleware { + public static $beforeControllerCalled = 0; + public static $afterControllerCalled = 0; + public static $afterExceptionCalled = 0; + public static $beforeOutputCalled = 0; + + public $beforeControllerOrder = 0; + public $afterControllerOrder = 0; + public $afterExceptionOrder = 0; + public $beforeOutputOrder = 0; + + public $controller; + public $methodName; + public $exception; + public $response; + public $output; + + private $beforeControllerThrowsEx; + + public function __construct($beforeControllerThrowsEx) { + self::$beforeControllerCalled = 0; + self::$afterControllerCalled = 0; + self::$afterExceptionCalled = 0; + self::$beforeOutputCalled = 0; + $this->beforeControllerThrowsEx = $beforeControllerThrowsEx; + } + + public function beforeController($controller, $methodName){ + self::$beforeControllerCalled++; + $this->beforeControllerOrder = self::$beforeControllerCalled; + $this->controller = $controller; + $this->methodName = $methodName; + if($this->beforeControllerThrowsEx){ + throw new \Exception(); + } + } + + public function afterException($controller, $methodName, \Exception $exception){ + self::$afterExceptionCalled++; + $this->afterExceptionOrder = self::$afterExceptionCalled; + $this->controller = $controller; + $this->methodName = $methodName; + $this->exception = $exception; + parent::afterException($controller, $methodName, $exception); + } + + public function afterController($controller, $methodName, Response $response){ + self::$afterControllerCalled++; + $this->afterControllerOrder = self::$afterControllerCalled; + $this->controller = $controller; + $this->methodName = $methodName; + $this->response = $response; + return parent::afterController($controller, $methodName, $response); + } + + public function beforeOutput($controller, $methodName, $output){ + self::$beforeOutputCalled++; + $this->beforeOutputOrder = self::$beforeOutputCalled; + $this->controller = $controller; + $this->methodName = $methodName; + $this->output = $output; + return parent::beforeOutput($controller, $methodName, $output); + } +} + + +class MiddlewareDispatcherTest extends \PHPUnit_Framework_TestCase { + + public $exception; + public $response; + private $out; + private $method; + private $controller; + + /** + * @var MiddlewareDispatcher + */ + private $dispatcher; + + + public function setUp() { + $this->dispatcher = new MiddlewareDispatcher(); + $this->controller = $this->getControllerMock(); + $this->method = 'method'; + $this->response = new Response(); + $this->out = 'hi'; + $this->exception = new \Exception(); + } + + + private function getAPIMock(){ + return $this->getMock('OC\AppFramework\Core\API', + array('getAppName'), array('app')); + } + + + private function getControllerMock(){ + return $this->getMock('OC\AppFramework\Controller\Controller', array('method'), + array($this->getAPIMock(), new Request())); + } + + + private function getMiddleware($beforeControllerThrowsEx=false){ + $m1 = new TestMiddleware($beforeControllerThrowsEx); + $this->dispatcher->registerMiddleware($m1); + return $m1; + } + + + public function testAfterExceptionShouldReturnResponseOfMiddleware(){ + $response = new Response(); + $m1 = $this->getMock('\OC\AppFramework\Middleware\Middleware', + array('afterException', 'beforeController')); + $m1->expects($this->never()) + ->method('afterException'); + + $m2 = $this->getMock('OC\AppFramework\Middleware\Middleware', + array('afterException', 'beforeController')); + $m2->expects($this->once()) + ->method('afterException') + ->will($this->returnValue($response)); + + $this->dispatcher->registerMiddleware($m1); + $this->dispatcher->registerMiddleware($m2); + + $this->dispatcher->beforeController($this->controller, $this->method); + $this->assertEquals($response, $this->dispatcher->afterException($this->controller, $this->method, $this->exception)); + } + + + public function testAfterExceptionShouldThrowAgainWhenNotHandled(){ + $m1 = new TestMiddleware(false); + $m2 = new TestMiddleware(true); + + $this->dispatcher->registerMiddleware($m1); + $this->dispatcher->registerMiddleware($m2); + + $this->setExpectedException('\Exception'); + $this->dispatcher->beforeController($this->controller, $this->method); + $this->dispatcher->afterException($this->controller, $this->method, $this->exception); + } + + + public function testBeforeControllerCorrectArguments(){ + $m1 = $this->getMiddleware(); + $this->dispatcher->beforeController($this->controller, $this->method); + + $this->assertEquals($this->controller, $m1->controller); + $this->assertEquals($this->method, $m1->methodName); + } + + + public function testAfterControllerCorrectArguments(){ + $m1 = $this->getMiddleware(); + + $this->dispatcher->afterController($this->controller, $this->method, $this->response); + + $this->assertEquals($this->controller, $m1->controller); + $this->assertEquals($this->method, $m1->methodName); + $this->assertEquals($this->response, $m1->response); + } + + + public function testAfterExceptionCorrectArguments(){ + $m1 = $this->getMiddleware(); + + $this->setExpectedException('\Exception'); + + $this->dispatcher->beforeController($this->controller, $this->method); + $this->dispatcher->afterException($this->controller, $this->method, $this->exception); + + $this->assertEquals($this->controller, $m1->controller); + $this->assertEquals($this->method, $m1->methodName); + $this->assertEquals($this->exception, $m1->exception); + } + + + public function testBeforeOutputCorrectArguments(){ + $m1 = $this->getMiddleware(); + + $this->dispatcher->beforeOutput($this->controller, $this->method, $this->out); + + $this->assertEquals($this->controller, $m1->controller); + $this->assertEquals($this->method, $m1->methodName); + $this->assertEquals($this->out, $m1->output); + } + + + public function testBeforeControllerOrder(){ + $m1 = $this->getMiddleware(); + $m2 = $this->getMiddleware(); + + $this->dispatcher->beforeController($this->controller, $this->method); + + $this->assertEquals(1, $m1->beforeControllerOrder); + $this->assertEquals(2, $m2->beforeControllerOrder); + } + + public function testAfterControllerOrder(){ + $m1 = $this->getMiddleware(); + $m2 = $this->getMiddleware(); + + $this->dispatcher->afterController($this->controller, $this->method, $this->response); + + $this->assertEquals(2, $m1->afterControllerOrder); + $this->assertEquals(1, $m2->afterControllerOrder); + } + + + public function testAfterExceptionOrder(){ + $m1 = $this->getMiddleware(); + $m2 = $this->getMiddleware(); + + $this->setExpectedException('\Exception'); + $this->dispatcher->beforeController($this->controller, $this->method); + $this->dispatcher->afterException($this->controller, $this->method, $this->exception); + + $this->assertEquals(1, $m1->afterExceptionOrder); + $this->assertEquals(1, $m2->afterExceptionOrder); + } + + + public function testBeforeOutputOrder(){ + $m1 = $this->getMiddleware(); + $m2 = $this->getMiddleware(); + + $this->dispatcher->beforeOutput($this->controller, $this->method, $this->out); + + $this->assertEquals(2, $m1->beforeOutputOrder); + $this->assertEquals(1, $m2->beforeOutputOrder); + } + + + public function testExceptionShouldRunAfterExceptionOfOnlyPreviouslyExecutedMiddlewares(){ + $m1 = $this->getMiddleware(); + $m2 = $this->getMiddleware(true); + $m3 = $this->getMock('\OC\AppFramework\Middleware\Middleware'); + $m3->expects($this->never()) + ->method('afterException'); + $m3->expects($this->never()) + ->method('beforeController'); + $m3->expects($this->never()) + ->method('afterController'); + + $this->dispatcher->registerMiddleware($m3); + + $this->dispatcher->beforeOutput($this->controller, $this->method, $this->out); + + $this->assertEquals(2, $m1->beforeOutputOrder); + $this->assertEquals(1, $m2->beforeOutputOrder); + } +} diff --git a/tests/lib/appframework/middleware/MiddlewareTest.php b/tests/lib/appframework/middleware/MiddlewareTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5e2930ac6a36a426127e164286ae1093a8006680 --- /dev/null +++ b/tests/lib/appframework/middleware/MiddlewareTest.php @@ -0,0 +1,83 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Middleware\Middleware; + + +class ChildMiddleware extends Middleware {}; + + +class MiddlewareTest extends \PHPUnit_Framework_TestCase { + + /** + * @var Middleware + */ + private $middleware; + private $controller; + private $exception; + private $api; + + protected function setUp(){ + $this->middleware = new ChildMiddleware(); + + $this->api = $this->getMock('OC\AppFramework\Core\API', + array(), array('test')); + + $this->controller = $this->getMock('OC\AppFramework\Controller\Controller', + array(), array($this->api, new Request())); + $this->exception = new \Exception(); + $this->response = $this->getMock('OCP\AppFramework\Http\Response'); + } + + + public function testBeforeController() { + $this->middleware->beforeController($this->controller, null); + $this->assertNull(null); + } + + + public function testAfterExceptionRaiseAgainWhenUnhandled() { + $this->setExpectedException('Exception'); + $afterEx = $this->middleware->afterException($this->controller, null, $this->exception); + } + + + public function testAfterControllerReturnResponseWhenUnhandled() { + $response = $this->middleware->afterController($this->controller, null, $this->response); + + $this->assertEquals($this->response, $response); + } + + + public function testBeforeOutputReturnOutputhenUnhandled() { + $output = $this->middleware->beforeOutput($this->controller, null, 'test'); + + $this->assertEquals('test', $output); + } + + +} diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3ed44282a7b0b3a625fd6ef88a2a67e90464123c --- /dev/null +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -0,0 +1,296 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Http\Http; +use OC\AppFramework\Http\Request; +use OC\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\JSONResponse; + + +class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { + + private $middleware; + private $controller; + private $secException; + private $secAjaxException; + private $request; + + public function setUp() { + $api = $this->getMock('OC\AppFramework\Core\API', array(), array('test')); + $this->controller = $this->getMock('OC\AppFramework\Controller\Controller', + array(), array($api, new Request())); + + $this->request = new Request(); + $this->middleware = new SecurityMiddleware($api, $this->request); + $this->secException = new SecurityException('hey', false); + $this->secAjaxException = new SecurityException('hey', true); + } + + + private function getAPI(){ + return $this->getMock('OC\AppFramework\Core\API', + array('isLoggedIn', 'passesCSRFCheck', 'isAdminUser', + 'isSubAdminUser', 'activateNavigationEntry', + 'getUserId'), + array('app')); + } + + + private function checkNavEntry($method, $shouldBeActivated=false){ + $api = $this->getAPI(); + + if($shouldBeActivated){ + $api->expects($this->once()) + ->method('activateNavigationEntry'); + } else { + $api->expects($this->never()) + ->method('activateNavigationEntry'); + } + + $sec = new SecurityMiddleware($api, $this->request); + $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function testSetNavigationEntry(){ + $this->checkNavEntry('testSetNavigationEntry', true); + } + + + private function ajaxExceptionStatus($method, $test, $status) { + $api = $this->getAPI(); + $api->expects($this->any()) + ->method($test) + ->will($this->returnValue(false)); + + // isAdminUser requires isLoggedIn call to return true + if ($test === 'isAdminUser') { + $api->expects($this->any()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + } + + $sec = new SecurityMiddleware($api, $this->request); + + try { + $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', + $method); + } catch (SecurityException $ex){ + $this->assertEquals($status, $ex->getCode()); + } + } + + public function testAjaxStatusLoggedInCheck() { + $this->ajaxExceptionStatus( + 'testAjaxStatusLoggedInCheck', + 'isLoggedIn', + Http::STATUS_UNAUTHORIZED + ); + } + + /** + * @NoCSRFRequired + * @NoAdminRequired + */ + public function testAjaxNotAdminCheck() { + $this->ajaxExceptionStatus( + 'testAjaxNotAdminCheck', + 'isAdminUser', + Http::STATUS_FORBIDDEN + ); + } + + /** + * @PublicPage + */ + public function testAjaxStatusCSRFCheck() { + $this->ajaxExceptionStatus( + 'testAjaxStatusCSRFCheck', + 'passesCSRFCheck', + Http::STATUS_PRECONDITION_FAILED + ); + } + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function testAjaxStatusAllGood() { + $this->ajaxExceptionStatus( + 'testAjaxStatusAllGood', + 'isLoggedIn', + 0 + ); + $this->ajaxExceptionStatus( + 'testAjaxStatusAllGood', + 'isAdminUser', + 0 + ); + $this->ajaxExceptionStatus( + 'testAjaxStatusAllGood', + 'isSubAdminUser', + 0 + ); + $this->ajaxExceptionStatus( + 'testAjaxStatusAllGood', + 'passesCSRFCheck', + 0 + ); + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function testNoChecks(){ + $api = $this->getAPI(); + $api->expects($this->never()) + ->method('passesCSRFCheck') + ->will($this->returnValue(true)); + $api->expects($this->never()) + ->method('isAdminUser') + ->will($this->returnValue(true)); + $api->expects($this->never()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + + $sec = new SecurityMiddleware($api, $this->request); + $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', + 'testNoChecks'); + } + + + private function securityCheck($method, $expects, $shouldFail=false){ + $api = $this->getAPI(); + $api->expects($this->once()) + ->method($expects) + ->will($this->returnValue(!$shouldFail)); + + // admin check requires login + if ($expects === 'isAdminUser') { + $api->expects($this->once()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + } + + $sec = new SecurityMiddleware($api, $this->request); + + if($shouldFail){ + $this->setExpectedException('\OC\AppFramework\Middleware\Security\SecurityException'); + } else { + $this->setExpectedException(null); + } + + $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); + } + + + /** + * @PublicPage + */ + public function testCsrfCheck(){ + $this->securityCheck('testCsrfCheck', 'passesCSRFCheck'); + } + + + /** + * @PublicPage + */ + public function testFailCsrfCheck(){ + $this->securityCheck('testFailCsrfCheck', 'passesCSRFCheck', true); + } + + + /** + * @NoCSRFRequired + * @NoAdminRequired + */ + public function testLoggedInCheck(){ + $this->securityCheck('testLoggedInCheck', 'isLoggedIn'); + } + + + /** + * @NoCSRFRequired + * @NoAdminRequired + */ + public function testFailLoggedInCheck(){ + $this->securityCheck('testFailLoggedInCheck', 'isLoggedIn', true); + } + + + /** + * @NoCSRFRequired + */ + public function testIsAdminCheck(){ + $this->securityCheck('testIsAdminCheck', 'isAdminUser'); + } + + + /** + * @NoCSRFRequired + */ + public function testFailIsAdminCheck(){ + $this->securityCheck('testFailIsAdminCheck', 'isAdminUser', true); + } + + + public function testAfterExceptionNotCaughtThrowsItAgain(){ + $ex = new \Exception(); + $this->setExpectedException('\Exception'); + $this->middleware->afterException($this->controller, 'test', $ex); + } + + + public function testAfterExceptionReturnsRedirect(){ + $api = $this->getMock('OC\AppFramework\Core\API', array(), array('test')); + $this->controller = $this->getMock('OC\AppFramework\Controller\Controller', + array(), array($api, new Request())); + + $this->request = new Request( + array('server' => array('HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'))); + $this->middleware = new SecurityMiddleware($api, $this->request); + $response = $this->middleware->afterException($this->controller, 'test', + $this->secException); + + $this->assertTrue($response instanceof RedirectResponse); + } + + + public function testAfterAjaxExceptionReturnsJSONError(){ + $response = $this->middleware->afterException($this->controller, 'test', + $this->secAjaxException); + + $this->assertTrue($response instanceof JSONResponse); + } + + +} diff --git a/tests/lib/appframework/routing/RoutingTest.php b/tests/lib/appframework/routing/RoutingTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a7aa922db12becd05a88115ca7608275d466f70f --- /dev/null +++ b/tests/lib/appframework/routing/RoutingTest.php @@ -0,0 +1,213 @@ +<?php + +namespace OC\AppFramework\Routing; + +use OC\AppFramework\DependencyInjection\DIContainer; +use OC\AppFramework\routing\RouteConfig; + + +class RouteConfigTest extends \PHPUnit_Framework_TestCase +{ + + public function testSimpleRoute() + { + $routes = array('routes' => array( + array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'GET') + )); + + $this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open'); + } + + public function testSimpleRouteWithMissingVerb() + { + $routes = array('routes' => array( + array('name' => 'folders#open', 'url' => '/folders/{folderId}/open') + )); + + $this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open'); + } + + public function testSimpleRouteWithLowercaseVerb() + { + $routes = array('routes' => array( + array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete') + )); + + $this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open'); + } + + /** + * @expectedException \UnexpectedValueException + */ + public function testSimpleRouteWithBrokenName() + { + $routes = array('routes' => array( + array('name' => 'folders_open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete') + )); + + // router mock + $router = $this->getMock("\OC_Router", array('create')); + + // load route configuration + $container = new DIContainer('app1'); + $config = new RouteConfig($container, $router, $routes); + + $config->register(); + } + + public function testSimpleRouteWithUnderScoreNames() + { + $routes = array('routes' => array( + array('name' => 'admin_folders#open_current', 'url' => '/folders/{folderId}/open', 'verb' => 'delete') + )); + + $this->assertSimpleRoute($routes, 'admin_folders.open_current', 'DELETE', '/folders/{folderId}/open', 'AdminFoldersController', 'openCurrent'); + } + + public function testResource() + { + $routes = array('resources' => array('accounts' => array('url' => '/accounts'))); + + $this->assertResource($routes, 'accounts', '/accounts', 'AccountsController', 'accountId'); + } + + public function testResourceWithUnderScoreName() + { + $routes = array('resources' => array('admin_accounts' => array('url' => '/admin/accounts'))); + + $this->assertResource($routes, 'admin_accounts', '/admin/accounts', 'AdminAccountsController', 'adminAccountId'); + } + + private function assertSimpleRoute($routes, $name, $verb, $url, $controllerName, $actionName) + { + // route mocks + $route = $this->mockRoute($verb, $controllerName, $actionName); + + // router mock + $router = $this->getMock("\OC_Router", array('create')); + + // we expect create to be called once: + $router + ->expects($this->once()) + ->method('create') + ->with($this->equalTo('app1.' . $name), $this->equalTo($url)) + ->will($this->returnValue($route)); + + // load route configuration + $container = new DIContainer('app1'); + $config = new RouteConfig($container, $router, $routes); + + $config->register(); + } + + private function assertResource($yaml, $resourceName, $url, $controllerName, $paramName) + { + // router mock + $router = $this->getMock("\OC_Router", array('create')); + + // route mocks + $indexRoute = $this->mockRoute('GET', $controllerName, 'index'); + $showRoute = $this->mockRoute('GET', $controllerName, 'show'); + $createRoute = $this->mockRoute('POST', $controllerName, 'create'); + $updateRoute = $this->mockRoute('PUT', $controllerName, 'update'); + $destroyRoute = $this->mockRoute('DELETE', $controllerName, 'destroy'); + + $urlWithParam = $url . '/{' . $paramName . '}'; + + // we expect create to be called once: + $router + ->expects($this->at(0)) + ->method('create') + ->with($this->equalTo('app1.' . $resourceName . '.index'), $this->equalTo($url)) + ->will($this->returnValue($indexRoute)); + + $router + ->expects($this->at(1)) + ->method('create') + ->with($this->equalTo('app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam)) + ->will($this->returnValue($showRoute)); + + $router + ->expects($this->at(2)) + ->method('create') + ->with($this->equalTo('app1.' . $resourceName . '.create'), $this->equalTo($url)) + ->will($this->returnValue($createRoute)); + + $router + ->expects($this->at(3)) + ->method('create') + ->with($this->equalTo('app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam)) + ->will($this->returnValue($updateRoute)); + + $router + ->expects($this->at(4)) + ->method('create') + ->with($this->equalTo('app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam)) + ->will($this->returnValue($destroyRoute)); + + // load route configuration + $container = new DIContainer('app1'); + $config = new RouteConfig($container, $router, $yaml); + + $config->register(); + } + + /** + * @param $verb + * @param $controllerName + * @param $actionName + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function mockRoute($verb, $controllerName, $actionName) + { + $container = new DIContainer('app1'); + $route = $this->getMock("\OC_Route", array('method', 'action'), array(), '', false); + $route + ->expects($this->exactly(1)) + ->method('method') + ->with($this->equalTo($verb)) + ->will($this->returnValue($route)); + + $route + ->expects($this->exactly(1)) + ->method('action') + ->with($this->equalTo(new RouteActionHandler($container, $controllerName, $actionName))) + ->will($this->returnValue($route)); + return $route; + } + +} + +/* +# +# sample routes.yaml for ownCloud +# +# the section simple describes one route + +routes: + - name: folders#open + url: /folders/{folderId}/open + verb: GET + # controller: name.split()[0] + # action: name.split()[1] + +# for a resource following actions will be generated: +# - index +# - create +# - show +# - update +# - destroy +# - new +resources: + accounts: + url: /accounts + + folders: + url: /accounts/{accountId}/folders + # actions can be used to define additional actions on the resource + actions: + - name: validate + verb: GET + on-collection: false + + * */ diff --git a/tests/lib/appframework/utility/MethodAnnotationReaderTest.php b/tests/lib/appframework/utility/MethodAnnotationReaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c68812aa5c76dbcb3c76ea4a1d0e50893c368c98 --- /dev/null +++ b/tests/lib/appframework/utility/MethodAnnotationReaderTest.php @@ -0,0 +1,55 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\AppFramework\Utility; + + +class MethodAnnotationReaderTest extends \PHPUnit_Framework_TestCase { + + + /** + * @Annotation + */ + public function testReadAnnotation(){ + $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest', + 'testReadAnnotation'); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + } + + + /** + * @Annotation + * @param test + */ + public function testReadAnnotationNoLowercase(){ + $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest', + 'testReadAnnotationNoLowercase'); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + $this->assertFalse($reader->hasAnnotation('param')); + } + + +} diff --git a/tests/lib/autoloader.php b/tests/lib/autoloader.php index 0e7d606ccf678b9baf752ea3cd5d001e76ad54ea..314a8ebee8d4c9ca86d101f0658d4b2555db4acb 100644 --- a/tests/lib/autoloader.php +++ b/tests/lib/autoloader.php @@ -19,15 +19,15 @@ class AutoLoader extends \PHPUnit_Framework_TestCase { } public function testLeadingSlashOnClassName() { - $this->assertEquals(array('files/storage/local.php'), $this->loader->findClass('\OC\Files\Storage\Local')); + $this->assertEquals(array('private/files/storage/local.php', 'files/storage/local.php'), $this->loader->findClass('\OC\Files\Storage\Local')); } public function testNoLeadingSlashOnClassName() { - $this->assertEquals(array('files/storage/local.php'), $this->loader->findClass('OC\Files\Storage\Local')); + $this->assertEquals(array('private/files/storage/local.php', 'files/storage/local.php'), $this->loader->findClass('OC\Files\Storage\Local')); } public function testLegacyPath() { - $this->assertEquals(array('legacy/files.php', 'files.php'), $this->loader->findClass('OC_Files')); + $this->assertEquals(array('private/legacy/files.php', 'private/files.php'), $this->loader->findClass('OC_Files')); } public function testClassPath() { @@ -54,11 +54,11 @@ class AutoLoader extends \PHPUnit_Framework_TestCase { } public function testLoadCoreNamespace() { - $this->assertEquals(array('foo/bar.php'), $this->loader->findClass('OC\Foo\Bar')); + $this->assertEquals(array('private/foo/bar.php', 'foo/bar.php'), $this->loader->findClass('OC\Foo\Bar')); } public function testLoadCore() { - $this->assertEquals(array('legacy/foo/bar.php', 'foo/bar.php'), $this->loader->findClass('OC_Foo_Bar')); + $this->assertEquals(array('private/legacy/foo/bar.php', 'private/foo/bar.php'), $this->loader->findClass('OC_Foo_Bar')); } public function testLoadPublicNamespace() { diff --git a/tests/lib/cache.php b/tests/lib/cache.php index 3dcf39f7d605df9b0c325264b25414c6f8d037e5..8fefa25f65d97f55468cd3835b33dd5031d30f3c 100644 --- a/tests/lib/cache.php +++ b/tests/lib/cache.php @@ -8,7 +8,7 @@ abstract class Test_Cache extends PHPUnit_Framework_TestCase { /** - * @var OC_Cache cache; + * @var \OC\Cache cache; */ protected $instance; diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 038cb21b2576a54ac1b76d635a3279951a0a94d5..3767c83fcb1c28d76153c0e6de733ee4705d728a 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -20,7 +20,9 @@ * */ -class Test_Cache_File extends Test_Cache { +namespace Test\Cache; + +class FileCache extends \Test_Cache { private $user; private $datadir; @@ -30,8 +32,8 @@ class Test_Cache_File extends Test_Cache { public function setUp() { //clear all proxies and hooks so we can do clean testing - OC_FileProxy::clearProxies(); - OC_Hook::clear('OC_Filesystem'); + \OC_FileProxy::clearProxies(); + \OC_Hook::clear('OC_Filesystem'); //disabled atm //enable only the encryption hook if needed @@ -44,27 +46,27 @@ class Test_Cache_File extends Test_Cache { $storage = new \OC\Files\Storage\Temporary(array()); \OC\Files\Filesystem::mount($storage,array(),'/'); $datadir = str_replace('local::', '', $storage->getId()); - $this->datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data'); - OC_Config::setValue('datadirectory', $datadir); + $this->datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data'); + \OC_Config::setValue('datadirectory', $datadir); - OC_User::clearBackends(); - OC_User::useBackend(new OC_User_Dummy()); + \OC_User::clearBackends(); + \OC_User::useBackend(new \OC_User_Dummy()); //login - OC_User::createUser('test', 'test'); + \OC_User::createUser('test', 'test'); - $this->user=OC_User::getUser(); - OC_User::setUserId('test'); + $this->user = \OC_User::getUser(); + \OC_User::setUserId('test'); //set up the users dir - $rootView=new \OC\Files\View(''); + $rootView = new \OC\Files\View(''); $rootView->mkdir('/test'); - $this->instance=new OC_Cache_File(); + $this->instance=new \OC\Cache\File(); } public function tearDown() { - OC_User::setUserId($this->user); - OC_Config::setValue('datadirectory', $this->datadir); + \OC_User::setUserId($this->user); + \OC_Config::setValue('datadirectory', $this->datadir); } } diff --git a/tests/lib/cache/usercache.php b/tests/lib/cache/usercache.php new file mode 100644 index 0000000000000000000000000000000000000000..21b7f848ab6d85f4a4ce83c6a71cf414826b423d --- /dev/null +++ b/tests/lib/cache/usercache.php @@ -0,0 +1,68 @@ +<?php +/** +* ownCloud +* +* @author Robin Appelman +* @copyright 2012 Robin Appelman icewind@owncloud.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +namespace Test\Cache; + +class UserCache extends \Test_Cache { + private $user; + private $datadir; + + public function setUp() { + //clear all proxies and hooks so we can do clean testing + \OC_FileProxy::clearProxies(); + \OC_Hook::clear('OC_Filesystem'); + + //disabled atm + //enable only the encryption hook if needed + //if(OC_App::isEnabled('files_encryption')) { + // OC_FileProxy::register(new OC_FileProxy_Encryption()); + //} + + //set up temporary storage + \OC\Files\Filesystem::clearMounts(); + $storage = new \OC\Files\Storage\Temporary(array()); + \OC\Files\Filesystem::mount($storage,array(),'/'); + $datadir = str_replace('local::', '', $storage->getId()); + $this->datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data'); + \OC_Config::setValue('datadirectory', $datadir); + + \OC_User::clearBackends(); + \OC_User::useBackend(new \OC_User_Dummy()); + + //login + \OC_User::createUser('test', 'test'); + + $this->user = \OC_User::getUser(); + \OC_User::setUserId('test'); + + //set up the users dir + $rootView=new \OC\Files\View(''); + $rootView->mkdir('/test'); + + $this->instance=new \OC\Cache\UserCache(); + } + + public function tearDown() { + \OC_User::setUserId($this->user); + \OC_Config::setValue('datadirectory', $this->datadir); + } +} diff --git a/tests/lib/tags.php b/tests/lib/tags.php new file mode 100644 index 0000000000000000000000000000000000000000..97e3734cfda6826c0a9b93bed95540ebf4ad1379 --- /dev/null +++ b/tests/lib/tags.php @@ -0,0 +1,166 @@ +<?php +/** +* ownCloud +* +* @author Thomas Tanghus +* @copyright 2012-13 Thomas Tanghus (thomas@tanghus.net) +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +class Test_Tags extends PHPUnit_Framework_TestCase { + + protected $objectType; + protected $user; + protected $backupGlobals = FALSE; + + public function setUp() { + + OC_User::clearBackends(); + OC_User::useBackend('dummy'); + $this->user = uniqid('user_'); + $this->objectType = uniqid('type_'); + OC_User::createUser($this->user, 'pass'); + OC_User::setUserId($this->user); + $this->tagMgr = new OC\TagManager($this->user); + + } + + public function tearDown() { + //$query = OC_DB::prepare('DELETE FROM `*PREFIX*vcategories` WHERE `item_type` = ?'); + //$query->execute(array('test')); + } + + public function testInstantiateWithDefaults() { + $defaultTags = array('Friends', 'Family', 'Work', 'Other'); + + $tagger = $this->tagMgr->load($this->objectType, $defaultTags); + + $this->assertEquals(4, count($tagger->getTags())); + } + + public function testAddTags() { + $tags = array('Friends', 'Family', 'Work', 'Other'); + + $tagger = $this->tagMgr->load($this->objectType); + + foreach($tags as $tag) { + $result = $tagger->add($tag); + $this->assertGreaterThan(0, $result, 'add() returned an ID <= 0'); + $this->assertTrue((bool)$result); + } + + $this->assertFalse($tagger->add('Family')); + $this->assertFalse($tagger->add('fAMILY')); + + $this->assertCount(4, $tagger->getTags(), 'Wrong number of added tags'); + } + + public function testAddMultiple() { + $tags = array('Friends', 'Family', 'Work', 'Other'); + + $tagger = $this->tagMgr->load($this->objectType); + + foreach($tags as $tag) { + $this->assertFalse($tagger->hasTag($tag)); + } + + $result = $tagger->addMultiple($tags); + $this->assertTrue((bool)$result); + + foreach($tags as $tag) { + $this->assertTrue($tagger->hasTag($tag)); + } + + $this->assertCount(4, $tagger->getTags(), 'Not all tags added'); + } + + public function testIsEmpty() { + $tagger = $this->tagMgr->load($this->objectType); + + $this->assertEquals(0, count($tagger->getTags())); + $this->assertTrue($tagger->isEmpty()); + + $result = $tagger->add('Tag'); + $this->assertGreaterThan(0, $result, 'add() returned an ID <= 0'); + $this->assertNotEquals(false, $result, 'add() returned false'); + $this->assertFalse($tagger->isEmpty()); + } + + public function testdeleteTags() { + $defaultTags = array('Friends', 'Family', 'Work', 'Other'); + $tagger = $this->tagMgr->load($this->objectType, $defaultTags); + + $this->assertEquals(4, count($tagger->getTags())); + + $tagger->delete('family'); + $this->assertEquals(3, count($tagger->getTags())); + + $tagger->delete(array('Friends', 'Work', 'Other')); + $this->assertEquals(0, count($tagger->getTags())); + + } + + public function testRenameTag() { + $defaultTags = array('Friends', 'Family', 'Wrok', 'Other'); + $tagger = $this->tagMgr->load($this->objectType, $defaultTags); + + $this->assertTrue($tagger->rename('Wrok', 'Work')); + $this->assertTrue($tagger->hasTag('Work')); + $this->assertFalse($tagger->hastag('Wrok')); + $this->assertFalse($tagger->rename('Wrok', 'Work')); + + } + + public function testTagAs() { + $objids = array(1, 2, 3, 4, 5, 6, 7, 8, 9); + + $tagger = $this->tagMgr->load($this->objectType); + + foreach($objids as $id) { + $tagger->tagAs($id, 'Family'); + } + + $this->assertEquals(1, count($tagger->getTags())); + $this->assertEquals(9, count($tagger->getIdsForTag('Family'))); + } + + /** + * @depends testTagAs + */ + public function testUnTag() { + $objIds = array(1, 2, 3, 4, 5, 6, 7, 8, 9); + + // Is this "legal"? + $this->testTagAs(); + $tagger = $this->tagMgr->load($this->objectType); + + foreach($objIds as $id) { + $this->assertTrue(in_array($id, $tagger->getIdsForTag('Family'))); + $tagger->unTag($id, 'Family'); + $this->assertFalse(in_array($id, $tagger->getIdsForTag('Family'))); + } + + $this->assertEquals(1, count($tagger->getTags())); + $this->assertEquals(0, count($tagger->getIdsForTag('Family'))); + } + + public function testFavorite() { + $tagger = $this->tagMgr->load($this->objectType); + $this->assertTrue($tagger->addToFavorites(1)); + $this->assertTrue($tagger->removeFromFavorites(1)); + } + +} diff --git a/tests/lib/vcategories.php b/tests/lib/vcategories.php deleted file mode 100644 index df5f600f20da3a479daacea277dbb8fe953498f9..0000000000000000000000000000000000000000 --- a/tests/lib/vcategories.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php -/** -* ownCloud -* -* @author Thomas Tanghus -* @copyright 2012 Thomas Tanghus (thomas@tanghus.net) -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -//require_once("../lib/template.php"); - -class Test_VCategories extends PHPUnit_Framework_TestCase { - - protected $objectType; - protected $user; - protected $backupGlobals = FALSE; - - public function setUp() { - - OC_User::clearBackends(); - OC_User::useBackend('dummy'); - $this->user = uniqid('user_'); - $this->objectType = uniqid('type_'); - OC_User::createUser($this->user, 'pass'); - OC_User::setUserId($this->user); - - } - - public function tearDown() { - //$query = OC_DB::prepare('DELETE FROM `*PREFIX*vcategories` WHERE `item_type` = ?'); - //$query->execute(array('test')); - } - - public function testInstantiateWithDefaults() { - $defcategories = array('Friends', 'Family', 'Work', 'Other'); - - $catmgr = new OC_VCategories($this->objectType, $this->user, $defcategories); - - $this->assertEquals(4, count($catmgr->categories())); - } - - public function testAddCategories() { - $categories = array('Friends', 'Family', 'Work', 'Other'); - - $catmgr = new OC_VCategories($this->objectType, $this->user); - - foreach($categories as $category) { - $result = $catmgr->add($category); - $this->assertTrue((bool)$result); - } - - $this->assertFalse($catmgr->add('Family')); - $this->assertFalse($catmgr->add('fAMILY')); - - $this->assertEquals(4, count($catmgr->categories())); - } - - public function testdeleteCategories() { - $defcategories = array('Friends', 'Family', 'Work', 'Other'); - $catmgr = new OC_VCategories($this->objectType, $this->user, $defcategories); - $this->assertEquals(4, count($catmgr->categories())); - - $catmgr->delete('family'); - $this->assertEquals(3, count($catmgr->categories())); - - $catmgr->delete(array('Friends', 'Work', 'Other')); - $this->assertEquals(0, count($catmgr->categories())); - - } - - public function testrenameCategory() { - $defcategories = array('Friends', 'Family', 'Wrok', 'Other'); - $catmgr = new OC_VCategories($this->objectType, $this->user, $defcategories); - - $this->assertTrue($catmgr->rename('Wrok', 'Work')); - $this->assertTrue($catmgr->hasCategory('Work')); - $this->assertFalse($catmgr->hasCategory('Wrok')); - $this->assertFalse($catmgr->rename('Wrok', 'Work')); - - } - - public function testAddToCategory() { - $objids = array(1, 2, 3, 4, 5, 6, 7, 8, 9); - - $catmgr = new OC_VCategories($this->objectType, $this->user); - - foreach($objids as $id) { - $catmgr->addToCategory($id, 'Family'); - } - - $this->assertEquals(1, count($catmgr->categories())); - $this->assertEquals(9, count($catmgr->idsForCategory('Family'))); - } - - /** - * @depends testAddToCategory - */ - public function testRemoveFromCategory() { - $objids = array(1, 2, 3, 4, 5, 6, 7, 8, 9); - - // Is this "legal"? - $this->testAddToCategory(); - $catmgr = new OC_VCategories($this->objectType, $this->user); - - foreach($objids as $id) { - $this->assertTrue(in_array($id, $catmgr->idsForCategory('Family'))); - $catmgr->removeFromCategory($id, 'Family'); - $this->assertFalse(in_array($id, $catmgr->idsForCategory('Family'))); - } - - $this->assertEquals(1, count($catmgr->categories())); - $this->assertEquals(0, count($catmgr->idsForCategory('Family'))); - } - -} diff --git a/version.php b/version.php new file mode 100644 index 0000000000000000000000000000000000000000..eb2e9a4a68ba0305af3a915f7e968d87bf5aa253 --- /dev/null +++ b/version.php @@ -0,0 +1,17 @@ +<?php + +// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel when updating major/minor version number. +$OC_Version=array(5, 80, 8, 0); + +// The human radable string +$OC_VersionString='6.0 pre alpha'; + +// The ownCloud edition +$OC_Edition=''; + +// The ownCloud channel +$OC_Channel=''; + +// The build number +$OC_Build=''; +