source: trunk/common/db/attachment.php @ 1184

Revision 1164, 6.4 KB checked in by bogdan2412, 4 months ago (diff)

Make infoarena compatible with HPHP.

  • Implemented APC caching support since eaccelerator is not compatible with HPHP and although we support memcached, we do not use it on live.
  • Replaced instances of create_function_cached with php anonymous functions. This bumps the PHP version requirement to 5.3, but it allows the code to work with HPHP, since dynamic function generation is replaced with staticly analyzable functions. This also removes a horrible, terrible hack in Textile.php which was storing the current instance of the Textile class being processed as a static variable so that it could be accessed by anonymous functions.
  • Replaced occurrences of assert with log_assert.
  • When running under HPHP, IA_HPHP_ENV is defined and is used to bypass some incompatible code (redundant ini configuration checks).
  • Fixed some includes that were dependent on the working directory being www/
  • Included a sample HPHP configuration file and a Makefile with compilation commands.

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

  • Property svn:eol-style set to native
Line 
1<?php
2
3require_once(IA_ROOT_DIR."common/db/db.php");
4require_once(IA_ROOT_DIR."common/attachment.php");
5require_once(IA_ROOT_DIR."common/cache.php");
6
7// Add $attachment to cache if not null and return $attachment.
8function _attachment_cache_add($attachment) {
9    if (!is_null($attachment)) {
10        log_assert_valid(attachment_validate($attachment));
11        mem_cache_set("attachment-by-id:{$attachment['id']}", $attachment);
12        mem_cache_set("attachment-by-name:".
13                $attachment['page'] . '$' . $attachment['name'], $attachment);
14    }
15    return $attachment;
16}
17
18function _attachment_cache_delete($att) {
19    mem_cache_delete("attachment-by-id:{$att['id']}");
20    mem_cache_delete("attachment-by-name:".$att['page']."$".$att['name']);
21}
22
23// Get attachment by name
24function attachment_get($name, $page) {
25    log_assert(is_attachment_name($name));
26    log_assert(is_page_name($page));
27    $page = normalize_page_name($page);
28
29    if (($res = mem_cache_get("attachment-by-name:$page$$name")) !== false) {
30        return $res;
31    }
32
33    $query = sprintf("SELECT *, DATE_FORMAT(`timestamp`, '%%Y-%%M-%%D %%h:%%i:%%s')
34                      FROM ia_file
35                      WHERE BINARY `name` = '%s' AND
36                            `page` = '%s'",
37                     db_escape($name), db_escape($page));
38
39    // This way nulls (missing attachments) get cached too.
40    $attachment = db_fetch($query);
41    if ($attachment != null) {
42        return _attachment_cache_add($attachment);
43    } else {
44        return mem_cache_set("attachment-by-name:$page$$name", null);
45    }
46}
47
48function attachment_get_by_id($id) {
49    if (($res = mem_cache_get("attachment-by-id:$id")) !== false) {
50        return $res;
51    }
52
53    $query = sprintf("SELECT *
54                      FROM ia_file
55                      WHERE `id` = '%s'",
56                     db_escape($id));
57
58    // This way nulls (missing attachments) get cached too.
59    $attachment = db_fetch($query);
60    if ($attachment != null) {
61        return _attachment_cache_add($attachment);
62    } else {
63        return mem_cache_set("attachment-by-id:$id", null);
64    }
65}
66
67// Update an attachment. FIXME: hash args.
68function attachment_update($id, $name, $size, $mime_type, $page, $user_id,
69        $remote_ip_info) {
70    $attachment = array(
71            'id' => $id,
72            'name' => $name,
73            'size' => $size,
74            'mime_type' => $mime_type,
75            'page' => normalize_page_name($page),
76            'user_id' => $user_id,
77            'timestamp' => db_date_format(),
78            'remote_ip_info' => $remote_ip_info,
79    );
80
81    db_update('ia_file', $attachment, '`id` = '.db_quote($id));
82
83    _attachment_cache_add($attachment);
84}
85
86// Inserts an attachment in the db
87function attachment_insert($name, $size, $mime_type, $page, $user_id,
88        $remote_ip_info) {
89    $attachment = array(
90            'name' => $name,
91            'size' => $size,
92            'mime_type' => $mime_type,
93            'page' => normalize_page_name($page),
94            'user_id' => $user_id,
95            'timestamp' => db_date_format(),
96            'remote_ip_info' => $remote_ip_info,
97    );
98
99    db_insert('ia_file', $attachment);
100    $attachment['id'] = db_insert_id();
101    _attachment_cache_add($attachment);
102
103    return $attachment['id'];
104}
105
106// Delete an attachment, from both the db and the disk.
107// Returns success value.
108function attachment_delete($attach) {
109    log_assert_valid(attachment_validate($attach));
110
111    db_query(sprintf("DELETE FROM ia_file WHERE `id` = %s",
112            db_escape($attach['id'])));
113    if (db_affected_rows() != 1) {
114        return false;
115    }
116    _attachment_cache_delete($attach);
117    if (!@unlink(attachment_get_filepath($attach))) {
118        return false;
119    }
120    return true;
121}
122
123function attachment_rename($attach, $new_name) {
124    log_assert_valid(attachment_validate($attach));
125
126    db_query(sprintf("UPDATE ia_file SET `name` = \"%s\" WHERE `id` = %s",
127            db_escape($new_name), db_escape($attach['id'])));
128    if (db_affected_rows() != 1) {
129        return false;
130    }
131
132    _attachment_cache_delete($attach);
133    $new_attach = $attach;
134    $new_attach['name'] = $new_name;
135    _attachment_cache_add($new_attach);
136
137    if (!@rename(attachment_get_filepath($attach), attachment_get_filepath($new_attach))) {
138        return false;
139    }
140    return true;
141}
142
143// Delete by id. Just in case you want to do an extra query.
144function attachment_delete_by_id($attid) {
145    attachment_delete(attachment_get_by_id($attid));
146}
147
148// Obtain list with all attachments matching name $name and belonging
149// to page $page.
150//
151// You may use % as a wildcard
152function attachment_get_all($page, $name='%', $start = 0, $count = 99999999) {
153    log_assert(is_whole_number($start));
154    log_assert(is_whole_number($count));
155    $query = sprintf("SELECT ia_file.*, ia_user.username, ia_user.full_name as user_fullname
156                      FROM ia_file
157                      LEFT JOIN ia_user ON ia_user.id = ia_file.user_id
158                      WHERE ia_file.page LIKE '%s' AND ia_file.`name` LIKE '%s'
159                      ORDER BY ia_file.`timestamp` DESC, ia_file.`name`
160                      LIMIT %d, %d",
161                     db_escape($page), db_escape($name), $start, $count);
162    return db_fetch_all($query);
163}
164
165// _count for the above.
166function attachment_get_count($page, $name='%', $start = 0, $count = 99999999) {
167    log_assert(is_whole_number($start));
168    log_assert(is_whole_number($count));
169    $query = sprintf("SELECT COUNT(*)
170                      FROM ia_file
171                      LEFT JOIN ia_user ON ia_user.id = ia_file.user_id
172                      WHERE ia_file.page LIKE '%s' AND ia_file.`name` LIKE '%s'
173                      ORDER BY ia_file.`timestamp` DESC, ia_file.`name`
174                      LIMIT %d, %d",
175                     db_escape($page), db_escape($name), $start, $count);
176    return db_query_value($query);
177}
178
179// Returns "real file name" (as stored on the file system) for a given
180// attachment id.
181//
182// NOTE: You can't just put this into db.php or any other module shared
183// with the judge since it`s dependent on the www server setup.
184// FIXME: does this belong here?
185function attachment_get_filepath($attach) {
186    log_assert(is_array($attach));
187    return IA_ROOT_DIR.'attach/'.
188            strtolower(preg_replace('/[^a-z0-9\.\-_]/i', '_', $attach['page'])) . '_' .
189            preg_replace('/[^a-z0-9\.\-_]/i', '_', $attach['name']) . '_' .
190            $attach['id'];
191}
192
193?>
Note: See TracBrowser for help on using the repository browser.