fileimagearbehavior

This the forum to discuss about the fileimagearbehavior extension. New ideas, bugs, questions are welcome here.

Hi,

You will add this new feature? (random number generator)

Hi again,

actually, we have something like this :

/images/{prefix} + join(’_’, primaryKeys) + {suffix} + {extension}

If i understand well, you want something like :

/images/{prefix} + date(‘YmdHis’) + {suffix} + {extension}

But how to get the generated url later ? with primary keys, it never changes for a given model (unless you modify the primary keys by hand, or rename the file). but the date method seems to me difficult, because the file name is not saved in any database.

Maybe I don’t understand well ? Because you want ‘autoGenerateFileName’, but it is already the case, the only difference is that te method is based on primary keys.

It seems simple enough to me to change each prefix to never have any name conflict, or change the destination folder.

With an example, Imagine we have a class Book and a class Recipe:




// configuration of book's behavior:

'relativeWebRootFolder' => 'images',

'prefix' => 'book_'


// configuration of recipe's behavior:

'relativeWebRootFolder' => 'images',

'prefix' => 'recipe_'


// or, change directory :


// configuration of book's behavior:

'relativeWebRootFolder' => 'images/books'


// configuration of recipe's behavior:

'relativeWebRootFolder' => 'images/recipes'



And you will never get some name clashes (the tables need to have a primary key, of course), since a primary key is unique and that the prefix can do a difference too.

if you prefix, you will have for example

  • images/book_1.pdf
  • images/book_2.pdf
  • images/recipe_1.pdf
  • images/recipe_2.pdf

and so on

and if you change directory :

  • images/books/1.pdf
  • images/books/2.pdf
  • images/recipes/1.pdf
  • images/recipes/2.pdf

Tell me if I misunderstood something ;

Hi,

Thanks for explain.

With this dont need random numbers.

I think that its the better method. Paperclip from rails do it too.

Hi,

You can do a method to get full file url (absolute) and relative file url.

This is usefull when create email content or external content that cannot be relative.

the getFileUrl method always return an absolute url. It uses internally Yii::app()->baseUrl.

For those who knows rails (the ruby framework), there is a plugin called paperclip which pretty does the same thing as the yii fileimagearbehavior extension. I discovered it recently ;

Hello,

I posted a question on the extention page but I guess this is wher it belongs, sorrie for that :slight_smile:

I have a for wher an immage should be attached and uploaded. I want the image to be required. If I set this in the model. I get the error from my validator saying the image is not filled in. If the image is not required all is working fine. How can i make the file field a required option using fileinageARbehavior? Do i need to modifie the controler and if so how?

Thanks in advance.

FileARBehavior’s glob function can give varying results when no files are found.

This should be ann empty array, but can be FALSE (see PHP documentation on glob).

This gives an error because it tries to loop over FALSE in deleteFile.

Fix in FileARBehavior.php




protected function deleteFile($path, $fname) {

	$fs = $this->getAnyExistingFilesName($path, $fname);

	if (is_array($fs) && count($fs) > 0) {

		foreach ($fs as $f) unlink($f);

	}

}



There’s a small bugs in your FileAR Behavior.

I run xampp on Windows, and if the extension is in upper case, then it won’t upload the file.

I have to change the following code:


