]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Some fixups of patches not already migrated to trunk to bring inline with PEAR coding...
authorZach Copley <zach@controlyourself.ca>
Thu, 25 Dec 2008 14:46:01 +0000 (09:46 -0500)
committerZach Copley <zach@controlyourself.ca>
Thu, 25 Dec 2008 14:46:01 +0000 (09:46 -0500)
darcs-hash:20081225144601-7b5ce-4846f3d036c36037836d15ed672c10ba33f9f84c.gz

12 files changed:
_darcs/inventory
_darcs/patches/20081225144601-7b5ce-4846f3d036c36037836d15ed672c10ba33f9f84c.gz [new file with mode: 0644]
_darcs/pristine/actions/profilesettings.php
_darcs/pristine/classes/Avatar.php
_darcs/pristine/classes/Profile.php
_darcs/pristine/lib/settingsaction.php
_darcs/tentative_inventory [deleted file]
_darcs/tentative_pristine
actions/profilesettings.php
classes/Avatar.php
classes/Profile.php
lib/settingsaction.php

index da63f8216a3766f9ab9b16fe3a3b08c90fce8395..22b47336e14e8bf629be354bb532ad8cae9651c5 100644 (file)
@@ -124,4 +124,6 @@ csarven@controlyourself.ca**20081210021607]
 [Jcrop CSS updates to original/preview views
 csarven@controlyourself.ca**20081210025922] 
 [Actually crop your avatar when hitting 'crop' button on profile
-Zach Copley <zach@controlyourself.ca>**20081212043018] 
\ No newline at end of file
+Zach Copley <zach@controlyourself.ca>**20081212043018] 
+[Some fixups of patches not already migrated to trunk to bring inline with PEAR coding stds
+Zach Copley <zach@controlyourself.ca>**20081225144601] 
\ No newline at end of file
diff --git a/_darcs/patches/20081225144601-7b5ce-4846f3d036c36037836d15ed672c10ba33f9f84c.gz b/_darcs/patches/20081225144601-7b5ce-4846f3d036c36037836d15ed672c10ba33f9f84c.gz
new file mode 100644 (file)
index 0000000..6a5d9a9
Binary files /dev/null and b/_darcs/patches/20081225144601-7b5ce-4846f3d036c36037836d15ed672c10ba33f9f84c.gz differ
index caec2f93d7407c45c879f2a83be605df355a96ee..d861919b920e7f18e5ed3fe89a515faff95eb118 100644 (file)
@@ -54,13 +54,17 @@ class ProfilesettingsAction extends SettingsAction
             return;
         }
 
-               if ($this->arg('save')) {
-                       $this->save_profile();
-               } else if ($this->arg('upload')) {
-                       $this->upload_avatar();
-               } else if ($this->arg('changepass')) {
-                       $this->change_password();
-               }
+        if ($this->arg('save')) {
+            $this->save_profile();
+        } else if ($this->arg('upload')) {
+            $this->upload_avatar();
+        } else if ($this->arg('crop')) {
+            $this->crop_avatar();
+        } else if ($this->arg('changepass')) {
+            $this->change_password();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
 
     }
 
@@ -70,31 +74,30 @@ class ProfilesettingsAction extends SettingsAction
         $user = common_current_user();
         $profile = $user->getProfile();
 
