From a1bcc79bca798b6f10b1f5004f846a55708c548a Mon Sep 17 00:00:00 2001 From: Ian Denhardt Date: Fri, 27 May 2011 16:57:29 -0400 Subject: [PATCH] Initial work on a redo of the photo plugin. not yet functional. --- .../GNUsocialPhoto/GNUsocialPhotoPlugin.php | 162 ++++++++++++++++++ plugins/GNUsocialPhoto/Photo.php | 120 +++++++++++++ plugins/GNUsocialPhoto/newphoto.php | 130 ++++++++++++++ plugins/GNUsocialPhoto/newphotoform.php | 82 +++++++++ plugins/GNUsocialPhoto/showphoto.php | 32 ++++ 5 files changed, 526 insertions(+) create mode 100644 plugins/GNUsocialPhoto/GNUsocialPhotoPlugin.php create mode 100644 plugins/GNUsocialPhoto/Photo.php create mode 100644 plugins/GNUsocialPhoto/newphoto.php create mode 100644 plugins/GNUsocialPhoto/newphotoform.php create mode 100644 plugins/GNUsocialPhoto/showphoto.php diff --git a/plugins/GNUsocialPhoto/GNUsocialPhotoPlugin.php b/plugins/GNUsocialPhoto/GNUsocialPhotoPlugin.php new file mode 100644 index 0000000000..27a3285558 --- /dev/null +++ b/plugins/GNUsocialPhoto/GNUsocialPhotoPlugin.php @@ -0,0 +1,162 @@ +. + * + * @category Widget + * @package GNU Social + * @author Ian Denhardt + * @copyright 2011 Free Software Foundation, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +class GNUsocialPhotoPlugin extends MicroAppPlugin +{ + + function onCheckSchema() + { + $schema = Schema::get(); + + $schema->ensureTable('photo', Photo::schemaDef()); + + return true; + } + + function onAutoload($cls) + { + $dir = dirname(__FILE__); + switch($cls) + { + case 'Photo': + include_once $dir . '/Photo.php'; + break; + case 'NewPhotoForm': + include_once $dir . '/newphotoform.php'; + break; + case 'NewphotoAction': + include_once $dir . '/newphoto.php'; + break; + default: + break; + } + return true; + } + + function onRouterInitialized($m) + { + $m->connect('main/photo/new', array('action' => 'newphoto')); + $m->connect('main/photo/:id', array('action' => 'showphoto')); + return true; + } + + function entryForm($out) + { + return new NewPhotoForm($out); + } + + function appTitle() + { + return _('Photo'); + } + + function tag() + { + return 'Photo'; + } + + function types() + { + return array(Photo::OBJECT_TYPE); + } + + function saveNoticeFromActivity($activity, $actor, $options=array()) + { + + if(count($activity->objects) != 1) { + throw new Exception('Too many activity objects.'); + } + + $photoObj = $activity->objects[0]; + + if ($photoObj->type != Photo::OBJECT_TYPE) { + throw new Exception('Wrong type for object.'); + } + + $photo_uri = $photoObj->largerImage; + $thumb_uri = $photo_uri; + if(!empty($photoObj->thumbnail)){ + $thumb_uri = $photoObj->thumbnail; + } + + $description = $photoObj->description; + $title = $photoObj->title; + + $options['object_type'] = Photo::OBJECT_TYPE; + + Photo::saveNew($actor, $photo_uri, $thumb_uri, $title, $description, $options); + + } + + function activityObjectFromNotice($notice) + { + + $photo = Photo::getByNotice($notice); + + $object = new ActivityObject(); + $object->id = $notice->uri; + $object->type = Photo::OBJECT_TYPE; + $object->title = $photo->title; + $object->summary = $notice->content; + $object->link = $notice->bestUrl(); + + $object->largerImage = $photo->photo_uri; + $object->thumbnail = $photo->thumb_uri; + $object->description = $photo->description; + + return $object; + + } + + function showNotice($notice, $out) + { + $photo = Photo::getByNotice($notice); + if ($photo) { + if($photo->title){ + // TODO: ugly. feel like we should have a more abstract way + // of choosing the h-level. + $out->element('h3', array(), $title); + } + $out->element('img', array('src' => $photo->photo_uri, + 'width' => '100%')); + // TODO: add description + } + } + + function deleteRelated($notice) + { + $photo = Photo::getByNotice($notice); + if ($photo) { + $photo->delete(); + } + } +} diff --git a/plugins/GNUsocialPhoto/Photo.php b/plugins/GNUsocialPhoto/Photo.php new file mode 100644 index 0000000000..f6d932a300 --- /dev/null +++ b/plugins/GNUsocialPhoto/Photo.php @@ -0,0 +1,120 @@ +. + * + * @package GNU Social + * @author Ian Denhardt + * @copyright 2011 Free Software Foundation, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + */ + +if(!defined('STATUSNET')){ + exit(1); +} + +/** + * Data class for photos. + */ + +class Photo extends Managed_DataObject +{ + const OBJECT_TYPE = 'http://activitystrea.ms/schema/1.0/photo'; + + public $__table = 'photo'; // table name + public $id; // char (36) // UUID + public $uri; // varchar (255) // This is the corresponding notice's uri. + public $photo_uri; // varchar (255) + public $thumb_uri; // varchar (255) + public $title; // varchar (255) + public $description; // text + public $profile_id; // int + + public function staticGet($k, $v=null) + { + return Memcached_DataObject::staticGet('photo', $k, $v); + } + + public function getByNotice($notice) + { + return self::staticGet('uri', $notice->uri); + } + + public function getNotice() + { + return Notice::staticGet('uri', $this->uri); + } + + public static function schemaDef() + { + return array( + 'description' => 'A photograph', + 'fields' => array( + 'id' => array('type' => 'char', + 'length' => 36, + 'not null' => true, + 'description' => 'UUID'), + 'uri' => array('type' => 'varchar', + 'length' => 255, + 'not null' => true), + 'photo_uri' => array('type' => 'varchar', + 'length' => 255, + 'not null' => true), + 'photo_uri' => array('type' => 'varchar', + 'length' => 255, + 'not null' => true), + 'profile_id' => array('type' => 'int', 'not null' => true), + ), + 'primary key' => array('id'), + 'foreign keys' => array('photo_profile_id__key' => array('profile' => array('profile_id' => 'id'))), + ); + } + + function saveNew($profile, $photo_uri, $thumb_uri, $title, $description, $options=array()) + { + $photo = new Photo(); + + $photo->id = UUID::gen(); + $photo->profile_id = $profile->id; + $photo->photo_uri = $photo_uri; + $photo->thumb_uri = $thumb_uri; + + + $options['object_type'] = Photo::OBJECT_TYPE; + + if (!array_key_exists('uri', $options)) { + $options['uri'] = common_local_url('showphoto', array('id' => $photo->id)); + } + + if (!array_key_exists('rendered', $options)) { + $options['rendered'] = sprintf("\"%s\"", $photo_uri, + $title); + } + + $photo->uri = $options['uri']; + + $photo->insert(); + + return Notice::saveNew($profile->id, + '', + 'web', + $options); + + } +} diff --git a/plugins/GNUsocialPhoto/newphoto.php b/plugins/GNUsocialPhoto/newphoto.php new file mode 100644 index 0000000000..18ae5523a0 --- /dev/null +++ b/plugins/GNUsocialPhoto/newphoto.php @@ -0,0 +1,130 @@ +. + * + * @package GNU Social + * @author Ian Denhardt + * @copyright 2011 Free Software Foundation, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + */ + +if(!defined('STATUSNET')){ + exit(1); +} + +class NewphotoAction extends Action +{ + var $user = null; + + function prepare($args) + { + parent::prepare($args); + $this->user = common_current_user(); + + if(empty($this->user)){ + throw new ClientException(_('Must be logged in to post a photo'), + 403); + } + + if($this->isPost()){ + $this->checkSessionToken(); + } + + return true; + } + + function handle($args) + { + parent::handle($args); + + if ($this->isPost()) { + $this->handlePost($args); + } else { + $this->showPage(); + } + } + + 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->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); + return; + } */ + + $profile = $this->user->getProfile(); + + $options = array(); + + ToSelector::fillOptions($this, $options); + + try { + $this->handleUpload(); + } catch (Exception $e) { + $this->showForm($e->getMessage()); + return; + } + + + common_redirect($photo->uri, 303); + } + + function getUpload() + { + $imagefile = ImageFile::fromUpload('photo_upload'); + + if($imagefile === null) { + throw new Exception(_('No file uploaded')); + } + + $title = $this->trimmed('title'); + $description = $this->trimmed('description'); + + $new_filename = UUID::gen() . image_type_to_extension($imagefile->type); + move_uploaded_file($imagefile->filepath, INSTALLDIR . '/file/' . $new_filename); + + // XXX: we should be using https where we can. TODO: detect whether the server + // supports this. + $photo_uri = 'http://' . common_config('site', 'server') . '/file/' + . $new_filename; + $thumb_uri = $photo_uri; + + + $photo = Photo::saveNew($profile, $photo_uri, $thumb_uri, $title, + $description, $options); + + } + + function showContent() + { + $form = new NewPhotoForm(); + $form->show(); + } +} + + diff --git a/plugins/GNUsocialPhoto/newphotoform.php b/plugins/GNUsocialPhoto/newphotoform.php new file mode 100644 index 0000000000..4ef51ca097 --- /dev/null +++ b/plugins/GNUsocialPhoto/newphotoform.php @@ -0,0 +1,82 @@ +. + * + * @package GNU Social + * @author Ian Denhardt + * @copyright 2011 Free Software Foundation, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + */ + +if(!defined('STATUSNET')){ + exit(1); +} + +class NewPhotoForm extends Form +{ + function id() + { + return "form_new_photo"; + } + + function action() + { + return common_local_url('newphoto'); + } + + function formClass() + { + return 'form_settings ajax-notice'; + } + + function formData() + { + $this->out->elementStart('fieldset', array('id' => 'new_photo_data')); + $this->out->elementStart('ul', 'form_data'); + + $this->li(); + $this->out->input('title', _('Title'), null, _('Photo title (optional).')); + $this->unli(); + + $this->li(); + $this->out->element('input', array('name' => 'photo_upload', + 'type' => 'file', + 'id' => 'photo_upload')); + $this->unli(); + + $this->li(); + $this->textarea('description', _('Description'), null, _('Description of the photo (optional).')); + $this->unli(); + + $this->out->elementEnd('ul'); + + $toWidget = new ToSelector($this->out, + common_current_user(), + null); + $toWidget->show(); + + $this->out->elementEnd('fieldset'); + } + + function formActions() + { + $this->out->submit('photo-submit', _m('BUTTON', 'Save')); + } +} diff --git a/plugins/GNUsocialPhoto/showphoto.php b/plugins/GNUsocialPhoto/showphoto.php new file mode 100644 index 0000000000..b97a0565f9 --- /dev/null +++ b/plugins/GNUsocialPhoto/showphoto.php @@ -0,0 +1,32 @@ +. + * + * @package GNU Social + * @author Ian Denhardt + * @copyright 2011 Free Software Foundation, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + */ + +if(!defined('STATUSNET')){ + exit(1); +} + +