Upload di immagini

Grazie all’ottima documentazione di Yii sono riuscito in pochissimo tempo ad aggiungere ad un form un campo immagine. Al momento però, mi si presentano due problemi:

  1. quando faccio l’aggiornamento di un record, non riesco a salvare le modifiche in quanto mi richiede ancora l’immagine.

  2. avrei anche bisogno di ridimensionare l’immagine. Devo fare “a mano” o ci sono dei tool offerti da Yii?

Ciao.

Usa l’estensione image per ridimensionare:

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

In che senso ti richiede ancora l’immagine ? Non ho capito.

Guarda anche il seguente Topic:

http://www.yiiframework.com/forum/index.php?/topic/1777-optional-image-upload-on-update/page__p__9993__hl__update+image

Se metti il codice forse e’ meglio.

Intanto grazie per l’ottimo link che mi hai passato. Che codice ti può servire? Io ho seguito queste istruzioni:

http://www.yiiframework.com/wiki/2/how-to-upload-a-file-using-a-model/

Metto uno screenshot allegato a questo post. In pratica se arrivo alla pagina di modifica e faccio salva senza fare nulla… mi mostra la schermata che ho allegato.

Ecco il codice.




    <tr>

      <td width="50%" align="right"><?php echo $form->labelEx($model,'immagine'); ?></td>

      <td width="50%" align="left"><?php echo CHtml::activeFileField($model, 'immagine'); ?></td>

    </tr>



Così a naso, mi sta venendo in mente che potrebbe avere senso fare una cosa del tipo:




<?php if ($model->immagine == "") : ?>

    <tr>

      <td width="50%" align="right"><?php echo $form->labelEx($model,'immagine'); ?></td>

      <td width="50%" align="left"><?php echo CHtml::activeFileField($model, 'immagine'); ?></td>

    </tr>

<?php else: ?>

    <tr>

      <td width="50%" align="right"><?php echo $form->labelEx($model,'immagine'); ?></td>

      <td width="50%" align="left"><img src="" ... ... /></td>

    </tr>

<?php endif; ?>



e magari aggiungerci un bottone per eliminare l’immagine. Che devo fare?

No la vista lasciala stare.

Hai visto il link ?

http://www.yiiframework.com/forum/index.php?/topic/1777-optional-image-upload-on-update/page__p__9993__hl__update+image

Nel Model delle immagini aggiungi ‘allowEmpty’=>true nella funzione rules.

Nell’azione Update devi controllare il nome del file immagine, se esiste non aggiorni se non esiste salvi l’immagine.

Salvataggio tutto ok. Ora è la volta del link per ridimensionare le immagini.