-               common_element_start('form', array('method' => 'POST',
-                                                                                  'id' => 'profilesettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('profilesettings')));
-               common_hidden('token', common_session_token());
-               
-               # too much common patterns here... abstractable?
-               
-               common_input('nickname', _('Nickname'),
-                                        ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
-                                        _('1-64 lowercase letters or numbers, no punctuation or spaces'));
-               common_input('fullname', _('Full name'),
-                                        ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
-               common_input('homepage', _('Homepage'),
-                                        ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
-                                        _('URL of your homepage, blog, or profile on another site'));
-               common_textarea('bio', _('Bio'),
-                                               ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
-                                               _('Describe yourself and your interests in 140 chars'));
-               common_input('location', _('Location'),
-                                        ($this->arg('location')) ? $this->arg('location') : $profile->location,
-                                        _('Where you are, like "City, State (or Region), Country"'));
-               common_input('tags', _('Tags'),
-                                        ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
-                                        _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
+        common_element_start('form', array('method' => 'POST',
+                                           'id' => 'profilesettings',
+                                           'action' => common_local_url('profilesettings')));
+        common_hidden('token', common_session_token());
+        
+        # too much common patterns here... abstractable?
+        
+        common_input('nickname', _('Nickname'),
+                     ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
+                     _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+        common_input('fullname', _('Full name'),
+                     ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
+        common_input('homepage', _('Homepage'),
+                     ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
+                     _('URL of your homepage, blog, or profile on another site'));
+        common_textarea('bio', _('Bio'),
+                        ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
+                        _('Describe yourself and your interests in 140 chars'));
+        common_input('location', _('Location'),
+                     ($this->arg('location')) ? $this->arg('location') : $profile->location,
+                     _('Where you are, like "City, State (or Region), Country"'));
+        common_input('tags', _('Tags'),
+                     ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
+                     _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
 
         $language = common_language();
         common_dropdown('language', _('Language'), get_nice_language_list(), _('Preferred language'), true, $language);
@@ -112,7 +115,6 @@ class ProfilesettingsAction extends SettingsAction
 
         common_element_end('form');
 
-
     }
 
     function show_avatar_form()
@@ -137,24 +139,40 @@ class ProfilesettingsAction extends SettingsAction
                                            common_local_url('profilesettings')));
         common_hidden('token', common_session_token());
 
-               if ($original) {
-                       common_element('img', array('src' => $original->url,
-                                                                               'class' => 'avatar original',
-                                                                               'width' => $original->width,
-                                                                               'height' => $original->height,
-                                                                               'alt' => $user->nickname));
-               }
+        if ($original) {
+            common_element_start('div', array('id'=>'avatar_original', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Original:"));
+            common_element_start('div', array('id'=>'avatar_original_view'));
+            common_element('img', array('src' => $original->url,
+                                        'class' => 'avatar original',
+                                        'width' => $original->width,
+                                        'height' => $original->height,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+        }
 
         $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
 
-               if ($avatar) {
-                       common_element('img', array('src' => $avatar->url,
-                                                                               'class' => 'avatar profile',
-                                                                               'width' => AVATAR_PROFILE_SIZE,
-                                                                               'height' => AVATAR_PROFILE_SIZE,
-                                                                               'alt' => $user->nickname));
-               }
-
+        if ($avatar) {
+            common_element_start('div', array('id'=>'avatar_preview', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Preview:"));
+            common_element_start('div', array('id'=>'avatar_preview_view'));
+            common_element('img', array('src' => $original->url,//$avatar->url,
+                                        'class' => 'avatar profile',
+                                        'width' => AVATAR_PROFILE_SIZE,
+                                        'height' => AVATAR_PROFILE_SIZE,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+
+            foreach(array('avatar_crop_x', 'avatar_crop_y', 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
+                common_element('input', array('name' => $crop_info,
+                                              'type' => 'hidden',
+                                              'id' => $crop_info));
+            }
+            common_submit('crop', _('Crop'));
+        }
 
         common_element('input', array('name' => 'MAX_FILE_SIZE',
                                       'type' => 'hidden',
@@ -163,7 +181,6 @@ class ProfilesettingsAction extends SettingsAction
 
         common_element_start('p');
 
-
         common_element('input', array('name' => 'avatarfile',
                                       'type' => 'file',
                                       'id' => 'avatarfile'));
@@ -390,8 +407,25 @@ class ProfilesettingsAction extends SettingsAction
             $this->show_form(_('Failed updating avatar.'));
         }
 
-               @unlink($_FILES['avatarfile']['tmp_name']);
-       }
+        @unlink($_FILES['avatarfile']['tmp_name']);
+    }
+
+    function crop_avatar() {
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        $x = $this->arg('avatar_crop_x');
+        $y = $this->arg('avatar_crop_y');
+        $w = $this->arg('avatar_crop_w');
+        $h = $this->arg('avatar_crop_h');
+
+        if ($profile->crop_avatars($x, $y, $w, $h)) {
+            $this->show_form(_('Avatar updated.'), true);
+        } else {
+            $this->show_form(_('Failed updating avatar.'));
+        }
+    }
 
     function nickname_exists($nickname)
     {
index 4fdb99d35e7e306a2c37ff3207c1760e9f66bee9..9ae920647adfbae0c7ce6e767eca7fa7ec243c91 100644 (file)
@@ -79,20 +79,63 @@ class Avatar extends Memcached_DataObject
         }
     }
 
-       function to_image() {
-               $filepath = common_avatar_path($this->filename);
-               if ($this->mediatype == 'image/gif') {
-                       return imagecreatefromgif($filepath);
-               } else if ($this->mediatype == 'image/jpeg') {
-                       return imagecreatefromjpeg($filepath);
-               } else if ($this->mediatype == 'image/png') {
-                       return imagecreatefrompng($filepath);
-               } else {
-                       return NULL;
-               }
-       }
-       
-       function &pkeyGet($kv) {
-               return Memcached_DataObject::pkeyGet('Avatar', $kv);
-       }
+    function scale_and_crop($size, $x, $y, $w, $h) 
+    {
+
+        $image_s = imagecreatetruecolor($size, $size);
+        $image_a = $this->to_image();
+
+        # Retain alpha channel info if possible for .pngs
+        $background = imagecolorallocate($image_s, 0, 0, 0);
+        ImageColorTransparent($image_s, $background);
+        imagealphablending($image_s, false);
+
+        imagecopyresized($image_s, $image_a, 0, 0, $x, $y, $size, $size, $w, $h);
+
+        $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
+
+        $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
+
+        if ($this->mediatype == 'image/jpeg') {
+            imagejpeg($image_s, common_avatar_path($filename));
+        } else {
+            imagepng($image_s, common_avatar_path($filename));
+        }
+
+        $cropped = DB_DataObject::factory('avatar');
+        $cropped->profile_id = $this->profile_id;
+        $cropped->width = $size;
+        $cropped->height = $size;
+        $cropped->original = false;
+        $cropped->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
+        $cropped->filename = $filename;
+        $cropped->url = common_avatar_url($filename);
+        $cropped->created = DB_DataObject_Cast::dateTime(); # current time
+
+        if ($cropped->insert()) {
+            return $cropped;
+        } else {
+            return NULL;
+        }
+    }
+
+    function to_image() 
+    {
+        $filepath = common_avatar_path($this->filename);
+        if ($this->mediatype == 'image/gif') {
+            return imagecreatefromgif($filepath);
+        } else if ($this->mediatype == 'image/jpeg') {
+            return imagecreatefromjpeg($filepath);
+        } else if ($this->mediatype == 'image/png') {
+            return imagecreatefrompng($filepath);
+        } else {
+            return NULL;
+        }
+    }
+    
+    function &pkeyGet($kv) 
+    {
+        return Memcached_DataObject::pkeyGet('Avatar', $kv);
+    }
+
 }
index 3b6ac1d7f2438422dc39818855963510bf882775..31bdf71d59b9923abacbab890e692b8864f442bf 100644 (file)
@@ -121,15 +121,39 @@ class Profile extends Memcached_DataObject
         return $avatar;
     }
 
-       function delete_avatars() {
-               $avatar = new Avatar();
-               $avatar->profile_id = $this->id;
-               $avatar->find();
-               while ($avatar->fetch()) {
-                       $avatar->delete();
-               }
-               return true;
-       }
+    function crop_avatars($x, $y, $w, $h) 
+    {
+
+        $avatar = $this->getOriginalAvatar();
+        $this->delete_avatars(false); # don't delete original
+
+        foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
+            # We don't do a scaled one if original is our scaled size
+            if (!($avatar->width == $size && $avatar->height == $size)) {
+                $s = $avatar->scale_and_crop($size, $x, $y, $w, $h);
+                if (!$s) {
+                    return NULL;
+                }
+            }
+        }
+        return true;
+    }
+
+    function delete_avatars($original=true) 
+    {
+        $avatar = new Avatar();
+        $avatar->profile_id = $this->id;
+        $avatar->find();
+        while ($avatar->fetch()) {
+            if ($avatar->original) {
+                if ($original == false) {
+                    continue;
+                }
+            }
+            $avatar->delete();
+        }
+        return true;
+    }
 
     function getBestName()
     {
index 62de39d4593875fe763a42c8d5f0c26f2e57b500..03bac3a93b0173f9ffcf1a6dc5fbc78162bd809a 100644 (file)
@@ -60,12 +60,25 @@ class SettingsAction extends Action
         }
     }
 
-       function form_header($title, $msg=NULL, $success=false) {
-               common_show_header($title,
-                                  NULL,
-                                  array($msg, $success),
-                                                  array($this, 'show_top'));
-       }
+    function form_header($title, $msg=NULL, $success=false) 
+    {
+        common_show_header($title,
+                           array($this, 'show_header'),
+                           array($msg, $success),
+                           array($this, 'show_top'));
+    }
+
+    function show_header() 
+    {
+        common_element('link', array('rel' => 'stylesheet',
+                                     'type' => 'text/css',
+                                     'href' => common_path('js/jcrop/jquery.Jcrop.css?version='.LACONICA_VERSION),
+                                     'media' => 'screen, projection, tv'));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.pack.js')));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.go.js')));
+    }
 
     function show_top($arr)
     {
diff --git a/_darcs/tentative_inventory b/_darcs/tentative_inventory
deleted file mode 100644 (file)
index da63f82..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-Starting with tag:
-[TAG 0.6.4.1
-Evan Prodromou <evan@controlezvous.ca>**20081220204906] 
-[identica badge by Kent Brewster. For more information see:
-Sarven Capadisli <csarven@controlyourself.ca>**20081218003302
- http://kentbrewster.com/identica-badge/
- Copy and paste the following wherever you want the badge to show up:
- <script type="text/javascript" src="http://identi.ca/js/identica-badge.js">
- {
-    "user":"kentbrew",
-    "server":"identi.ca",
-    "headerText":" and friends"
- }
- </script>
-        
- Substitute your own ID in the user parameter.
-] 
-[more information in subscription notices
-Evan Prodromou <evan@prodromou.name>**20081212171135] 
-[first step of phpcs-cleanup of index.php
-Evan Prodromou <evan@prodromou.name>**20081221002332] 
-[reformatting for phpcs in lib/util.php
-Evan Prodromou <evan@prodromou.name>**20081221003016] 
-[some modifications to assuage phpcs
-Evan Prodromou <evan@prodromou.name>**20081221003955] 
-[reformat lib/daemon.php for phpcs
-Evan Prodromou <evan@prodromou.name>**20081221004607] 
-[reformat for phpcs
-Evan Prodromou <evan@prodromou.name>**20081221005837] 
-[reformat lib/jabber.php for phpcs, including doc comments
-Evan Prodromou <evan@prodromou.name>**20081222173249] 
-[reformat lib/language.php for PEAR Coding Standards
-Evan Prodromou <evan@prodromou.name>**20081222193029] 
-[bring mailbox.php into line with PEAR Coding Standards (mostly)
-Evan Prodromou <evan@prodromou.name>**20081222195041] 
-[bring messaging section (inbox, outbox, mailbox) into PEAR Code Standards compliance
-Evan Prodromou <evan@prodromou.name>**20081222201304
- Actually refactored the method names on these classes to come into
- complete compliance with the code standards. Untested; maybe there are
- some bad method names now.
-] 
-[reformat and document lib/mail.php for phpcs conformance
-Evan Prodromou <evan@prodromou.name>**20081223173330] 
-[bring lib/noticelist.php into line with PEAR code standards
-Evan Prodromou <evan@prodromou.name>**20081223190851] 
-[incorrect label on notice list file comment
-Evan Prodromou <evan@prodromou.name>**20081223191430] 
-[replace all tabs with four spaces
-Evan Prodromou <evan@prodromou.name>**20081223191907
- The PEAR coding standards decree: no tabs, but indent by four spaces.
- I've done a global search-and-replace on all tabs, replacing them by
- four spaces. This is a huge change, but it will go a long way to
- getting us towards phpcs-compliance. And that means better code
- readability, and that means more participation.
-] 
-[replace NULL with null
-Evan Prodromou <evan@prodromou.name>**20081223192129
- Another global search-and-replace update. Here, I've replaced the PHP
- keyword 'NULL' with its lowercase version. This is another PEAR code
- standards change.
-] 
-[change function headers to K&R style
-Evan Prodromou <evan@prodromou.name>**20081223193323
- Another huge change, for PEAR code standards compliance. Function
- headers have to be in K&R style (opening brace on its own line),
- instead of having the opening brace on the same line as the function
- and parameters. So, a little perl magic found all the function
- definitions and move the opening brace to the next line (properly
- indented... usually).
-] 
-[TRUE => true, FALSE => false
-Evan Prodromou <evan@prodromou.name>**20081223194428
- More PEAR coding standards global changes. Here, I've changed all
- instances of TRUE to true and FALSE to false.
-] 
-[move opening brace of class declaration to next line
-Evan Prodromou <evan@prodromou.name>**20081223194923
- Another gigantor PEAR coding standards patch. Here, I've moved the
- opening curly bracket on a class statement to the following line.
-] 
-[Twitter-bridge: fix for Twitter's new strict policy of rejecting HTTP POSTs with invalid "expect" headers
-Zach Copley <zach@controlyourself.ca>**20081225152207] 
-[whitespace changes in actions/register.php after global search-and-replace
-Evan Prodromou <evan@prodromou.name>**20081223195722] 
-[Laconica-specific extensions for Twitter API
-Evan Prodromou <evan@prodromou.name>**20081230202019] 
-[add laconica-specific methods to htaccess.sample
-Evan Prodromou <evan@prodromou.name>**20081230202513] 
-[add laconica methods to unauthed ones
-Evan Prodromou <evan@prodromou.name>**20081230203747] 
-[implement api/laconica/version method
-Evan Prodromou <evan@prodromou.name>**20081230205939] 
-[add some breaks so that switch statement works
-Evan Prodromou <evan@prodromou.name>**20081230210114] 
-[implement the api/laconica/config method
-Evan Prodromou <evan@prodromou.name>**20081230211444] 
-[better serialization of arrays and booleans in config output
-Evan Prodromou <evan@prodromou.name>**20081230211957] 
-[wrapper element for config.xml
-Evan Prodromou <evan@prodromou.name>**20081230212202] 
-[trac750 Automatically update linked Facebook users' statuses
-Zach Copley <zach@controlyourself.ca>**20090105010407] 
-[trac750 configurable sync flags for Facebook app (noticesync, replysync)
-Zach Copley <zach@controlyourself.ca>**20090105040212] 
-[trac750 added some output to the facebook_update.php script
-Zach Copley <zach@controlyourself.ca>**20090105045603] 
-[Jcrop v2 (POST cropping to be completed)
-csarven@controlyourself.ca**20081210021607] 
-[Jcrop CSS updates to original/preview views
-csarven@controlyourself.ca**20081210025922] 
-[Actually crop your avatar when hitting 'crop' button on profile
-Zach Copley <zach@controlyourself.ca>**20081212043018] 
\ No newline at end of file
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..04a3f84cd79ac8a54c72b0bb941f305cf75d9e06 100644 (file)
@@ -0,0 +1,287 @@
+hunk ./actions/profilesettings.php 57
+-              if ($this->arg('save')) {
+-                      $this->save_profile();
+-              } else if ($this->arg('upload')) {
+-                      $this->upload_avatar();
+-              } else if ($this->arg('changepass')) {
+-                      $this->change_password();
+-              }
++        if ($this->arg('save')) {
++            $this->save_profile();
++        } else if ($this->arg('upload')) {
++            $this->upload_avatar();
++        } else if ($this->arg('crop')) {
++            $this->crop_avatar();
++        } else if ($this->arg('changepass')) {
++            $this->change_password();
++        } else {
++            $this->show_form(_('Unexpected form submission.'));
++        }
+hunk ./actions/profilesettings.php 77
+-              common_element_start('form', array('method' => 'POST',
+-                                                                                 'id' => 'profilesettings',
+-                                                                                 'action' =>
+-                                                                                 common_local_url('profilesettings')));
+-              common_hidden('token', common_session_token());
+-              
+-              # too much common patterns here... abstractable?
+-              
+-              common_input('nickname', _('Nickname'),
+-                                       ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
+-                                       _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+-              common_input('fullname', _('Full name'),
+-                                       ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
+-              common_input('homepage', _('Homepage'),
+-                                       ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
+-                                       _('URL of your homepage, blog, or profile on another site'));
+-              common_textarea('bio', _('Bio'),
+-                                              ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
+-                                              _('Describe yourself and your interests in 140 chars'));
+-              common_input('location', _('Location'),
+-                                       ($this->arg('location')) ? $this->arg('location') : $profile->location,
+-                                       _('Where you are, like "City, State (or Region), Country"'));
+-              common_input('tags', _('Tags'),
+-                                       ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
+-                                       _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
++        common_element_start('form', array('method' => 'POST',
++                                           'id' => 'profilesettings',
++                                           'action' => common_local_url('profilesettings')));
++        common_hidden('token', common_session_token());
++        
++        # too much common patterns here... abstractable?
++        
++        common_input('nickname', _('Nickname'),
++                     ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
++                     _('1-64 lowercase letters or numbers, no punctuation or spaces'));
++        common_input('fullname', _('Full name'),
++                     ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
++        common_input('homepage', _('Homepage'),
++                     ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
++                     _('URL of your homepage, blog, or profile on another site'));
++        common_textarea('bio', _('Bio'),
++                        ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
++                        _('Describe yourself and your interests in 140 chars'));
++        common_input('location', _('Location'),
++                     ($this->arg('location')) ? $this->arg('location') : $profile->location,
++                     _('Where you are, like "City, State (or Region), Country"'));
++        common_input('tags', _('Tags'),
++                     ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
++                     _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
+hunk ./actions/profilesettings.php 118
+-
+hunk ./actions/profilesettings.php 142
+-              if ($original) {
+-                      common_element('img', array('src' => $original->url,
+-                                                                              'class' => 'avatar original',
+-                                                                              'width' => $original->width,
+-                                                                              'height' => $original->height,
+-                                                                              'alt' => $user->nickname));
+-              }
++        if ($original) {
++            common_element_start('div', array('id'=>'avatar_original', 'class'=>'avatar_view'));
++            common_element('h3', null, _("Original:"));
++            common_element_start('div', array('id'=>'avatar_original_view'));
++            common_element('img', array('src' => $original->url,
++                                        'class' => 'avatar original',
++                                        'width' => $original->width,
++                                        'height' => $original->height,
++                                        'alt' => $user->nickname));
++            common_element_end('div');
++            common_element_end('div');
++        }
+hunk ./actions/profilesettings.php 157
+-              if ($avatar) {
+-                      common_element('img', array('src' => $avatar->url,
+-                                                                              'class' => 'avatar profile',
+-                                                                              'width' => AVATAR_PROFILE_SIZE,
+-                                                                              'height' => AVATAR_PROFILE_SIZE,
+-                                                                              'alt' => $user->nickname));
+-              }
++        if ($avatar) {
++            common_element_start('div', array('id'=>'avatar_preview', 'class'=>'avatar_view'));
++            common_element('h3', null, _("Preview:"));
++            common_element_start('div', array('id'=>'avatar_preview_view'));
++            common_element('img', array('src' => $original->url,//$avatar->url,
++                                        'class' => 'avatar profile',
++                                        'width' => AVATAR_PROFILE_SIZE,
++                                        'height' => AVATAR_PROFILE_SIZE,
++                                        'alt' => $user->nickname));
++            common_element_end('div');
++            common_element_end('div');
+hunk ./actions/profilesettings.php 169
++            foreach(array('avatar_crop_x', 'avatar_crop_y', 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
++                common_element('input', array('name' => $crop_info,
++                                              'type' => 'hidden',
++                                              'id' => $crop_info));
++            }
++            common_submit('crop', _('Crop'));
++        }
+hunk ./actions/profilesettings.php 184
+-
+hunk ./actions/profilesettings.php 410
+-              @unlink($_FILES['avatarfile']['tmp_name']);
+-      }
++        @unlink($_FILES['avatarfile']['tmp_name']);
++    }
++
++    function crop_avatar() {
++
++        $user = common_current_user();
++        $profile = $user->getProfile();
++
++        $x = $this->arg('avatar_crop_x');
++        $y = $this->arg('avatar_crop_y');
++        $w = $this->arg('avatar_crop_w');
++        $h = $this->arg('avatar_crop_h');
++
++        if ($profile->crop_avatars($x, $y, $w, $h)) {
++            $this->show_form(_('Avatar updated.'), true);
++        } else {
++            $this->show_form(_('Failed updating avatar.'));
++        }
++    }
+hunk ./classes/Avatar.php 82
+-      function to_image() {
+-              $filepath = common_avatar_path($this->filename);
+-              if ($this->mediatype == 'image/gif') {
+-                      return imagecreatefromgif($filepath);
+-              } else if ($this->mediatype == 'image/jpeg') {
+-                      return imagecreatefromjpeg($filepath);
+-              } else if ($this->mediatype == 'image/png') {
+-                      return imagecreatefrompng($filepath);
+-              } else {
+-                      return NULL;
+-              }
+-      }
+-      
+-      function &pkeyGet($kv) {
+-              return Memcached_DataObject::pkeyGet('Avatar', $kv);
+-      }
++    function scale_and_crop($size, $x, $y, $w, $h) 
++    {
++
++        $image_s = imagecreatetruecolor($size, $size);
++        $image_a = $this->to_image();
++
++        # Retain alpha channel info if possible for .pngs
++        $background = imagecolorallocate($image_s, 0, 0, 0);
++        ImageColorTransparent($image_s, $background);
++        imagealphablending($image_s, false);
++
++        imagecopyresized($image_s, $image_a, 0, 0, $x, $y, $size, $size, $w, $h);
++
++        $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
++
++        $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
++
++        if ($this->mediatype == 'image/jpeg') {
++            imagejpeg($image_s, common_avatar_path($filename));
++        } else {
++            imagepng($image_s, common_avatar_path($filename));
++        }
++
++        $cropped = DB_DataObject::factory('avatar');
++        $cropped->profile_id = $this->profile_id;
++        $cropped->width = $size;
++        $cropped->height = $size;
++        $cropped->original = false;
++        $cropped->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
++        $cropped->filename = $filename;
++        $cropped->url = common_avatar_url($filename);
++        $cropped->created = DB_DataObject_Cast::dateTime(); # current time
++
++        if ($cropped->insert()) {
++            return $cropped;
++        } else {
++            return NULL;
++        }
++    }
++
++    function to_image() 
++    {
++        $filepath = common_avatar_path($this->filename);
++        if ($this->mediatype == 'image/gif') {
++            return imagecreatefromgif($filepath);
++        } else if ($this->mediatype == 'image/jpeg') {
++            return imagecreatefromjpeg($filepath);
++        } else if ($this->mediatype == 'image/png') {
++            return imagecreatefrompng($filepath);
++        } else {
++            return NULL;
++        }
++    }
++    
++    function &pkeyGet($kv) 
++    {
++        return Memcached_DataObject::pkeyGet('Avatar', $kv);
++    }
++
+hunk ./classes/Profile.php 124
+-      function delete_avatars() {
+-              $avatar = new Avatar();
+-              $avatar->profile_id = $this->id;
+-              $avatar->find();
+-              while ($avatar->fetch()) {
+-                      $avatar->delete();
+-              }
+-              return true;
+-      }
++    function crop_avatars($x, $y, $w, $h) 
++    {
++
++        $avatar = $this->getOriginalAvatar();
++        $this->delete_avatars(false); # don't delete original
++
++        foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
++            # We don't do a scaled one if original is our scaled size
++            if (!($avatar->width == $size && $avatar->height == $size)) {
++                $s = $avatar->scale_and_crop($size, $x, $y, $w, $h);
++                if (!$s) {
++                    return NULL;
++                }
++            }
++        }
++        return true;
++    }
++
++    function delete_avatars($original=true) 
++    {
++        $avatar = new Avatar();
++        $avatar->profile_id = $this->id;
++        $avatar->find();
++        while ($avatar->fetch()) {
++            if ($avatar->original) {
++                if ($original == false) {
++                    continue;
++                }
++            }
++            $avatar->delete();
++        }
++        return true;
++    }
+hunk ./lib/settingsaction.php 63
+-      function form_header($title, $msg=NULL, $success=false) {
+-              common_show_header($title,
+-                                 NULL,
+-                                 array($msg, $success),
+-                                                 array($this, 'show_top'));
+-      }
++    function form_header($title, $msg=NULL, $success=false) 
++    {
++        common_show_header($title,
++                           array($this, 'show_header'),
++                           array($msg, $success),
++                           array($this, 'show_top'));
++    }
++
++    function show_header() 
++    {
++        common_element('link', array('rel' => 'stylesheet',
++                                     'type' => 'text/css',
++                                     'href' => common_path('js/jcrop/jquery.Jcrop.css?version='.LACONICA_VERSION),
++                                     'media' => 'screen, projection, tv'));
++        common_element('script', array('type' => 'text/javascript',
++                                       'src' => common_path('js/jcrop/jquery.Jcrop.pack.js')));
++        common_element('script', array('type' => 'text/javascript',
++                                       'src' => common_path('js/jcrop/jquery.Jcrop.go.js')));
++    }
index caec2f93d7407c45c879f2a83be605df355a96ee..d861919b920e7f18e5ed3fe89a515faff95eb118 100644 (file)
@@ -54,13 +54,17 @@ class ProfilesettingsAction extends SettingsAction
             return;
         }
 
-               if ($this->arg('save')) {
-                       $this->save_profile();
-               } else if ($this->arg('upload')) {
-                       $this->upload_avatar();
-               } else if ($this->arg('changepass')) {
-                       $this->change_password();
-               }
+        if ($this->arg('save')) {
+            $this->save_profile();
+        } else if ($this->arg('upload')) {
+            $this->upload_avatar();
+        } else if ($this->arg('crop')) {
+            $this->crop_avatar();
+        } else if ($this->arg('changepass')) {
+            $this->change_password();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
 
     }
 
@@ -70,31 +74,30 @@ class ProfilesettingsAction extends SettingsAction
         $user = common_current_user();
         $profile = $user->getProfile();
 
-               common_element_start('form', array('method' => 'POST',
-                                                                                  'id' => 'profilesettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('profilesettings')));
-               common_hidden('token', common_session_token());
-               
-               # too much common patterns here... abstractable?
-               
-               common_input('nickname', _('Nickname'),
-                                        ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
-                                        _('1-64 lowercase letters or numbers, no punctuation or spaces'));
-               common_input('fullname', _('Full name'),
-                                        ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
-               common_input('homepage', _('Homepage'),
-                                        ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
-                                        _('URL of your homepage, blog, or profile on another site'));
-               common_textarea('bio', _('Bio'),
-                                               ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
-                                               _('Describe yourself and your interests in 140 chars'));
-               common_input('location', _('Location'),
-                                        ($this->arg('location')) ? $this->arg('location') : $profile->location,
-                                        _('Where you are, like "City, State (or Region), Country"'));
-               common_input('tags', _('Tags'),
-                                        ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
-                                        _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
+        common_element_start('form', array('method' => 'POST',
+                                           'id' => 'profilesettings',
+                                           'action' => common_local_url('profilesettings')));
+        common_hidden('token', common_session_token());
+        
+        # too much common patterns here... abstractable?
+        
+        common_input('nickname', _('Nickname'),
+                     ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
+                     _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+        common_input('fullname', _('Full name'),
+                     ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
+        common_input('homepage', _('Homepage'),
+                     ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
+                     _('URL of your homepage, blog, or profile on another site'));
+        common_textarea('bio', _('Bio'),
+                        ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
+                        _('Describe yourself and your interests in 140 chars'));
+        common_input('location', _('Location'),
+                     ($this->arg('location')) ? $this->arg('location') : $profile->location,
+                     _('Where you are, like "City, State (or Region), Country"'));
+        common_input('tags', _('Tags'),
+                     ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
+                     _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
 
         $language = common_language();
         common_dropdown('language', _('Language'), get_nice_language_list(), _('Preferred language'), true, $language);
@@ -112,7 +115,6 @@ class ProfilesettingsAction extends SettingsAction
 
         common_element_end('form');
 
-
     }
 
     function show_avatar_form()
@@ -137,24 +139,40 @@ class ProfilesettingsAction extends SettingsAction
                                            common_local_url('profilesettings')));
         common_hidden('token', common_session_token());
 
-               if ($original) {
-                       common_element('img', array('src' => $original->url,
-                                                                               'class' => 'avatar original',
-                                                                               'width' => $original->width,
-                                                                               'height' => $original->height,
-                                                                               'alt' => $user->nickname));
-               }
+        if ($original) {
+            common_element_start('div', array('id'=>'avatar_original', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Original:"));
+            common_element_start('div', array('id'=>'avatar_original_view'));
+            common_element('img', array('src' => $original->url,
+                                        'class' => 'avatar original',
+                                        'width' => $original->width,
+                                        'height' => $original->height,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+        }
 
         $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
 
-               if ($avatar) {
-                       common_element('img', array('src' => $avatar->url,
-                                                                               'class' => 'avatar profile',
-                                                                               'width' => AVATAR_PROFILE_SIZE,
-                                                                               'height' => AVATAR_PROFILE_SIZE,
-                                                                               'alt' => $user->nickname));
-               }
-
+        if ($avatar) {
+            common_element_start('div', array('id'=>'avatar_preview', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Preview:"));
+            common_element_start('div', array('id'=>'avatar_preview_view'));
+            common_element('img', array('src' => $original->url,//$avatar->url,
+                                        'class' => 'avatar profile',
+                                        'width' => AVATAR_PROFILE_SIZE,
+                                        'height' => AVATAR_PROFILE_SIZE,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+
+            foreach(array('avatar_crop_x', 'avatar_crop_y', 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
+                common_element('input', array('name' => $crop_info,
+                                              'type' => 'hidden',
+                                              'id' => $crop_info));
+            }
+            common_submit('crop', _('Crop'));
+        }
 
         common_element('input', array('name' => 'MAX_FILE_SIZE',
                                       'type' => 'hidden',
@@ -163,7 +181,6 @@ class ProfilesettingsAction extends SettingsAction
 
         common_element_start('p');
 
-
         common_element('input', array('name' => 'avatarfile',
                                       'type' => 'file',
                                       'id' => 'avatarfile'));
@@ -390,8 +407,25 @@ class ProfilesettingsAction extends SettingsAction
             $this->show_form(_('Failed updating avatar.'));
         }
 
-               @unlink($_FILES['avatarfile']['tmp_name']);
-       }
+        @unlink($_FILES['avatarfile']['tmp_name']);
+    }
+
+    function crop_avatar() {
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        $x = $this->arg('avatar_crop_x');
+        $y = $this->arg('avatar_crop_y');
+        $w = $this->arg('avatar_crop_w');
+        $h = $this->arg('avatar_crop_h');
+
+        if ($profile->crop_avatars($x, $y, $w, $h)) {
+            $this->show_form(_('Avatar updated.'), true);
+        } else {
+            $this->show_form(_('Failed updating avatar.'));
+        }
+    }
 
     function nickname_exists($nickname)
     {
index 4fdb99d35e7e306a2c37ff3207c1760e9f66bee9..9ae920647adfbae0c7ce6e767eca7fa7ec243c91 100644 (file)
@@ -79,20 +79,63 @@ class Avatar extends Memcached_DataObject
         }
     }
 
-       function to_image() {
-               $filepath = common_avatar_path($this->filename);
-               if ($this->mediatype == 'image/gif') {
-                       return imagecreatefromgif($filepath);
-               } else if ($this->mediatype == 'image/jpeg') {
-                       return imagecreatefromjpeg($filepath);
-               } else if ($this->mediatype == 'image/png') {
-                       return imagecreatefrompng($filepath);
-               } else {
-                       return NULL;
-               }
-       }
-       
-       function &pkeyGet($kv) {
-               return Memcached_DataObject::pkeyGet('Avatar', $kv);
-       }
+    function scale_and_crop($size, $x, $y, $w, $h) 
+    {
+
+        $image_s = imagecreatetruecolor($size, $size);
+        $image_a = $this->to_image();
+
+        # Retain alpha channel info if possible for .pngs
+        $background = imagecolorallocate($image_s, 0, 0, 0);
+        ImageColorTransparent($image_s, $background);
+        imagealphablending($image_s, false);
+
+        imagecopyresized($image_s, $image_a, 0, 0, $x, $y, $size, $size, $w, $h);
+
+        $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
+
+        $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
+
+        if ($this->mediatype == 'image/jpeg') {
+            imagejpeg($image_s, common_avatar_path($filename));
+        } else {
+            imagepng($image_s, common_avatar_path($filename));
+        }
+
+        $cropped = DB_DataObject::factory('avatar');
+        $cropped->profile_id = $this->profile_id;
+        $cropped->width = $size;
+        $cropped->height = $size;
+        $cropped->original = false;
+        $cropped->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
+        $cropped->filename = $filename;
+        $cropped->url = common_avatar_url($filename);
+        $cropped->created = DB_DataObject_Cast::dateTime(); # current time
+
+        if ($cropped->insert()) {
+            return $cropped;
+        } else {
+            return NULL;
+        }
+    }
+
+    function to_image() 
+    {
+        $filepath = common_avatar_path($this->filename);
+        if ($this->mediatype == 'image/gif') {
+            return imagecreatefromgif($filepath);
+        } else if ($this->mediatype == 'image/jpeg') {
+            return imagecreatefromjpeg($filepath);
+        } else if ($this->mediatype == 'image/png') {
+            return imagecreatefrompng($filepath);
+        } else {
+            return NULL;
+        }
+    }
+    
+    function &pkeyGet($kv) 
+    {
+        return Memcached_DataObject::pkeyGet('Avatar', $kv);
+    }
+
 }
index 3b6ac1d7f2438422dc39818855963510bf882775..31bdf71d59b9923abacbab890e692b8864f442bf 100644 (file)
@@ -121,15 +121,39 @@ class Profile extends Memcached_DataObject
         return $avatar;
     }
 
-       function delete_avatars() {
-               $avatar = new Avatar();
-               $avatar->profile_id = $this->id;
-               $avatar->find();
-               while ($avatar->fetch()) {
-                       $avatar->delete();
-               }
-               return true;
-       }
+    function crop_avatars($x, $y, $w, $h) 
+    {
+
+        $avatar = $this->getOriginalAvatar();
+        $this->delete_avatars(false); # don't delete original
+
+        foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
+            # We don't do a scaled one if original is our scaled size
+            if (!($avatar->width == $size && $avatar->height == $size)) {
+                $s = $avatar->scale_and_crop($size, $x, $y, $w, $h);
+                if (!$s) {
+                    return NULL;
+                }
+            }
+        }
+        return true;
+    }
+
+    function delete_avatars($original=true) 
+    {
+        $avatar = new Avatar();
+        $avatar->profile_id = $this->id;
+        $avatar->find();
+        while ($avatar->fetch()) {
+            if ($avatar->original) {
+                if ($original == false) {
+                    continue;
+                }
+            }
+            $avatar->delete();
+        }
+        return true;
+    }
 
     function getBestName()
     {
index 62de39d4593875fe763a42c8d5f0c26f2e57b500..03bac3a93b0173f9ffcf1a6dc5fbc78162bd809a 100644 (file)
@@ -60,12 +60,25 @@ class SettingsAction extends Action
         }
     }
 
-       function form_header($title, $msg=NULL, $success=false) {
-               common_show_header($title,
-                                  NULL,
-                                  array($msg, $success),
-                                                  array($this, 'show_top'));
-       }
+    function form_header($title, $msg=NULL, $success=false) 
+    {
+        common_show_header($title,
+                           array($this, 'show_header'),
+                           array($msg, $success),
+                           array($this, 'show_top'));
+    }
+
+    function show_header() 
+    {
+        common_element('link', array('rel' => 'stylesheet',
+                                     'type' => 'text/css',
+                                     'href' => common_path('js/jcrop/jquery.Jcrop.css?version='.LACONICA_VERSION),
+                                     'media' => 'screen, projection, tv'));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.pack.js')));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.go.js')));
+    }
 
     function show_top($arr)
     {