2009年3月28日星期六

Re: [fw-mvc] form->getValues and file upload

Simone,

In case the file was already received, the received method returns true and
not null.
Only when the upload is not possible due to failed validation it returns
false, and null by getValues().

The reason is, that when the file is not uploaded (because it's not valid)
it will of course also not have a value due to being empty.

For the next minor release, the change you mentioned is no longer necessary
as you can get file informations since several weeks also after the file has
already been received.

Greetings
Thomas Weidner, I18N Team Leader, Zend Framework
http://www.thomasweidner.com

----- Original Message -----
From: "Simone Cosci" <s.cosci@nextidea.it>
To: <fw-mvc@lists.zend.com>
Sent: Saturday, March 28, 2009 2:48 AM
Subject: Re: [fw-mvc] form->getValues and file upload


>
>> On Thu, Mar 26, 2009 at 4:59 PM, Abraham Block <atblock@gmail.com> wrote:
>>> Why would you need to do getValues more than once?
>>
>> Sorry, that's not what I meant. Let me put it this way...
>>
>> When you request the value of something, if that's your only intent,
>> shouldn't the value of the source remain unchanged in the process?
>> For example, $object->getName() should just return the Name and not
>> change the value of Name in the process. Or, in this case, if you
>> request values for the elements of a form, would you expect to change
>> the values of those elements in the process?
>>
>> It seems like the change in value, the tmp files being removed, is
>> unexpected when I'm calling $form->getValues. What do you think?
>>
>> Also, if you're working with form file elements, don't you have to
>> make sure that you process the uploaded files before calling something
>> like $object->saveEntry($form->getValues())? (or you have to use
>> $form->getValue('property') )
>>
>> -Ed
>>
>
> Hi, I'm a newbie of ZF so I' don't know if what I did it's OK or not
> this case; anyway,
> that's how I did to avoid this problem:
>
> 1) create an extension of Zend_Form_Element_File overloading the
> getValue() method and removing from it only this code:
> if (!$this->receive()) {
> return null;
> }
>
> as follow
>
> class Planet_Form_Element_File extends Zend_Form_Element_File
> {
> public function init()
> {
> $t = Zend_Registry::getInstance()->translate;
> $label = (null !== $t) ? $t->_($this->getName()) :
> ucfirst(str_replace("_", " ", $this->getName()));
> $this->setLabel($label);
> }
>
> public function loadDefaultDecorators()
> {
>
> $this->setDecorators(array(
> 'ViewHelper',
> 'Errors',
> array('decorator' => array('td' => 'HtmlTag'), 'options' =>
> array('tag' => 'td')),
> array('Label', array('tag' => 'td')),
> array('decorator' => array('tr' => 'HtmlTag'), 'options' =>
> array('tag' => 'tr'))
> ));
>
> }
>
> /**
> * Processes the file, returns null or the filename only
> * For the complete path, use getFileName
> *
> * @return null|string
> */
> public function getValue()
> {
> if (!is_null($this->_value)) {
> return $this->_value;
> }
>
> $content =
> $this->getTransferAdapter()->getFileName($this->getName());
> if (empty($content)) {
> return null;
> }
>
> if (!$this->isValid(null)) {
> return null;
> }
>
> $filenames = $this->getFileName();
> if (count($filenames) == 1) {
> $this->_value = basename($filenames);
> return $this->_value;
> }
>
> $this->_value = array();
> foreach($filenames as $filename) {
> $this->_value[] = basename($filename);
> }
>
> return $this->_value;
> }
> }
>
> Then to handle the files use (forward methods to) an adapter (forced to
> Zend_File_Transfer_Adapter_Http 'cause there's no other :p) like this
>
> /** Planet_Exception */
> require_once 'Planet/Exception.php';
>
> class Planet_File_Transfer extends Zend_File_Transfer
> {
> /**
> * Transfer Adapter
> *
> * @var Zend_File_Transfer_Adapter_Http
> */
> protected $_adapter;
>
> /**
> * Creates a file processing handler
> *
> * @param string $protocol Protocol to use
> */
> public function __construct($protocol = null)
> {
> switch (strtoupper($protocol)) {
> default:
> $adapter = 'Zend_File_Transfer_Adapter_Http';
> break;
> }
>
> Zend_Loader::loadClass($adapter);
> $this->_adapter = new $adapter();
> if (!$this->_adapter instanceof
> Zend_File_Transfer_Adapter_Abstract) {
> require_once 'Zend/File/Transfer/Exception.php';
> throw new Zend_File_Transfer_Exception("Adapter " . $adapter
> . " does not extend Zend_File_Transfer_Adapter'");
> }
>
> return $this->_adapter;
> }
>
> /**
> * Wraps the methods of the adapter object
> *
> * @param string $method
> * @param array $params
> * @return mixed
> */
> public function __call($method, $params)
> {
> if(!$this->_adapter instanceof
> Zend_File_Transfer_Adapter_Abstract ||
> !method_exists($this->_adapter,$method)){
> throw new Planet_Exception('Adapter has not a method ' .
> $method);
> return false;
> }
> return call_user_func_array(array($this->_adapter, $method),
> $params);
> }
>
> /**
> * Get a property of the adapter object
> *
> * @param string $property
> * @return mixed
> */
> public function __get($property)
> {
> if(!property_exists(get_class($this->_adapter), $property)){
> throw new Planet_Exception('Adapter has not a property ' .
> $property);
> return false;
> }
> return $this->_adapter->$property;
> }
>
> /**
> * Set a property of the adapter object
> *
> * @param string $property
> * @param mixed $value
> * @return Zend_File_Transfer_Adapter_Abstract
> */
> public function __set($property, $value) {
> if(!property_exists(get_class($this->_adapter), $property)){
> throw new Planet_Exception('Adapter has not a property ' .
> $property);
> return false;
> }
> $this->_adapter->$property = $value;
> return $this->_adapter;
> }
>
>
> }
>
> And use it :
>
> in form script)
> $attached_file = new Planet_Form_Element_File('attached_file');
> $this->addElement($attached_file);
>
>
> in server receiver script)
>
> $upload = new Planet_File_Transfer();
> $files = $upload->getFileInfo();
>
> so the file is still in your tmp dir and have to be manually
> moved as usual
>
> I did also a Planet_Image_Handler that uses an adapter:
> 1) Planet_Image_Magick (or)
> 2) Planet_Image_Gd
> for the image handling (resizing) under a common interface
> Planet_Image_Adapter_Interface
> this is to create 3 images from 1 ... renaming them into
> 123_0.jpg (big)
> 123_1.jpg (med)
> 123_2.jpg (small)
>
> foreach ($files as $file => $info)
> {
> $resizeMap = array(1,2,3);
> if(file_exists($info['tmp_name']))
> {
> $size = getimagesize($info['tmp_name']);
> $class =
> Zend_Registry::getInstance()->configuration->image->adapter->class;
> $image_handler = new Planet_Image_Handler( new
> $class($info) );
>
> $image_handler->getAdapter()->setTargetDir(APPLICATION_PATH .
> '/usr/admin/html/files/');
> $image_handler->init();
> /** debug */
> // $image_handler->getAdapter()->setVerbose(true);
> foreach($resizeMap as $k => $q)
> {
> $imageName = $id . '_' . ($k) . '.jpg';
> $new_w = intval($size[0]/$q);
> $new_h = intval($size[1]/$q);
> $image_handler->setTarget(APPLICATION_PATH .
> '/usr/admin/html/files/' . $imageName);
> $image_handler->resize($new_w, $new_h);
> $image_handler->save();
> }
> $image_handler->getAdapter()->cleanup();
> }
> }
> }
>
> Hope this help
>
> Bye
> Simone
>
> --
> ________________________________________________________________________________
>
> Simone Cosci - Planet S.r.l. Sistemi informatici
> Via Giorgio Ambrosoli, 39 - 50018, Scandicci, Firenze, Italy
> WEB: http://www.planetweb.it - http://www.ticka.it
> E-Mail s.cosci@nextidea.it
> Tel. +39 055 7350271 - Fax. +39 055 7351109 - Cell. 347 4237084
> ________________________________________________________________________________
>

没有评论: