Bonjour,

Comme vous l'avez deviner mon soucis est relatif au plugin Upload offert par Grafikart, alors voilà même en plaçant la règle de sécurité pour les extensions :

'media_file' => array(
'rule' => array('fileExtension', array('gif', 'jpeg', 'png', 'jpg'), true),
'message' => 'Merci de soumettre une image de format valide.',
'allowEmpty' => true,
),

Et bien mon script laisse tout passer, y compris les .exe ......... Je sais que le problème vient de chez moi, je ne mets pas en cause le plugin, mais j'aimerais comprendre pourquoi ^^' .

Merci d'avance :)

12 réponses


MrFiz
Auteur
Réponse acceptée

J'ai trouvé ce qui ne fonctionnait pas:
Dans mon action du controller je précise les champs à enregistrer: le soucis c'est que si je mets 'media', ça n'utilise pas la règle pour les extensions, et si j'utilise media_file, ça utilise bien la règle mais n'enregistre pas le chemin en BDD.

Merci encore de votre aide !

Bonjour.
Pour commencer, à quoi sert ton true dans la règle ?
Ensuite, que veux tu que l'on te dise juste avec ta règle du validate ?
Peut-être que le problème vient d'autre chose.

MrFiz
Auteur

Bonjour, une erreur de ma part, j'ai mis true alors qu'il y est par défaut ..
Voici le UploadBehavior:(le même que sur le git de grafikart, je n'y ai pas touché.

<?php
class UploadBehavior extends ModelBehavior{
    /**
    * Fields is used to define fields that are "uploadable"
    * array(
    * 'avatar' => 'img/:id'
    * )
    *
    * :id => Record ID
    * :id1000 => ceil( Record ID / 1000 )
    * :id100 => ceil( Record ID / 100 )
    * :y => year
    * :m => month
    * :uid => user id (Auth.User.id)
    * :md5 => random MD5
    **/
    private $defaultOptions = array(
        'fields' => array()
    );
    private $options = array();
    public function setup(Model $model, $config = array()){
        $this->options$model->alias] = array_merge($this->defaultOptions, $config);
    }
    /**
    * CakePHP Model Functions
    **/
    public function afterSave(Model $model, $created, $options = array()){
        $data = $model->data;
        foreach($this->options$model->alias]'fields'] as $field => $path){
           if(
                isset($data$model->alias]$field . '_file']) &&
                !empty($data$model->alias]$field . '_file']'name']) &&
                (
                    !$model->whitelist ||
                    empty($model->whitelist) ||
                    in_array($field, $model->whitelist)
                )
            ){
                $file = $data$model->alias]$field . '_file'];
                $extension = strtolower(pathinfo($file'name'], PATHINFO_EXTENSION));
                $path = $this->getUploadPath($model, $path, $extension);
                $dirname = dirname($path);
                if(!file_exists(WWW_ROOT . $dirname)){
                    mkdir(WWW_ROOT . $dirname, 0777, true);
                }
                $model->deleteOldUpload($field);
                $model->move_uploaded_file(
                    $file'tmp_name'],
                    WWW_ROOT . $path
                );
                chmod(WWW_ROOT . $path, 0777);
                $model->saveField($field, '/' . $path);
           }
        }
    }
    public function beforeDelete(Model $model, $cascade = true){
        foreach($this->options$model->alias]'fields'] as $field => $path){
            $model->deleteOldUpload($field);
        }
        return true;
    }
    /**
     * Alias for the move_uploaded_file function, so it can be mocked for testing purpose
    */
    public function move_uploaded_file(Model $model, $source, $destination){
        move_uploaded_file($source, $destination);
    }
    /**
     * Custom Validation Rules
     */
    public function fileExtension(Model $model, $check, $extensions, $allowEmpty = true){
        $file = current($check);
        if($allowEmpty && empty($file'tmp_name'])){
            return true;
        }
        $extension = strtolower(pathinfo($file'name'] , PATHINFO_EXTENSION));
        echo $extension;
        //return
        echo in_array($extension, $extensions);
    }
    /**
    * MISC
    **/
    private function getUploadPath(Model $model, $path, $extension){
        $path = trim($path, '/');
        $replace = array(
            ':id1000' => ceil($model->id / 1000),
            ':id100' => ceil($model->id / 100),
            ':id' => $model->id,
            ':y' => date('Y'),
            ':m' => date('m'),
            ':uid' => CakeSession::read('Auth.User.id'),
            ':md5' => md5(rand() . uniqid() . time())
        );
        $path = strtr($path, $replace) . '.' . $extension;
        return $path;
    }
    public function deleteOldUpload(Model $model, $field){
        $file = $model->field($field);
        if(empty($file)){
            return true;
        }
        $info = pathinfo($file);
        $subfiles = glob(WWW_ROOT . $info'dirname'] . DS . $info'filename'] . '_*x*.*');
        if(file_exists(WWW_ROOT . $file)){
            unlink(WWW_ROOT . $file);
        }
        if($subfiles){
            foreach($subfiles as $file){
                unlink($file);
            }
        }
    }

}

On peut voir le model en entier, ainsi que la fonction du controller ?

