X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=classes%2FFile.php;h=2390f848de28f420abb06dd211c237ea32467406;hb=d4be5349b30f49fa049dbfc854bb2a95eeb1d5c1;hp=977c02bce68ef2d57a3a8c17bd64a86c2d1003c9;hpb=3255e2e1b81ce6d8d867e924eeacff2c9e53d706;p=quix0rs-gnu-social.git diff --git a/classes/File.php b/classes/File.php index 977c02bce6..2390f848de 100644 --- a/classes/File.php +++ b/classes/File.php @@ -31,10 +31,10 @@ class File extends Managed_DataObject public $filehash; // varchar(64) indexed public $mimetype; // varchar(50) public $size; // int(4) - public $title; // varchar(191) not 255 because utf8mb4 takes more space + public $title; // text() public $date; // int(4) public $protected; // int(4) - public $filename; // varchar(191) not 255 because utf8mb4 takes more space + public $filename; // text() public $width; // int(4) public $height; // int(4) public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP @@ -52,10 +52,10 @@ class File extends Managed_DataObject 'filehash' => array('type' => 'varchar', 'length' => 64, 'not null' => false, 'description' => 'sha256 of the file contents, only for locally stored files of course'), 'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'), 'size' => array('type' => 'int', 'description' => 'size of resource when available'), - 'title' => array('type' => 'varchar', 'length' => 191, 'description' => 'title of resource when available'), + 'title' => array('type' => 'text', 'description' => 'title of resource when available'), 'date' => array('type' => 'int', 'description' => 'date of resource according to http query'), 'protected' => array('type' => 'int', 'description' => 'true when URL is private (needs login)'), - 'filename' => array('type' => 'varchar', 'length' => 191, 'description' => 'if a local file, name of the file'), + 'filename' => array('type' => 'text', 'description' => 'if file is stored locally (too) this is the filename'), 'width' => array('type' => 'int', 'description' => 'width in pixels, if it can be described as such and data is available'), 'height' => array('type' => 'int', 'description' => 'height in pixels, if it can be described as such and data is available'), @@ -94,26 +94,31 @@ class File extends Managed_DataObject // We don't have the file's URL since before, so let's continue. } - if (!Event::handle('StartFileSaveNew', array(&$redir_data, $given_url))) { - throw new ServerException('File not saved due to an aborted StartFileSaveNew event.'); - } - $file = new File; - $file->urlhash = self::hashurl($given_url); $file->url = $given_url; if (!empty($redir_data['protected'])) $file->protected = $redir_data['protected']; if (!empty($redir_data['title'])) $file->title = $redir_data['title']; if (!empty($redir_data['type'])) $file->mimetype = $redir_data['type']; if (!empty($redir_data['size'])) $file->size = intval($redir_data['size']); if (isset($redir_data['time']) && $redir_data['time'] > 0) $file->date = intval($redir_data['time']); - $file_id = $file->insert(); + $file->saveFile(); + return $file; + } + + public function saveFile() { + $this->urlhash = self::hashurl($this->url); + + if (!Event::handle('StartFileSaveNew', array(&$this))) { + throw new ServerException('File not saved due to an aborted StartFileSaveNew event.'); + } + + $this->id = $this->insert(); - if ($file_id === false) { + if ($this->id === false) { throw new ServerException('File/URL metadata could not be saved to the database.'); } - Event::handle('EndFileSaveNew', array($file, $redir_data, $given_url)); - return $file; + Event::handle('EndFileSaveNew', array($this)); } /** @@ -124,7 +129,6 @@ class File extends Managed_DataObject * - optionally save a file_to_post record * - return the File object with the full reference * - * @fixme refactor this mess, it's gotten pretty scary. * @param string $given_url the URL we're looking at * @param Notice $notice (optional) * @param bool $followRedirects defaults to true @@ -143,69 +147,30 @@ class File extends Managed_DataObject throw new ServerException('No canonical URL from given URL to process'); } - $file = null; - - try { - $file = File::getByUrl($given_url); - } catch (NoResultException $e) { - // First check if we have a lookup trace for this URL already - try { - $file_redir = File_redirection::getByUrl($given_url); - $file = File::getKV('id', $file_redir->file_id); - if (!$file instanceof File) { - // File did not exist, let's clean up the File_redirection entry - $file_redir->delete(); - } - } catch (NoResultException $e) { - // We just wanted to doublecheck whether a File_thumbnail we might've had - // actually referenced an existing File object. - } - } + $redir = File_redirection::where($given_url); + $file = $redir->getFile(); // If we still don't have a File object, let's create one now! - if (!$file instanceof File) { - // @fixme for new URLs this also looks up non-redirect data - // such as target content type, size, etc, which we need - // for File::saveNew(); so we call it even if not following - // new redirects. - $redir_data = File_redirection::where($given_url); - if (is_array($redir_data)) { - $redir_url = $redir_data['url']; - } elseif (is_string($redir_data)) { - $redir_url = $redir_data; - $redir_data = array(); - } else { - // TRANS: Server exception thrown when a URL cannot be processed. - throw new ServerException(sprintf(_("Cannot process URL '%s'"), $given_url)); - } - - if ($redir_url === $given_url || !$followRedirects) { + if (empty($file->id)) { + if ($redir->url === $given_url || !$followRedirects) { // Save the File object based on our lookup trace - $file = File::saveNew($redir_data, $given_url); + $file->saveFile(); } else { - // This seems kind of messed up... for now skipping this part - // if we're already under a redirect, so we don't go into - // horrible infinite loops if we've been given an unstable - // redirect (where the final destination of the first request - // doesn't match what we get when we ask for it again). - // - // Seen in the wild with clojure.org, which redirects through - // wikispaces for auth and appends session data in the URL params. - $file = self::processNew($redir_url, $notice, /*followRedirects*/false); - File_redirection::saveNew($redir_data, $file->id, $given_url); + $file->saveFile(); + $redir->file_id = $file->id; + $redir->insert(); } + } - if (!$file instanceof File) { - // This should only happen if File::saveNew somehow did not return a File object, - // though we have an assert for that in case the event there might've gone wrong. - // If anything else goes wrong, there should've been an exception thrown. - throw new ServerException('URL processing failed without new File object'); - } + if (!$file instanceof File || empty($file->id)) { + // This should not happen + throw new ServerException('URL processing failed without new File object'); } if ($notice instanceof Notice) { File_to_post::processNew($file, $notice); } + return $file; } @@ -391,28 +356,47 @@ class File extends Managed_DataObject return $protocol.'://'.$server.$path.$filename; } + static $_enclosures = array(); + function getEnclosure(){ + if (isset(self::$_enclosures[$this->getID()])) { + common_debug('Found cached enclosure for file id=='.$this->getID()); + return self::$_enclosures[$this->getID()]; + } + $enclosure = (object) array(); foreach (array('title', 'url', 'date', 'modified', 'size', 'mimetype') as $key) { $enclosure->$key = $this->$key; } - $needMoreMetadataMimetypes = array(null, 'application/xhtml+xml'); + $needMoreMetadataMimetypes = array(null, 'application/xhtml+xml', 'text/html'); if (!isset($this->filename) && in_array(common_bare_mime($enclosure->mimetype), $needMoreMetadataMimetypes)) { // This fetches enclosure metadata for non-local links with unset/HTML mimetypes, // which may be enriched through oEmbed or similar (implemented as plugins) Event::handle('FileEnclosureMetadata', array($this, &$enclosure)); } - if (empty($enclosure->mimetype) || in_array(common_bare_mime($enclosure->mimetype), $needMoreMetadataMimetypes)) { + if (empty($enclosure->mimetype)) { // This means we either don't know what it is, so it can't // be shown as an enclosure, or it is an HTML link which // does not link to a resource with further metadata. throw new ServerException('Unknown enclosure mimetype, not enough metadata'); } + + self::$_enclosures[$this->getID()] = $enclosure; return $enclosure; } + public function hasThumbnail() + { + try { + $this->getThumbnail(); + } catch (Exception $e) { + return false; + } + return true; + } + /** * Get the attachment's thumbnail record, if any. * Make sure you supply proper 'int' typed variables (or null). @@ -451,17 +435,11 @@ class File extends Managed_DataObject return $filepath; } - public function getUrl() + public function getUrl($prefer_local=true) { - if (!empty($this->filename)) { + if ($prefer_local && !empty($this->filename)) { // A locally stored file, so let's generate a URL for our instance. - $url = self::url($this->filename); - if (self::hashurl($url) !== $this->urlhash) { - // For indexing purposes, in case we do a lookup on the 'url' field. - // also we're fixing possible changes from http to https, or paths - $this->updateUrl($url); - } - return $url; + return self::url($this->filename); } // No local filename available, return the URL we have stored