diff options
-rw-r--r-- | config/config.sample.php | 3 | ||||
-rw-r--r-- | core/avatar/controller.php | 147 | ||||
-rw-r--r-- | core/css/styles.css | 6 | ||||
-rw-r--r-- | core/js/avatar.js | 9 | ||||
-rw-r--r-- | core/js/jquery.avatar.js | 75 | ||||
-rw-r--r-- | core/routes.php | 17 | ||||
-rw-r--r-- | core/templates/layout.user.php | 5 | ||||
-rw-r--r-- | lib/avatar.php | 86 | ||||
-rw-r--r-- | lib/base.php | 8 | ||||
-rw-r--r-- | lib/installer.php | 1 | ||||
-rw-r--r-- | lib/notsquareexception.php | 12 | ||||
-rw-r--r-- | lib/public/avatar.php | 12 | ||||
-rw-r--r-- | settings/css/settings.css | 2 | ||||
-rw-r--r-- | settings/js/personal.js | 96 | ||||
-rw-r--r-- | settings/personal.php | 5 | ||||
-rw-r--r-- | settings/templates/personal.php | 15 | ||||
-rw-r--r-- | settings/templates/users.php | 6 | ||||
-rw-r--r-- | tests/data/testavatar.png | bin | 0 -> 3705 bytes | |||
-rw-r--r-- | tests/lib/avatar.php | 26 |
19 files changed, 531 insertions, 0 deletions
diff --git a/config/config.sample.php b/config/config.sample.php index 0afad880c17..29085af4716 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -212,6 +212,9 @@ $CONFIG = array( /* cl parameters for libreoffice / openoffice */ 'preview_office_cl_parameters' => '', +/* whether avatars should be enabled */ +'enable_avatars' => true, + // Extra SSL options to be used for configuration 'openssl' => array( //'config' => '/absolute/location/of/openssl.cnf', diff --git a/core/avatar/controller.php b/core/avatar/controller.php new file mode 100644 index 00000000000..5264327b641 --- /dev/null +++ b/core/avatar/controller.php @@ -0,0 +1,147 @@ +<?php +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class OC_Core_Avatar_Controller { + public static function getAvatar($args) { + if (!\OC_User::isLoggedIn()) { + $l = new \OC_L10n('core'); + header("HTTP/1.0 403 Forbidden"); + \OC_Template::printErrorPage($l->t("Permission denied")); + return; + } + + $user = stripslashes($args['user']); + $size = (int)$args['size']; + if ($size > 2048) { + $size = 2048; + } + // Undefined size + elseif ($size === 0) { + $size = 64; + } + + $avatar = new \OC_Avatar(); + $image = $avatar->get($user, $size); + + \OC_Response::disableCaching(); + \OC_Response::setLastModifiedHeader(time()); + if ($image instanceof \OC_Image) { + \OC_Response::setETagHeader(crc32($image->data())); + $image->show(); + } elseif ($image === false) { + \OC_JSON::success(array('user' => $user, 'size' => $size)); + } + } + + public static function postAvatar($args) { + $user = \OC_User::getUser(); + + if (isset($_POST['path'])) { + $path = stripslashes($_POST['path']); + $view = new \OC\Files\View('/'.$user.'/files'); + $newAvatar = $view->file_get_contents($path); + } + + if (!empty($_FILES)) { + $files = $_FILES['files']; + if ( + $files['error'][0] === 0 && + is_uploaded_file($files['tmp_name'][0]) && + !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0]) + ) { + $newAvatar = file_get_contents($files['tmp_name'][0]); + unlink($files['tmp_name'][0]); + } + } + + try { + $avatar = new \OC_Avatar(); + $avatar->set($user, $newAvatar); + \OC_JSON::success(); + } catch (\OC\NotSquareException $e) { + $image = new \OC_Image($newAvatar); + + if ($image->valid()) { + \OC_Cache::set('tmpavatar', $image->data(), 7200); + \OC_JSON::error(array("data" => array("message" => "notsquare") )); + } else { + $l = new \OC_L10n('core'); + $type = substr($image->mimeType(), -3); + if ($type === 'peg') { $type = 'jpg'; } + if ($type !== 'jpg' && $type !== 'png') { + \OC_JSON::error(array("data" => array("message" => $l->t("Unknown filetype")) )); + } + + if (!$img->valid()) { + \OC_JSON::error(array("data" => array("message" => $l->t("Invalid image")) )); + } + } + } catch (\Exception $e) { + \OC_JSON::error(array("data" => array("message" => $e->getMessage()) )); + } + } + + public static function deleteAvatar($args) { + $user = OC_User::getUser(); + + try { + $avatar = new \OC_Avatar(); + $avatar->remove($user); + \OC_JSON::success(); + } catch (\Exception $e) { + \OC_JSON::error(array("data" => array("message" => $e->getMessage()) )); + } + } + + public static function getTmpAvatar($args) { + $user = OC_User::getUser(); + + $tmpavatar = \OC_Cache::get('tmpavatar'); + if (is_null($tmpavatar)) { + $l = new \OC_L10n('core'); + \OC_JSON::error(array("data" => array("message" => $l->t("No temporary profile picture available, try again")) )); + return; + } + + $image = new \OC_Image($tmpavatar); + \OC_Response::disableCaching(); + \OC_Response::setLastModifiedHeader(time()); + \OC_Response::setETagHeader(crc32($image->data())); + $image->show(); + } + + public static function postCroppedAvatar($args) { + $user = OC_User::getUser(); + if (isset($_POST['crop'])) { + $crop = $_POST['crop']; + } else { + $l = new \OC_L10n('core'); + \OC_JSON::error(array("data" => array("message" => $l->t("No crop data provided")) )); + return; + } + + $tmpavatar = \OC_Cache::get('tmpavatar'); + if (is_null($tmpavatar)) { + $l = new \OC_L10n('core'); + \OC_JSON::error(array("data" => array("message" => $l->t("No temporary profile picture available, try again")) )); + return; + } + + $image = new \OC_Image($tmpavatar); + $image->crop($crop['x'], $crop['y'], $crop['w'], $crop['h']); + try { + $avatar = new \OC_Avatar(); + $avatar->set($user, $image->data()); + // Clean up + \OC_Cache::remove('tmpavatar'); + \OC_JSON::success(); + } catch (\Exception $e) { + \OC_JSON::error(array("data" => array("message" => $e->getMessage()) )); + } + } +} diff --git a/core/css/styles.css b/core/css/styles.css index bf78af15af5..faa458dd58e 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -40,6 +40,11 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari .header-right { float:right; vertical-align:middle; padding:0.5em; } .header-right > * { vertical-align:middle; } +header .avatardiv { + float:right; + margin-top: 6px; + margin-right: 6px; +} /* INPUTS */ input[type="text"], input[type="password"], input[type="search"], input[type="number"], input[type="email"], input[type="url"], @@ -624,6 +629,7 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } .hidden { display:none; } .bold { font-weight:bold; } .center { text-align:center; } +.inlineblock { display: inline-block; } #notification-container { position: fixed; top: 0px; width: 100%; text-align: center; z-index: 101; line-height: 1.2;} #notification, #update-notification { z-index:101; background-color:#fc4; border:0; padding:0 .7em .3em; display:none; position: relative; top:0; -moz-border-radius-bottomleft:1em; -webkit-border-bottom-left-radius:1em; border-bottom-left-radius:1em; -moz-border-radius-bottomright:1em; -webkit-border-bottom-right-radius:1em; border-bottom-right-radius:1em; } diff --git a/core/js/avatar.js b/core/js/avatar.js new file mode 100644 index 00000000000..a731519244a --- /dev/null +++ b/core/js/avatar.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + $('header .avatardiv').avatar(OC.currentUser, 32); + // Personal settings + $('#avatar .avatardiv').avatar(OC.currentUser, 128); + // User settings + $.each($('td.avatar .avatardiv'), function(i, element) { + $(element).avatar($(element).parent().parent().data('uid'), 32); + }); +}); diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js new file mode 100644 index 00000000000..dc73d8f0d91 --- /dev/null +++ b/core/js/jquery.avatar.js @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * This plugins inserts the right avatar for the user, depending on, whether + * he has a custom uploaded avatar, or not and show a placeholder with the + * first letter of the users displayname instead. + * For this it asks the core_avatar_get route, thus this plugin is fit very + * tightly fitted for owncloud. It may not work anywhere else. + * + * You may use this on any <div></div> + * Here I'm using <div class="avatardiv"></div> as an example. + * + * There are 3 ways to call this: + * + * 1. $('.avatardiv').avatar('jdoe', 128); + * This will make the div to jdoe's fitting avatar, with the size of 128px. + * + * 2. $('.avatardiv').avatar('jdoe'); + * This will make the div to jdoe's fitting avatar. If the div aready has a + * height, it will be used for the avatars size. Otherwise this plugin will + * search for 'size' DOM data, to use it for avatar size. If neither are + * available it will default to 64px. + * + * 3. $('.avatardiv').avatar(); + * This will search the DOM for 'user' data, to use as the username. If there + * is no username available it will default to a placeholder with the value of + * "x". The size will be determined the same way, as the second example did. + */ + +(function ($) { + $.fn.avatar = function(user, size) { + if (typeof(size) === 'undefined') { + if (this.height() > 0) { + size = this.height(); + } else if (this.data('size') > 0) { + size = this.data('size'); + } else { + size = 64; + } + } + + this.height(size); + this.width(size); + + if (typeof(user) === 'undefined') { + if (typeof(this.data('user')) !== 'undefined') { + user = this.data('user'); + } else { + this.placeholder('x'); + return; + } + } + + // sanitize + user = user.replace(/\//g,''); + + var $div = this; + + OC.Router.registerLoadedCallback(function() { + var url = OC.Router.generate('core_avatar_get', {user: user, size: size}); + $.get(url, function(result) { + if (typeof(result) === 'object') { + $div.placeholder(result.user); + } else { + $div.html('<img src="'+url+'">'); + } + }); + }); + }; +}(jQuery)); diff --git a/core/routes.php b/core/routes.php index f0f8ce571e2..a0d06bf807e 100644 --- a/core/routes.php +++ b/core/routes.php @@ -58,6 +58,23 @@ $this->create('core_lostpassword_reset_password', '/lostpassword/reset/{token}/{ ->post() ->action('OC_Core_LostPassword_Controller', 'resetPassword'); +// Avatar routes +$this->create('core_avatar_get_tmp', '/avatar/tmp') + ->get() + ->action('OC_Core_Avatar_Controller', 'getTmpAvatar'); +$this->create('core_avatar_get', '/avatar/{user}/{size}') + ->get() + ->action('OC_Core_Avatar_Controller', 'getAvatar'); +$this->create('core_avatar_post', '/avatar/') + ->post() + ->action('OC_Core_Avatar_Controller', 'postAvatar'); +$this->create('core_avatar_delete', '/avatar/') + ->delete() + ->action('OC_Core_Avatar_Controller', 'deleteAvatar'); +$this->create('core_avatar_post_cropped', '/avatar/cropped') + ->post() + ->action('OC_Core_Avatar_Controller', 'postCroppedAvatar'); + // Not specifically routed $this->create('app_css', '/apps/{app}/{file}') ->requirements(array('file' => '.*.css')) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 1e0f4a75c3c..3a46680c3fc 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -45,6 +45,11 @@ <a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud"><img class="svg" src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a> <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> + + <?php if (\OC_Config::getValue('enable_avatars', true) === true): ?> + <div class="avatardiv"></div> + <?php endif; ?> + <ul id="settings" class="svg"> <span id="expand" tabindex="0" role="link"> <span id="expandDisplayName"><?php p(trim($_['user_displayname']) != '' ? $_['user_displayname'] : $_['user_uid']) ?></span> diff --git a/lib/avatar.php b/lib/avatar.php new file mode 100644 index 00000000000..9b2a7fe07cf --- /dev/null +++ b/lib/avatar.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * This class gets and sets users avatars. + */ + +class OC_Avatar { + /** + * @brief get the users avatar + * @param $user string which user to get the avatar for + * @param $size integer size in px of the avatar, defaults to 64 + * @return mixed \OC_Image containing the avatar or false if there's no image + */ + public function get ($user, $size = 64) { + $view = new \OC\Files\View('/'.$user); + + if ($view->file_exists('avatar.jpg')) { + $ext = 'jpg'; + } elseif ($view->file_exists('avatar.png')) { + $ext = 'png'; + } else { + return false; + } + + $avatar = new OC_Image(); + $avatar->loadFromData($view->file_get_contents('avatar.'.$ext)); + $avatar->resize($size); + return $avatar; + } + + /** + * @brief sets the users avatar + * @param $user string user to set the avatar for + * @param $data mixed imagedata or path to set a new avatar + * @throws Exception if the provided file is not a jpg or png image + * @throws Exception if the provided image is not valid + * @throws \OC\NotSquareException if the image is not square + * @return void + */ + public function set ($user, $data) { + if (\OC_Appconfig::getValue('files_encryption', 'enabled') === "yes") { + $l = \OC_L10N::get('lib'); + throw new \Exception($l->t("Custom profile pictures don't work with encryption yet")); + } + + $view = new \OC\Files\View('/'.$user); + + $img = new OC_Image($data); + $type = substr($img->mimeType(), -3); + if ($type === 'peg') { $type = 'jpg'; } + if ($type !== 'jpg' && $type !== 'png') { + $l = \OC_L10N::get('lib'); + throw new \Exception($l->t("Unknown filetype")); + } + + if (!$img->valid()) { + $l = \OC_L10N::get('lib'); + throw new \Exception($l->t("Invalid image")); + } + + if (!($img->height() === $img->width())) { + throw new \OC\NotSquareException(); + } + + $view->unlink('avatar.jpg'); + $view->unlink('avatar.png'); + $view->file_put_contents('avatar.'.$type, $data); + } + + /** + * @brief remove the users avatar + * @param $user string user to delete the avatar from + * @return void + */ + public function remove ($user) { + $view = new \OC\Files\View('/'.$user); + $view->unlink('avatar.jpg'); + $view->unlink('avatar.png'); + } +} diff --git a/lib/base.php b/lib/base.php index b5c12a683ff..b66e58f54b4 100644 --- a/lib/base.php +++ b/lib/base.php @@ -266,6 +266,14 @@ class OC { OC_Util::addScript('router'); OC_Util::addScript("oc-requesttoken"); + // avatars + if (\OC_Config::getValue('enable_avatars', true) === true) { + \OC_Util::addScript('placeholder'); + \OC_Util::addScript('3rdparty', 'md5/md5.min'); + \OC_Util::addScript('jquery.avatar'); + \OC_Util::addScript('avatar'); + } + OC_Util::addStyle("styles"); OC_Util::addStyle("apps"); OC_Util::addStyle("fixes"); diff --git a/lib/installer.php b/lib/installer.php index b9684eaeea0..a1d2173e22c 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -426,6 +426,7 @@ class OC_Installer{ 'OC_API::', 'OC_App::', 'OC_AppConfig::', + 'OC_Avatar', 'OC_BackgroundJob::', 'OC_Config::', 'OC_DB::', diff --git a/lib/notsquareexception.php b/lib/notsquareexception.php new file mode 100644 index 00000000000..03dba8fb25f --- /dev/null +++ b/lib/notsquareexception.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +class NotSquareException extends \Exception { +} diff --git a/lib/public/avatar.php b/lib/public/avatar.php new file mode 100644 index 00000000000..6da8e83a9af --- /dev/null +++ b/lib/public/avatar.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +class Avatar extends \OC_Avatar { +} diff --git a/settings/css/settings.css b/settings/css/settings.css index d5ffe448482..7b147d5b960 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -21,6 +21,8 @@ input#openid, input#webdav { width:20em; } input#identity { width:20em; } #email { width: 17em; } +#avatar .warning { width: 350px; } + .msg.success{ color:#fff; background-color:#0f0; padding:3px; text-shadow:1px 1px #000; } .msg.error{ color:#fff; background-color:#f00; padding:3px; text-shadow:1px 1px #000; } diff --git a/settings/js/personal.js b/settings/js/personal.js index 8ad26c086b5..d9b6836568e 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -34,6 +34,7 @@ function changeDisplayName(){ $('#oldDisplayName').text($('#displayName').val()); // update displayName on the top right expand button $('#expandDisplayName').text($('#displayName').val()); + updateAvatar(); } else{ $('#newdisplayname').val(data.data.displayName); @@ -44,6 +45,76 @@ function changeDisplayName(){ } } +function selectAvatar (path) { + $.post(OC.Router.generate('core_avatar_post'), {path: path}, avatarResponseHandler); +} + +function updateAvatar () { + $('header .avatardiv').avatar(OC.currentUser, 32); + $('#avatar .avatardiv').avatar(OC.currentUser, 128); +} + +function showAvatarCropper() { + var $dlg = $('<div class="hidden" id="cropperbox" title="'+t('settings', 'Crop')+'"><img id="cropper" src="'+OC.Router.generate('core_avatar_get_tmp')+'"></div>'); + $('body').append($dlg); + + $cropperbox = $('#cropperbox'); + $cropper = $('#cropper'); + + $cropper.on('load', function() { + $cropperbox.show(); + + $cropper.Jcrop({ + onChange: saveCoords, + onSelect: saveCoords, + aspectRatio: 1, + boxHeight: 500, + boxWidth: 500, + setSelect: [0, 0, 300, 300] + }); + + $cropperbox.ocdialog({ + buttons: [{ + text: t('settings', 'Crop'), + click: sendCropData, + defaultButton: true + }], + close: function(){ + $(this).remove(); + } + }); + }); +} + +function sendCropData() { + var cropperdata = $('#cropper').data(); + var data = { + x: cropperdata.x, + y: cropperdata.y, + w: cropperdata.w, + h: cropperdata.h + }; + $('#cropperbox').remove(); + $.post(OC.Router.generate('core_avatar_post_cropped'), {crop: data}, avatarResponseHandler); +} + +function saveCoords(c) { + $('#cropper').data(c); +} + +function avatarResponseHandler(data) { + $warning = $('#avatar .warning'); + $warning.hide(); + if (data.status === "success") { + updateAvatar(); + } else if (data.data.message === "notsquare") { + showAvatarCropper(); + } else { + $warning.show(); + $warning.text(data.data.message); + } +} + $(document).ready(function(){ $("#passwordbutton").click( function(){ if ($('#pass1').val() !== '' && $('#pass2').val() !== '') { @@ -128,6 +199,31 @@ $(document).ready(function(){ } }); + var uploadparms = { + done: function(e, data) { + avatarResponseHandler(data.result); + } + }; + + $('#uploadavatarbutton').click(function(){ + $('#uploadavatar').click(); + }); + + $('#uploadavatar').fileupload(uploadparms); + + $('#selectavatar').click(function(){ + OC.dialogs.filepicker(t('settings', "Select a profile picture"), selectAvatar, false, "image"); + }); + + $('#removeavatar').click(function(){ + $.ajax({ + type: 'DELETE', + url: OC.Router.generate('core_avatar_delete'), + success: function(msg) { + updateAvatar(); + } + }); + }); } ); OC.Encryption = { diff --git a/settings/personal.php b/settings/personal.php index 112eaa3c748..88e8802663d 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -15,6 +15,11 @@ OC_Util::addScript( 'settings', 'personal' ); OC_Util::addStyle( 'settings', 'settings' ); OC_Util::addScript( '3rdparty', 'chosen/chosen.jquery.min' ); OC_Util::addStyle( '3rdparty', 'chosen' ); +\OC_Util::addScript('files', 'jquery.fileupload'); +if (\OC_Config::getValue('enable_avatars', true) === true) { + \OC_Util::addScript('3rdparty/Jcrop', 'jquery.Jcrop.min'); + \OC_Util::addStyle('3rdparty/Jcrop', 'jquery.Jcrop.min'); +} OC_App::setActiveNavigationEntry( 'personal' ); $storageInfo=OC_Helper::getStorageInfo('/'); diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 63e1258b958..fcef0f8a578 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -80,6 +80,21 @@ if($_['passwordChangeSupported']) { } ?> +<?php if (\OC_Config::getValue('enable_avatars', true) === true): ?> +<form id="avatar" method="post" action="<?php p(\OC_Helper::linkToRoute('core_avatar_post')); ?>"> + <fieldset class="personalblock"> + <legend><strong><?php p($l->t('Profile picture')); ?></strong></legend> + <div class="avatardiv"></div><br> + <div class="warning hidden"></div> + <div class="inlineblock button" id="uploadavatarbutton"><?php p($l->t('Upload new')); ?></div> + <input type="file" class="hidden" name="files[]" id="uploadavatar"> + <div class="inlineblock button" id="selectavatar"><?php p($l->t('Select new from Files')); ?></div> + <div class="inlineblock button" id="removeavatar"><?php p($l->t('Remove image')); ?></div><br> + <?php p($l->t('Either png or jpg. Ideally square but you will be able to crop it.')); ?> + </fieldset> +</form> +<?php endif; ?> + <form> <fieldset class="personalblock"> <legend><strong><?php p($l->t('Language'));?></strong></legend> diff --git a/settings/templates/users.php b/settings/templates/users.php index 22450fdf25f..445e5ce2fd5 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -81,6 +81,9 @@ $_['subadmingroups'] = array_flip($items); <table class="hascontrols" data-groups="<?php p(json_encode($allGroups));?>"> <thead> <tr> + <?php if (\OC_Config::getValue('enable_avatars', true) === true): ?> + <th id='headerAvatar'></th> + <?php endif; ?> <th id='headerName'><?php p($l->t('Username'))?></th> <th id="headerDisplayName"><?php p($l->t( 'Display Name' )); ?></th> <th id="headerPassword"><?php p($l->t( 'Password' )); ?></th> @@ -96,6 +99,9 @@ $_['subadmingroups'] = array_flip($items); <?php foreach($_["users"] as $user): ?> <tr data-uid="<?php p($user["name"]) ?>" data-displayName="<?php p($user["displayName"]) ?>"> + <?php if (\OC_Config::getValue('enable_avatars', true) === true): ?> + <td class="avatar"><div class="avatardiv"></div></td> + <?php endif; ?> <td class="name"><?php p($user["name"]); ?></td> <td class="displayName"><span><?php p($user["displayName"]); ?></span> <img class="svg action" src="<?php p(image_path('core', 'actions/rename.svg'))?>" diff --git a/tests/data/testavatar.png b/tests/data/testavatar.png Binary files differnew file mode 100644 index 00000000000..24770fb634f --- /dev/null +++ b/tests/data/testavatar.png diff --git a/tests/lib/avatar.php b/tests/lib/avatar.php new file mode 100644 index 00000000000..027e88d726d --- /dev/null +++ b/tests/lib/avatar.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Avatar extends PHPUnit_Framework_TestCase { + + public function testAvatar() { + $this->markTestSkipped("Setting custom avatars with encryption doesn't work yet"); + + $avatar = new \OC_Avatar(); + + $this->assertEquals(false, $avatar->get(\OC_User::getUser())); + + $expected = new OC_Image(\OC::$SERVERROOT.'/tests/data/testavatar.png'); + $avatar->set(\OC_User::getUser(), $expected->data()); + $expected->resize(64); + $this->assertEquals($expected->data(), $avatar->get(\OC_User::getUser())->data()); + + $avatar->remove(\OC_User::getUser()); + $this->assertEquals(false, $avatar->get(\OC_User::getUser())); + } +} |