Bonjour.
Ce n'est pas la peine de nous montrer le code du plugin, par preuve du contraire, le plugin est parfaitement fonctionnel, il ne peut donc pas être responsable de l'erreur que tu rencontre.
Est-ce que tu as bien fait la déclaration du plugin par le actAs dans ton modèle ?
As-tu bien nommé le champ dans ton input du formulaire comme l'attend le plugin ?

MrFiz
Auteur

Bonjour.
J'ai bien écrit plus haut : "Je sais que le problème vient de chez moi, je ne mets pas en cause le plugin, mais j'aimerais comprendre pourquoi" :)

Mon formulaire

<?= $this->Form->create('Post', array('type' => 'file')); ?>
    <?= $this->Form->input('title', array('label' => "Titre : ")); ?>
    <?= $this->Form->input('media_file', array('label' => "Image : ", 'type' => 'file')); ?>
    <?= $this->Form->input('content', array('label' => "Contenu : ", 'type' => 'textarea')); ?>
    <?= $this->Form->input('online', array('label' => "En ligne", 'type' => 'checkbox')); ?>
<?= $this->Form->end('Sauvegarder'); ?>

Le modèle entier

<?php
class Post extends AppModel{
    public $actsAs = array(
        'Upload.Upload' => array(
            'fields' => array(
                'media' => 'img/upload/posts/:id'
            )
        )
    );
    public $validate = array(
        'title' => array(
            'AN' => array(
                'rule' => '#[a-zA-Z0-9_\-\'\"]#',
                'message' => 'Ce champ ne doit contenir que des chiffres, des lettres, des tirets, des apostrophes et des guillemets.',
            ),
            'ML' => array(
                'rule' => array('between', '5', '255'),
                'allowEmpty' => false,
                'required' => true,
                'message' => 'Le titre doit contenir entre 5 et 255 caractères.',
            ),
        ),
        'media_file' => array(
            'rule' => array('fileExtension', array('gif', 'jpeg', 'png', 'jpg'), true),
            'message' => 'Merci de soumettre une image de format valide.',
            'allowEmpty' => true,
        ),
        'content' => array(
            'AN' => array(
                'rule' => '#[a-zA-Z0-9_\-\'\"]#',
                'message' => 'Ce champ ne doit contenir que des chiffres, des lettres, des tirets, des apostrophes et des guillemets.',
            ),
            'ML' => array(
                'rule' => array('minLength', '10'),
                'message' => 'Ce champ doit contenir au moins dix caractères.',
            ),
        ),
        ''
    );
    function afterFind($results, $primary = false){
        foreach($results as $k => $result){
            if(isset($result$this->alias]'slug'])){
                $results$k]$this->alias]'url'] = '/' . $result$this->alias]'slug'];
            }
        }
        return $results;
    }
}

La fonction :

function admin_create(){
        if($this->request->is('post')){
            $this->request->data'Post']'id']=null;
            $this->request->data'Post']'created']=null;
            if($this->Post->save($this->request->data, array('fieldList' => array('title','content', 'created')))){
                $this->Session->setFlash("Le post à bien été enregistré","success");
            }
            else{
                $this->Session->setFlash("Erreur lors de la sauvegarde en base de données","error");
            }
        }
    }

Voilà j'espère que vous pourrez m'aider, merci d'avance ! :)

En l’occurrence ce n'est pas le même behavior que sur github. Ligne 77
Remplace

public function fileExtension(Model $model, $check, $extensions, $allowEmpty = true){
        $file = current($check);
        if($allowEmpty && empty($file'tmp_name'])){
            return true;
        }
        $extension = strtolower(pathinfo($file'name'] , PATHINFO_EXTENSION));
        echo $extension;
        //return
        echo in_array($extension, $extensions);
    }

Par

public function fileExtension(Model $model, $check, $extensions, $allowEmpty = true){
        $file = current($check);
        if($allowEmpty && empty($file'tmp_name'])){
            return true;
        }
        $extension = strtolower(pathinfo($file'name'] , PATHINFO_EXTENSION));
        return in_array($extension, $extensions);
    }
MrFiz
Auteur

J'ai fait cette modification pour comprendre pourquoi ça fonctionnait alors que ça ne devrait pas, mais j'ai oublié de le remettre, malheureusement ça ne résout pas mon problème :/

MrFiz
Auteur

Je relance un peu le sujet, après mes tentatives inefficaces... :/
Je sèche un peu.

static Validation::extension(mixed $check, array $extensions = array('gif', 'jpeg', 'png', 'jpg'))

Cette règle vérifie les extensions valides de fichier, comme .jpg ou .png. Permet la vérification d’extensions multiples, en les passant sous forme de tableau.

public $validate = array(
        'image' => array(
            'rule' => array('extension', array('gif', 'jpeg', 'png', 'jpg')),
            'message' => 'Merci de soumettre une image valide.'
        )
);
MrFiz
Auteur

Merci, je vais essayer de suite je vous tiens au courant :)

MrFiz
Auteur

Bon malheureusement, ça ne fonctionne pas.. Merci quand même pour la proposition :)