fancyupload

Hallo,

ich bin ganz neu bei yii und auch mit dem mvc modell habe ich noch wenig erfahrung.

Ich baue mir gerade mithilfe der tutorials und vielem herumprobieren einen backendbereich zusammen,

nun wollte ich es ermöglichen, dass bilder hochgeladen werden können, als user avatar und diese in der datenbank

gespeichert werden als blob.

Habe dabei die extension sfancy upload gefunden und wollte das einfach mal testweiße einbauen, also copy and paste modus aktiviert doch so einfach ist das anscheinend nicht (oder ich bin zu blöd x))

soweit mein versuch (model user und crud sind über yiic shell erstellt)

habe eigentlich fast alles von der dokumentation übernommen…

zur sfancyupload doku

1.) extension in den folder kopiert

2.) in view/user/_form.php view code von der doku angehängt




..

'url'=>$this->createUrl('user/UploadedFiles'),

..



3.) in controllers/UserController/UserController.php und wieder code von der duke angehängt




..

public function actionUploadedFiles()

..



ich weiß, man sollte verstehen was man macht und ich einfach copy and paste, aber sitze da jetzt echt schon lange dran und bin über jeden tipp dankbar :)

lg milo

Hi und willkommen,

ich kann leider über die Extension nicht viel sagen, da ich sie noch nie selbst verwendet hab. Aber ich würd an deiner Stelle erst mal probieren, das ganze mit “Bordmitteln”, also ohne Extension hinzubekommen. Hier gibts z.B. nen Kochbuch-Artikel zum Thema File-Upload. Wenn du zu viel auf einmal machst, multipliziert sich die Anzahl deiner möglichen Fehlerquellen und es wird schwierig, dir zu helfen. ;)

Hey, guys,

Thanks for trying fancyupload. I’ve released a new version 1.1, please, take a look at extensions for downloading the latest file (there are a few improvements and working code samples)

I’m sorry don’t speak German, but I’ll try to help you.

Could you please perform the following test in your application?

1 - Create a folder called tmp under your protected folder, which will store the uploaded files and give it write permission /full access (in Linux chmod 777, in Windows Everyone Full Control). So we have now /protected/tmp to store files.

2 - Put the following code in your protected/controllers/SiteController.php:

//this is to render the view fancy.php, where we will call the widget sfancyupload

public function actionFancy(){

$this->render('fancy');

}

//this is to manage the uploaded files

public function actionUploadedFiles(){

$file = CUploadedFile::getInstanceByName("Filedata");





$return = array(


        'status' => '1',


        'name' => $file->getName()


);





/**


 * ATENTION: this is for demonstration purposes only.


 * In a real world application, you'd better validate


 * the files according to your needs


 */


switch(CFileHelper::getMimeType($file->getTempName())){


   case 'application/zip':


       break;





   case 'image/jpeg':


       $info = @getimagesize($file->getTempName());


        if ($info) {


            $return['width']  = $info[0];


            $return['height'] = $info[1];


            $return['mime']   = $info['mime'];


        }


       break;





   default:


        $return = array(


            'status' => '0',


            'error' => 'Filetype not allowed'


        );


}





//here we'll use the folder tmp to store the uploaded files


$file->saveAs(Yii::app()->getBasePath().'/tmp/'.$file->getName());





//this is to return, in case of images, the width and height to the view


echo json_encode($return);

}

3 - Create a file under protected/views/site and name it fancy.php. Put the following code inside:

<?php

//$this->layout = ‘fancy’;

$statusBoxId = ‘fancy-status’;

$clearButton = ‘fancy-clear’;

$uploadButton = ‘fancy-upload’;

