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

Revision 1100, 13.9 KB checked in by bogdan2412, 2 years ago (diff)

Updated database dump

Updated db-strip script to remove user's remote ip information and also cleanup
entries previously left orphan in ia_user_round, ia_round_task and in
ia_*_tags. Also made it erase more useless stuff from the forum while keeping
more users, more jobs and more textblock history.

The total size of the dump is actually smaller now, even though it has more
relevant data.

Also fixed a bug in textblock_grep which caused the grep macro to stop working.

  • 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/db/tags.php");
5require_once(IA_ROOT_DIR."common/db/attachment.php");
6require_once(IA_ROOT_DIR."common/security.php");
7require_once(IA_ROOT_DIR."common/textblock.php");
8require_once(IA_ROOT_DIR."common/common.php");
9
10// Textblock-related db functions.
11//
12// FIXME: this is beyond retarded, refactor mercilessly.
13
14// Add a new revision
15// FIXME: hash parameter?
16function textblock_add_revision(
17        $name, $title, $content, $user_id, $security = "public",
18        $forum_topic = null, $timestamp = null, $creation_timestamp = null,
19        $remote_ip_info = null) {
20    $name = normalize_page_name($name);
21
22    // Change special characters in content
23    $content = text_change_special_chars($content);
24
25    $tb = array(
26            'name' => $name,
27            'title' => $title,
28            'text' => $content,
29            'user_id' => $user_id,
30            'security' => $security,
31            'forum_topic' => $forum_topic,
32            'timestamp' => $timestamp,
33            'creation_timestamp' => $creation_timestamp,
34            'remote_ip_info' => $remote_ip_info,
35    );
36    log_assert_valid(textblock_validate($tb));
37
38    // get current revision
39    $query = sprintf("SELECT * FROM ia_textblock
40                      WHERE `name` = '%s'",
41                     db_escape($name));
42    $current_revision = db_fetch($query);
43
44    if ($current_revision) {
45        // copy current version to revision table
46        db_insert('ia_textblock_revision', $current_revision);
47
48        // replace current version
49        $query = sprintf("DELETE FROM ia_textblock
50                          WHERE `name` = '%s'
51                          LIMIT 1",
52                         db_escape($name));
53        db_query($query);
54    }
55
56    // Evil.
57    if ($creation_timestamp === null) {
58        $creation_timestamp = db_date_format();
59    } else {
60        log_assert(is_db_date($creation_timestamp), "Invalid timestamp");
61    }
62    if ($timestamp === null) {
63        $timestamp = db_date_format();
64    } else {
65        log_assert(is_db_date($timestamp), "Invalid timestamp");
66    }
67    $query = sprintf("INSERT INTO ia_textblock
68            (name, `text`, `title`, `creation_timestamp`,
69                    `timestamp`, `user_id`, `security`, `forum_topic`,
70                    `remote_ip_info`)
71            VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', %s, %s)",
72            db_escape($name), db_escape($content), db_escape($title),
73            db_escape($creation_timestamp), db_escape($timestamp),
74            db_escape($user_id), db_escape($security), db_quote($forum_topic),
75            db_quote($remote_ip_info));
76    return db_query($query);
77}
78
79// Delete $revision from database
80// The revision is identified by name and timestamp
81// $curr is true if $revision is the current revision and false otherwise
82function textblock_delete_revision($revision, $curr)
83{
84    if ($curr == false) {
85        $name = $revision['name'];
86        $timestamp = $revision['timestamp'];
87        $query = "DELETE FROM `ia_textblock_revision`
88            WHERE `name` = ".db_quote($name)." &&
89                `timestamp` = ".db_quote($timestamp);
90        db_query($query);
91    } else {
92        $name = $revision['name'];
93        $query = "REPLACE INTO `ia_textblock`
94                    (SELECT * FROM `ia_textblock_revision`
95                    WHERE `name` = ".db_quote($name)."
96                    ORDER BY `timestamp` DESC LIMIT 1)";
97        db_query($query);
98
99        //delete last_rev from ia_textblock_revision
100        $query = "DELETE FROM `ia_textblock_revision`
101                WHERE `name` = ".db_quote($name)."
102                ORDER BY `timestamp` DESC LIMIT 1";
103        db_query($query);
104    }
105}
106
107// This is the function called by most query functions.
108function textblock_complex_query($options)
109{
110    // log_print_r($options);
111
112    $field_list = "`name`, `title`, `creation_timestamp`, `timestamp`, `security`, `user_id`,
113            `forum_topic`, `remote_ip_info`";
114
115    // Select content.
116    if (getattr($options, 'content', false) == true) {
117        $field_list .= ", `text`";
118    }
119
120    // Add a join for username.
121    if (getattr($options, 'username', false) == true) {
122        $field_list .= ", `username` as `user_name`, `full_name` as `user_fullname`, rating_cache";
123        $join = "LEFT JOIN ia_user ON `user_id` = `ia_user`.`id`";
124    } else {
125        $join = "";
126    }
127
128    // prefix or page_name
129    if (getattr($options, 'page_name') === null) {
130        log_assert(is_string($options['prefix']));
131        $where = sprintf("WHERE `name` LIKE '%s%%'", db_escape(strtolower($options['prefix'])));
132    } else {
133        $where = sprintf("WHERE `name` = '%s'", db_escape(strtolower($options['page_name'])));
134    }
135
136    if (strtolower(getattr($options, 'order') == 'desc')) {
137        $order = 'DESC';
138    } else {
139        $order = 'ASC';
140    }
141
142    // When doing a history query.
143    if (getattr($options, 'history', false) == true) {
144        log_assert(is_whole_number($options['limit_start']));
145        log_assert(is_whole_number($options['limit_count']));
146        $query = sprintf("SELECT $field_list FROM ia_textblock $join %s
147                          UNION ALL SELECT $field_list FROM ia_textblock_revision $join %s
148                          ORDER BY `timestamp` %s LIMIT %d, %d",
149                          $where, $where, $order, $options['limit_start'], $options['limit_count']);
150    } else {
151        $query = "SELECT $field_list FROM ia_textblock
152                  $join $where ORDER BY ia_textblock.`creation_timestamp` $order";
153    }
154    // log_print("QUERY: " . $query);
155    return db_fetch_all($query);
156}
157
158// Get a certain revision of a textblock. Parameters:
159//  $name:      Textblock name.
160//  $rev_num:   Revision number. Latest if null(default).
161//  $username:  Get user name info.
162function textblock_get_revision($name, $rev_num = null, $username = false)
163{
164    $name = normalize_page_name($name);
165    log_assert(is_normal_page_name($name));
166    if (is_null($rev_num)) {
167        // Quick latest revision query.
168        $res = textblock_complex_query(array(
169                'page_name' => $name,
170                'content' => true,
171                'username' => $username,
172        ));
173    } else {
174        $res = textblock_complex_query(array(
175                'page_name' => $name,
176                'content' => true,
177                'username' => $username,
178                'history' => true,
179                'limit_start' => (int)$rev_num - 1,
180                'limit_count' => 1,
181        ));
182    }
183    return array_key_exists(0, $res) ? $res[0] : null;
184}
185
186// Get all revisions of a text_block.
187// $name:       The textblock name.
188// $content:    If true also get content. Defaults to false.
189// $username:   If true join for username. Defaults to true.
190function textblock_get_revision_list($name, $content = false, $username = true,
191        $start = 1, $count = 99999999) {
192    $name = normalize_page_name($name);
193    log_assert(is_normal_page_name($name));
194    return textblock_complex_query(array(
195            'content' => $content,
196            'username' => $username,
197            'page_name' => $name,
198            'history' => true,
199            'limit_start' => $start - 1,
200            'limit_count' => $count,
201    ));
202}
203
204// Get all textblocks(without content) with a certain prefix).
205// Ordered by name.
206function textblock_get_by_prefix($prefix, $content = false, $username = false,
207        $order = 'asc') {
208    return textblock_complex_query(array(
209            'content' => $content,
210            'username' => $username,
211            'prefix' => $prefix,
212            'order' => $order,
213    ));
214}
215
216// Get all textblocks(without content) with a certain prefix.
217// Ordered by name.
218function textblock_get_changes($prefix, $content = false, $username = true,
219                               $offset = 0, $count = 50) {
220    return textblock_complex_query(array(
221            'content' => $content,
222            'username' => $username,
223            'prefix' => $prefix,
224            'history' => true,
225            'order' => 'desc',
226            'limit_start' => $offset,
227            'limit_count' => $count,
228    ));
229}
230
231// Count revisions for a certain textblock.
232// FIXME: undefined if it doesn't exist.
233function textblock_get_revision_count($name) {
234    $name = normalize_page_name($name);
235    log_assert(is_normal_page_name($name));
236
237    $query = sprintf("SELECT COUNT(*) AS `cnt` FROM ia_textblock_revision
238                      WHERE `name` = '%s'",
239                    db_escape(strtolower($name)));
240    $row = db_fetch($query);
241    return $row['cnt'] + 1;
242}
243
244// Grep through textblocks. This is mostly a hack needed for macro_grep.php
245// Also used for round deletion
246function textblock_grep($substr, $page, $regexp = false, $offset = null, $count = null) {
247    if (!$regexp) {
248        $compare = "LIKE";
249    } else {
250        $compare = "REGEXP";
251    }
252    $query = sprintf("SELECT `name`, `title`, `creation_timestamp`, `timestamp`,
253                            `user_id`, `security`, `forum_topic`,
254                            `remote_ip_info`
255                      FROM ia_textblock
256                      WHERE `name` LIKE '%s' AND
257                            (`text` $compare '%s' OR `title` $compare '%s')
258                      ORDER BY `name`",
259                      db_escape($page), db_escape($substr), db_escape($substr));
260
261    if (is_whole_number($offset) && is_whole_number($count)) {
262        $query .= sprintf(" LIMIT %s, %s",
263                          db_escape($offset), db_escape($count));
264    }
265    return db_fetch_all($query);
266}
267
268function textblock_grep_count($substr, $page, $regexp = false) {
269    if (!$regexp) {
270        $compare = "LIKE";
271    } else {
272        $compare = "REGEXP";
273    }
274    $query = sprintf("SELECT COUNT(*) as `cnt`
275                      FROM ia_textblock
276                      WHERE `name` LIKE '%s' AND
277                            (`text` $compare '%s' OR `title` $compare '%s')",
278                      db_escape($page), db_escape($substr), db_escape($substr));
279    return db_fetch($query);
280}
281
282// Delete a certain page, including all revisions and attachments.
283// WARNING: This is irreversible.
284function textblock_delete($page_name) {
285    $page_name = normalize_page_name($page_name);
286    log_assert(is_normal_page_name($page_name));
287
288    $pageesc = db_escape($page_name);
289    $atts = attachment_get_all($page_name);
290    foreach ($atts as $att) {
291        if (!attachment_delete($att)) {
292            log_warn('Could not delete attachment from '.$page_name);
293            return false;
294        }
295    }
296    tag_clear('textblock', $page_name);
297
298    db_query("DELETE FROM `ia_textblock_revision` WHERE `name` = '$pageesc'");
299    db_query("DELETE FROM `ia_textblock` WHERE `name` = '$pageesc'");
300
301    return (db_affected_rows() != 0);
302}
303
304// Move a page from old_name to new_name.
305// Also drags attachments.
306function textblock_move($old_name, $new_name) {
307    $old_name = normalize_page_name($old_name);
308    $new_name = normalize_page_name($new_name);
309    log_assert(is_normal_page_name($old_name));
310    log_assert(is_normal_page_name($new_name));
311    //log_print("Moving textblock $old_name to $new_name");
312
313    // Move current version.
314    $query = sprintf("UPDATE `ia_textblock`
315                      SET `name` = '%s'
316                      WHERE `name` = '%s'",
317                      db_escape($new_name), db_escape($old_name));
318    db_query($query);
319
320    // Move history.
321    $query = sprintf("UPDATE `ia_textblock_revision`
322                      SET `name` = '%s'
323                      WHERE `name` = '%s'",
324                      db_escape($new_name), db_escape($old_name));
325    db_query($query);
326
327    // Get a list of attachments.
328    $files = attachment_get_all($old_name);
329
330    // Move attachments in db.
331    $query = sprintf("UPDATE `ia_file`
332                      SET `page` = '%s'
333                      WHERE `page` = '%s'",
334                      db_escape($new_name), db_escape($old_name));
335    db_query($query);
336
337    // Move attachments on disk. Ooops.
338    foreach ($files as $file) {
339        $old_filename = attachment_get_filepath($file);
340        $file['page'] = $new_name;
341        $new_filename = attachment_get_filepath($file);
342
343        if (!@rename($old_filename, $new_filename)) {
344            log_error("Failed moving attachment from $old_filename to $new_filename");
345        }
346    }
347}
348
349// Copy a textblock to new_name.
350// Also copies attachments.
351function textblock_copy($old_textblock, $new_name, $user_id, $remote_ip_info) {
352    log_assert(!textblock_validate($old_textblock));
353    $new_name = normalize_page_name($new_name);
354    log_assert(is_normal_page_name($new_name));
355
356    $new_textblock = $old_textblock;
357    $new_textblock['name'] = $new_name;
358    $new_textblock['user_id'] = $user_id;
359    $new_textblock['creation_timestamp'] = null;
360    // Keep creation_timestamp correct when textblock with new name already exists
361    $aux = textblock_get_revision($new_name);
362    if ($aux) {
363        $new_textblock['creation_timestamp'] = $aux['creation_timestamp'];
364    }
365    textblock_add_revision($new_textblock['name'], $new_textblock['title'],
366                           $new_textblock['text'], $new_textblock['user_id'],
367                           $new_textblock['security'],
368                           $new_textblock['forum_topic'],
369                           null, $new_textblock['creation_timestamp'],
370                           $remote_ip_info);
371
372    // Get a list of attachments.
373    $files = attachment_get_all($old_textblock["name"]);
374
375    // Copy attachments in db and hard drive
376    foreach ($files as $file) {
377        // Copy in db and get new id
378        $new_id = attachment_insert($file['name'], $file['size'],
379                $file['mime_type'], $new_name, $user_id, $remote_ip_info);
380
381        // Copy on hard drive
382        $old_filename = attachment_get_filepath($file);
383        $file['page'] = $new_name;
384        $file['id'] = $new_id;
385        $new_filename = attachment_get_filepath($file);
386
387        if (!@copy($old_filename, $new_filename)) {
388            log_error("Failed copying attachment from $old_filename to $new_filename");
389        }
390    }
391}
392
393?>
Note: See TracBrowser for help on using the repository browser.