Bin will be removed on June 1, 2014 in favor of http://gist.github.com. Please save all your pastes before then. So long, and thanks for all the fish!×
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/**
 * This behavior makes it easy to upload files of any type. It validates and
 * sorts uploaded files by field, file type, and size. Support for naming
 * callback methods makes it easy to use different types of naming schemes.
 *
 * Regular expressions are supported for mime-type matching, and multiple
 * fields can be uploaded at the same time.
 *
 * The path of the saved file will be saved in the column which is equal to
 * the name of the form field used to upload the file.
 *
 * @author Dan Sondergaard <dan1990@gmail.com>
 * @copyright Copyright(c) 2008, Dan Sondergaard
 * @version 0.1
 */
class FileBehavior extends ModelBehavior {
   
    var $settings = array();
   
    /**
     * Initiate behavior for the model using specified settings. Settings are
     * specified as an array with the following structure:
     *
     * <code>
     * var $actsAs = array(
     *     'File' => array(
     *         'fieldName' => array(
     *             '/regex/' => array(
     *             'destination' => 'path/to/save/to',
     *             'naming' => array('userSpecifiedFunction'),
     *             'max' => 1024,
     *             'extension' => true
     *         )
     *     ),
     *     'file' => array(
     *         '/application\/pdf/' => array(
     *             'destination' => 'files/documents/',
     *             'naming' => array('hash'),
     *             'max' => 100,
     *             'extension' => true
     *         )
     *       )
     *    )
     * );
     * </code>
     *
     * @param object $Model Model using the behavior
     * @param array $settings Settings to override for model.
     * @access public
     */
    function setup(&$Model, $settings = array()) {
        if (!isset($this->settings[$Model->alias])) {
            $this->settings[$Model->alias] = array(
                'file' => array(
                    '/image\/(png|jpg|gif)/' => array(
                        'destination' => 'files/',
                        'max' => 5242880,
                        'naming' => 'hash',
                        'extension' => true
                    )
                )
            );
        }
        $this->settings[$Model->alias] = array_merge(
             $this->settings[$Model->alias],
             ife(is_array($settings), $settings, array())
        );
    }
   
    /**
     * Saves uploaded files to locations given in the options for each
     * mime-type, and provides basic validation for file size. Also takes
     * care of naming by calling a user-specified method (defaults to
     * Model::hash()).
     *
     * @param object $Model Model using the behavior
     * @access public
     */
    function beforeSave(&$Model) {
        foreach ($this->settings[$Model->alias] as $field => $types) {
            foreach ($types as $pattern => $options) {
                if (preg_match($pattern, $Model->data[$Model->alias][$field]['type'])) {
                    $supported = true;
                   
                    // Get the name of the file using a callback function defined
                    // in the model. Defaults to a function called hash(). The first
                    // argument is the file array generated by PHP.
                    if (is_array($options['naming'])) {
                        $options['naming'] = $options['naming'][0];
                        $name = $Model->{$options['naming']}(&$Model->data[$Model->alias][$field]);
                    } else {
                        $name = $options['naming'];
                    }
                   
                    // Checks if the file is larger than allowed. The variable
                    // $options['max'] defaults to 0, which means that there is no limit.
                    if ($options['max'] > 0 && $Model->data[$Model->alias][$field]['size'] >= $options['max']) {
                        $Model->invalidate($field, __('Sorry, this file is too big.', true));
                    }
                   
                    // Check if we're supposed to append the extension to the unique file name.
                    $info = pathinfo($Model->data[$Model->alias][$field]['name']);
                    $filename = ife($options['extension'], $name . '.' . $info['extension'], $name);
                   
                    $path = WWW_ROOT . $options['destination'];
                    if (!is_dir($path)) {
                        mkdir($path);
                    }
                   
                    if (move_uploaded_file($Model->data[$Model->alias][$field]['tmp_name'], $path . $filename)) {
                        $Model->data[$Model->alias][$field] = '/' . $options['destination'] . $filename;
                    } else {
                        return false;
                    }
                    break;
                }
            }
           
            if (!$supported) {
                $Model->invalidate($field, __('Sorry, this file type is not supported.', true));
            }
        }
        return ife(count($Model->validationErrors) > 0, false, true);
    }
   
    /**
     * Deletes files when the record they belong to is deleted.
     *
     * @param object $Model Model using the behavior
     * @access public
     */
    function beforeDelete(&$Model) {
        foreach ($this->settings[$Model->alias] as $field => $types) {
            $Model->data = $Model->read();
            unlink(WWW_ROOT . $Model->data[$Model->alias][$field]);
        }
        return true;
    }
   
}
?>