$this->widget(‘application.extensions.fancyupload.SFancyUpload’,

array(


    'name'=&gt;'form-fancy',


    'statusBoxId'=&gt;&#036;statusBoxId,


    'clearButton'=&gt;&#036;clearButton,


    'uploadButton'=&gt;&#036;uploadButton,


    'clearButtonLabel'=&gt;'Limpar Lista',


    'uploadButtonLabel'=&gt;'Enviar',


    'targetLabel'=&gt;'Selecionar Arquivos',


    'options'=&gt; array(


            'verbose'=&gt;true,


            'url'=&gt;&#036;this-&gt;createUrl('site/UploadedFiles'),


            'multiple'=&gt;true,


            'target'=&gt;'fancy-browse',


            'typeFilter'=&gt;array('Imagens (jpg, jpeg, gif, png)'=&gt;'*.jpg; *.jpeg; *.gif; *.png'),//,'Arquivos Compactados'=&gt;'*.zip; *.rar'),


            //'instantStart'=&gt;true,


            //'data'=&gt;array('teste'=&gt;&#036;uploadButton),


        ),





        


    'callbacks' =&gt; array(


        //'onComplete' =&gt; 'function(){alert(&quot;Complete&quot;);}',


        //'onCancel' =&gt; 'function(evt,queueId,fileObj,data){alert(&quot;Cancelled&quot;);}',





        'onLoad'=&gt;&quot;function() {


                &#036;('&#036;statusBoxId').removeClass('hide');


                &#036;('fancy-fallback').destroy();





                // We relay the interactions with the overlayed flash to the link


                this.target.addEvents({


                        click: function() {


                                return false;


                        },


                        mouseenter: function() {


                                this.addClass('hover');


                        },


                        mouseleave: function() {


                                this.removeClass('hover');


                                this.blur();


                        },


                        mousedown: function() {


                                this.focus();


                        }


                });





                // Interactions for the 2 other buttons





                &#036;('&#036;clearButton').addEvent('click', function() {


                        up.remove(); // remove all files


                        return false;


                });





                &#036;('&#036;uploadButton').addEvent('click', function() {


                        up.start(); // start upload


                        return false;


                });


        }&quot;,








        'onFail'=&gt; 'function(error) {


                        switch (error) {


                                case &quot;hidden&quot;: // works after enabling the movie and clicking refresh


                                        alert(&quot;Para habilitar o sistema de upload, desbloqueie no seu browser e atualize.&quot;);


                                        break;


                                case &quot;blocked&quot;: // This no *full* fail, it works after the user clicks the button


                                        alert(&quot;Para habilitar o sistema de upload, habilite o filme flash bloqueado&quot;);


                                        break;


                                case &quot;empty&quot;: // Oh oh, wrong path


                                        alert(&quot;O sistema de upload parece estar faltando, por favor, tente mais tarde&quot;);


                                        break;


                                case &quot;flash&quot;: // no flash 9+ <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/sad.gif' class='bbc_emoticon' alt=':(' />


                                        alert(&quot;Precisa ter o plugin do Adobe Flash 9 ou superior para usar o upload&quot;)


                        }


                }',





        'onFileSuccess'=&gt; &quot;function(file, response) {


            var json = new Hash(JSON.decode(response, true) || {});





            if (json.get('status') == '1') {


                    file.element.addClass('file-success');


                    //file.element.set({style: 'background-image:url(/pirata/images/site/bt_favstar.gif)'});





                    file.info.set('html', '&lt;strong&gt;Arquivo enviado:&lt;/strong&gt; (' + json.get('width') + ' x ' + json.get('height') + 'px, &lt;em&gt;' + json.get('mime') + '&lt;/em&gt;)');


            } else {


                    file.element.addClass('file-failed');


                    file.info.set('html', '&lt;strong&gt;Erro no envio:&lt;/strong&gt; (' + (json.get('error') ? (json.get('error') + ' #' + json.get('code')) : response));


            }


        }&quot;,








        'onSelectFail'=&gt; &quot;function(files) {


                files.each(function(file) {


                        new Element('li', {


                                'class': 'validation-error',


                                html: file.validationErrorMessage || file.validationError,


                                title: MooTools.lang.get('FancyUpload', 'removeTitle'),


                                events: {


                                        click: function() {


                                                this.destroy();


                                        }


                                }


                        }).inject(this.list, 'top');


                }, this);


        }&quot;,








        /*'onFileComplete'=&gt; &quot;function(file) {


                up.fileRemove(file);


        }&quot;,*/





        'onComplete'=&gt;&quot;function() {


           // &#036;('fancy-status').setStyle('display','none');


           //up.remove();


           el = &#036;&#036;('.file-success');


           for (i=0; i&lt;el.length; i++){


               el[i].destroy();


           }


        }&quot;,

