Add icons/icon upload to Oauth apps

This commit is contained in:
Zach Copley 2010-01-07 01:55:57 -08:00
parent 1e5b2a497e
commit 48e5f2b3c5
6 changed files with 193 additions and 57 deletions

View File

@ -81,7 +81,7 @@ class EditApplicationAction extends OwnerDesignAction
/** /**
* Handle the request * Handle the request
* *
* On GET, show the form. On POST, try to save the group. * On GET, show the form. On POST, try to save the app.
* *
* @param array $args unused * @param array $args unused
* *
@ -91,31 +91,49 @@ class EditApplicationAction extends OwnerDesignAction
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost($args);
} else {
$this->showForm();
}
}
// CSRF protection function handlePost($args)
$token = $this->trimmed('token'); {
if (!$token || $token != common_session_token()) { // Workaround for PHP returning empty $_POST and $_FILES when POST
$this->clientError(_('There was a problem with your session token.')); // length > post_max_size in php.ini
return;
}
$cur = common_current_user(); if (empty($_FILES)
&& empty($_POST)
if ($this->arg('cancel')) { && ($_SERVER['CONTENT_LENGTH'] > 0)
common_redirect(common_local_url('showapplication', ) {
array( $msg = _('The server was unable to handle that much POST ' .
'nickname' => $cur->nickname, 'data (%s bytes) due to its current configuration.');
'id' => $this->app->id) $this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
), 303); return;
} elseif ($this->arg('save')) {
$this->trySave();
} else {
$this->clientError(_('Unexpected form submission.'));
}
} else {
$this->showForm();
} }
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token.'));
return;
}
$cur = common_current_user();
if ($this->arg('cancel')) {
common_redirect(common_local_url('showapplication',
array(
'nickname' => $cur->nickname,
'id' => $this->app->id)
), 303);
} elseif ($this->arg('save')) {
$this->trySave();
} else {
$this->clientError(_('Unexpected form submission.'));
}
} }
function showForm($msg=null) function showForm($msg=null)
@ -149,7 +167,7 @@ class EditApplicationAction extends OwnerDesignAction
$homepage = $this->trimmed('homepage'); $homepage = $this->trimmed('homepage');
$callback_url = $this->trimmed('callback_url'); $callback_url = $this->trimmed('callback_url');
$type = $this->arg('app_type'); $type = $this->arg('app_type');
$access_type = $this->arg('access_type'); $access_type = $this->arg('default_access_type');
if (empty($name)) { if (empty($name)) {
$this->showForm(_('Name is required.')); $this->showForm(_('Name is required.'));
@ -214,6 +232,7 @@ class EditApplicationAction extends OwnerDesignAction
// Checked in prepare() above // Checked in prepare() above
assert(!is_null($cur)); assert(!is_null($cur));
assert(!is_null($this->app));
$orig = clone($this->app); $orig = clone($this->app);
@ -225,16 +244,18 @@ class EditApplicationAction extends OwnerDesignAction
$this->app->callback_url = $callback_url; $this->app->callback_url = $callback_url;
$this->app->type = $type; $this->app->type = $type;
if ($access_type == 'r') {
$this->app->setAccessFlags(true, false);
} else {
$this->app->setAccessFlags(true, true);
}
$result = $this->app->update($orig); $result = $this->app->update($orig);
common_debug("access_type = $access_type");
if ($access_type == 'r') {
$this->app->access_type = 1;
} else {
$this->app->access_type = 3;
}
if (!$result) { if (!$result) {
common_log_db_error($app, 'UPDATE', __FILE__); common_log_db_error($this->app, 'UPDATE', __FILE__);
$this->serverError(_('Could not update application.')); $this->serverError(_('Could not update application.'));
} }

View File

@ -71,7 +71,7 @@ class NewApplicationAction extends OwnerDesignAction
/** /**
* Handle the request * Handle the request
* *
* On GET, show the form. On POST, try to save the group. * On GET, show the form. On POST, try to save the app.
* *
* @param array $args unused * @param array $args unused
* *
@ -83,29 +83,46 @@ class NewApplicationAction extends OwnerDesignAction
parent::handle($args); parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost($args);
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token.'));
return;
}
$cur = common_current_user();
if ($this->arg('cancel')) {
common_redirect(common_local_url('apps',
array('nickname' => $cur->nickname)), 303);
} elseif ($this->arg('save')) {
$this->trySave();
} else {
$this->clientError(_('Unexpected form submission.'));
}
} else { } else {
$this->showForm(); $this->showForm();
} }
} }
function handlePost($args)
{
// Workaround for PHP returning empty $_POST and $_FILES when POST
// length > post_max_size in php.ini
if (empty($_FILES)
&& empty($_POST)
&& ($_SERVER['CONTENT_LENGTH'] > 0)
) {
$msg = _('The server was unable to handle that much POST ' .
'data (%s bytes) due to its current configuration.');
$this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
return;
}
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token.'));
return;
}
$cur = common_current_user();
if ($this->arg('cancel')) {
common_redirect(common_local_url('apps',
array('nickname' => $cur->nickname)), 303);
} elseif ($this->arg('save')) {
$this->trySave();
} else {
$this->clientError(_('Unexpected form submission.'));
}
}
function showForm($msg=null) function showForm($msg=null)
{ {
$this->msg = $msg; $this->msg = $msg;
@ -130,14 +147,14 @@ class NewApplicationAction extends OwnerDesignAction
function trySave() function trySave()
{ {
$name = $this->trimmed('name'); $name = $this->trimmed('name');
$description = $this->trimmed('description'); $description = $this->trimmed('description');
$source_url = $this->trimmed('source_url'); $source_url = $this->trimmed('source_url');
$organization = $this->trimmed('organization'); $organization = $this->trimmed('organization');
$homepage = $this->trimmed('homepage'); $homepage = $this->trimmed('homepage');
$callback_url = $this->trimmed('callback_url'); $callback_url = $this->trimmed('callback_url');
$type = $this->arg('app_type'); $type = $this->arg('app_type');
$access_type = $this->arg('access_type'); $access_type = $this->arg('default_access_type');
if (empty($name)) { if (empty($name)) {
$this->showForm(_('Name is required.')); $this->showForm(_('Name is required.'));
@ -241,14 +258,16 @@ class NewApplicationAction extends OwnerDesignAction
$app->consumer_key = $consumer->consumer_key; $app->consumer_key = $consumer->consumer_key;
$result = $app->insert(); $this->app_id = $app->insert();
if (!$result) { if (!$this->app_id) {
common_log_db_error($app, 'INSERT', __FILE__); common_log_db_error($app, 'INSERT', __FILE__);
$this->serverError(_('Could not create application.')); $this->serverError(_('Could not create application.'));
$app->query('ROLLBACK'); $app->query('ROLLBACK');
} }
$this->uploadLogo($app);
$app->query('COMMIT'); $app->query('COMMIT');
common_redirect(common_local_url('apps', common_redirect(common_local_url('apps',
@ -256,5 +275,40 @@ class NewApplicationAction extends OwnerDesignAction
} }
/**
* Handle an image upload
*
* Does all the magic for handling an image upload, and crops the
* image by default.
*
* @return void
*/
function uploadLogo($app)
{
if ($_FILES['app_icon']['error'] ==
UPLOAD_ERR_OK) {
try {
$imagefile = ImageFile::fromUpload('app_icon');
} catch (Exception $e) {
common_debug("damn that sucks");
$this->showForm($e->getMessage());
return;
}
$filename = Avatar::filename($app->id,
image_type_to_extension($imagefile->type),
null,
'oauth-app-icon-'.common_timestamp());
$filepath = Avatar::path($filename);
move_uploaded_file($imagefile->filepath, $filepath);
$app->setOriginal($filename);
}
}
} }