if ($file && strpos($this->extension, $file->extensionName) !== FALSE) {

into


if ($file && strpos(strtolower($this->extension), strtolower($file->extensionName)) !== FALSE) {

For it to run. This is just a work around. I think we should check the mime types of the uploaded files for extension.

Thank you for this great extension. I managed to get in work immediately and I it is nice to generate all kinds of thumbs and manipulations without extra work.

To make it absolutely perfect and the best image component of all times, it would be great to attach an array of images to a model and allow an arbitrary number of images to be processed with exactly the same options and formats.

Currently, I would have to add lets say 5 image variables and 5 behaviors, even if I want the same behaviors or am I missing something? Has anybody ever tried something like that?

But I would have to integrate it with a multiple upload component…Which is the multiple upload component you would recommend in the moment? I looked at xupload but it seems to be outdated.

maybe someone can post his thoughts on that, cheers, Dennis

I am having troubles figuring out how to use this with files that have already been uploaded. I’m using Xupload to upload the files.

It puts the files into: /images/uploads and saves the record in my Images model.

I want to now run the View controller and display the image, but the following returns null:


echo "File Name: ".$model->ImgBehavior->FileUrl;

In my model I have the following:




	public $ImgBehaviorAttrib;


	public function rules()

	{


		return array(

                        ...

			array('ImgBehaviorAttrib', 'file', 'types' => 'png, gif, jpg', 'allowEmpty' => true),

                        ...

		);


public function behaviors() {

		return array(

			'ImgBehavior' => array(

				'class' => 'ImageARBehavior',

				'attribute' => 'ImbBehaviorAttrib', // this must exist

				'extension' => 'png, gif, jpg', // possible extensions, comma separated

				'prefix' => 'img_',

				'relativeWebRootFolder' => 'images/imgBehaviour', // this folder must exist

				

				# 'forceExt' => png, // this is the default, every saved image will be a png one.

				# Set to null if you want to keep the original format

				

				//'useImageMagick' => 'G:\wamp\imagemagick', # I want to use imagemagick instead of GD, and

				# it is located in /usr/bin on my computer.

				

				// this will define formats for the image.

				// The format 'normal' always exist. This is the default format, by default no

				// suffix or no processing is enabled.

				'formats' => array(

					// create a thumbnail grayscale format

					'thumb' => array(

						'suffix' => '_thumb',

						'process' => array('resize' => array(60, 60), 'grayscale' => true),

					),

					// create a large one (in fact, no resize is applied)

					'large' => array(

						'suffix' => '_large',

					),

					// and override the default :

					'normal' => array(

						'process' => array('resize' => array(200, 200)),

					),

				),

				

				'defaultName' => 'default', // when no file is associated, this one is used by getFileUrl

				// defaultName need to exist in the relativeWebRootFolder path, and prefixed by prefix,

				// and with one of the possible extensions. if multiple formats are used, a default file must exist

				// for each format. Name is constructed like this :

				//     {prefix}{name of the default file}{suffix}{one of the extension}

			)

		);

	}



I am not sure what the attribute is used for in this circumstance since I’ve already uploaded the file. Is it just for the form?

Hope it isnt 2 late


<?php echo "File Name: ".$model->behaviorName->FileUrl($format); ?>

where $format can be left blank if you only have one format or want to get the normal format, which the default one.

you can also use


<?php echo $data->behaviorName->getFileUrl($format); ?>

Great extension BTW

I am still having problems understanding how this works.

In my Images Model I have:




class Images extends MyWebsiteActiveRecord

{

	//For ImgBehaviour extension

	public $filename;


...

public function rules()

	{

		return array(

...

			array('filename', 'file', 'types' => 'png, gif, jpg', 'allowEmpty' => true),

		);

	}

...

public function behaviors() {

		return array(

			'ImgBehavior' => array(

				'class' => 'ImageARBehavior',

				'attribute' => 'filename', // this must exist

				'extension' => 'png, gif, jpg', // possible extensions, comma separated

				'prefix' => 'img_',

				'relativeWebRootFolder' => 'images/imgBehaviour', // this folder must exist

				

				# 'forceExt' => png, // this is the default, every saved image will be a png one.

				# Set to null if you want to keep the original format

				

				//'useImageMagick' => 'G:\wamp\imagemagick', # I want to use imagemagick instead of GD, and

				# it is located in /usr/bin on my computer.

				

				// this will define formats for the image.

				// The format 'normal' always exist. This is the default format, by default no

				// suffix or no processing is enabled.

				'formats' => array(

					// create a thumbnail grayscale format

					'thumb' => array(

						'suffix' => '_thumb',

						'process' => array('crop' => array(200, 200), 'grayscale' => true),

					),

					// create a large one (in fact, no resize is applied)

					'large' => array(

						'suffix' => '_large',

					),

					// and override the default :

					'normal' => array(

						'process' => array('resize' => array(800, 800)),

					),

				),

				

				'defaultName' => 'default', // when no file is associated, this one is used by getFileUrl

				// defaultName need to exist in the relativeWebRootFolder path, and prefixed by prefix,

				// and with one of the possible extensions. if multiple formats are used, a default file must exist

				// for each format. Name is constructed like this :

				//     {prefix}{name of the default file}{suffix}{one of the extension}

			),



In my view file I have




$format = 'thumb'; // for this example you can use 'large' or 'thumb'

echo "Filename = ".$model->ImgBehavior->getFileUrl($format);



In the XUploadAction I have




public function run()

	{

		$this->init();

		$model = new XUploadForm;

		$model->file = CUploadedFile::getInstance($model, 'file');

		$model->mime_type = $model->file->getType();

		$model->size = $model->file->getSize();

		$model->name = $model->file->getName();

/*The above is the native Xupload Action grabbing the data.*/


/*I have added this */

$newImage = new Images;

$newImage->filename = CUploadedFile::getInstance($model, 'file');

/*End addition */


		if ($model->validate()) {

			$path = $this->path.DIRECTORY_SEPARATOR.$this->_subfolder.DIRECTORY_SEPARATOR;

			if(!is_dir($path)){

				mkdir($path);

			}

			

			

			$model->file->saveAs($path.$model->name);

			

			//Saves new image in model

			$newImage->save();


		}




I don’t get any error messages when the uploading runs. Xupload saves the file, but no new thumbs, etc. are created. When loading the view $model->ImgBehavior->getFileUrl($format) returns null.

Here’s how to intergate Xupload with fileimagebehaviour.

Edit FileARBehavior.php


	

public function afterSave($evt) {

                //$file = CUploadedFile::getInstance($this->owner, $this->attribute);

                //change to 

		$file = $this->owner->{$this->attribute};

...



In XuploadAction.php

-Create a new instance of your model and assign the uploaded file from Xupload model to your model.




		$newImage = new Images;

		$newImage->filename = $model->name;

		$newImage->file = CUploadedFile::getInstance($model, 'file');



I hope this helps somebody!

One more question though, how do you chain the image processing commands?

Here are my formats:


		'formats' => array(

					// create a thumbnail grayscale format

					'thumb' => array(

						'suffix' => '_thumb',

						'process' => array('crop' => array(200, 200)),

					),

					// create a large one (in fact, no resize is applied)

					'large' => array(

						'suffix' => '_large',

						'process' => array('resize' => array(2000, 1200)),

					),

					// and override the default :

					'normal' => array(

						'process' => array('resize' => array(800, 800)),

					),

				),

I would like to run the large format first, and then have normal use the already resized large one for processing and then have the thumbnail process the normal format one.

Also, I would like to run crop & resize at the same time for the thumbnail.

There is an error when using ImageMagick and chaining the crop/resize commands. It results in an image of 1px size being created.




                    'thumb' => array(

                                                'suffix' => '_thumb',

                                                'process' => array(

                                                     'resize' => array(400, 400),

                                                     'crop' => array(200, 200),

                                                ),

                                        ),

It works fine in GD. Really wierd.

Other chained commands, like the following are fine in ImageMagick & GD.


                                        'normal' => array(

                                                'process' => array(

                                                'resize' => array(800, 800),

                                                'quality' => array('70'),

                                                'sharpen' => array('5'),

                                                ),

                                        ),

However, once I add crop using ImageMagick it makes the file 1px by 1px. However, the filesize on disk is the correct size and image with 200px dimensions.

Using crop by itself without resize works too.

How will this post end?

Hello,

This extension is really nice, but I’m having two problems that I’m not sure how to solve.

  1. My primary key is automatically generated via javascript, using a concatenation of different values from the form fields. When I create the image, everything is OK, but if I update the image fields, then I have to upload again the image, to avoid having no image at all. What’s more, the previous image that was associated to another ID is left on the directory, and it is not deleted.

  2. How can I have more than one image associated to a model?

Thanks a lot for a great extension!

Arturo.

If you want to make more SEO friendly image file names without having to hack the extension, a really quick (and somewhat) dirty approach could be to use .htaccess

My set up is as follows:

All my product photos go into the following place:

images/products/

FIlename is like img_1.png, img_2.png (etc)

But I want to refrence the images to be more friendly like my-actual-product-name_1.png => img_1.png

So I wrote some little RewriteRule logic to handle that and placed it inside of .htaccess inside of images/products:




RewriteEngine On

RewriteRule ^(.*?)_(.*?)\.(png|jpg|gif)$ img_$2\.$3 [L]



Hth somebody!

Cheers