//‘onBeforeStart’=>"function() {

//var hash = {};

//document.cookie.split(/;\s*/).each(function(cookie) {

//cookie = cookie.split(’=’);

//if (cookie.length == 2) {

//hash[decodeURIComponent(cookie[0])] = decodeURIComponent(cookie[1]);

//}

//});

//

//up.setOptions({

//data: {cookieName: hash[‘myfield’], myfield: $(‘myfield’).get(‘value’)}

//});

//}",

    )


    


));

?>

4 - Save all and access the url http://yourapplication/site/fancy or http://yourapplication/index.php?r=site/fancy

You should see two bars and three links: to select files, upload them and clear the queue

I’ve just tested this and the code above worked for me.

Please let me know if it works for you now.

:)

Regards!!!

Hi scoob.junior,

thanks for your reply (and coding this extension), i will test your code tomorrow and post the result x)

[- i switch back to german because of the forum category -]

Danke auch dir Mike, habe das tutorial ausprobiert und es funktioniert schon ganz gut, auch das speicher in der datenbank haut super hin, jetzt wollte ich aber die bilder auch noch resizen, was wiederum nicht so gut funktioniert hat…

da ich natürlich wieder mal faul bin wollte ich ich die image extension benutzen:

Mein versuch nr 1 (dachte mir ich könnte vl die render funktion von image benutzen)




private function storeUserImage($model, $attribute, $max_width, $max_height)

{

  $file = CUploadedFile::getInstance($model, $attribute);


  $image = Yii::app()->image->load($file->getName());

  $image->resize(100, 100);

			

  if(!$file->getHasError()) 

  { 

    $model->profile_picture = file_get_contents($image->render());

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

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

  }

 

  return $file;

}



Abgesehen davon, dass ich mir nicht sicher bin ob file_get_contents($image->render()) funktioniert habe ich das prinzipielle problem, das die extension mein image nicht als solches erkennt, weil es halt .tmp ist.

Versuch nummer 2 (mit zwischenspeichern)




private function storeUserImage($model, $attribute, $max_width, $max_height)

