diff --git a/README.md b/README.md index e80a72f..c33deb8 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ The preferred way to install this extension via [composer](http://getcomposer.or Either run ``` -php composer.phar require --prefer-dist mohorev/yii2-upload-behavior "*" +php composer.phar require --prefer-dist maxodrom/yii2-upload-behavior "*" ``` or add this code line to the `require` section of your `composer.json` file: ```json -"mohorev/yii2-upload-behavior": "*" +"maxodrom/yii2-upload-behavior": "*" ``` Usage @@ -143,7 +143,103 @@ class User extends ActiveRecord } ``` -Example view file: +## Flexible configuration for path and URL generation + +More flexible configuration for `path` and/or `url` behavior properties is that to use +callbacks or array for defining `path` or `url` generation logic. + +#### I. Via callbacks + +```php +/** + * @inheritdoc + */ +public function behaviors() +{ + return [ + [ + 'class' => \mohorev\file\UploadImageBehavior::class, + 'attribute' => 'image', + 'scenarios' => ['insert', 'update'], + 'placeholder' => '@app/modules/user/assets/images/userpic.jpg', + 'path' => function ($model) { + /** @var \app\models\UserProfile $model */ + $basePath = '@webroot/upload/profiles/'; + $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + return $basePath . $path; + }, + 'url' => function ($model) { + /** @var \app\models\UserProfile $model */ + $baseUrl = '@web/upload/profiles/'; + $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + return $baseUrl . $path; + }, + 'thumbs' => [ + 'thumb' => ['width' => 400, 'quality' => 90], + 'preview' => ['width' => 200, 'height' => 200], + 'news_thumb' => ['width' => 200, 'height' => 200, 'bg_color' => '000'], + ], + ], + ]; +} +``` + +#### II. Via array configuration by defining class and its static methods for path/URL generation + +```php +/** + * @inheritdoc + */ +public function behaviors() +{ + return [ + [ + 'class' => \mohorev\file\UploadImageBehavior::class, + 'attribute' => 'image', + 'scenarios' => ['insert', 'update'], + 'placeholder' => '@app/modules/user/assets/images/userpic.jpg', + 'path' => [UserProfile::class, 'buildAvatarPath'], + 'url' => [UserProfile::class, 'buildAvatarUrl'], + 'thumbs' => [ + 'thumb' => ['width' => 400, 'quality' => 90], + 'preview' => ['width' => 200, 'height' => 200], + 'news_thumb' => ['width' => 200, 'height' => 200, 'bg_color' => '000'], + ], + ], + ]; +} + +/** + * Define two static methos in your model for path and URL generation + */ +/** + * @param \app\models\UserProfile|\yii\db\ActiveRecord $profile + * @return string + */ +public static function buildAvatarPath(UserProfile $model) +{ + $basePath = '@webroot/upload/profiles/'; + $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + + return $basePath . $path; +} + +/** + * @param \app\models\UserProfile|\yii\db\ActiveRecord $profile + * @return string + */ +public static function buildAvatarUrl(UserProfile $model) +{ + $baseUrl = '@web/upload/profiles/'; + $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + + return $baseUrl . $path; +} +``` + +### Usage in views + +Example: ```php ['enctype' => 'multipart/form-data']]); ?> diff --git a/composer.json b/composer.json index 72e17f7..54ee886 100644 --- a/composer.json +++ b/composer.json @@ -1,18 +1,22 @@ { - "name": "mohorev/yii2-upload-behavior", + "name": "maxodrom/yii2-upload-behavior", "description": "Upload behavior for Yii 2", "keywords": ["yii2", "extension", "behavior", "file", "image", "upload", "resize", "thumb"], - "homepage": "https://github.com/mohorev/yii2-upload-behavior", + "homepage": "https://github.com/maxodrom/yii2-upload-behavior", "type": "yii2-extension", "license": "BSD-3-Clause", "support": { - "issues": "https://github.com/mohorev/yii2-upload-behavior/issues?state=open", - "source": "https://github.com/mohorev/yii2-upload-behavior" + "issues": "https://github.com/maxodrom/yii2-upload-behavior/issues?state=open", + "source": "https://github.com/maxodrom/yii2-upload-behavior" }, "authors": [ { "name": "Alexander Mohorev", "email": "dev.mohorev@gmail.com" + }, + { + "name": "Max Alexandrov", + "email": "max@7u3.ru" } ], "repositories": [ diff --git a/src/UploadBehavior.php b/src/UploadBehavior.php index 34d5978..a794ba6 100644 --- a/src/UploadBehavior.php +++ b/src/UploadBehavior.php @@ -54,11 +54,55 @@ class UploadBehavior extends Behavior */ public $scenarios = []; /** - * @var string the base path or path alias to the directory in which to save files. + * @var string|callable|array Base path or path alias to the directory in which to save files, + * or callable for setting up your custom path generation logic. + * If $path is callable, callback signature should be as follow and return a string: + * + * ```php + * function (\yii\db\ActiveRecord $model) + * { + * // do something... + * return $string; + * } + * ``` + * If this property is set up as array, it should be, for example, like as follow ['\app\models\UserProfile', 'buildAvatarPath'], + * where first element is class name, while second is its static method that should be called for path generation. + * + * Example: + * ```php + * public static function buildAvatarPath(\yii\db\ActiveRecord $model) + * { + * $basePath = '@webroot/upload/avatars/'; + * $suffix = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + * return $basePath . $suffix; + * } + * ``` */ public $path; /** - * @var string the base URL or path alias for this file + * @var string|callable|array Base URL or path alias for this file, + * or callable for setting up your custom URL generation logic. + * If $url is callable, callback signature should be as follow and return a string: + * + * ```php + * function (\yii\db\ActiveRecord $model) + * { + * // do something... + * return $string; + * } + * ``` + * If this property is set up as array, it should be, for example, like as follow ['\app\models\UserProfile', 'buildAvatarUrl'], + * where first element is class name, while second is its static method that should be called for URL generation. + * + * Example: + * ```php + * public static function buildAvatarUrl(\yii\db\ActiveRecord $model) + * { + * $baseUrl = '@web/upload/avatars/'; + * $suffix = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); + * return $baseUrl . $suffix; + * } + * ``` */ public $url; /** @@ -177,7 +221,7 @@ public function beforeSave() /** * This method is called at the end of inserting or updating a record. - * @throws \yii\base\InvalidArgumentException + * @throws \yii\base\Exception */ public function afterSave() { @@ -210,6 +254,7 @@ public function afterDelete() * @param string $attribute * @param boolean $old * @return string|null the file path. + * @throws \yii\base\InvalidConfigException */ public function getUploadPath($attribute, $old = false) { @@ -225,6 +270,7 @@ public function getUploadPath($attribute, $old = false) * Returns file url for the attribute. * @param string $attribute * @return string|null + * @throws \yii\base\InvalidConfigException */ public function getUploadUrl($attribute) { @@ -252,15 +298,23 @@ protected function resolvePath($path) { /** @var BaseActiveRecord $model */ $model = $this->owner; - return preg_replace_callback('/{([^}]+)}/', function ($matches) use ($model) { - $name = $matches[1]; - $attribute = ArrayHelper::getValue($model, $name); - if (is_string($attribute) || is_numeric($attribute)) { - return $attribute; - } else { - return $matches[0]; - } - }, $path); + if (is_string($path)) { + return preg_replace_callback('/{([^}]+)}/', function ($matches) use ($model) { + $name = $matches[1]; + $attribute = ArrayHelper::getValue($model, $name); + if (is_string($attribute) || is_numeric($attribute)) { + return $attribute; + } else { + return $matches[0]; + } + }, $path); + } elseif (is_callable($path) || is_array($path)) { + return call_user_func($path, $model); + } else { + throw new InvalidArgumentException( + '$path argument must be a string, array or callable: ' . gettype($path) . ' given.' + ); + } } /** diff --git a/src/UploadImageBehavior.php b/src/UploadImageBehavior.php index c2417dc..36a459f 100644 --- a/src/UploadImageBehavior.php +++ b/src/UploadImageBehavior.php @@ -128,7 +128,8 @@ protected function afterUpload() } /** - * @throws \yii\base\InvalidArgumentException + * @throws \yii\base\Exception + * @throws \yii\base\InvalidConfigException */ protected function createThumbs() { @@ -161,6 +162,7 @@ protected function createThumbs() * @param string $profile * @param boolean $old * @return string + * @throws \yii\base\InvalidConfigException */ public function getThumbUploadPath($attribute, $profile = 'thumb', $old = false) { @@ -177,6 +179,8 @@ public function getThumbUploadPath($attribute, $profile = 'thumb', $old = false) * @param string $attribute * @param string $profile * @return string|null + * @throws \yii\base\Exception + * @throws \yii\base\InvalidConfigException */ public function getThumbUploadUrl($attribute, $profile = 'thumb') {