[EXTENSION] CFile

Does it make sense, I mean, are there reasonably many cases when we need such atomicity in filesystems? Besides, that FS functionality could barely be emulated (eg. through tmp files) by php. What do you think?

I have a problem when using file->set() within CGridView :(

Attribute ‘country_flag’ contains the pathname of the country’s flag graphic that I want to display if the pathname is correct and the file exists, otherwise leave the cell blank instead of displaying the broken image icon:




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'countries-grid',

	'dataProvider'=>$model->search(),

	'columns'=>array(

		'country_code',

		'country_name',

		'country_currency',

		'country_flag',

		array(

			'name'=>'country_flag',

			'header'=>'Flag Image',

			'value'=>'Yii::app()->file->set($data->country_flag)->exists ? $data->country_flag : NULL',

			'type'=>'image',

		),

		'country_enabled:boolean',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Unfortunately I get this error:




CException

Description


Path to filesystem object is not specified within CFile::set method



How do I solve this? Thanks for the help.

Hi,

As I see it, you need to make sure that $data->country_flag is set (contains some value) before you supply it to CFile’s ‘set’ method.

Thanks for your quick reply. The thing is that $data->country_flag does contain a value.

If instead I use:




'value'=>'strlen(trim($data->country_flag)) > 0 ? $data->country_flag : NULL',



it correctly displays the graphic file, but only for correct, non-empty pathnames where the file exists. If the pathname is incorrect or even if it’s correct but the graphic file doesn’t exist, it displays the broken image icon. My intention is to validate the pathname and the existence of the file.

Any suggestions? Thanks for the help.

Could you post here the value causing the exception?

Once again, thanks for the help. Here’s my data:

As you can see, most records are complete except for Test Country, whose country_flag is by default NULL. The error happens even if Test Country is not in the database.

Hm, when I asked the value causing the exception, I meant not the data from the DB but the value of ‘$data->country_flag’ (let’s say var_dump($data->country_flag)). You see when you’re doing




'value'=>'Yii::app()->file->set($data->country_flag)->exists ? $data->country_flag : NULL',



with $data->country_flag valuated to null or an empty string CFile raises the exception. The easiest way is to check ‘$data->country_flag’ before CFile call, i.e. ensure that CFile accepts some meaningful value.

I now understand that’s the only way it works then. I can check for a null value easily, but what I hoped the function would do for me was to verify that the meaningful (non-null) value was also verifiable so it could raise a specific exception such as “file not found”. Thanks.

I’ll think it over, meanwhile you can always fork CFile at Github (http://github.com/idlesign/ist-yii-cfile) and propose the patch to master branch, you’re certainly welcome.

Yes, I’ll take a look at it. Thanks again for your help.

On Windows everything’s ok but when I moved the application to Linux I got the following errors

posix_getpwuid() expects parameter 1 to be long, string given

Source File

/var/www/upload/protected/extensions/file/CFile.php(563)

And when I changed public function getOwner($getName=true) to public function getOwner($getName=false)

I got

posix_getgrgid() expects parameter 1 to be long, string given

Source File

/var/www/upload/protected/extensions/file/CFile.php(586)

I had to change public function getGroup($getName=true) to public function getGroup($getName=false)

to got it working

Hi, Spyros, it’s been a while :)

Please have a try with this quick-fixed version (0.6.1):

http://github.com/idlesign/ist-yii-cfile/raw/master/CFile.php

And, before you did that, I would ask you to dump $this->_owner before line 563, and $this->_group before line 586, as to give me a clue what string is given to ‘posix_getpwuid’ and ‘posix_getgrgid’ instead of long.

I did it

The strange is that it dumps 1000

:blink:

Hm, 1000, strange it is. Expected that function should return the name of your first non-meta group.

We then should expect that posix_getgrgid(1000) doesn’t work either, but that doesn’t make sense. Could you test it?

Does 0.6.1 fix work?

Yes 0.6.1 fixed it

Hello, first of all thank you for this wonderful extension. It has been very helpful.

I am a beginner of Yii and php but I changed a few things that I needed.

The first is on the send function

            header('Cache-control: private');


            header('Pragma: private');


            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');





            header('Content-Type: '.&#036;content_type);


            header('Content-Transfer-Encoding: binary');


            header('Content-Length: '.&#036;this-&gt;size(false));


            header('Content-Disposition: attachment;filename=&quot;'.&#036;filename.'&quot;');

by:

            header('Cache-control: private');


            header('Pragma: private');


            header('Content-Description: File Transfer');


            header('Expires: 0');


            header('Content-Type: '.&#036;content_type);


            header('Content-Transfer-Encoding: binary');


            header('Content-Length: '.&#036;this-&gt;size(false));


            header('Content-Disposition: attachment;filename=&quot;'. &#036;this-&gt;basename . '&quot;');

The second thing is that I modified setContents function adding a parameter to indicate whether the content will be added or not.

"public function setContents($contents=null, $addcontents=false, $autocreate=true)"

        if (&#33;(&#036;addcontents)) {


            if(&#036;this-&gt;writeable &amp;&amp; file_put_contents(&#036;this-&gt;_realpath, &#036;contents)&#33;==false)


                return &#036;this;


        } else {


            if(&#036;this-&gt;writeable &amp;&amp; file_put_contents(&#036;this-&gt;_realpath, &#036;contents, FILE_APPEND)&#33;==false)


                return &#036;this;


        }

I do not know if it’s the right way but it worked. I hope it is helpful to make a fix if necessary.

Greetings!

Version 0.7 is available, introducing flags for setContents() method

  • new: ‘flags’ argument for setContents() method (proposed by TeKi)

  • fix: parameter type checks (for ‘posix_getpwuid’ & ‘posix_getgrgid’ functions) added to getOwner and getGroup methods (spotted by Spyros)

http://www.yiiframework.com/extension/cfile/

Hi!

great extension!

I have a few proposals for future versions. I hope I don’t ask for too much!

It would be great if there where methods to calculate different checksums for the files (possibly crc32, sha1, md5)

eg something like this (NOT tested!):


	public function getMD5()

	{

		if ($this->isFile)

		{

			Yii::trace('Calculating MD5 checksum for "'.$this->_realpath.$this->_filename.$this->_extension.'"', 'ext.file');

            if ($this->readable)

			{

				$md5 = md5_file($this->_realpath.$this->_filename.$this->_extension);

				return $md5;

			}

			return false;

		}

		else

		{

			$this->addLog(__METHOD__.' method is available only for files', 'warning');

			return false;

		}

	}



and maybe a way to compare two files. to compare a file there is a interesting solution found here

keep up the good work!

regards

Hi,

I am using PHP version 5.1.6, on line 238 $pathinfo[‘filename’] is used.

‘filename’ can be used since PHP version 5.2.0 so this throws a PHP error: undefined index ‘filename’ for me.

I have solved this problem by checking the PHP version:




        if (version_compare(PHP_VERSION, '5.2.0') >= 0)

          $this->_filename = $pathinfo['filename'];

        else

          $this->_filename = basename($this->_isUploaded?$this->_uploadedInstance->getName():$this->_realpath);



Ran into some trouble with permissions.

Permissions were messed up using $file->permissions=755 for example.

Fixed on line 1063 with:




$permissions = octdec(str_pad($permissions, 4, "0", STR_PAD_LEFT));