View File

@ -55,7 +55,6 @@ class ShowApplicationAction extends OwnerDesignAction
var $owner = null; var $owner = null;
var $msg = null; var $msg = null;
var $success = null; var $success = null;
@ -187,6 +186,14 @@ class ShowApplicationAction extends OwnerDesignAction
$this->elementStart('ul', 'entity_application_details'); $this->elementStart('ul', 'entity_application_details');
$this->elementStart('li', 'entity_application-icon');
if (!empty($this->application->icon)) {
$this->element('img', array('src' => $this->application->icon));
}
$this->elementEnd('li');
$this->elementStart('li', 'entity_application_name'); $this->elementStart('li', 'entity_application_name');
$this->element('span', array('class' => 'big'), $this->application->name); $this->element('span', array('class' => 'big'), $this->application->name);
$this->raw(sprintf(_(' by %1$s'), $this->application->organization)); $this->raw(sprintf(_(' by %1$s'), $this->application->organization));

View File

@ -75,4 +75,17 @@ class Oauth_application extends Memcached_DataObject
} }
} }
function setOriginal($filename)
{
$imagefile = new ImageFile($this->id, Avatar::path($filename));
// XXX: Do we want to have a bunch of different size icons? homepage, stream, mini?
// or just one and control size via CSS? --Zach
$orig = clone($this);
$this->icon = Avatar::url($filename);
common_debug(common_log_objstring($this));
return $this->update($orig);
}
} }

