Je souhaite télécharger des images dans mon application Cakephp 3.0. Mais je reçois le message d'erreur:
Notice (8): Undefined index: Images [APP/Controller/ImagesController.php, line 55]
Existe-t-il déjà des exemples de téléchargement de fichiers (plusieurs fichiers à la fois) dans CakePHP 3.0? Parce que je ne peux trouver que des exemples pour cakePHP 2.x!
Je pense que j'ai besoin d'ajouter une méthode de validation personnalisée dans mon ImagesTable.php? Mais je ne peux pas le faire fonctionner.
ImagesTable
public function initialize(array $config) {
$validator
->requirePresence('image_path', 'create')
->notEmpty('image_path')
->add('processImageUpload', 'custom', [
'rule' => 'processImageUpload'
])
}
public function processImageUpload($check = array()) {
if(!is_uploaded_file($check['image_path']['tmp_name'])){
return FALSE;
}
if (!move_uploaded_file($check['image_path']['tmp_name'], WWW_ROOT . 'img' . DS . 'images' . DS . $check['image_path']['name'])){
return FALSE;
}
$this->data[$this->alias]['image_path'] = 'images' . DS . $check['image_path']['name'];
return TRUE;
}
ImagesController
public function add()
{
$image = $this->Images->newEntity();
if ($this->request->is('post')) {
$image = $this->Images->patchEntity($image, $this->request->data);
$data = $this->request->data['Images'];
//var_dump($this->request->data);
if(!$data['image_path']['name']){
unset($data['image_path']);
}
// var_dump($this->request->data);
if ($this->Images->save($image)) {
$this->Flash->success('The image has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The image could not be saved. Please, try again.');
}
}
$images = $this->Images->Images->find('list', ['limit' => 200]);
$projects = $this->Images->Projects->find('list', ['limit' => 200]);
$this->set(compact('image', 'images', 'projects'));
$this->set('_serialize', ['image']);
}
Image add.ctp
<?php
echo $this->Form->input('image_path', [
'label' => 'Image',
'type' => 'file'
]
);
?>
Entité image
protected $_accessible = [
'image_path' => true,
];
Peut-être que ce qui suit pourrait aider. C'est un comportement qui vous aide à télécharger des fichiers très facilement!
http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/
Faites-moi savoir si vous avez du mal.
Greetz
Dans votre fichier de vue, ajoutez comme ceci, dans mon cas Utilisateurs/dashboard.ctp
<div class="ChImg">
<?php
echo $this->Form->create($particularRecord, ['enctype' => 'multipart/form-data']);
echo $this->Form->input('upload', ['type' => 'file']);
echo $this->Form->button('Update Details', ['class' => 'btn btn-lg btn-success1 btn-block padding-t-b-15']);
echo $this->Form->end();
?>
</div>
Dans votre contrôleur, ajoutez comme ceci, Dans mon cas UsersController
if (!empty($this->request->data)) {
if (!empty($this->request->data['upload']['name'])) {
$file = $this->request->data['upload']; //put the data into a var for easy use
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
$setNewFileName = time() . "_" . Rand(000000, 999999);
//only process if the extension is valid
if (in_array($ext, $arr_ext)) {
//do the actual uploading of the file. First arg is the tmp name, second arg is
//where we are putting it
move_uploaded_file($file['tmp_name'], WWW_ROOT . '/upload/avatar/' . $setNewFileName . '.' . $ext);
//prepare the filename for database entry
$imageFileName = $setNewFileName . '.' . $ext;
}
}
$getFormvalue = $this->Users->patchEntity($particularRecord, $this->request->data);
if (!empty($this->request->data['upload']['name'])) {
$getFormvalue->avatar = $imageFileName;
}
if ($this->Users->save($getFormvalue)) {
$this->Flash->success('Your profile has been sucessfully updated.');
return $this->redirect(['controller' => 'Users', 'action' => 'dashboard']);
} else {
$this->Flash->error('Records not be saved. Please, try again.');
}
}
Avant de l'utiliser, créez un dossier dans Webroot named upload/avatar .
Remarque: l’entrée ('Nom ici') est utilisée dans
$this->request->data['upload']['name']
vous pouvez l’imprimer si vous voulez voir le résultat du tableau.
Cela fonctionne comme un charme dans CakePHP 3.x
Maintenant que tout le monde fait de la publicité pour ses plugins ici, laissez-moi le faire aussi. J'ai vérifié le comportement Uploadable lié à l'autre question, c'est assez simple et à moitié fait semble-t-il.
Si vous souhaitez une solution complète conçue pour évoluer au niveau de l’entreprise, vérifiez FileStorage out. Il possède certaines fonctionnalités que je n'ai jamais vues dans d'autres implémentations, telles que le fait de s'assurer que votre système ne rencontrera pas de limitations du système de fichiers si vous obtenez vraiment beaucoup de fichiers. Cela fonctionne avec Imagine pour traiter les images. Vous pouvez les utiliser seuls ou en combinaison, ceci suit SoC .
Il est entièrement basé sur les événements, vous pouvez tout changer en implémentant vos propres écouteurs d'événements. Il faudra un niveau d’expérience intermédiaire avec CakePHP.
Il existe un guide de démarrage rapide pour voir à quel point il est facile de le mettre en œuvre. Le code suivant en est extrait, c’est un exemple complet, veuillez consulter le guide de démarrage rapide, il est plus détaillé.
class Products extends Table {
public function initialize() {
parent::initialize();
$this->hasMany('Images', [
'className' => 'ProductImages',
'foreignKey' => 'foreign_key',
'conditions' => [
'Documents.model' => 'ProductImage'
]
]);
$this->hasMany('Documents', [
'className' => 'FileStorage.FileStorage',
'foreignKey' => 'foreign_key',
'conditions' => [
'Documents.model' => 'ProductDocument'
]
]);
}
}
class ProductsController extends ApController {
// Upload an image
public function upload($productId = null) {
if (!$this->request->is('get')) {
if ($this->Products->Images->upload($productId, $this->request->data)) {
$this->Session->set(__('Upload successful!');
}
}
}
}
class ProductImagesTable extends ImageStorageTable {
public function uploadImage($productId, $data) {
$data['adapter'] = 'Local';
$data['model'] = 'ProductImage',
$data['foreign_key'] = $productId;
$entity = $this->newEntity($data);
return $this->save($data);
}
public function uploadDocument($productId, $data) {
$data['adapter'] = 'Local';
$data['model'] = 'ProductDocument',
$data['foreign_key'] = $productId;
$entity = $this->newEntity($data);
return $this->save($data);
}
}
Nous utilisons https://github.com/josegonzalez/cakephp-upload avec un grand succès dans notre application de production, et ce depuis assez longtemps.
Support remarquable pour l'utilisation de "Flysystem" ( https://flysystem.thephpleague.com/ ) - ce qui représente des abstractions d'un ou de plusieurs systèmes de fichiers spécifiques. -brainer, ou Dropbox ou n'importe quel endroit que vous voulez :-)
Vous pouvez trouver des plugins connexes (de haute qualité) sur le téléchargement de fichiers ici: https://github.com/FriendsOfCake/awesome-cakephp#files - J'ai utilisé "Proffer" avec succès, et c'est par aucun moyen "presque fait" ou quoi que ce soit semblable - les deux a toutes mes recommandations et est à mes yeux la production prête!
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\Network\Exception\InternalErrorException;
use Cake\Utility\Text;
/**
* Upload component
*/
class UploadRegCompanyComponent extends Component
{
public $max_files = 1;
public function send( $data )
{
if ( !empty( $data ) )
{
if ( count( $data ) > $this->max_files )
{
throw new InternalErrorException("Error Processing Request. Max number files accepted is {$this->max_files}", 1);
}
foreach ($data as $file)
{
$filename = $file['name'];
$file_tmp_name = $file['tmp_name'];
$dir = WWW_ROOT.'img'.DS.'uploads/reg_companies';
$allowed = array('png', 'jpg', 'jpeg');
if ( !in_array( substr( strrchr( $filename , '.') , 1 ) , $allowed) )
{
throw new InternalErrorException("Error Processing Request.", 1);
}
elseif( is_uploaded_file( $file_tmp_name ) )
{
move_uploaded_file($file_tmp_name, $dir.DS.Text::uuid().'-'.$filename);
}
}
}
}
}
/*Path to Images folder*/
$dir = WWW_ROOT . 'img' .DS. 'thumbnail';
/*Explode the name and ext*/
$f = explode('.',$data['image']['name']);
$ext = '.'.end($f);
/*Generate a Name in my case i use ID & slug*/
$filename = strtolower($id."-".$slug);
/*Associate the name to the extension */
$image = $filename.$ext;
/*Initialize you object and update you table in my case videos*/
$Videos->image = $image;
if ($this->Videos->save($Videos)) {
/*Save image in the thumbnail folders and replace if exist */
move_uploaded_file($data['image']['tmp_name'],$dir.DS.$filename.'_o'.$ext);
unlink($dir.DS.$filename.'_o'.$ext);
}