%PDF- %PDF-
Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/file/models/ |
Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/file/models/File.php |
<?php /** * @link https://www.humhub.org/ * @copyright Copyright (c) 2016 HumHub GmbH & Co. KG * @license https://www.humhub.com/licences */ namespace humhub\modules\file\models; use humhub\components\behaviors\GUID; use humhub\components\behaviors\PolymorphicRelation; use humhub\components\ActiveRecord; use humhub\modules\content\components\ContentActiveRecord; use humhub\modules\content\components\ContentAddonActiveRecord; use humhub\modules\user\models\User; use Yii; use yii\base\InvalidArgumentException; use yii\db\Exception; use yii\helpers\Url; use yii\web\UploadedFile; /** * This is the model class for table "file". * * The followings are the available columns in table 'file': * @property integer $id * @property string $guid * @property string $file_name * @property string $title * @property string $mime_type * @property string $size * @property string $object_model * @property integer $object_id * @property integer $content_id * @property string $created_at * @property integer $created_by * @property string $updated_at * @property integer $updated_by * @property integer $show_in_stream * @property string $hash_sha1 * * @property \humhub\modules\user\models\User $createdBy * @property \humhub\modules\file\components\StorageManager $store * @property FileHistory[] $historyFiles * * @mixin PolymorphicRelation * @mixin GUID * * Following properties are optional and for module depended use: * - title * * @since 0.5 */ class File extends FileCompat { /** * @event Event that is triggered after a new file content has been stored. */ const EVENT_AFTER_NEW_STORED_FILE = 'afterNewStoredFile'; /** * @var int $old_updated_by */ public $old_updated_by; /** * @var string $old_updated_at */ public $old_updated_at; /** * @var \humhub\modules\file\components\StorageManagerInterface the storage manager */ private $_store = null; /** * @inheritdoc */ public static function tableName() { return 'file'; } /** * @inheritdoc */ public function rules() { return [ [['mime_type'], 'string', 'max' => 150], [['mime_type'], 'match', 'not' => true, 'pattern' => '/[^a-zA-Z0-9\.รค\/\-\+]/', 'message' => Yii::t('FileModule.base', 'Invalid Mime-Type')], [['file_name', 'title'], 'string', 'max' => 255], [['size'], 'integer'], ]; } /** * @inheritdoc */ public function behaviors() { return [ [ 'class' => PolymorphicRelation::class, 'mustBeInstanceOf' => [ActiveRecord::class], ], [ 'class' => GUID::class, ], ]; } /** * Gets query for [[FileHistory]]. * * @return \yii\db\ActiveQuery */ public function getHistoryFiles() { return $this->hasMany(FileHistory::class, ['file_id' => 'id'])->orderBy(['created_at' => SORT_DESC, 'id' => SORT_DESC]); } /** * @inheritdoc */ public function beforeSave($insert) { $this->old_updated_by = $this->getOldAttribute('updated_by'); $this->old_updated_at = $this->getOldAttribute('updated_at'); return parent::beforeSave($insert); } /** * @inheritdoc */ public function beforeDelete() { $this->store->delete(); FileHistory::deleteAll(['file_id' => $this->id]); return parent::beforeDelete(); } /** * Returns the url to this file * * Available params (see also: DownloadAction) * - variant: the requested file variant * - download: force download option (default: false) * * @param array $params the params * @param boolean $absolute * @return string the url to the file download */ public function getUrl($params = [], $absolute = true) { // Handle old 'suffix' attribute for HumHub prior 1.1 versions if (is_string($params)) { $suffix = $params; $params = []; if ($suffix != '') { $params['variant'] = $suffix; } } $params['guid'] = $this->guid; $params['hash_sha1'] = $this->getHash(8); array_unshift($params, '/file/file/download'); return Url::to($params, $absolute); } /** * Get hash * * @param int Return number of first chars of the file hash, 0 - unlimit * @return string */ public function getHash($length = 0) { if (empty($this->hash_sha1) && $this->store->has()) { $this->updateAttributes(['hash_sha1' => sha1_file($this->store->get())]); } return $length ? substr($this->hash_sha1, 0, $length) : $this->hash_sha1; } /** * Checks if given file can read. * * If the file is not an instance of HActiveRecordContent or HActiveRecordContentAddon * the file is readable for all. * @param string|User $userId * @return bool */ public function canRead($userId = "") { $object = $this->getPolymorphicRelation(); if ($object !== null && ($object instanceof ContentActiveRecord || $object instanceof ContentAddonActiveRecord)) { return $object->content->canView($userId); } return true; } /** * Checks if given file can deleted. * * If the file is not an instance of ContentActiveRecord or ContentAddonActiveRecord * the file is readable for all unless there is method canEdit or canDelete implemented. */ public function canDelete($userId = null) { $object = $this->getPolymorphicRelation(); // File is not bound to an object if ($object === null) { return true; } if ($object instanceof ContentAddonActiveRecord) { /** @var ContentAddonActiveRecord $object */ return $object->canEdit($userId) || $object->content->canEdit($userId); } elseif ($object instanceof ContentActiveRecord) { /** @var ContentActiveRecord $object */ return $object->content->canEdit($userId); } elseif ($object instanceof ActiveRecord && method_exists($object, 'canEdit')) { /** @var ActiveRecord $object */ return $object->canEdit($userId); } return false; } /** * Checks if this file record is already attached to record. * * @return boolean is whether in use or not */ public function isAssigned() { return ($this->object_model != ""); } /** * Checks if this file is attached to the given record * @param ActiveRecord $record * @return bool */ public function isAssignedTo(ActiveRecord $record) { return $this->object_model === get_class($record) && $this->object_id == $record->getPrimaryKey(); } /** * Returns the StorageManager * * @return \humhub\modules\file\components\StorageManagerInterface * @throws \yii\base\InvalidConfigException */ public function getStore() { if ($this->_store === null) { $this->_store = Yii::createObject(Yii::$app->getModule('file')->storageManagerClass); $this->_store->setFile($this); } return $this->_store; } /** * Returns all attached Files of the given $record. * * @param \yii\db\ActiveRecord $record * @return File[] */ public static function findByRecord(\yii\db\ActiveRecord $record) { return self::findAll(['object_model' => $record->className(), 'object_id' => $record->getPrimaryKey()]); } /** * Get File History by ID * * @param int $fileHistoryId * @return FileHistory|null */ public function getFileHistoryById($fileHistoryId): ?FileHistory { if (empty($fileHistoryId) || $this->isNewRecord) { return null; } return FileHistory::findOne(['id' => $fileHistoryId, 'file_id' => $this->id]); } /** * Sets a new file content based on an UploadedFile, new File or a file path. * * @param UploadedFile|File|string $file File object or path * @param bool $skipHistoryEntry Skipping the creation of a history entry, even if enabled by the record * @since 1.10 */ public function setStoredFile($file, $skipHistoryEntry = false) { $this->beforeNewStoredFile($skipHistoryEntry); if ($file instanceof UploadedFile) { $this->store->set($file); } elseif ($file instanceof File) { if ($file->isAssigned()) { throw new InvalidArgumentException('Already assigned File records cannot stored as another File record.'); } $this->store->setByPath($file->store->get()); $file->delete(); } elseif (is_string($file) && is_file($file)) { $this->store->setByPath($file); } $this->afterNewStoredFile(); } /** * Sets a new file content by a given string. * * @param string $content * @param bool $skipHistoryEntry Skipping the creation of a history entry, even if enabled by the record * @since 1.10 */ public function setStoredFileContent($content, $skipHistoryEntry = false) { $this->beforeNewStoredFile($skipHistoryEntry); $this->store->setContent($content); $this->afterNewStoredFile(); } /** * Steps that must be executed before a new file content is set. * @param bool $skipHistoryEntry Skipping the creation of a history entry, even if enabled by the record */ private function beforeNewStoredFile(bool $skipHistoryEntry) { if ($this->isNewRecord) { throw new Exception('File Record must be saved before setting a new file content.'); } if ($this->store->has() && FileHistory::isEnabled($this) && !$skipHistoryEntry) { FileHistory::createEntryForFile($this); } $this->store->delete(null, [FileHistory::VARIANT_PREFIX . '*']); } /** * Steps that must be performed after a new file content has been set. */ private function afterNewStoredFile() { if ($this->store->has()) { // Make sure to update updated_by & updated_at and avoid save() $this->beforeSave(false); $this->updateAttributes([ 'hash_sha1' => sha1_file($this->store->get()), 'size' => filesize($this->store->get()), 'updated_by' => $this->updated_by, 'updated_at' => $this->updated_at, ]); $this->trigger(self::EVENT_AFTER_NEW_STORED_FILE); } } }