{

  $file = CUploadedFile::getInstance($model, $attribute);


  $file->saveAs($file->getName()); //save picture on server tmp

  $image = Yii::app()->image->load($file->getName());

  $image->resize(100, 100);

  $image->save($file->getName());

  ...



Doch bereits schn bei $image->save($file->getName()); bekomme ich:




PHP Error

Description


include(CArray.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory

Source File


C:\xampp\htdocs\yii\framework\YiiBase.php(338)


00326:      * @param string class name

00327:      * @return boolean whether the class has been loaded successfully

00328:      */

00329:     public static function autoload($className)

00330:     {

00331:         // use include so that the error PHP file may appear

00332:         if(isset(self::$_coreClasses[$className]))

00333:             include(YII_PATH.self::$_coreClasses[$className]);

00334:         else if(isset(self::$_classes[$className]))

00335:             include(self::$_classes[$className]);

00336:         else

00337:         {

00338: include($className.'.php');

00339:             return class_exists($className,false) || interface_exists($className,false);

00340:         }

00341:         return true;

00342:     }

00343: 

00344:     /**

00345:      * Writes a trace message.

00346:      * This method will only log a message when the application is in debug mode.

00347:      * @param string message to be logged

00348:      * @param string category of the message

00349:      * @see log

00350:      */


Stack Trace


#0 C:\xampp\htdocs\yii\framework\YiiBase.php(338): autoload()

#1 unknown(0): autoload()

#2 C:\xampp\htdocs\bm2\protected\extensions\image\drivers\Image_GD_Driver.php(80): spl_autoload_call()

#3 C:\xampp\htdocs\bm2\protected\extensions\image\Image.php(334): Image_GD_Driver->process()

#4 C:\xampp\htdocs\bm2\protected\controllers\UserController.php(111): Image->save()

#5 C:\xampp\htdocs\yii\framework\web\actions\CInlineAction.php(32): UserController->actionCreate()

#6 C:\xampp\htdocs\yii\framework\web\CController.php(300): CInlineAction->run()

#7 C:\xampp\htdocs\yii\framework\web\filters\CFilterChain.php(129): UserController->runAction()

#8 C:\xampp\htdocs\yii\framework\web\filters\CFilter.php(41): CFilterChain->run()

#9 C:\xampp\htdocs\yii\framework\web\CController.php(957): CAccessControlFilter->filter()

#10 C:\xampp\htdocs\yii\framework\web\filters\CInlineFilter.php(59): UserController->filterAccessControl()

#11 C:\xampp\htdocs\yii\framework\web\filters\CFilterChain.php(126): CInlineFilter->filter()

#12 C:\xampp\htdocs\yii\framework\web\CController.php(283): CFilterChain->run()

#13 C:\xampp\htdocs\yii\framework\web\CController.php(257): UserController->runActionWithFilters()

#14 C:\xampp\htdocs\yii\framework\web\CWebApplication.php(310): UserController->run()

#15 C:\xampp\htdocs\yii\framework\web\CWebApplication.php(120): CWebApplication->runController()

#16 C:\xampp\htdocs\yii\framework\base\CApplication.php(135): CWebApplication->processRequest()

#17 C:\xampp\htdocs\bm2\index.php(11): CWebApplication->run()



lg milo

Fix:

just put these code into /protected/components/CArray.php, :rolleyes: , works good !




<?php

/**

 * Array helper class.

 *

 * $Id: arr.php 3769 2008-12-15 00:48:56Z zombor $

 *

 * @package    Core

 * @author     Kohana Team

 * @copyright  (c) 2007-2008 Kohana Team

 * @license    http://kohanaphp.com/license.html

 */

class CArray {


	/**

	 * Return a callback array from a string, eg: limit[10,20] would become

	 * array('limit', array('10', '20'))

	 *

	 * @param   string  callback string

	 * @return  array

	 */

	public static function callback_string($str)

	{

		// command[param,param]

		if (preg_match('/([^\[]*+)\[(.+)\]/', (string) $str, $match))

		{

			// command

			$command = $match[1];


			// param,param

			$params = preg_split('/(?<!\\\\),/', $match[2]);

			$params = str_replace('\,', ',', $params);

		}

		else

		{

			// command

			$command = $str;


			// No params

			$params = NULL;

		}


		return array($command, $params);

	}


	/**

	 * Rotates a 2D array clockwise.

	 * Example, turns a 2x3 array into a 3x2 array.

	 *

	 * @param   array    array to rotate

	 * @param   boolean  keep the keys in the final rotated array. the sub arrays of the source array need to have the same key values.

	 *                   if your subkeys might not match, you need to pass FALSE here!

	 * @return  array

	 */

	public static function rotate($source_array, $keep_keys = TRUE)

	{

		$new_array = array();

		foreach ($source_array as $key => $value)

		{

			$value = ($keep_keys === TRUE) ? $value : array_values($value);

			foreach ($value as $k => $v)

			{

				$new_array[$k][$key] = $v;

			}

		}


		return $new_array;

	}


	/**

	 * Removes a key from an array and returns the value.

	 *

	 * @param   string  key to return

	 * @param   array   array to work on

	 * @return  mixed   value of the requested array key

	 */

	public static function remove($key, & $array)

	{

		if ( ! array_key_exists($key, $array))

			return NULL;


		$val = $array[$key];

		unset($array[$key]);


		return $val;

	}


	

	/**

	 * Extract one or more keys from an array. Each key given after the first

	 * argument (the array) will be extracted. Keys that do not exist in the

	 * search array will be NULL in the extracted data.

	 *

	 * @param   array   array to search

	 * @param   string  key name

	 * @return  array

	 */

	public static function extract(array $search, $keys)

	{

		// Get the keys, removing the $search array

		$keys = array_slice(func_get_args(), 1);


		$found = array();

		foreach ($keys as $key)

		{

			if (isset($search[$key]))

			{

				$found[$key] = $search[$key];

			}

			else

			{

				$found[$key] = NULL;

			}

		}


		return $found;

	}


	/**

	 * Because PHP does not have this function.

	 *

	 * @param   array   array to unshift

	 * @param   string  key to unshift

	 * @param   mixed   value to unshift

	 * @return  array

	 */

	public static function unshift_assoc( array & $array, $key, $val)

	{

		$array = array_reverse($array, TRUE);

		$array[$key] = $val;

		$array = array_reverse($array, TRUE);


		return $array;

	}


	/**

	 * Because PHP does not have this function, and array_walk_recursive creates

	 * references in arrays and is not truly recursive.

	 *

	 * @param   mixed  callback to apply to each member of the array

	 * @param   array  array to map to

	 * @return  array

	 */

	public static function map_recursive($callback, array $array)

	{

		foreach ($array as $key => $val)

		{

			// Map the callback to the key

			$array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val);

		}


		return $array;

	}


	/**

	 * Binary search algorithm.

	 *

	 * @param   mixed    the value to search for

	 * @param   array    an array of values to search in

	 * @param   boolean  return false, or the nearest value

	 * @param   mixed    sort the array before searching it

	 * @return  integer

	 */

	public static function binary_search($needle, $haystack, $nearest = FALSE, $sort = FALSE)

	{

		if ($sort === TRUE)

		{

			sort($haystack);

		}


		$high = count($haystack);

		$low = 0;


		while ($high - $low > 1)

		{

			$probe = ($high + $low) / 2;

			if ($haystack[$probe] < $needle)

			{

				$low = $probe;

			}

			else

			{

				$high = $probe;

			}

		}


		if ($high == count($haystack) OR $haystack[$high] != $needle)

		{

			if ($nearest === FALSE)

				return FALSE;


			// return the nearest value

			$high_distance = $haystack[ceil($low)] - $needle;

			$low_distance = $needle - $haystack[floor($low)];


			return ($high_distance >= $low_distance) ? $haystack[ceil($low)] : $haystack[floor($low)];

		}


		return $high;

	}


	/**

	 * Emulates array_merge_recursive, but appends numeric keys and replaces

	 * associative keys, instead of appending all keys.

	 *

	 * @param   array  any number of arrays

	 * @return  array

	 */

	public static function merge()

	{

		$total = func_num_args();


		$result = array();

		for ($i = 0; $i < $total; $i++)

		{

			foreach (func_get_arg($i) as $key => $val)

			{

				if (isset($result[$key]))

				{

					if (is_array($val))

					{

						// Arrays are merged recursively

						$result[$key] = arr::merge($result[$key], $val);

					}

					elseif (is_int($key))

					{

						// Indexed arrays are appended

						array_push($result, $val);

					}

					else

					{

						// Associative arrays are replaced

						$result[$key] = $val;

					}

				}

				else

				{

					// New values are added

					$result[$key] = $val;

				}

			}

		}


		return $result;

	}


	/**

	 * Overwrites an array with values from input array(s).

	 * Non-existing keys will not be appended!

	 *

	 * @param   array   key array

	 * @param   array   input array(s) that will overwrite key array values

	 * @return  array

	 */

	public static function overwrite($array1)

	{

		foreach (array_slice(func_get_args(), 1) as $array2)

		{

			foreach ($array2 as $key => $value)

			{

				if (array_key_exists($key, $array1))

				{

					$array1[$key] = $value;

				}

			}

		}


		return $array1;

	}


	/**

	 * Fill an array with a range of numbers.

	 *

	 * @param   integer  stepping

	 * @param   integer  ending number

	 * @return  array

	 */

	public static function range($step = 10, $max = 100)

	{

		if ($step < 1)

			return array();


		$array = array();

		for ($i = $step; $i <= $max; $i += $step)

		{

			$array[$i] = $i;

		}


		return $array;

	}


	/**

	 * Recursively convert an array to an object.

	 *

	 * @param   array   array to convert

	 * @return  object

	 */

	public static function to_object(array $array, $class = 'stdClass')

	{

		$object = new $class;


		foreach ($array as $key => $value)

		{

			if (is_array($value))

			{

				// Convert the array to an object

				$value = arr::to_object($value, $class);

			}


			// Add the value to the object

			$object->{$key} = $value;

		}


		return $object;

	}


} // End arr