| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2021-04-19 18:51:05 +00:00
										 |  |  | // {{{ License
 | 
					
						
							| 
									
										
										
										
											2021-02-19 10:34:21 +00:00
										 |  |  | // This file is part of GNU social - https://www.gnu.org/software/social
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // GNU social is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2021-04-19 18:51:05 +00:00
										 |  |  | // }}}
 | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-14 15:27:37 +00:00
										 |  |  | namespace Plugin\StoreRemoteMedia; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  | use App\Core\DB\DB; | 
					
						
							|  |  |  | use App\Core\Event; | 
					
						
							|  |  |  | use App\Core\GSFile; | 
					
						
							|  |  |  | use App\Core\HTTPClient; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:51:05 +00:00
										 |  |  | use App\Core\Modules\Plugin; | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  | use App\Entity\AttachmentThumbnail; | 
					
						
							|  |  |  | use App\Entity\AttachmentToNote; | 
					
						
							|  |  |  | use App\Entity\Note; | 
					
						
							|  |  |  | use App\Entity\RemoteURL; | 
					
						
							|  |  |  | use App\Entity\RemoteURLToAttachment; | 
					
						
							|  |  |  | use App\Util\Common; | 
					
						
							|  |  |  | use App\Util\TemporaryFile; | 
					
						
							| 
									
										
										
										
											2021-04-14 15:27:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 10:34:21 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The StoreRemoteMedia plugin downloads remotely attached files to local server. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package   GNUsocial | 
					
						
							| 
									
										
										
										
											2021-04-14 15:27:37 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-02-19 10:34:21 +00:00
										 |  |  |  * @author    Mikael Nordfeldth | 
					
						
							|  |  |  |  * @author    Stephen Paul Weber | 
					
						
							|  |  |  |  * @author    Mikael Nordfeldth | 
					
						
							|  |  |  |  * @author    Miguel Dantas | 
					
						
							|  |  |  |  * @author    Diogo Peralta Cordeiro | 
					
						
							|  |  |  |  * @copyright 2015-2016, 2019-2021 Free Software Foundation, Inc http://www.fsf.org | 
					
						
							|  |  |  |  * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-04-19 18:51:05 +00:00
										 |  |  | class StoreRemoteMedia extends Plugin | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     public function version(): string | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         return '3.0.0'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     public bool $store_original = false; // Whether to maintain a copy of the original media or only a thumbnail of it
 | 
					
						
							|  |  |  |     public ?int $thumbnail_width; | 
					
						
							|  |  |  |     public ?int $thumbnail_height; | 
					
						
							|  |  |  |     public ?int $max_size; | 
					
						
							|  |  |  |     public ?bool $smart_crop; | 
					
						
							| 
									
										
										
										
											2021-02-21 10:35:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     private function getStoreOriginal(): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->store_original; | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     private function getThumbnailWidth(): int | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         return $this->thumbnail_width ?? Common::config('thumbnail', 'width'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-30 13:36:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     private function getThumbnailHeight(): int | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->thumbnail_height ?? Common::config('thumbnail', 'height'); | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     private function getMaxSize(): int | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         return $this->max_size ?? Common::config('attachments', 'file_quota'); | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     private function getSmartCrop(): bool | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         return $this->smart_crop ?? Common::config('thumbnail', 'smart_crop'); | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-24 15:56:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |      * @param RemoteURL $remote_url | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |     public function onNewRemoteURLFromNote(RemoteURL $remote_url, Note $note): bool | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         // Embed is the plugin to handle these
 | 
					
						
							|  |  |  |         if ($remote_url->getMimetypeMajor() === 'text') { | 
					
						
							|  |  |  |             return Event::next; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         // Have we handled it already?
 | 
					
						
							|  |  |  |         $remoteurl_to_attachment = DB::find('remoteurl_to_attachment', | 
					
						
							|  |  |  |             ['remoteurl_id' => $remote_url->getId()]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If it was handled already
 | 
					
						
							|  |  |  |         if (!is_null($remoteurl_to_attachment)) { | 
					
						
							|  |  |  |             // Relate the note with the existing attachment
 | 
					
						
							|  |  |  |             DB::persist(AttachmentToNote::create([ | 
					
						
							|  |  |  |                 'attachment_id' => $remoteurl_to_attachment->getAttachmentId(), | 
					
						
							|  |  |  |                 'note_id'       => $note->getId(), | 
					
						
							|  |  |  |             ])); | 
					
						
							|  |  |  |             DB::flush(); | 
					
						
							|  |  |  |             return Event::stop; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // Retrieve media
 | 
					
						
							|  |  |  |             $get_response = HTTPClient::get($remote_url->getRemoteUrl()); | 
					
						
							|  |  |  |             $media        = $get_response->getContent(); | 
					
						
							|  |  |  |             $mimetype     = $get_response->getHeaders()['content-type'][0]; | 
					
						
							|  |  |  |             unset($get_response); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Ensure we still want to handle it
 | 
					
						
							|  |  |  |             if ($mimetype != $remote_url->getMimetype()) { | 
					
						
							|  |  |  |                 $remote_url->setMimetype($mimetype); | 
					
						
							|  |  |  |                 DB::persist($remote_url); | 
					
						
							|  |  |  |                 DB::flush(); | 
					
						
							|  |  |  |                 if ($remote_url->getMimetypeMajor() === 'text') { | 
					
						
							|  |  |  |                     return Event::next; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |             // Create an attachment for this
 | 
					
						
							|  |  |  |             $temp_file = new TemporaryFile(); | 
					
						
							|  |  |  |             $temp_file->write($media); | 
					
						
							|  |  |  |             $attachment = GSFile::sanitizeAndStoreFileAsAttachment($temp_file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Relate the remoteurl with the attachment
 | 
					
						
							|  |  |  |             DB::persist(RemoteURLToAttachment::create([ | 
					
						
							|  |  |  |                 'remoteurl_id'  => $remote_url->getId(), | 
					
						
							|  |  |  |                 'attachment_id' => $attachment->getId(), | 
					
						
							|  |  |  |             ])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Relate the note with the attachment
 | 
					
						
							|  |  |  |             DB::persist(AttachmentToNote::create([ | 
					
						
							|  |  |  |                 'attachment_id' => $attachment->getId(), | 
					
						
							|  |  |  |                 'note_id'       => $note->getId(), | 
					
						
							|  |  |  |             ])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DB::flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Should we create a thumb and delete the original file?
 | 
					
						
							|  |  |  |             if (!$this->getStoreOriginal()) { | 
					
						
							|  |  |  |                 $thumbnail = AttachmentThumbnail::getOrCreate( | 
					
						
							|  |  |  |                     attachment: $attachment, | 
					
						
							|  |  |  |                     width: $this->getThumbnailWidth(), | 
					
						
							|  |  |  |                     height: $this->getThumbnailHeight(), | 
					
						
							|  |  |  |                     crop: $this->getSmartCrop() | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |                 $attachment->deleteStorage(); | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |             return Event::stop; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Event raised when GNU social polls the plugin for information about it. | 
					
						
							|  |  |  |      * Adds this plugin's version information to $versions array | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param &$versions array inherited from parent | 
					
						
							| 
									
										
										
										
											2021-04-14 15:27:37 +00:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-02-16 18:30:21 +00:00
										 |  |  |      * @return bool true hook value | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-08-12 15:03:30 +01:00
										 |  |  |     public function onPluginVersion(array &$versions): bool | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-12 00:39:36 +01:00
										 |  |  |         $versions[] = [ | 
					
						
							|  |  |  |             'name'        => 'StoreRemoteMedia', | 
					
						
							|  |  |  |             'version'     => $this->version(), | 
					
						
							|  |  |  |             'author'      => 'Mikael Nordfeldth, Diogo Peralta Cordeiro', | 
					
						
							|  |  |  |             'homepage'    => GNUSOCIAL_PROJECT_URL, | 
					
						
							|  |  |  |             'description' => // TRANS: Plugin description.
 | 
					
						
							|  |  |  |                 _m('Plugin for downloading remotely attached files to local server.'), | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |         return Event::next; | 
					
						
							| 
									
										
										
										
											2015-10-01 22:18:47 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-14 15:27:37 +00:00
										 |  |  | } |