Temo di aver fatto quella che in gerco si definisce porcata… ma al momento non riesco a fare di meglio =(:




  public function actionCreate() {

    $model = new Automobili;

    if(isset($_POST['Automobili'])) {

      $model->attributes = $_POST['Automobili'];

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

      $image = Yii::app()->image->load(Yii::app()->basePath."/../images/".$model->immagine);

      $image->resize(640,480)->rotate(45)->quality(75)->sharpen(20);

      $image->save();

      if($model->save()) {

        $model->immagine->saveAs(Yii::app()->basePath."/../images/".$model->immagine);

        $this->redirect(array('view','id'=>$model->id));

      }

    }

    $this->render('create',array(

      'model'=>$model,

    ));

  }



Non e’ niente male, per farlo piu’ mvc puoi spostare questa parte di codice:


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

      $image = Yii::app()->image->load(Yii::app()->basePath."/../images/".$model->immagine);

      $image->resize(640,480)->rotate(45)->quality(75)->sharpen(20);

      $image->save();



Nella after save, solo se il model e’ newRecord.

Ho tentato con





  public function actionCreate() {


    $model = new Automobili;

    if(isset($_POST['Automobili'])) {

      $model->attributes = $_POST['Automobili'];

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

      if($model->save()) {

        

        $model->immagine->saveAs(Yii::app()->basePath."/../images/".$model->immagine);

        $image = Yii::app()->image->load(Yii::app()->basePath."/../images/".$model->immagine);

        $image->resize(640,480);

        $image->save();


        $this->redirect(array('view','id'=>$model->id));

      }

    }


    $this->render('create',array(

      'model'=>$model,

    ));

  }



L’immagine viene salvata correttamente. Ma non ridimensionata. In oltre si genera un eccezione:




PHP Error


Descrizione


include(CArray.php): failed to open stream: No such file or directory


File Sorgente


/var/www/yii/framework/YiiBase.php(395)


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

00384:      */

00385:     public static function autoload($className)

00386:     {

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

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

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

00390:         else if(isset(self::$classMap[$className]))

00391:             include(self::$classMap[$className]);

00392:         else

00393:         {

00394:             if(strpos($className,'\\')===false)

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

00396:             else  // class name with namespace in PHP 5.3

00397:             {

00398:                 $namespace=str_replace('\\','.',ltrim($className,'\\'));

00399:                 if(($path=self::getPathOfAlias($namespace))!==false)

00400:                     include($path.'.php');

00401:                 else

00402:                     return false;

00403:             }

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

00405:         }

00406:         return true;

00407:     }

Stack Trace


#0 /var/www/yii/framework/YiiBase.php(395): autoload()

#1 unknown(0): autoload()

#2 /var/www/anacletobazzi/protected/extensions/image/drivers/Image_GD_Driver.php(80): spl_autoload_call()

#3 /var/www/anacletobazzi/protected/extensions/image/Image.php(334): Image_GD_Driver->process()

#4 /var/www/anacletobazzi/protected/controllers/AutomobiliController.php(45): Image->save()

#5 /var/www/yii/framework/web/actions/CInlineAction.php(57): AutomobiliController->actionCreate()

#6 /var/www/yii/framework/web/CController.php(300): CInlineAction->run()

#7 /var/www/yii/framework/web/filters/CFilterChain.php(133): AutomobiliController->runAction()

#8 /var/www/yii/framework/web/filters/CFilter.php(41): CFilterChain->run()

#9 /var/www/yii/framework/web/CController.php(1084): CAccessControlFilter->filter()

#10 /var/www/yii/framework/web/filters/CInlineFilter.php(59): AutomobiliController->filterAccessControl()

#11 /var/www/yii/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter()

#12 /var/www/yii/framework/web/CController.php(283): CFilterChain->run()

#13 /var/www/yii/framework/web/CController.php(257): AutomobiliController->runActionWithFilters()

#14 /var/www/yii/framework/web/CWebApplication.php(324): AutomobiliController->run()

#15 /var/www/yii/framework/web/CWebApplication.php(121): CWebApplication->runController()

#16 /var/www/yii/framework/base/CApplication.php(135): CWebApplication->processRequest()

#17 /var/www/anacletobazzi/index.php(13): CWebApplication->run()



… che chiedo scusa … ma non so leggere e correggere. Faccio qualche ricerca per risolvere questo problema. Vi tengo aggiornati. Se avete la soluzione vi prego di condividerla con me =(.

Uops!

Il segreto era tutto racchiuso nell’installazione:

[indent]Installation ¶

Extract image folder under protected/extensions

Extract helpers folder under protected[/indent]

Non avevo installato correttamente la cartella helpers. Ho ricercato, infatti, l’errore che mi veniva fuori: e sono tornato proprio sulla pagina di questa estensione. Ho riletto tutto da capo ed ho fatot più attenzione questa volta. Grazie ancora per l’aiuto. Spero che queste mie disavventure possano essere di aiuto agli altri italiofoni di questo forum.

Ciao volevo sapere come avevi fatto a fare l’upload dell’immagine…

io vorrei fare upload dell’immagine nella cartella images ovviamente chiamo l’immagine con “id” dello User in questo modo è univoco…

poi per visualizzarlo vedo solo se nella cartella images c’è altrimenti nulla…

Ho modificato il “_form” in modo tale da potere inserire l’immagine ma non mi è chiaro poi come dal controller lo salvo…

ho installato anche l’estensione “image” per effettuare il ridimensionamento ma mi chiedevo se puoi darmi qualche dritta!

grazie mille

Anche io uso la stessa estensione.

Nel file di configurazione devi aggiungere il componente.




    'image' => array(

      'class' => 'application.extensions.image.CImageComponent',

      'driver' => 'GD',

      'params' => array('directory' => '/opt/local/bin/')

    ),



E quando salvi puoi fare una cosa simile alla mia:




  public function actionCreate() {

    $model = new Moto;

    if (isset($_POST['Moto'])) {

      $model->attributes = $_POST['Moto'];

      if ($model->save()) {

        if(@$_FILES["Moto"]["name"]["immagine"]) {

          if (CUploadedFile::getInstance($model, 'immagine') != "") {

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

            $model->immagine->saveAs(Yii::app()->basePath . "/../images/moto_".($model->id)."_" . (@$_FILES["Moto"]["name"]["immagine"]));

            $image = Yii::app()->image->load(Yii::app()->basePath . "/../images/moto_".($model->id)."_" . (@$_FILES["Moto"]["name"]["immagine"]));

            $image->resize(179, 179);

            $image->save();

          }

          $model->immagine = "moto_" . ($model->id) . "_". ($_FILES["Moto"]["name"]["immagine"]);

          $model->save();

        }

        $this->redirect(array('view', 'id' => $model->id));

      }

    }

    $this->render('create', array(

      'model' => $model,

    ));

  }



Purtroppo io mi sono imbattuto in PHPv5.1 quindi ho dovuto prendere qualche accorgimento per far funzionare correttamente la libreria. Ovviamente devi modificare il nome dell’array super globale $_FILES ed il gioco è fatto.

Diamine =) Mi hai appena fatto notare che avevo lasciato in sospeso questo post. In quel tempo credo di aver postato la soluzione solo nel post inglese.

MHMHMH domanda…

ma nel tuo "models" come hai dichiarato immagine???

perchè altrimenti a me ovviamente da come errore "La proprietà "User"."immagine" non è definita.".

grazie!

Nel model si chiama "immagine".

Però mi stanno venendo in mente alcune cose. In primis, che bisogna dire che il form non è un form normale quindi:




  <?php $form = $this->beginWidget('CActiveForm', array(

    'id'=>'automobili-form',

    'enableAjaxValidation'=>false,

    'htmlOptions'=>array('enctype'=>'multipart/form-data'),

  )); ?>



e ti vorrei far notare questo:




'htmlOptions'=>array('enctype'=>'multipart/form-data'),



Poi il campo immagine, nel form ce l’ho così:




<?php echo CHtml::activeFileField($model, 'immagine'); ?>



Dimmi se ora funziona.

No mi dice"La proprietà "User"."immagine" non è definita."

sbaglio sicuramente a dichiarare "immagine" dentro al models "User.php"

Vuoi mandarmi il model che così ci guardo?

Ok prova a dargli un occhio se hai tempo tieni conto che nel db non vorrei mettere la voce “immagine” dato che sarebbe l’avatar dell’utente lo salvo in una cartella e metto come nome "id"e poi per visualizzarlo guardo se c’è…

Mmmm non vedo il campo immagine. Io fossi in te, creerei un campo immagine di tipo varchar. Quando un utente mette su il suo avatar viene memorizzato li. Poi, che tu voglia usare l’id dell’utente o un altro valore cambia poco. Al più, puoi mettere in database 0 se non c’è l’immagine oppure 1 se c’è. Automaticamente, tu sai che l’immagine corrisponde esattamente all’id dell’utente.

Ti consiglio di fare così anche perchè andare a controllare se esiste un determinato file su disco è più dispendioso che controllare un campo di database. Anzi … quando fai login puoi caricare sull’utente ANCHE un valore che ti dice se ha o meno l’avatar e magari accercervi con Yii::app()->user->avatar oppure Yii::app()->user->hasAvatar().

Vedi tu.