View File

@ -81,6 +81,21 @@ class ApplicationEditForm extends Form
} }
} }
/**
* HTTP method used to submit the form
*
* For image data we need to send multipart/form-data
* so we set that here too
*
* @return string the method to use for submitting
*/
function method()
{
$this->enctype = 'multipart/form-data';
return 'post';
}
/** /**
* class of the form * class of the form
* *
@ -134,6 +149,7 @@ class ApplicationEditForm extends Form
{ {
if ($this->application) { if ($this->application) {
$id = $this->application->id; $id = $this->application->id;
$icon = $this->application->icon;
$name = $this->application->name; $name = $this->application->name;
$description = $this->application->description; $description = $this->application->description;
$source_url = $this->application->source_url; $source_url = $this->application->source_url;
@ -144,6 +160,7 @@ class ApplicationEditForm extends Form
$this->access_type = $this->application->access_type; $this->access_type = $this->application->access_type;
} else { } else {
$id = ''; $id = '';
$icon = '';
$name = ''; $name = '';
$description = ''; $description = '';
$source_url = ''; $source_url = '';
@ -154,11 +171,31 @@ class ApplicationEditForm extends Form
$this->access_type = ''; $this->access_type = '';
} }
$this->out->hidden('token', common_session_token());
$this->out->elementStart('ul', 'form_data'); $this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li');
$this->out->elementStart('li');
if (!empty($icon)) {
$this->out->element('img', array('src' => $icon));
}
$this->out->element('label', array('for' => 'app_icon'),
_('Icon'));
$this->out->element('input', array('name' => 'app_icon',
'type' => 'file',
'id' => 'app_icon'));
$this->out->element('p', 'form_guide', _('Icon for this application'));
$this->out->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden',
'id' => 'MAX_FILE_SIZE',
'value' => ImageFile::maxFileSizeInt()));
$this->out->elementEnd('li');
$this->out->elementStart('li');
$this->out->hidden('application_id', $id); $this->out->hidden('application_id', $id);
$this->out->hidden('token', common_session_token());
$this->out->input('name', _('Name'), $this->out->input('name', _('Name'),
($this->out->arg('name')) ? $this->out->arg('name') : $name); ($this->out->arg('name')) ? $this->out->arg('name') : $name);
@ -215,7 +252,7 @@ class ApplicationEditForm extends Form
// Default to Browser // Default to Browser
if ($this->application->type == Oauth_application::$browser if ($this->application->type == Oauth_application::$browser
|| empty($this->applicaiton->type)) { || empty($this->application->type)) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';
} }

View File

@ -93,6 +93,10 @@ class ApplicationList extends Widget
$this->out->elementStart('li', array('class' => 'application', $this->out->elementStart('li', array('class' => 'application',
'id' => 'oauthclient-' . $this->application->id)); 'id' => 'oauthclient-' . $this->application->id));
if (!empty($this->application->icon)) {
$this->out->element('img', array('src' => $this->application->icon));
}
$this->out->elementStart('a', $this->out->elementStart('a',
array('href' => common_local_url( array('href' => common_local_url(
'showapplication', 'showapplication',