source: trunk/common/attachment.php @ 1159

Revision 1159, 7.8 KB checked in by adrian.budau, 2 months ago (diff)

Fix more errors that occured durring the deployment of the avatar optimisation

Fixes to the attachments control. Users can't upload an attachment called avatar.
Now the avatar can be deleted.
Fixes to the image resize script regarding gif files (it used to enter an infinite loop)

REVIEW URL  http://reviewboard.infoarena.ro/r/181/

  • Property svn:eol-style set to native
Line 
1<?php
2require_once(IA_ROOT_DIR . "common/db/attachment.php");
3
4// Validates an attachment struct.
5function attachment_validate($att) {
6    $errors = array();
7
8    // FIXME How to handle this?
9    log_assert(is_array($att), "You didn't even pass an array");
10
11    if (!is_normal_page_name(getattr($att, 'page', ''))) {
12        $errors['page'] = 'Nume de pagina invalid.';
13    }
14
15    if (!is_attachment_name(getattr($att, 'name', ''))) {
16        $errors['page'] = 'Nume de pagina invalid.';
17    }
18
19    if (!is_user_id(getattr($att, 'user_id'))) {
20        $errors['user_id'] = 'ID de utilizator invalid';
21    }
22
23    if (!is_string(getattr($att, 'mime_type', 'text/plain'))) {
24        $errors['mime_type'] = 'Bad mime type';
25    }
26
27    // NOTE: missing timestamp is OK!!!
28    // It stands for 'current moment'.
29    if (!is_db_date(getattr($att, 'timestamp', db_date_format()))) {
30        $errors['timestamp'] = 'Timestamp invalid.';
31    }
32
33    return $errors;
34}
35
36// Get a file's mime type.
37function get_mime_type($filename) {
38    if (function_exists("finfo_open")) {
39        // FIXME: cache.
40        $finfo = finfo_open(FILEINFO_MIME);
41
42        log_assert($finfo !== false,
43                   'fileinfo is active but finfo_open() failed');
44
45        $res = finfo_file($finfo, $filename);
46        finfo_close($finfo);
47        log_print('get_mime_type('.$filename.'): finfo yields '.$res);
48        return $res;
49    }
50    if (function_exists("mime_content_type")) {
51        $res = @mime_content_type($filename);
52        if ($res !== false) {
53            return $res;
54        }
55    }
56    log_warn("fileinfo extension failed, defaulting mime type to application/octet-stream.");
57    return "application/octet-stream";
58}
59
60// Resize 2D coordinates according to 'textual' instructions
61// Given a (width, height) pair, resize it (compute new pair) according to
62// resize instructions.
63//
64// Resize instructions may be:
65// # example    # description
66// 100x100      Keep aspect ratio, resize as to fit a 100x100 box.
67//              Coordinates are not enlarged if they already fit the given box.
68// @50x86       Ignore aspect ratio, resize to exactly 50x86.
69// 50%          Scale dimensions; only integer percentages allowed.
70// L100x100     Layout resize: same as 100x100 only it will enlarge coordinates
71//              if coordinates already fit target box. Use this where layout
72//              matters.
73//
74// Returns 2-element array: (width, height) or null if invalid format
75function resize_coordinates($width, $height, $resize) {
76    // 100x100 or @100x100 or L100x100
77    if (preg_match('/^([\@L]?)([0-9]+)x([0-9]+)$/i', $resize, $matches)) {
78        $flag = strtolower($matches[1]);
79        $boxw = (float)$matches[2];
80        $boxh = (float)$matches[3];
81
82        if ('@' == $flag) {
83            // exact fit, ignore aspect ratio
84            return array($boxw, $boxh);
85        }
86        else {
87            // keep aspect ratio
88
89            $layout = ('l' == $flag);
90            $ratio = 1.0;
91            if ($width > $boxw || $layout) {
92                $ratio = $boxw / $width;
93            }
94            if ($height * $ratio > $boxh) {
95                $ratio = $boxh / $height;
96            }
97
98            return array(floor($ratio * $width), floor($ratio * $height));
99        }
100    }
101    // zoom: 50%
102    elseif (preg_match('/^([0-9]+)%$/', $resize, $matches)) {
103        $ratio = (float)$matches[1] / 100;
104        return array(floor($ratio * $width), floor($ratio * $height));
105    }
106    // invalid format
107    else {
108        return null;
109    }
110}
111
112function is_textfile($mime_type) {
113    return substr($mime_type, 0, 5) == "text/";
114}
115
116function dos_to_unix($file_path) {
117    system("dos2unix ".$file_path);
118}
119
120function is_grader_testfile($file_name) {
121    $pattern = '/^grader_test(\d)*\.(ok|in)$/';
122    if (preg_match($pattern, $file_name) == false) {
123        return false;
124    } else {
125        return true;
126    }
127}
128
129function is_problem_page($page_name) {
130    $pattern = '/^problema\/' . IA_RE_TASK_ID . '$/';
131    if (preg_match($pattern, $page_name) == false) {
132        return false;
133    } else {
134        return true;
135    }
136}
137
138function add_ending_newline($file_path) {
139    $content = file_get_contents($file_path);
140    if ($content[strlen($content) - 1] != "\n") {
141        $content .= "\n";
142        file_put_contents($file_path, $content);
143        return true;
144    }
145    return false;
146}
147
148/**
149 * Resizes an image whose filepath is given by the parameters into a new
150 * location specified by the other parameters
151 *
152 * Returns whether or not the image has been successfully resized
153 * Note that it returns false if the image doesn't have a known file-type
154 *
155 * The $new_filepath parameter if ommited or given as null will result in the
156 * image being outputted directly to the client
157 *
158 * @param  array   $image_info         An array containing information about the
159 *                                     original image: width, height, mime-type
160 * @param  string  $filepath
161 * @param  array   $new_image_info     An array containing the new width and
162 *                                     height
163 * @param  string  $new_filepath
164 * @return bool
165 */
166function image_resize($image_info, $filepath, $new_image_info,
167        $new_filepath = null) {
168    list($image_width, $image_height, $image_type, $image_attribute) = $image_info;
169    list($new_image_width, $new_image_height) = $new_image_info;
170
171    switch ($image_type) {
172        case IMAGETYPE_GIF:
173            // NOTE: animated GIFs become static. Only the first frame is saved
174            // Seems like a good thing anyway
175            $image = imagecreatefromgif($filepath);
176            $image_resized = imagecreate($new_image_width, $new_image_height);
177            // reset palette and transparent color to that of the original file
178            $trans_col = imagecolortransparent($image);
179            imagepalettecopy($image_resized, $image);
180            if ($trans_col != -1) {
181                imagefill($image_resized, 0, 0, $trans_col);
182            }
183            imagecolortransparent($image_resized, $trans_col);
184            imagecopyresampled($image_resized, $image, 0, 0, 0, 0,
185                    $new_image_width, $new_image_height, $image_width,
186                    $image_height);
187
188            if ($new_filepath != null) {
189                return imagegif($image_resized, $new_filepath);
190            }
191            return imagegif($image_resized);
192
193        case IMAGETYPE_JPEG:
194            $image = imagecreatefromjpeg($filepath);
195            $image_resized = imagecreatetruecolor($new_image_width,
196                    $new_image_height);
197            imagecopyresampled($image_resized, $image, 0, 0, 0, 0,
198                    $new_image_width, $new_image_height, $image_width,
199                    $image_height);
200
201            if ($new_filepath != null) {
202                return imagejpeg($image_resized, $new_filepath);
203            }
204            return imagejpeg($image_resized);
205
206        case IMAGETYPE_PNG:
207            $image = imagecreatefrompng($filepath);
208            $image_resized = imagecreatetruecolor($new_image_width,
209                    $new_image_height);
210            // turn off the alpha blending to keep the alpha channel
211            imagealphablending($image_resized, false);
212            // allocate transparent color
213            $col = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
214            // fill the image with the new color
215            imagefilledrectangle($image_resized, 0, 0, $new_image_width,
216                    $new_image_height, $col);
217            imagecopyresampled($image_resized, $image, 0, 0, 0, 0,
218                    $new_image_width, $new_image_height, $image_width,
219                    $image_height);
220            imagesavealpha($image_resized, true);
221            if ($new_filepath != null) {
222                return imagepng($image_resized, $new_filepath);
223            }
224            return imagepng($image_resized);
225
226        default:
227            // unsupported image type
228            return false;
229    }
230}
231?>
Note: See TracBrowser for help on using the repository browser.