]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - classes/Avatar.php
Moved Avatar retrieval into Avatar class
[quix0rs-gnu-social.git] / classes / Avatar.php
1 <?php
2 /**
3  * Table Definition for avatar
4  */
5 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
6
7 class Avatar extends Managed_DataObject
8 {
9     ###START_AUTOCODE
10     /* the code below is auto generated do not remove the above tag */
11
12     public $__table = 'avatar';                          // table name
13     public $profile_id;                      // int(4)  primary_key not_null
14     public $original;                        // tinyint(1)
15     public $width;                           // int(4)  primary_key not_null
16     public $height;                          // int(4)  primary_key not_null
17     public $mediatype;                       // varchar(32)   not_null
18     public $filename;                        // varchar(255)
19     public $url;                             // varchar(255)  unique_key
20     public $created;                         // datetime()   not_null
21     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
22
23     /* the code above is auto generated do not remove the tag below */
24     ###END_AUTOCODE
25         
26     public static function schemaDef()
27     {
28         return array(
29             'fields' => array(
30                 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
31                 'original' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'uploaded by user or generated?'),
32                 'width' => array('type' => 'int', 'not null' => true, 'description' => 'image width'),
33                 'height' => array('type' => 'int', 'not null' => true, 'description' => 'image height'),
34                 'mediatype' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'file type'),
35                 'filename' => array('type' => 'varchar', 'length' => 255, 'description' => 'local filename, if local'),
36                 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'avatar location'),
37                 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
38                 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
39             ),
40             'primary key' => array('profile_id', 'width', 'height'),
41             'unique keys' => array(
42                 'avatar_url_key' => array('url'),
43             ),
44             'foreign keys' => array(
45                 'avatar_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
46             ),
47             'indexes' => array(
48                 'avatar_profile_id_idx' => array('profile_id'),
49             ),
50         );
51     }
52
53     // We clean up the file, too
54     function delete()
55     {
56         $filename = $this->filename;
57         if (parent::delete() && file_exists(Avatar::path($filename))) {
58             @unlink(Avatar::path($filename));
59         }
60     }
61
62     /*
63      * Deletes all avatars (but may spare the original) from a profile.
64      * 
65      * @param   Profile $target     The profile we're deleting avatars of.
66      * @param   boolean $original   Whether original should be removed or not.
67      */
68     public static function deleteFromProfile(Profile $target, $original=true) {
69         try {
70             $avatars = self::getProfileAvatars($target);
71             foreach ($avatars as $avatar) {
72                 if ($avatar->original && !$original) {
73                     continue;
74                 }
75                 $avatar->delete();
76             }
77         } catch (NoAvatarException $e) {
78             // There are no avatars to delete, a sort of success.
79         }
80
81         return true;
82     }
83
84     static protected $_avatars = array();
85
86     /*
87      * Get an avatar by profile. Currently can't call newSize with $height
88      */
89     public static function byProfile(Profile $target, $width=null, $height=null)
90     {
91         $width  = (int) floor($width);
92         $height = !is_null($height) ? (int) floor($height) : null;
93         if (is_null($height)) {
94             $height = $width;
95         }
96
97         $size = "{$width}x{$height}";
98         if (!isset(self::$_avatars[$target->id])) {
99             self::$_avatars[$target->id] = array();
100         } elseif (isset(self::$_avatars[$target->id][$size])){
101             return self::$_avatars[$target->id][$size];
102         }
103
104         $avatar = null;
105         if (Event::handle('StartProfileGetAvatar', array($target, $width, &$avatar))) {
106             $avatar = self::pkeyGet(
107                 array(
108                     'profile_id' => $target->id,
109                     'width'      => $width,
110                     'height'     => $height,
111                 )
112             );
113             Event::handle('EndProfileGetAvatar', array($target, $width, &$avatar));
114         }
115
116         if (is_null($avatar)) {
117             // Obviously we can't find an avatar, so let's resize the original!
118             $avatar = Avatar::newSize($target, $width);
119         } elseif (!($avatar instanceof Avatar)) {
120             throw new NoAvatarException($target, $avatar);
121         }
122
123         self::$_avatars[$target->id]["{$avatar->width}x{$avatar->height}"] = $avatar;
124         return $avatar;
125     }
126
127     public static function getUploaded(Profile $target)
128     {
129         $avatar = new Avatar();
130         $avatar->profile_id = $target->id;
131         $avatar->original = true;
132         if (!$avatar->find(true)) {
133             throw new NoAvatarException($target, $avatar);
134         }
135         if (!file_exists(Avatar::path($avatar->filename))) {
136             // The delete call may be odd for, say, unmounted filesystems
137             // that cause a file to currently not exist, but actually it does...
138             $avatar->delete();
139             throw new NoAvatarException($target, $avatar);
140         }
141         return $avatar;
142     }
143
144     public static function getProfileAvatars(Profile $target) {
145         $avatar = new Avatar();
146         $avatar->profile_id = $target->id;
147         if (!$avatar->find()) {
148             throw new NoAvatarException($target, $avatar);
149         }
150         return $avatar->fetchAll();
151     }
152
153     /**
154      * Where should the avatar go for this user?
155      */
156     static function filename($id, $extension, $size=null, $extra=null)
157     {
158         if ($size) {
159             return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
160         } else {
161             return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
162         }
163     }
164
165     static function path($filename)
166     {
167         $dir = common_config('avatar', 'dir');
168
169         if ($dir[strlen($dir)-1] != '/') {
170             $dir .= '/';
171         }
172
173         return $dir . $filename;
174     }
175
176     static function url($filename)
177     {
178         $path = common_config('avatar', 'path');
179
180         if ($path[strlen($path)-1] != '/') {
181             $path .= '/';
182         }
183
184         if ($path[0] != '/') {
185             $path = '/'.$path;
186         }
187
188         $server = common_config('avatar', 'server');
189
190         if (empty($server)) {
191             $server = common_config('site', 'server');
192         }
193
194         $ssl = common_config('avatar', 'ssl');
195
196         if (is_null($ssl)) { // null -> guess
197             if (common_config('site', 'ssl') == 'always' &&
198                 !common_config('avatar', 'server')) {
199                 $ssl = true;
200             } else {
201                 $ssl = false;
202             }
203         }
204
205         $protocol = ($ssl) ? 'https' : 'http';
206
207         return $protocol.'://'.$server.$path.$filename;
208     }
209
210     function displayUrl()
211     {
212         $server = common_config('avatar', 'server');
213         if ($server && !empty($this->filename)) {
214             return Avatar::url($this->filename);
215         } else {
216             return $this->url;
217         }
218     }
219
220     static function urlByProfile(Profile $target, $width=null, $height=null) {
221         try {
222             return self::byProfile($target,  $width, $height)->displayUrl();
223         } catch (Exception $e) {
224             return self::defaultImage($width);
225         }
226     }
227
228     static function defaultImage($size)
229     {
230         static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
231                                   AVATAR_STREAM_SIZE => 'stream',
232                                   AVATAR_MINI_SIZE => 'mini');
233         return Theme::path('default-avatar-'.$sizenames[$size].'.png');
234     }
235
236     static function newSize(Profile $target, $width) {
237         $width = (int) floor($width);
238         if ($width < 1 || $width > common_config('avatar', 'maxsize')) {
239             // TRANS: An error message when avatar size is unreasonable
240             throw new Exception(_m('Avatar size too large'));
241         }
242
243         $original = Avatar::getUploaded($target);
244
245         $imagefile = new ImageFile($target->id, Avatar::path($original->filename));
246         $filename = $imagefile->resize($width);
247
248         $scaled = clone($original);
249         $scaled->original = false;
250         $scaled->width = $width;
251         $scaled->height = $width;
252         $scaled->url = Avatar::url($filename);
253         $scaled->filename = $filename;
254         $scaled->created = common_sql_now();
255
256         if (!$scaled->insert()) {
257             // TRANS: An error message when unable to insert avatar data into the db
258             throw new Exception(_m('Could not insert new avatar data to database'));
259         }
260
261         // Return the new avatar object
262         return $scaled;
263     }
264 }