Changeset 1069


Ignore:
Timestamp:
12/12/09 20:21:12 (2 years ago)
Author:
bogdan2412
Message:

Update tagging backend in preparation for task tagging.

A tag is now defined by both it's name and it's "type".

  • Added "type" column in ia_tags table.
  • Updated all common/tags common/db/tags functions.
  • Updated existing controllers to work with new backend.
Location:
trunk
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/common/common.php

    r997 r1069  
    163163 
    164164// Check valid score names. 
    165 // Does not check existence.  
     165// Does not check existence. 
    166166function is_score_name($score_name) { 
    167167    return preg_match('/^'.IA_RE_SCORE_NAME.'$/xi', $score_name) && 
     
    205205    return preg_match('/^'.IA_RE_TAG_NAME.'$/xi', $tag_name) && 
    206206           strlen($tag_name) < 64; 
     207} 
     208 
     209// Check tag type 
     210function is_tag_type($tag_type) { 
     211    return in_array($tag_type, array( 
     212        'author', 'contest', 'year', 'round', 'age_group', 
     213        'method', 'algorithm', 'tag' 
     214    )); 
     215} 
     216 
     217// Check tag 
     218function is_tag($tag) { 
     219    if (!is_array($tag)) { 
     220        return false; 
     221    } 
     222    if (!array_key_exists("name", $tag)) { 
     223        return false; 
     224    } 
     225    if (!array_key_exists("type", $tag)) { 
     226        return false; 
     227    } 
     228    return is_tag_name($tag["name"]) && is_tag_type($tag["type"]); 
    207229} 
    208230 
  • trunk/common/db/blog.php

    r943 r1069  
    55function blog_get_range($tag_name, $start, $range) { 
    66    if (is_tag_name($tag_name)) { 
    7         $tag_id = tag_get_id($tag_name); 
     7        $tag_id = tag_get_id(array("name" => $tag_name, "type" => "tag")); 
    88        if (is_null($tag_id)) { 
    99            $tag_id = -1; 
     
    1313        $where = "TRUE"; 
    1414    } 
    15     $query = sprintf("SELECT * FROM ia_textblock  
    16                       WHERE %s AND name LIKE 'blog/%%'  
     15    $query = sprintf("SELECT * FROM ia_textblock 
     16                      WHERE %s AND name LIKE 'blog/%%' 
    1717                      AND security <> 'private' 
    1818                      ORDER BY ia_textblock.creation_timestamp DESC 
    19                       LIMIT %s, %s",  
     19                      LIMIT %s, %s", 
    2020                     $where, db_quote((int)$start), db_quote((int)$range)); 
    2121    return db_fetch_all($query); 
     
    3030 
    3131function blog_get_comment_count($topic_id) { 
    32     $query = sprintf("SELECT `numReplies` FROM ia_smf_topics  
     32    $query = sprintf("SELECT `numReplies` FROM ia_smf_topics 
    3333                      WHERE ID_TOPIC = %d", db_escape($topic_id)); 
    3434    $result = db_fetch($query); 
     
    3838function blog_count($tag_name) { 
    3939    if (is_tag_name($tag_name)) { 
    40         $tag_id = tag_get_id($tag_name); 
     40        $tag_id = tag_get_id(array("name" => $tag_name, "type" => "tag")); 
    4141        if (is_null($tag_id)) { 
    4242            $tag_id = -1; 
     
    5454 
    5555function blog_get_tags() { 
    56     $query = "SELECT name,  
     56    $query = "SELECT name, 
    5757                     (SELECT COUNT(*) FROM ia_textblock_tags WHERE tag_id = id AND textblock_id LIKE 'blog/%%') AS cnt 
    58               FROM ia_tags WHERE id IN  
     58              FROM ia_tags WHERE id IN 
    5959              (SELECT DISTINCT tag_id FROM ia_textblock_tags WHERE textblock_id LIKE 'blog/%%') 
    6060              ORDER BY name"; 
  • trunk/common/db/tags.php

    r852 r1069  
    44require_once(IA_ROOT_DIR."common/common.php"); 
    55 
    6 // get list of all tag names 
    7 function tag_get_all_names() { 
    8     $query = sprintf("SELECT name FROM ia_tags"); 
     6// Get list of all tag names, filtered by type 
     7function tag_get_all($types = null) { 
     8    $query = "SELECT name, type FROM ia_tags"; 
     9    if (!is_null($types)) { 
     10        log_assert(is_array($types), "types should be an array"); 
     11        foreach ($types as $type) { 
     12            log_assert(is_tag_type($type)); 
     13        } 
     14 
     15        $query .= sprintf(" WHERE type IN (%s)", 
     16            implode(',', array_map('db_quote', $types)) 
     17        ); 
     18    } 
    919    return db_fetch_all($query); 
    1020} 
    1121 
    12 function tag_get_names($obj, $obj_id) { 
     22// Get list of all tags for a certain object, filtered by type 
     23function tag_get($obj, $obj_id, $type = null) { 
    1324    log_assert(is_taggable($obj)); 
    14     $query = sprintf("SELECT %s_id, tag_id, tags.name AS tag_name 
    15                       FROM ia_%s_tags AS obj_tags 
    16                       LEFT JOIN ia_tags AS tags ON obj_tags.tag_id = tags.id  
    17                       WHERE %s_id = %s", 
    18                       db_escape($obj), db_escape($obj), db_escape($obj),  db_quote($obj_id)); 
    19     return db_fetch_all($query);         
     25    log_assert(is_null($type) || is_tag_type($type)); 
     26    if (is_null($type)) { 
     27        $where_type = ""; 
     28    } else { 
     29        $where_type = sprintf(" AND tags.type = %s", db_quote($type)); 
     30    } 
     31    $query = sprintf( 
     32        "SELECT %s_id, tag_id, tags.name AS tag_name, tags.type AS tag_type 
     33        FROM ia_%s_tags AS obj_tags 
     34        LEFT JOIN ia_tags AS tags ON obj_tags.tag_id = tags.id 
     35        WHERE %s_id = %s%s", 
     36        db_escape($obj), db_escape($obj), db_escape($obj), 
     37        db_quote($obj_id), $where_type 
     38    ); 
     39    return db_fetch_all($query); 
    2040} 
    2141 
    22 // get tag id for a certain tag name 
    23 function tag_get_id($tag_name) { 
    24     log_assert(is_tag_name($tag_name)); 
    25     $query = sprintf("SELECT id FROM ia_tags WHERE name = %s", 
    26                      db_quote($tag_name)); 
     42// Get tag id for a certain tag 
     43function tag_get_id($tag) { 
     44    log_assert(is_tag($tag)); 
     45    $query = sprintf( 
     46        "SELECT id FROM ia_tags WHERE name = %s AND type = %s", 
     47        db_quote($tag["name"]), db_quote($tag["type"]) 
     48    ); 
    2749    $result = db_fetch($query); 
    2850    return $result['id']; 
    2951} 
    3052 
    31 // get list of tag ids for a list of tag names 
    32 function tag_get_ids($tag_names) { 
    33     foreach ($tag_names as &$name) { 
    34         log_assert(is_tag_name($name)); 
    35         $name = db_quote($name); 
     53// Get list of tag ids for a list of tags 
     54function tag_get_ids($tags) { 
     55    $tag_wheres = array(); 
     56    foreach ($tags as $tag) { 
     57        log_assert(is_tag($tag)); 
     58        $tag_wheres[] = sprintf("(name = %s AND type = %s)", 
     59            db_quote($tag["name"]), db_quote($tag["type"])); 
    3660    } 
    37     $query = sprintf("SELECT id FROM ia_tags WHERE name IN (%s)", implode(", ", $tag_names)); 
     61    $query = sprintf("SELECT id FROM ia_tags WHERE %s", 
     62        implode(" OR ", $tag_wheres)); 
    3863    return db_fetch_all($query); 
    3964} 
    4065 
    41 // build ugly where clause to be used in subqueries 
     66// Assign numeric id to a given tag name 
     67function tag_assign_id($tag) { 
     68    log_assert(is_tag($tag)); 
     69    $id = tag_get_id($tag); 
     70    if (is_null($id)) { 
     71        $query = sprintf("INSERT INTO ia_tags (name, type) VALUES (%s, %s)", 
     72            db_quote($tag['name']), db_quote($tag['type'])); 
     73        db_query($query); 
     74        return db_insert_id(); 
     75    } 
     76    return $id; 
     77} 
     78 
     79// Build ugly where clause to be used in subqueries 
    4280function tag_build_where($obj, $tag_ids, $parent_table = null) { 
    4381    log_assert(is_taggable($obj)); 
     
    5290    } 
    5391    $where = sprintf("(SELECT COUNT(*) FROM ia_%s_tags WHERE %s_id = %s.%s". 
    54                      " AND tag_id IN (%s)) = %d",  
    55                      db_escape($obj), db_escape($obj),  
    56                      db_escape($parent_table), db_escape($field),  
     92                     " AND tag_id IN (%s)) = %d", 
     93                     db_escape($obj), db_escape($obj), 
     94                     db_escape($parent_table), db_escape($field), 
    5795                     implode(", ", $tag_ids), count($tag_ids)); 
    5896    return $where; 
    5997} 
    6098 
    61 // assign numeric id to a given tag name  
    62 function tag_assign_id($tag_name) { 
    63     log_assert(is_tag_name($tag_name)); 
    64     $id = tag_get_id($tag_name); 
    65     if (is_null($id)) { 
    66         $query = sprintf("INSERT INTO ia_tags (name) VALUES (%s)", db_quote($tag_name)); 
    67         db_query($query); 
    68         return db_insert_id(); 
    69     } 
    70     return $id; 
    71 } 
    72  
    73 // get all objects containting all tags from a list of tag ids 
     99// Get all objects containting all tags from a list of tag ids 
    74100function tag_get_objects($obj, $tag_ids, $content = true) { 
    75101    log_assert(is_taggable($obj)); 
     
    77103    if ($content) { 
    78104        $fields = "*"; 
    79     } 
    80     else  
    81     if ($obj == 'textblock') { 
     105    } elseif ($obj == 'textblock') { 
    82106        $fields = "name"; 
    83     } 
    84     else { 
     107    } else { 
    85108        $fields = "id"; 
    86109    } 
    87     $query = sprintf("SELECT %s FROM ia_%s WHERE %s", $fields, db_escape($obj),  
     110    $query = sprintf("SELECT %s FROM ia_%s WHERE %s", $fields, db_escape($obj), 
    88111                     tag_build_where($obj, $tag_ids)); 
    89112    return db_fetch_all($query); 
    90113} 
    91114 
    92 // count the number of objects containing all tags from a list of tag ids 
     115// Count the number of objects containing all tags from a list of tag ids 
    93116function tag_count_objects($obj, $tag_ids) { 
    94117    log_assert(is_taggable($obj)); 
    95118    log_assert(is_array($tag_ids)); 
    96     $query = sprintf("SELECT COUNT(*) as `cnt` FROM ia_%s WHERE %s", db_escape($obj),  
     119    $query = sprintf("SELECT COUNT(*) as `cnt` FROM ia_%s WHERE %s", db_escape($obj), 
    97120                     tag_build_where($obj, $tag_ids)); 
    98121    $result = db_fetch($query); 
     
    100123} 
    101124 
    102 // check if a certain object has a certain tag  
     125// Clear all tags, filtered by type 
     126function tag_clear($obj, $obj_id, $type = null) { 
     127    log_assert(is_taggable($obj)); 
     128    log_assert(is_null($type) || is_tag_type($type)); 
     129    $where = sprintf("%s_id = %s", db_escape($obj), db_quote($obj_id)); 
     130    $query = sprintf("DELETE FROM ia_%s_tags WHERE %s AND tag_id IN (%s)", 
     131        db_escape($obj), $where, "%s" 
     132    ); 
     133    if (is_null($type)) { 
     134        $join = ""; 
     135    } else { 
     136        $join = "LEFT JOIN ia_tags AS tags ON obj_tags.tag_id = tags.id"; 
     137        $where .= sprintf(" AND tags.type = %s", db_quote($type)); 
     138    } 
     139    $subquery = sprintf("SELECT tag_id FROM ia_%s_tags AS obj_tags %s WHERE %s", 
     140        db_escape($obj), $join, $where); 
     141    $tag_ids = array(); 
     142    foreach (db_fetch_all($subquery) as $tag) { 
     143        $tag_ids[] = $tag["tag_id"]; 
     144    } 
     145    if ($tag_ids) { 
     146        $query = sprintf($query, implode(",", $tag_ids)); 
     147        db_query($query); 
     148    } 
     149} 
     150 
     151// Check if a certain object has a certain tag 
    103152function tag_exists($obj, $obj_id, $tag_id) { 
    104153    log_assert(is_taggable($obj)); 
     
    110159    if ($result['cnt'] == 0) { 
    111160        return false; 
    112     }  
     161    } 
    113162    return true; 
    114163} 
    115164 
    116 // clear all tags  
    117 function tag_clear($obj, $obj_id) { 
    118     log_assert(is_taggable($obj)); 
    119     $query = sprintf("DELETE FROM ia_%s_tags WHERE %s_id = %s", db_escape($obj), 
    120                      db_escape($obj), db_quote($obj_id)); 
    121     db_query($query); 
    122 } 
    123  
    124 // remove a tag 
     165// Remove a tag 
    125166function tag_remove($obj, $obj_id, $tag_id) { 
    126167    log_assert(is_taggable($obj)); 
     
    131172} 
    132173 
    133 // add a tag 
     174// Add a tag 
    134175function tag_add($obj, $obj_id, $tag_id) { 
    135176    log_assert(is_taggable($obj)); 
  • trunk/common/tags.php

    r852 r1069  
    3030} 
    3131 
    32 function tag_build_list($obj, $obj_id) { 
    33     $tag_list = tag_get_names($obj, $obj_id); 
     32function tag_build_list($obj, $obj_id, $type) { 
     33    $tag_list = tag_get($obj, $obj_id, $type); 
    3434    $tag_names = array(); 
    3535    foreach ($tag_list as $tag) { 
     
    3939} 
    4040 
    41 function tag_update($obj, $obj_id, $tag_data) { 
    42     tag_clear($obj, $obj_id); 
     41function tag_update($obj, $obj_id, $type, $tag_data) { 
     42    tag_clear($obj, $obj_id, $type); 
    4343    $tag_data = tag_split($tag_data); 
    4444    foreach ($tag_data as $tag_name) { 
    45         $tag_id = tag_assign_id($tag_name); 
     45        $tag_id = tag_assign_id(array("name" => $tag_name, "type" => $type)); 
    4646        tag_add($obj, $obj_id, $tag_id); 
    4747    } 
  • trunk/common/textblock.php

    r1057 r1069  
    4949        // 'stiri'. On the other hand, this operation is cached and we 
    5050        // shouldn't worry too much about performance. 
    51         if ($whole_news && tag_exists('textblock', $tb['name'], tag_get_id('stiri'))) { 
     51        if ($whole_news && tag_exists('textblock', $tb['name'], 
     52            tag_get_id(array("name" => 'stiri', "type" => "tag")))) { 
    5253            // Don't compute snippet for news -- they should be rendered as 
    5354            // they are in the snippet. 
  • trunk/www/controllers/account.php

    r997 r1069  
    7676 
    7777        // validate tag data 
    78         $data['tags'] = request('tags', tag_build_list("user", $user['id'])); 
     78        $data['tags'] = request('tags', tag_build_list("user", $user['id'], "tag")); 
    7979        tag_validate($data, $errors); 
    8080 
     
    162162            // update tags info 
    163163            if (identity_can('user-tag', $new_user)) { 
    164                 tag_update("user", $new_user['id'], $data['tags']); 
    165             } 
    166             $data['tags'] = tag_build_list("user", $new_user['id']); 
     164                tag_update("user", $new_user['id'], "tag", $data['tags']); 
     165            } 
     166            $data['tags'] = tag_build_list("user", $new_user['id'], "tag"); 
    167167 
    168168            // done. redirect to same page so user has a strong confirmation 
     
    175175        // form is displayed for the first time. Fill in default values 
    176176        $data = $user; 
    177         $data['tags'] = tag_build_list("user", $user['id']); 
     177        $data['tags'] = tag_build_list("user", $user['id'], "tag"); 
    178178 
    179179        // unset some fields we do not $data to carry 
  • trunk/www/controllers/blog.php

    r969 r1069  
    5858        $subpage['forum_topic'] = blog_get_forum_topic($subpage['name']); 
    5959        $subpage['comment_count'] = blog_get_comment_count($subpage['forum_topic']); 
    60         $subpage['tags'] = tag_get_names("textblock", $subpage['name']); 
     60        $subpage['tags'] = tag_get("textblock", $subpage['name']); 
    6161    } 
    6262 
     
    102102    $view['textblock'] = $page; 
    103103    $view['forum_topic'] = $page['forum_topic']; 
    104     $view['tags'] = tag_get_names("textblock", $page['name']); 
     104    $view['tags'] = tag_get("textblock", $page['name']); 
    105105    $view['first_textblock'] = textblock_get_revision($page_name, 1, true); 
    106106 
  • trunk/www/controllers/round.php

    r1026 r1069  
    100100 
    101101    // Tag data 
    102     $values['tags'] = request('tags', tag_build_list("round", $round_id)); 
     102    $values['tags'] = request('tags', tag_build_list("round", $round_id, "tag")); 
    103103 
    104104    // Validate the monkey. 
     
    169169 
    170170        if (identity_can('round-tag', $new_round)) { 
    171             tag_update("round", $new_round['id'], $values['tags']); 
     171            tag_update("round", $new_round['id'], "tag", $values['tags']); 
    172172        } 
    173173 
  • trunk/www/controllers/task.php

    r1053 r1069  
    6565 
    6666    // Tag data 
    67     $values['tags'] = request('tags', tag_build_list("task", $task_id)); 
     67    $values['tags'] = request('tags', tag_build_list("task", $task_id, "tag")); 
    6868 
    6969    // Task owner 
     
    138138 
    139139            if (identity_can('task-tag', $new_task)) { 
    140                 tag_update("task", $new_task['id'], $values['tags']); 
     140                tag_update("task", $new_task['id'], "tag", $values['tags']); 
    141141            } 
    142142 
  • trunk/www/controllers/textblock_edit.php

    r997 r1069  
    3636    $values['security'] = request('security', $page['security']); 
    3737    $values['forum_topic'] = request('forum_topic', $page['forum_topic']); 
    38     $values['tags'] = request('tags', tag_build_list("textblock", $page_name)); 
     38    $values['tags'] = request('tags', tag_build_list("textblock", $page_name, "tag")); 
    3939    $values['creation_timestamp'] = getattr($page, 'creation_timestamp'); 
    4040    $values['timestamp'] = null; 
     
    8282                                   remote_ip_info()); 
    8383            if (identity_can('textblock-tag', $new_page)) { 
    84                 tag_update("textblock", $new_page['name'], $values['tags']); 
     84                tag_update("textblock", $new_page['name'], "tag", $values['tags']); 
    8585            } 
    8686            flash('Am actualizat continutul'); 
  • trunk/www/views/tags_header.php

    r1055 r1069  
    4242} 
    4343<?php 
    44 $tag_names = tag_get_all_names(); 
     44$tag_names = tag_get_all(); 
    4545echo  "collection = [\n"; 
    4646foreach ($tag_names as $tag) { 
Note: See TracChangeset for help on using the changeset viewer.