<?php

/**
 *
 * INDEXU
 * Copyright(C), Nicecoder, 2000-2006, All Rights Reserved.
 *
 * INDEXU(tm) is protected by Indonesia and International copyright laws.
 * Unauthorized use or distribution of INDEXU(tm) is strictly prohibited,
 * violators will be prosecuted. To obtain a license for using INDEXU(tm),
 * please register at Nicecoder home page at http://www.nicecoder.com
 *
 * Author:
 *    Dody Rachmat Wicaksono (dody@nicecoder.com)
 *    M. Zuber (zubby@nicecoder.com)
 *
 */

  class clsLink {

    var $table_name      = "link";
    var $table_name_temp = "";
    var $query           = "";
    var $date_format     = "d-M-Y";
    var $max_rows        = "";
    var $template        = "";
    var $template_file   = "";
    var $header          = "";
    var $paging          = false;
    var $show_number     = true;
    var $pg_size         = "10";
    var $href            = "";
    var $more_param      = "";

    var $icon_new        = "<b><font style='font-family: Verdana; font-size: 11px; color: green;'>New</font></b>";
    var $icon_updated    = "<font style='font-family: Verdana; font-size: 11px; color: #000000;'><i>Upd.</i></font>";
    var $icon_top_rated  = "<b><font style='font-family: Verdana; font-size: 11px; color: #FF7200;'><i>Top Rated</i></font></b>";
    var $icon_hot        = "<b><font style='font-family: Verdana; font-size: 11px; color: #EE2655;'><i>Hot</i></font></b>";
    var $icon_pick       = "<b><font style='font-family: Verdana; font-size: 11px; color: #FF00F0;'><i>Pick</i></font></b>";

    var $category_table_name                   = "category";
    var $category_separator                    = " > ";
    var $path_separator                        = " : ";
    var $new_title                             = "New";
    var $show_new_link_by_category             = false;
    var $new_listing_date_format               = "l, F j Y";
    var $new_link_category_path_template       = "<p><b><%category_path%></b></p>";
    var $hot_link_category_path_template       = "<p><b><%category_path%></b></p>";
    var $top_rated_link_category_path_template = "<p><b><%category_path%></b></p>";
    var $hot_link_table_header                 = "";
    var $hot_link_table_footer                 = "";
    var $top_rated_link_table_header           = "";
    var $top_rated_link_table_footer           = "";
    var $pick_link_table_header                = "";
    var $pick_link_table_footer                = "";
    var $custom_field_offset                   = 27;   // start offset of the custom field

    var $fields_name                           = array();
    var $fields_text                           = array();
    var $fields_type                           = array();
    var $fields_size                           = array();
    var $fields_option                         = array();
    var $fields_img_width                      = array();
    var $fields_img_height                     = array();
    var $fields_file_size                      = array();
    var $fields_file_extension                 = array();
    var $fields_required                       = array();
    var $fields_searchable                     = array();
    var $fields_permission                     = array();

    var $autogenerate_form_text;     // template to generate input=text
    var $autogenerate_form_textarea; // template to generate <textarea>
    var $autogenerate_form_upload;   // template to generate upload link
    var $autogenerate_form_template; // template to generate fields

    var $editor_table_name                     = "editor";
    var $user_table_name                       = "user";
    var $favorite_table_name                   = "favorite";
    var $favorite_detail_table_name            = "favorite_detail";
    var $bad_link_table_name                   = "bad_link";

    var $votes_table_name                      = "votes";
    var $review_table_name                     = "review";
    var $rating_image_path                     = "";
    var $rev_rating_image_path                 = "";

    var $top_rated_limit                       = "10";
    var $hot_limit                             = "10";
    var $new_limit                             = "7"; // day
    var $updated_limit                         = "7"; // day
    var $curr_row                              = 0;
    var $bold                                  = false;
    var $keywords                              = "";
    var $bold_format                           = '<b><%$keyword%></b>';

    var $not_yet_rated    = '<a href="detail.php?id=<%$id%"> style="{text-decoration: none; color:#0080c0;}">Rate It!</a>';
    var $already_rated    = '<a href="detail.php?id=<%$id%"> style="{text-decoration: none; color:#0080c0;}">Visitor Ratings: </a>';
    var $not_yet_reviewed = '<a href="review.php?id=<%$id%"> style="{text-decoration: none; color:#f16c00;}">Write a Review!</a>';
    var $already_reviewed = '<a href="review.php?id=<%$id%"> style="{text-decoration: none; color:#f16c00;}">Member Ratings: </a>';

    // output only
    var $pagination                            = "";
    var $email_template_fields                 = "";
    var $num_rows                              = 0;
    var $new_link_number                       = 0;
    var $record_count_of_display               = "";

    var $lid;


    // method to get fields name
    // return :   array of field name
    // set value :  $this->fields_name
    //              $this->fields_type
    // -------------------------------

    function GetFields() {
      global $dbConn;

      // get link fields information
      $query = "select * from $this->table_name where link_id = 0";
      $result = $dbConn->Execute($query);
      $num_fields = $result->FieldCount();

      if ($result) {
        $i = 0;
        while ($i < $num_fields) {
          $fld           = $result->FetchField($i);
          $fields[]      = $fld->name;
          if ($i >= $this->custom_field_offset) {
            $row = $dbConn->FetchOne("select * from idx_custom_field where field_name = '$fld->name'");
            $fields_text[] = $row['field_text'];
            $fields_type[] = $row['field_type'];
            $fields_option[] = $row['field_option'];
            $fields_img_width[] = $row['field_img_width'];
            $fields_img_height[] = $row['field_img_height'];
            $fields_file_size[] = $row['field_file_size'];
            $fields_file_extension[] = $row['field_file_extension'];
            $fields_required[] = $row['required'];
            $fields_searchable[] = $row['searchable'];
            $fields_permission[] = $row['permission'];
          }
          else {
            $fields_text[] = '';
            $fields_type[] = '';
            $fields_option[] = '';
            $fields_img_width[] = '';
            $fields_img_height[] = '';
            $fields_file_size[] = '';
            $fields_file_extension[] = '';
            $fields_required[] = '';
            $fields_searchable[] = '';
            $fields_permission[] = '';
          }
          $fields_size[] = $fld->max_length;
          $i++;
        }
      }

      // set
      $this->fields_name = $fields;
      $this->fields_text = $fields_text;
      $this->fields_type = $fields_type;
      $this->fields_size = $fields_size;
      $this->fields_option = $fields_option;
      $this->fields_img_width = $fields_img_width;
      $this->fields_img_height = $fields_img_height;
      $this->fields_file_size = $fields_file_size;
      $this->fields_file_extension = $fields_file_extension;
      $this->fields_required = $fields_required;
      $this->fields_searchable = $fields_searchable;
      $this->fields_permission = $fields_permission;

      // return array

      return $fields;
    }


    // method to get the number of new listing
    // return :   number of new listing
    // ---------------------------------------

    function GetTotalNewListing($st, $dt, $cat, $rev) {
      global $dbConn;
      $date = date("Y-m-d", $dt);

      // get total new link

      if (empty($st)) {
        $query  = "select count(link_id) as nl from $this->table_name where new = 1 and suspended = 0";
        $result = $dbConn->Execute($query);
        $val = $result->Fields("nl");
        $query  = "select count(link_id) as nl
                   from $this->table_name
                   where new = 1 and suspended = 0
                         and (to_days(last_updated) - to_days(date)) > 0
                         and (to_days(last_updated) - to_days(date)) <= $this->updated_limit
                         and (to_days(now()) - to_days(date)) <= $this->new_limit";
        $result = $dbConn->Execute($query);
        $val = $val + $result->Fields("nl");
      }
      elseif ($st == 'date') {
        $query  = "select count(link_id) as nl
                   from $this->table_name
                   where (new = 1 and suspended = 0 and (date like '$date%' or last_updated like '$date%'))";
        $result = $dbConn->Execute($query);
        $val    = $result->Fields("nl");
      }
      elseif ($st == 'cat') {
        $date    = date("Y-m-d", $dt);

        $category_obj = new clsCategory;
        $category_obj->table_name      = $this->category_table_name;
        $category_obj->link_table_name = $this->table_name;
        $category_obj->separator       = $this->category_separator;
        $queue = $category_obj->GetChildren($cat);

        $query = "select count(link_id) as count
                  from $this->table_name
                  where (new = 1 and suspended = 0 and (date like '$date%' or last_updated like '$date%') and (0 != 0";

        while (list($key, $cat) = @each($queue)) {
          $query .= " or category_id = '$cat'";
        }

        $query .= " ))";

        $result = $dbConn->Execute($query);
        $val = $result->Fields("count");
      }

      return $val;
    }


    // method to get the path of new listing
    // return :   path of new listing
    // -------------------------------------

    function GetNewListingPath($st, $dt, $cat, $rev) {
      global $dbConn;
      $date = date($this->date_format, $dt);

      // get total new link

      $path = " $this->path_separator <a href=$this->href>$this->new_title</a>";

      if (empty($st))
        $path .= "";
      elseif ($st == 'date')
        $path .= " $this->path_separator $date";
      elseif ($st == 'cat') {
        $query  = "select name from $this->category_table_name where category_id = '$cat'";
        $result = $dbConn->Execute($query);
        $path .= " $this->path_separator <a href=\"new.php?st=date&amp;dt=$dt\">$date</a> $this->path_separator " . $result->Fields("name");
      }

      return $path;
    }


    // method to display new listings
    // return :   html of new listing
    // ------------------------------

    function DisplayNewListing($st, $dt, $cat, $rev) {
      global $dbConn;

      $tpl = new Template();

      $this->new_link_number = 1;

      // get hidden category
      $query  = "select category_id
                 from idx_category where visible = 0";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $hidden_cats[] = $result->Fields("category_id");
        $result->MoveNext();
      }

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      if (empty($st)) {

        // get date

        $query  = "select distinct date, last_updated
                   from $this->table_name where new = 1 and suspended = 0";
        $result = $dbConn->Execute($query);

        while (!$result->EOF) {
          $date         = $result->Fields("date");
          $last_updated = $result->Fields("last_updated");

          // compare which is the most recently
          $date         = date('Y-m-d', @strtotime($date));
          $last_updated = date('Y-m-d', @strtotime($last_updated));

          if ($date > $last_updated) {
            $dates[] = strtotime($date);
          }
          elseif ((date('Ymd') - date('Ymd', strtotime($date)) <= $this->new_limit) && (date('Ymd', strtotime($last_updated)) - date('Ymd', strtotime($date)) > 0)) {
            $dates[] = strtotime($date);
            $dates[] = strtotime($last_updated);
          }
          else {
            $dates[] = strtotime($last_updated);
          }
          $result->MoveNext();
        }

        // remove duplicate entry
        $new_dates = array ();

        $i = 0;
        $count_dates = @count($dates);
        while ($i < $count_dates) {
          $val = $dates[$i];

          if (!in_array($val, $new_dates))
            $new_dates[] = $val;

          $i++;
        }

        $dates = $new_dates;

        // sort queue [in timestamp format]
        rsort ($dates);

        // fetch by date

        $i = 0;
        $count_dates = @count($dates);

        while ($i < $count_dates) {
          $ts_date = $dates[$i];
          $date    = date("Y-m-d", $ts_date);

          $query2  = "select count(link_id) as nl
                      from $this->table_name
                      where (new = 1 and suspended = 0 and (date like '$date%' or last_updated like '$date%'))";

          // exclude hidden category
          while (list(, $v) = @each($hidden_cats)) {
            $query .= " and category_id <> $v";
          }
          @reset($hidden_cats);

          $result2          = $dbConn->Execute($query2);
          $total_by_dates[] = $result2->Fields("nl");

          $date_ls          = date($this->new_listing_date_format, $ts_date);

          $html .= "<p /><a href=\"new.php?st=date&amp;dt=$ts_date\">$date_ls</a> <i>($total_by_dates[$i])</i><br />";

          if ($this->show_new_link_by_category) {
            $basket = array ( "" );

            // get categories for each date

            $query2 = "select distinct category_id from $this->table_name
                       where (new = 1 and suspended = 0  and (date like '$date%' or last_updated like '$date%'))";

            // exclude hidden category
            while (list(, $v) = @each($hidden_cats)) {
              $query2 .= " and category_id <> $v";
            }
            @reset($hidden_cats);

            $result2 = $dbConn->Execute($query2);
            $num_cat = $result2->RecordCount();

            if ($result2) {
              $j = 0;

              while ($j < $num_cat) {
                $cat_id    = $result2->Fields("category_id");

                // get the main category
                $main_category_id = $category_obj->GetTopParentCategory($cat_id);
                if ($main_category_id != 0) {
                  $cat_id = $main_category_id;
                }
                $name = $category_obj->GetCategoryName($cat_id);

                if (!in_array($cat_id, $basket)) {
                  $basket[]     = $cat_id;

                  $cat_name     = $name;
                  $num_each_cat = $this->GetTotalNewListing('cat', $ts_date, $cat_id, '');

                  $html .= "<a href=\"new.php?st=cat&amp;id=$cat_id&amp;dt=$ts_date\">$cat_name</a> <i>($num_each_cat)</i>";
                  $html .= " - ";
                }

                $j++;
                $result2->MoveNext();
              }

              $html = substr($html, 0, strlen($html) - 3);
            }
          }

          $i++;
        }
      }

      if ($st == "date") {
        $date  = date("Y-m-d", $dt);

        // get categories, then save into an array

        $query = "select distinct category_id from $this->table_name
                  where (new = 1 and suspended = 0 and (date like '$date%' or last_updated like '$date%'))";

        // exclude hidden category
        while (list(, $v) = @each($hidden_cats)) {
          $query .= " and category_id <> $v";
        }
        @reset($hidden_cats);

        $result  = $dbConn->Execute($query);
        $num_cat = $result->RecordCount();

        while (!$result->EOF) {
          $categories[] = $result->Fields("category_id");
          $result->MoveNext();
        }

        // get in order categories by path alphabetically
        $categories                    = $category_obj->GetInOrderCategory($categories);

        // fetch data by categories

        $last_top_lv_cat               = -1;

        $i                             = 0;

        $count_categories = @count($categories);
        while ($i < $count_categories) {

          // get category path
          $top_lv_cat = $category_obj->GetTopParentCategory($categories[$i]);

          if ($top_lv_cat == 0)
            $top_lv_cat = $categories[$i];

          if ($top_lv_cat != $last_top_lv_cat) {
            $category_path   = $category_obj->GetCategoryPath($top_lv_cat, TRUE);
            $tpl->assign('category_path', $category_path);
            $html .= $tpl->fetch('var:' . $this->new_link_category_path_template);
            $last_top_lv_cat = $top_lv_cat;
          }

          $this->query = "select * from $this->table_name
                          where (new = 1 and suspended = 0 and  (date like '$date%' or last_updated like '$date%') and category_id = '$categories[$i]')";
          $html .= $this->Display();

          $i++;
        }
      }

      if ($st == "cat") {
        $date         = date("Y-m-d", $dt);
        $queue        = $category_obj->GetChildren($cat);

        $category_path   = $category_obj->GetCategoryPath($cat, TRUE);
        $tpl->assign('category_path', $category_path);
        $html .= $tpl->fetch('var:' . $this->new_link_category_path_template);

        $this->query = "select * from $this->table_name
                        where (new = 1 and suspended = 0 and (date like '$date%' or last_updated like '$date%') and (0 != 0";

        while (list($key, $cat) = @each($queue)) {
          $this->query .= " or category_id = '$cat'";
        }

        $this->query .= " ))";

        $html .= $this->Display();
      }

      return $html;
    }


    // method to display links
    // return :   html of hot listing
    // -------------------------------

    function DisplayHotListing() {
      global $dbConn;

      $tpl = new Template();

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // get all main category

      $query  = "select category_id from $this->category_table_name where parent_id = 0 and visible = 1";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $main_categories[] = $result->Fields("category_id");
        $result->MoveNext();
      }

      // get in order categories by path alphabetically

      $main_categories = $category_obj->GetInOrderCategory($main_categories);

      $i               = 0;

      $count_main_categories = @count($main_categories);
      while ($i < $count_main_categories) {
        $main_cat_id = $main_categories[$i];
        $queue       = $category_obj->GetChildren($main_cat_id);

        // build query

        $this->query = "select * from $this->table_name
                        where hits <> 0 and suspended = 0 and (0!=0 ";
        $j           = 0;

        $count_queue = @count($queue);
        while ($j < $count_queue) {
          $cat_id = $queue[$j];
          $this->query .= "or category_id = '$cat_id' ";
          $j++;
        }

        $this->query .= ") order by hits desc limit $this->hot_limit";

        $result = $dbConn->Execute($this->query);

        if ($result->RecordCount()) {
          $query   = "update $this->table_name set hot = 1 where 0 != 0 ";
          while (!$result->EOF) {
            $link_id = $result->Fields("link_id");
            $query .= " or link_id = '$link_id' ";
            $result->MoveNext();
          }
          $result = $dbConn->Execute($query);
        }

        $this->curr_row = 0;
        $html_temp      = $this->Display();

        if (!empty($html_temp)) {
          $name            = $category_obj->GetCategoryName($main_cat_id);
          $tpl->assign('category', $name);
          $html .= $tpl->fetch('var:' . $this->hot_link_table_header);
          $html .= $html_temp;
          $html .= $this->hot_link_table_footer;
        }

        $i++;
      }

      return $html;
    }


    // method to display top rated links
    // return :   html of top rated listing
    // ------------------------------------

    function DisplayTopRatedListing() {
      global $dbConn;

      // reset
      $query  = "update $this->table_name set top_rated = 0";
      $result = $dbConn->Execute($query);

      $tpl          = new Template();

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // get all main category

      $query  = "select category_id from $this->category_table_name where parent_id = 0 and visible = 1";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $main_categories[] = $result->Fields("category_id");
        $result->MoveNext();
      }

      // get in order categories by path alphabetically

      $main_categories = $category_obj->GetInOrderCategory($main_categories);

      $i               = 0;

      $count_main_categories = @count($main_categories);
      while ($i < $count_main_categories) {
        $main_cat_id = $main_categories[$i];
        $queue       = $category_obj->GetChildren($main_cat_id);

        // build query

        $this->query = "select * from $this->table_name
                        where votes <> 0 and suspended = 0 and (0!=0 ";
        $j           = 0;

        $count_queue = @count($queue);
        while ($j < $count_queue) {
          $cat_id = $queue[$j];
          $this->query .= "or category_id = '$cat_id' ";
          $j++;
        }

        $this->query .= ") order by rating desc limit $this->top_rated_limit";

        $result = $dbConn->Execute($this->query);

        if ($result->RecordCount()) {
          $query   = "update $this->table_name set top_rated = 1 where 0 != 0 ";
          while (!$result->EOF) {
            $link_id = $result->Fields("link_id");
            $query .= " or link_id = '$link_id' ";
            $result->MoveNext();
          }
          $result = $dbConn->Execute($query);
        }

        $this->curr_row = 0;
        $html_temp      = $this->Display();

        if ($html_temp != "") {
          $name            = $category_obj->GetCategoryName($main_cat_id);
          $tpl->assign('category', $name);
          $html .= $tpl->fetch('var:' . $this->top_rated_link_table_header);
          $html .= $html_temp;
          $html .= $this->top_rated_link_table_footer;
        }

        $i++;
      }

      return $html;
    }


    // method to display editor pick links
    // return :   html of hot listing
    // -------------------------------

    function DisplayEditorPickListing() {
      global $dbConn;
      $tpl          = new Template();
      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // get all main category
      $query = "select category_id from $this->category_table_name where parent_id = 0 and visible = 1";
      $result                        = $dbConn->Execute($query);

      while (!$result->EOF) {
        $main_categories[] = $result->Fields("category_id");
        $result->MoveNext();
      }
      $result->Close();

      // get in order categories by path alphabetically
      $main_categories = $category_obj->GetInOrderCategory($main_categories);

      $i               = 0;

      $count_main_categories = @count($main_categories);
      while ($i < $count_main_categories) {
        $main_cat_id = $main_categories[$i];
        $queue       = $category_obj->GetChildren($main_cat_id);
        $cat         = $main_categories[$i];

        // build query
        $this->query = "select * from $this->table_name where ((0!=0 ";
        $j           = 0;

        $count_queue = @count($queue);
        while ($j < $count_queue) {
          $cat_id = $queue[$j];
          $this->query .= "or category_id = '$cat_id' ";
          $j++;
        }

        $this->query .= ") and pick = 1 and suspended = 0) limit 10";

        $this->curr_row = 0;
        $html_temp      = $this->Display();

        if ($html_temp != "") {
          $name            = $category_obj->GetCategoryName($main_cat_id);
          $tpl->assign('category', $name);
          $html .= $tpl->fetch('var:' . $this->pick_link_table_header);
          $html .= $html_temp;
          $html .= $this->pick_link_table_footer;
        }

        $i++;
      }

      return $html;
    }


    // method to display links
    // return :   html
    // set :      $this->record_count_of_display
    // -----------------------------------------

    function Display($validation = false) {
      global $dbConn, $no_image_file, $pg_which, $admin_template_path;

      $tpl       = new Template();

      $link_icon = "../admin_tpl/images/tree_node.gif";
      $link_icon = "<img src=\"$link_icon\" border=\"0\" alt=\"\" /> ";

      $fields    = $this->GetFields();

      // pagination

      if ($this->paging) {
        if (empty($pg_which)) {
          $pg_which = 1;
        }
        $result                        = $dbConn->PageExecute($this->query, $pg_which, $this->pg_size);
        $this->record_count_of_display = $num_rows = $result->RecordCount();
        $nav                           = new navigator;
        $nav->pg_size                  = $this->pg_size;
        $nav->href                     = $this->href;
        $nav->more_param               = $this->more_param;
        $nav->page_file                = $this->page_file;
        $nav->page_title               = $this->page_title;
        $nav->pg_which                 = $pg_which;
        $nav->rec_count                = $num_rows;
        $nav->init();
        $this->pagination              = $nav->print_all();
        $i                             = $nav->rec_start;
        $this->max_rows                = 100000;
      }
      else {
        $result                        = $dbConn->Execute($this->query);
        $this->record_count_of_display = $num_rows = $result->RecordCount();
        $i                             = 0;
      }

      if ($num_rows != 0) {
        $links = $this->header;
      }

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // fetching data

      $number                        = 0;

      while (!$result->EOF && $this->curr_row < $this->max_rows) {

        // get field's value
        $j = 0;
        $count_fields = @count($fields);
        while ($j < $count_fields) {
          $$fields[$j] = trim($result->Fields("$fields[$j]"));
          $j++;
        }

        if ($validation)
          $vid = $result->Fields("vid");

        $result->MoveNext();

        if ($this->new_link_number == 0)
          $number = $i + 1;
        else {
          $this->new_link_number++;
          $number = $this->new_link_number - 1;
        }

        $date                    = date($this->date_format, @strtotime($date));

        // category's path

        $category_path           = $category_obj->GetCategoryPath($category_id);
        $category_path_with_link = $category_obj->GetCategoryPath($category_id, TRUE);

        // if it has additional category
        if ($cat1 != 0 or !empty($cat1)) {
          $cpath2                  = $category_obj->GetCategoryPath($cat1);
          $cpath2_link             = $category_obj->GetCategoryPath($cat1, TRUE);

          $category_path           = $category_path . "<br /> " . $cpath2;
          $category_path_with_link = $category_path_with_link . "<br /> " . $cpath2_link;
        }

        if ($cat2 != 0 or !empty($cat2)) {
          $cpath2                  = $category_obj->GetCategoryPath($cat2);
          $cpath2_link             = $category_obj->GetCategoryPath($cat2, TRUE);

          $category_path           = $category_path . "<br /> " . $cpath2;
          $category_path_with_link = $category_path_with_link . "<br /> " . $cpath2_link;
        }

        // review
        $tpl->assign('id', $link_id);
        $this->not_yet_rated = $tpl->fetch('var:' . $this->not_yet_rated);

        $tpl->assign('id', $link_id);
        $this->already_rated = $tpl->fetch('var:' . $this->already_rated);

        $tpl->assign('id', $link_id);
        $this->not_yet_reviewed = $tpl->fetch('var:' . $this->not_yet_reviewed);

        $tpl->assign('id', $link_id);
        $this->already_reviewed = $tpl->fetch('var:' . $this->already_reviewed);

        $avgr                   = $avg_review * 2;

        if ($avgr < 1) {
          $review_image = $this->not_yet_reviewed;
          $review_img   = "<img src=\"" . $this->rev_rating_image_path . "0.gif\"" . " alt=\"\" />";
        }
        else {
          if (round($avgr) == 1)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "0half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 2)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "1.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 3)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "1half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 4)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "2.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 5)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "2half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 6)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "3.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 7)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "3half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 8)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "4.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 9)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "4half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 10)
            $review_image = "<img src=\"" . $this->rev_rating_image_path . "5.gif\"" . " alt=\"\" />";

          $review_img   = $review_image;
          $review_image = $this->already_reviewed . $review_image;
        }

        // review

        $avgr = $rating * 2;

        if ($avgr < 1) {
          $rating_image  = $this->not_yet_rated;
          $rating_image2 = $rating_image;
          $rating_img    = "<img src=\"" . $this->rating_image_path . "0.gif\"" . " alt=\"\" />";
        }
        else {
          if (round($avgr) == 1)
            $rating_image = "<img src=\"" . $this->rating_image_path . "0half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 2)
            $rating_image = "<img src=\"" . $this->rating_image_path . "1.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 3)
            $rating_image = "<img src=\"" . $this->rating_image_path . "1half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 4)
            $rating_image = "<img src=\"" . $this->rating_image_path . "2.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 5)
            $rating_image = "<img src=\"" . $this->rating_image_path . "2half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 6)
            $rating_image = "<img src=\"" . $this->rating_image_path . "3.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 7)
            $rating_image = "<img src=\"" . $this->rating_image_path . "3half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 8)
            $rating_image = "<img src=\"" . $this->rating_image_path . "4.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 9)
            $rating_image = "<img src=\"" . $this->rating_image_path . "4half.gif\"" . " alt=\"\" />";
          elseif (round($avgr) == 10)
            $rating_image = "<img src=\"" . $this->rating_image_path . "5.gif\"" . " alt=\"\" />";

          $rating_img    = $rating_image;
          $rating_image2 = $rating_image;
          $rating_image  = $this->already_rated . $rating_image;
        }

        // -- template function

        if ($this->show_number)
          $tpl->assign('number', $number);

        global $id;
        $tpl->assign('id', $id);

        if ($updated) {
          $tpl->assign('updated', '1');
          $tpl->assign('new', '');
        }
        elseif ($new) {
          $tpl->assign('new', '1');
          $tpl->assign('updated', '');
        }
        else {
          $tpl->assign('updated', '');
          $tpl->assign('new', '');
        }

        if ($hot)
          $tpl->assign('hot', '1');
        else
          $tpl->assign('hot', '');

        if ($top_rated)
          $tpl->assign('top_rated', '1');
        else
          $tpl->assign('top_rated', '');

        if ($pick)
          $tpl->assign('pick', '1');
        else
          $tpl->assign('pick', '');

        if ($number % 2)
          $tbl_class = "tbl_light";
        else
          $tbl_class = "tbl_light2";

        $tpl->assign('tbl_class', $tbl_class);

        $tpl->assign('rating_image', $rating_image);
        $tpl->assign('rating_image2', $rating_image2);
        $tpl->assign('review_image', $review_image);

        $tpl->assign('id', $link_id);
        $tpl->assign('link_id', $link_id);
        $tpl->assign('vid', $vid);
        $tpl->assign('fav_id', $id);   // fix can not delete fav. link

        // title for mod rewrite
        $title_mod = strtolower($title);
        $title_mod = SEOReplace($title_mod);
        $tpl->assign('title_mod', $title_mod);


        // detail url <%$detail_url%>
        if (GetModRewriteStatus()=='1') {
          $mod_rewrite_pattern = GetModRewritePatternDetail();
          $mod_rewrite_pattern = str_replace('{$link_title}',$title_mod,$mod_rewrite_pattern);
          $mod_rewrite_pattern = str_replace('{$link_id}',$link_id,$mod_rewrite_pattern);
          $detail_page_url     = strtolower($mod_rewrite_pattern);
        }
        else {
          $detail_page_url     = "detail.php?linkid=$link_id";
        }
        $tpl->assign('detail_page_url', $detail_page_url);


        // bold keyword
        if ($this->bold) {
          $this->bold_format = str_replace('<%$keyword%>','\\0',$this->bold_format);
          $keywords = $this->keywords;

          $pattern = @implode('|', $keywords);
          $title = preg_replace("/$pattern/msi", $this->bold_format, $title);
          $description = preg_replace("/$pattern/msi", $this->bold_format, $description);
          $disp_url = preg_replace("/$pattern/msi", $this->bold_format, $url);
        }

        if (empty($link_id) && $validation)
          $val_type = "<font color=\"green\" size=\"1\">New</font>";
        elseif (!empty($link_id) && $validation)
          $val_type = "<font color=\"blue\" size=\"1\">Modify</font>";

        if ($validation)
          $tpl->assign('val_type', $val_type);

        // exclude
        $exclude = array (
          'new',
          'updated',
          'pick',
          'top_rated',
          'hot'
        );

        $j = 0;
        $count_fields = @count($fields);
        while ($j < $count_fields) {
          // image
          if ($this->fields_type[$j] == "IMAGE")
            if ($$fields[$j] == "")
              $$fields[$j] = $no_image_file;

          // review and rating
          if ($fields[$j] == 'reviews' && empty($$fields[$j])) {
            $$fields[$j] = '0';
          }

          if ($fields[$j] == 'avg_review' && empty($$fields[$j]))
            $$fields[$j] = '0.00';

          if (!in_array($fields[$j], $exclude)) {
            if ($fields[$j] == 'description' || $fields[$j] == 'official_review' || $this->fields_type[$j] == 'TEXT') {
              $$fields[$j] = preg_replace("/>(\r\n|\r|\n)/msi", ">", $$fields[$j]);
              $$fields[$j] = nl2br($$fields[$j]);
            }
            if ($this->fields_type[$j] == 'SELECT' || $this->fields_type[$j] == 'MULTISELECT' || $this->fields_type[$j] == 'CHECKBOX' || $this->fields_type[$j] == 'RADIO') {
              $v_field = explode(",", trim($$fields[$j]));
              $v_option = explode("\n", $this->fields_option[$j]);
              $v_fields = array();
              while (list($k, $v) = @each($v_field)) {
                while (list($kk, $vv) = @each($v_option)) {
                  $vvv = explode("|", trim($vv));
                  if (!$vvv[1]) {
                    $vvv[1] = $vvv[0];
                  }
                  if ($v == $vvv[0]) {
                    $v_fields[] = $vvv[1];
                  }
                }
                @reset($v_option);
              }
              $$fields[$j] = implode(", ", $v_fields);
            }
            $tpl->assign($fields[$j], $$fields[$j]);
          }

          $j++;
        }

        $chk_box = "<input type=checkbox name=chkbox_$number value=$link_id>";

        if ($validation)
          $chk_box = "<input type=checkbox name=chkbox_$number value=$vid>";

        $tpl->assign('chk_box', $chk_box);
        $tpl->assign('category_path', $category_path);
        $tpl->assign('category_path_with_link', $category_path_with_link);
        $tpl->assign('disp_url', $disp_url);
        $tpl->assign('link_icon', $link_icon);

        $tpl->assign('rating_img', $rating_img);
        $tpl->assign('review_img', $review_img);

        // paid listing data

        $query         = "select * from idx_paid_listing where link_id = '$link_id'";
        $row2          = $dbConn->FetchOne($query);
        $raw_premium   = $row2["premium"];
        $raw_sponsored = $row2["sponsored"];
        $raw_expire    = $row2["expire"];
        $raw_paid      = $row2["paid"];

        $premium       = 0;
        $sponsored     = 0;

        if ($raw_paid == 1 &&
            $raw_premium == 1 &&
            @strtotime("now") < @strtotime($raw_expire)) {
              $premium   = 1;
              $sponsored = 0;
        }

        if ($raw_paid == 1 &&
            $raw_sponsored == 1 &&
            @strtotime("now") < @strtotime($raw_expire)) {
              $premium   = 0;
              $sponsored = 1;
        }

        $tpl->assign('expire', $raw_expire);
        $tpl->assign('premium', $premium);
        $tpl->assign('sponsored', $sponsored);


        // keep this variable from being erased by smarty

        //error msg
        $tpl->assign('error_msg', '<%$error_msg%>');

        //favorite form
        $tpl->assign('favorite', '<%$favorite%>');

        //tell a friend form
        $tpl->assign('friend_name', '<%$friend_name%>');
        $tpl->assign('friend_email', '<%$friend_email%>');
        $tpl->assign('my_name', '<%$my_name%>');
        $tpl->assign('my_email', '<%$my_email%>');

        //review form
        $tpl->assign('username', '<%$username%>');
        $tpl->assign('rev_subject', '<%$rev_subject%>');
        $tpl->assign('rev_rating', '<%$rev_rating%>');
        $tpl->assign('rev_review', '<%$rev_review%>');
        $tpl->assign('rev_name', '<%$rev_name%>');
        $tpl->assign('rev_email', '<%$rev_email%>');
        $tpl->assign('rev_no_login', '<%$rev_no_login%>');

        if (empty($this->template)) {
          $links .= $tpl->fetch($this->template_file);
        }
        else {
          $links .= $tpl->fetch('var:' . $this->template);
        }
        // -- end of template function

        $this->curr_row++;
        $number++;
        $i++;
      }

      return $links;
    }


    // method to generate custom field form
    // return :   html of custom field
    // ------------------------------------

    function GenerateCustomFieldForm($add_form = false) {
      global $dbConn;

      $tpl    = new Template();

      $fields = $this->GetFields();

      $i      = $this->custom_field_offset;

      $count_fields = @count($fields);
      while ($i < $count_fields) {
        $field = $fields[$i];
        global $$field;

        if (strpos($_SERVER['PHP_SELF'], 'search.php') !== false) {
          // hide unsearchable field except for admin
          if ($this->fields_type[$i] == 'IMAGE'|| $this->fields_type[$i] == 'FILE' || (!$this->fields_searchable[$i] && strpos($_SERVER['PHP_SELF'], '/admin/') === false)) {
            $i++;
            continue;
          }
        }

        // check permission
        if ($this->fields_permission[$i]) {
          if ($this->fields_permission[$i] == 1 && !$_COOKIE['COOKIE_USERNAME']) {
            $i++;
            continue;
          }
          if ($this->fields_permission[$i] == 2 && strpos($_SERVER['PHP_SELF'], '/admin/') === false) {
            $i++;
            continue;
          }
        }

        switch($this->fields_type[$i]) {
          case "TEXTAREA" :
            $form[$i] = $this->autogenerate_form_textarea;
            break;
          case "IMAGE" :
            if($add_form) {
              $form[$i] = $this->autogenerate_form_image_add;
            }
            else {
              $form[$i] = $this->autogenerate_form_image;
              // hide "remove checkbox" for required field, except for admin
              if ($this->fields_required[$i] && strpos($_SERVER['PHP_SELF'], '/admin/') === false) {
                $form[$i] = preg_replace("|<!-- checkbox_start -->.*?<!-- checkbox_end -->|ms", "", $form[$i]);
              }
              else {
                $form[$i] = preg_replace("/<!-- checkbox_start -->|<!-- checkbox_end -->/ms", "", $form[$i]);
              }
            }
            break;
          case "FILE" :
            if($add_form) {
              $form[$i] = $this->autogenerate_form_file_add;
            }
            else {
              $form[$i] = $this->autogenerate_form_file;
              // hide "remove checkbox" for required field, except for admin
              if ($this->fields_required[$i] && strpos($_SERVER['PHP_SELF'], '/admin/') === false) {
                $form[$i] = preg_replace("|<!-- checkbox_start -->.*?<!-- checkbox_end -->|ms", "", $form[$i]);
              }
              else {
                $form[$i] = preg_replace("/<!-- checkbox_start -->|<!-- checkbox_end -->/ms", "", $form[$i]);
              }
            }
            break;
          case "RADIO" :
            $form[$i] = $this->autogenerate_form_radio;
            break;
          case "CHECKBOX" :
            $form[$i] = $this->autogenerate_form_checkbox;
            break;
          case "SELECT" :
            $form[$i] = $this->autogenerate_form_select;
            break;
          case "MULTISELECT" :
            $form[$i] = $this->autogenerate_form_multiselect;
            break;
          case "DATE" :
            $form[$i] = $this->autogenerate_form_date;
            break;
          case "DATETIME" :
            $form[$i] = $this->autogenerate_form_datetime;
            break;
          default:
            $form[$i] = $this->autogenerate_form_text;
        }

        // preserve _remove & _upload vars
        $tpl->assign("$fields[$i]_upload", "<%\$$fields[$i]_upload%>");
        $tpl->assign("$fields[$i]_remove", "<%\$$fields[$i]_remove%>");
        $form[$i] = str_replace("<%\$field_name%>", $fields[$i], $form[$i]);

        switch($this->fields_type[$i]) {
          case "RADIO" :
            $fields_option = explode("\n", $this->fields_option[$i]);
            $option_text = '';
            while (list($k, $v) = @each($fields_option)) {
              $v = explode("|", trim($v));
              if (!$v[1]) {
                $v[1] = $v[0];
              }
              $tpl->assign("field_value", $v[0]);
              $tpl->assign("field_text", $v[1]);
              $tpl->assign("checked", ($v[0] == $$fields[$i]) ? 'checked="checked"' : '');
              $option_text .= $tpl->fetch('var:' . $form[$i]);
            }
            $form[$i] = $option_text;
            break;
          case "CHECKBOX" :
            $fields_option = explode("\n", $this->fields_option[$i]);
            $option_text = '';
            while (list($k, $v) = @each($fields_option)) {
              $v = explode("|", trim($v));
              if (!$v[1]) {
                $v[1] = $v[0];
              }
              $tpl->assign("field_value", $v[0]);
              $tpl->assign("field_text", $v[1]);
              if (!is_array($$fields[$i])) {
                $tpl->assign("checked", ereg($v[0], $$fields[$i]) ? 'checked="checked"' : '');
              }
              else {
                $tpl->assign("checked", in_array($v[0], $$fields[$i]) ? 'checked="checked"' : '');
              }
              $option_text .= $tpl->fetch('var:' . $form[$i]);
            }
            $form[$i] = $option_text;
            break;
          case "SELECT" :
            $fields_option = explode("\n", $this->fields_option[$i]);
            $option_text = "<option value=''></option>";
            while (list($k, $v) = @each($fields_option)) {
              $selected = '';
              $v = explode("|", trim($v));
              if (!$v[1]) {
                $v[1] = $v[0];
              }
              if ($v[0] == $$fields[$i]) {
                $selected = 'selected="selected"';
              }
              $option_text .= "<option value='$v[0]' $selected>$v[1]</option>";
            }
            $tpl->assign("field_option", $option_text);
            break;
          case "MULTISELECT" :
            $fields_option = explode("\n", $this->fields_option[$i]);
            $option_text = '';
            while (list($k, $v) = @each($fields_option)) {
              $selected = '';
              $v = explode("|", trim($v));
              if (!$v[1]) {
                $v[1] = $v[0];
              }
              if (!is_array($$fields[$i])) {
                if (ereg($v[0], $$fields[$i])) {
                  $selected = 'selected="selected"';
                }
              }
              else {
                if (in_array($v[0], $$fields[$i])) {
                  $selected = 'selected="selected"';
                }
              }
              $option_text .= "<option value='$v[0]' $selected>$v[1]</option>";
            }
            $tpl->assign("field_option", $option_text);
            break;
          default:
            $tpl->assign("field_value", $$fields[$i]);
        }

        $form[$i]   = $tpl->fetch('var:' . $form[$i]);

        $field_name = $fields[$i];
        $form_field = stripslashes($form[$i]);

        // generate output
        if ($this->fields_text[$i]) {
          $tpl->assign("field_name", $this->fields_text[$i]);
        }
        else {
          $tpl->assign("field_name", ucwords(str_replace('_', ' ', $field_name)));
        }
        $tpl->assign("form_field", $form_field);
        $tpl->assign("counter", $counter++);
        $line .= $tpl->fetch($this->autogenerate_form_template);

        $i++;
      }
      return $line;
    }


    // method to add new link
    // return :   0: success
    //            1: pending
    //            2: not allowed
    //            3: sql error
    // set var :  $email_template_fields
    // ------------------------------------------

    function Add($pass_through_permission = false) {
      global $dbConn, $cat, $add_cat1, $add_cat2;
      global $allowed_file_extension, $error_msg, $base_path, $folder, $msg;
      global $max_image_width, $max_image_height, $max_file_size, $enable_html_tag, $allowed_html_tag;
      $folder = 'upload_files';

      if (empty($add_cat1))
        $add_cat1 = 0;

      if (empty($add_cat2))
        $add_cat2 = 0;

      // get custom field

      $fields = $this->GetFields();

      $i      = 1;

      $count_fields = @count($fields);
      while ($i < $count_fields) {
        $field = $fields[$i];
        global $$field;

        // custom field required check
        if ($i >= $this->custom_field_offset) {
          if ($this->fields_required[$i]) {
            // admin can by pass all
            if (!$pass_through_permission) {
              $blank = 0;
              if (!is_array($$field)) {
                if ($this->fields_type[$i] != "IMAGE" && $this->fields_type[$i] != "FILE") {
                  if (!strlen(trim($$field))) {
                    $blank = 1;
                  }
                }
                else {
                  // check current file size
                  if ($_FILES[$field]['size'] == 0) {
                    $blank = 1;
                  }
                }
              }
              else {
                if (!@count($$field)) {
                  $blank = 1;
                }
              }

              if ($blank) {
                // check permission
                if ($this->fields_permission[$i]) {
                  if ($this->fields_permission[$i] == 1 && !$_COOKIE['COOKIE_USERNAME']) {
                    $blank = 0;
                  }
                  if ($this->fields_permission[$i] == 2 && strpos($_SERVER['PHP_SELF'], '/admin/') === false) {
                    $blank = 0;
                  }
                }
              }

              if ($blank) {
                if ($this->fields_text[$i]) {
                  $error_msg = str_replace('<%$field_name%>', $this->fields_text[$i], $msg['10350']);
                }
                else {
                  $error_msg = str_replace('<%$field_name%>', ucwords(str_replace('_', ' ', $field)), $msg['10350']);
                }
                return -1;
              }
            }
          }
        }

        // HTML tags check
        if ($enable_html_tag) {
          // allow some tags specified on $allowed_html_tag
          $$field = RemoveEvilTags($$field, $allowed_html_tag);
        }
        else {
          // remove all tags
          $$field = RemoveEvilTags($$field);
        }

        if ($i != 1) {
          $custom_fields_name .= ",";
          $custom_fields_value .= ",";
        }

        $custom_fields_name .= $field;

        if($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
          if ($this->fields_file_extension[$i]) {
            $allowed_file_extensionx = explode(",", $this->fields_file_extension[$i]);
          }
          else {
            $allowed_file_extensionx = explode(",", $allowed_file_extension);
          }
          if(!empty($_FILES[$field]['name'])) {
            // get file extension
            $temp = explode(".",$_FILES[$field]['name']);
            $last = count($temp)-1;
            $file_ext[$field] = $temp[$last];
            $field_name = $field;

            // admin can by pass all
            if (!$pass_through_permission) {

              // check image extension
              if(!in_array($file_ext[$field],$allowed_file_extensionx)) {
                $error_msg = $msg["10317"];
                return -1;
              }

              // check file size
              if(($_FILES[$field]['size'] / 1024) > ($this->fields_file_size[$i]) ? $this->fields_file_size[$i] : $max_file_size) {
                $error_msg = $msg["10320"];
                return -1;
              }
              clearstatcache();

              if ($this->fields_type[$i]=="IMAGE") {
                // check image dimension
                $image_size = @GetImageSize($_FILES[$field]['tmp_name']);
                clearstatcache();

                // check image width
                if($image_size[0] > ($this->fields_img_width[$i]) ? $this->fields_img_width[$i] : $max_image_width) {
                  $error_msg = $msg["10314"];
                  return -1;
                }

                // check image height
                if($image_size[1] > ($this->fields_img_height[$i]) ? $this->fields_img_height[$i] : $max_image_height) {
                  $error_msg = $msg["10315"];
                  return -1;
                }
              }
            }

            // put file in queue
            $file_obj['src'] = $_FILES[$field]['tmp_name'];
            $file_obj['dst'] = $base_path . $folder. "/". $field ."_ID.". $file_ext[$field];
            $file_queue[$field] = $file_obj;
          }
        }

        if ($field == 'date') {
          $custom_fields_value .= "now()";
        }
        elseif ($field == 'category_id')
          $custom_fields_value .= $cat;
        elseif ($field == 'hits')
          $custom_fields_value .= 0;
        elseif ($field == 'votes')
          $custom_fields_value .= 0;
        elseif ($field == 'rating')
          $custom_fields_value .= 0;
        elseif ($field == 'new')
          $custom_fields_value .= 0;
        elseif ($field == 'hot')
          $custom_fields_value .= 0;
        elseif ($field == 'top_rated')
          $custom_fields_value .= 0;
        elseif ($field == 'pick')
          $custom_fields_value .= 0;
        elseif ($field == 'updated')
          $custom_fields_value .= 0;
        elseif ($field == 'cat1')
          $custom_fields_value .= $add_cat1;
        elseif ($field == 'cat2')
          $custom_fields_value .= $add_cat2;
        elseif ($field == 'password') {

          // generate pwd
          mt_srand ((double)microtime() * 1000000);
          $pwd    = mt_rand();
          $pwd    = substr($pwd, -4, 4);

          $$field = $pwd;
          $custom_fields_value .= $pwd;
        }
        elseif ($field == 'bid')
          if (empty($bid)) {
            $custom_fields_value .= 0;
            $bid = 0;
          }
          else
            $custom_fields_value .= "'" . $$field . "'";
        else {
          if (!is_array($$field)) {
            $custom_fields_value .= "'" . $$field . "'";
          }
          else {
            $custom_fields_value .= "'" . @implode(',', $$field) . "'";
          }
        }

        $i++;
      }

      $this->email_template_fields = str_replace(",", ",\$", $custom_fields_name);
      $this->email_template_fields = "\$link_id,\$category,\$" . $this->email_template_fields;

      // get category permission

      $category_obj                  = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;
      $add_permission                = $category_obj->GetAddLinkPermission($cat);

      if ($pass_through_permission)
        $add_permission = 0;

      // no need approval

      if ($add_permission == 0) {

        //insert into db

        $query   = "insert into $this->table_name ($custom_fields_name) values ($custom_fields_value)";
        $result  = $dbConn->Execute($query);

        // get link_id

        global $link_id;
        $link_id = $dbConn->InsertID();

        // copy file
        while (list($k, $v) = @each($file_queue)) {
          $v['dst'] = str_replace('ID', $link_id, $v['dst']);
          if (@copy($v['src'],$v['dst'])) {
            $relatif_path = $folder. "/". $k ."_". $link_id .".". $file_ext[$k];
            $query = "update idx_link set $k = '$relatif_path' where link_id = '$link_id'";
            $dbConn->Execute($query);
          }
        }

        // add ownership if available
        if(!empty($_COOKIE['COOKIE_USERNAME']) && $_COOKIE['COOKIE_USERNAME'] != 'admin') {
          $query  = "insert into idx_link_user (link_id, username)
                     values ('$link_id','$_COOKIE[COOKIE_USERNAME]')";
          $result = $dbConn->Execute($query);
        }

        if ($result)
          return 0;
        else
          return 3;
      }

      // need to approve

      elseif ($add_permission == 1) {

        //insert into db

        $this->table_name_temp = $this->table_name . "_temp";

        $query = "insert into $this->table_name_temp ($custom_fields_name) values ($custom_fields_value)";
        $result = $dbConn->Execute($query);

        // get vid

        $vid = $dbConn->InsertID();

        // copy file
        while (list($k, $v) = @each($file_queue)) {
          $v['dst'] = str_replace('ID', 'temp'.$vid, $v['dst']);
          if (@copy($v['src'],$v['dst'])) {
            $relatif_path = $folder. "/". $k ."_temp". $vid .".". $file_ext[$k];
            $query = "update $this->table_name_temp set $k = '$relatif_path' where vid = '$vid'";
            $dbConn->Execute($query);
          }
        }

        // add ownership if available
        if(!empty($_COOKIE['COOKIE_USERNAME']) && $_COOKIE['COOKIE_USERNAME'] != 'admin') {
          $query  = "insert into idx_link_temp_user (vid, username)
                     values ('$vid','$_COOKIE[COOKIE_USERNAME]')";
          $result = $dbConn->Execute($query);
        }

        return 1;
      }

      // not allowed

      elseif ($add_permission == 2)
        return 2;
    }


    // method to display modify link
    // input :    $status = "display_form"
    //                      "process_form"
    //                      "search"
    // return :   0: success
    //            1: pending
    //            2: incorrect password
    //            3: sql error
    // set var :  $email_template_fields
    // ------------------------------------------

    function Modify($status, $id, $pass_through_all = false, $editor = false) {
      global $dbConn, $cat, $add_cat1, $add_cat2, $pflag, $error_msg;
      global $allowed_file_extension, $error_msg, $base_path, $folder, $msg;
      global $max_image_width, $max_image_height, $max_file_size, $no_image_file, $enable_html_tag, $allowed_html_tag;
      $folder = 'upload_files';

      // get fields

      $fields       = $this->GetFields();

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      if ($status == 'display_form') {
        $tpl = new Template();

        // get old values
        $query  = "select * from $this->table_name where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $i = 0;

        $count_fields = @count($fields);
        while ($i < $count_fields) {
          $field = $fields[$i];
          global $$field;

          $i++;
        }

        // required to generate image field
        $this->lid         = $id;

        $i = 0;
        $count_fields = @count($fields);
        while ($i < $count_fields) {
          if ($pflag != "modify" || $this->fields_type[$i] == "IMAGE" || $this->fields_type[$i] == "FILE") {
            $$fields[$i] = $result->Fields("$fields[$i]");
          }

          if (!is_array($$fields[$i])) {
            $$fields[$i] = htmlspecialchars(stripslashes($$fields[$i]));
          }

          // image/file
          if ($this->fields_type[$i] == "IMAGE" || $this->fields_type[$i] == "FILE") {
            if ($$fields[$i] == "") {
              if ($this->fields_type[$i] == "IMAGE") {
                $$fields[$i] = $no_image_file;
              }
            }
            else {

              // admin cp
              if ($pass_through_all && $$fields[$i] != "" && !$editor) {
              }

              // editor cp
              if ($editor && $$fields[$i] != "") {
                $$fields[$i] = "../{$$fields[$i]}";
              }

              // public cp
              if (!$pass_through_all && $$fields[$i] != "") {
                if (eregi('/cp/', $_SERVER['REQUEST_URI'])) {
                  $$fields[$i] = "../{$$fields[$i]}";
                }
              }
            }
          }

          if ($pass_through_all)
            if ($fields[$i] == "new" || $fields[$i] == "hot" || $fields[$i] == "top_rated" || $fields[$i] == "suspended"
              || $fields[$i] == "pick" || $fields[$i] == "updated")
              $$fields[$i] = ShowRadioButton($fields[$i], "Yes,No", "1,0", $$fields[$i]);

          $tpl->assign($fields[$i], $$fields[$i]);
          $i++;
        }

        if (empty($category_id)) {
          $query       = "select * from $this->table_name where link_id = '$id'";
          $result      = $dbConn->Execute($query);
          $category_id = $result->Fields("category_id");
        }

        if ($editor) {
          // get editor category
          $categories = $this->GetEditorCategory($_COOKIE['COOKIE_USERNAME']);

          // build query
          $query      = "select * from idx_category where 0!=0";

          while (list(, $v) = @each($categories)) {
            $query .= " or category_id = $v";
          }

          $category_obj->query = $query;
          $category            = $category_obj->DisplayCategoryListBox($category_id, 0, 2);
          $category_obj->query = '';
          $add_cat1 = str_replace("<select name=\"cat\">", "<select name=\"add_cat1\">",
                      $category_obj->DisplayCategoryListBox($cat1));
          $add_cat2 = str_replace("<select name=\"cat\">", "<select name=\"add_cat2\">",
                      $category_obj->DisplayCategoryListBox($cat2));
        }
        else {
          if ($pass_through_all) {
            $category = $category_obj->DisplayCategoryListBox($category_id, 0, 1);
            $add_cat1 = str_replace("<select name=\"cat\">", "<select name=\"add_cat1\">",
                        $category_obj->DisplayCategoryListBox($cat1, 0, 1));
            $add_cat2 = str_replace("<select name=\"cat\">", "<select name=\"add_cat2\">",
                        $category_obj->DisplayCategoryListBox($cat2, 0, 1));
          }
          else {
            $category = $category_obj->DisplayCategoryListBox($category_id);
            $add_cat1 = str_replace("<select name=\"cat\">", "<select name=\"add_cat1\">",
                        $category_obj->DisplayCategoryListBox($cat1));
            $add_cat2 = str_replace("<select name=\"cat\">", "<select name=\"add_cat2\">",
                        $category_obj->DisplayCategoryListBox($cat2));
          }
        }

        $add_cat1 = str_replace("<option value=\"\">", "<option value=\"0\">", $add_cat1);
        $add_cat1 = str_replace("Main Category", "Do not have additional category", $add_cat1);
        $add_cat2 = str_replace("<option value=\"\">", "<option value=\"0\">", $add_cat2);
        $add_cat2 = str_replace("Main Category", "Do not have additional category", $add_cat2);

        $tpl->assign('add_cat1', $add_cat1);
        $tpl->assign('add_cat2', $add_cat2);

        $tpl->assign('category', $category);
        $tpl->assign('error_msg', $error_msg);

        $custom_field_form = $this->GenerateCustomFieldForm();

        if (!empty($custom_field_form))
          $custom_field_form = $this->header . $custom_field_form;

        $tpl->assign('custom_field_form', $custom_field_form);
        $tpl->display($this->template_file);
      }
      elseif ($status == 'process_form') {
        // get values
        $sql_old = "select * from $this->table_name where link_id = '$id'";
        $result_old = $dbConn->Execute($sql_old);

        $i = 0;

        $count_fields = @count($fields);
        while ($i < $count_fields) {
          $field = $fields[$i];
          $old[$field] = $result_old->Fields($field);
          global $$field;

          // custom field required check
          if ($i >= $this->custom_field_offset) {
            if ($this->fields_required[$i]) {
              // admin can by pass all
              if (!$pass_through_all) {
                $blank = 0;
                if (!is_array($$field)) {
                  if ($this->fields_type[$i] != "IMAGE" && $this->fields_type[$i] != "FILE") {
                    if (!strlen(trim($$field))) {
                      $blank = 1;
                    }
                  }
                  else {
                    // check current file size and the old value too
                    if ($_FILES[$field]['size'] == 0 && !$old[$field]) {
                      $blank = 1;
                    }
                  }
                }
                else {
                  if (!@count($$field)) {
                    $blank = 1;
                  }
                }

                if ($blank) {
                  // check permission
                  if ($this->fields_permission[$i]) {
                    if ($this->fields_permission[$i] == 1 && !$_COOKIE['COOKIE_USERNAME']) {
                      $blank = 0;
                    }
                    if ($this->fields_permission[$i] == 2 && strpos($_SERVER['PHP_SELF'], '/admin/') === false) {
                      $blank = 0;
                    }
                  }
                }


                if ($blank) {
                  if ($this->fields_text[$i]) {
                    $error_msg = str_replace('<%$field_name%>', $this->fields_text[$i], $msg['10350']);
                  }
                  else {
                    $error_msg = str_replace('<%$field_name%>', ucwords(str_replace('_', ' ', $field)), $msg['10350']);
                  }
                  return -1;
                }
              }
            }
          }

          // HTML tags check
          if ($enable_html_tag) {
            // allow some tags specified on $allowed_html_tag
            $$field = RemoveEvilTags($$field, $allowed_html_tag);
          }
          else {
            // remove all tags
            $$field = RemoveEvilTags($$field);
          }


          if($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
            if ($this->fields_file_extension[$i]) {
              $allowed_file_extensionx = explode(",", $this->fields_file_extension[$i]);
            }
            else {
              $allowed_file_extensionx = explode(",", $allowed_file_extension);
            }
            if(!empty($_FILES[$field]['name'])) {
              // get file extension
              $temp = explode(".",$_FILES[$field]['name']);
              $last = count($temp)-1;
              $file_ext[$field] = $temp[$last];
              $field_name = $field;

              // admin can by pass all
              if (!$pass_through_all) {

                // check file extension
                if(!in_array($file_ext[$field],$allowed_file_extensionx)) {
                  $error_msg = $msg["10317"];
                  return -1;
                }

                // check file size
                if(($_FILES[$field]['size'] / 1024) > ($this->fields_file_size[$i]) ? $this->fields_file_size[$i] : $max_file_size) {
                  $error_msg = $msg["10320"];
                  return -1;
                }
                clearstatcache();

                if ($this->fields_type[$i]=="IMAGE") {
                  // check image dimension
                  $image_size = @getimagesize($_FILES[$field]['tmp_name']);
                  clearstatcache();

                  // check image width
                  if($image_size[0] > ($this->fields_img_width[$i]) ? $this->fields_img_width[$i] : $max_image_width) {
                    $error_msg = $msg["10314"];
                    return -1;
                  }

                  // check image height
                  if($image_size[1] > ($this->fields_img_height[$i]) ? $this->fields_img_height[$i] : $max_image_height) {
                    $error_msg = $msg["10315"];
                    return -1;
                  }
                }
              }

              // put file in queue
              $file_obj['src'] = $_FILES[$field]['tmp_name'];
              $file_obj['dst'] = $base_path . $folder. "/". $field ."_ID.". $file_ext[$field];
              $file_queue[$field] = $file_obj;
            }
          }

          if ($i != 0 && $field != 'password') {
            $custom_fields_name .= ",";
            $custom_fields_value .= ",";
          }

          if ($field == 'date') {
            $custom_fields_value .= "now()";
            $custom_fields_name .= $field;
          }
          elseif ($field == 'category_id') {
            $custom_fields_value .= "'$cat'";
            $custom_fields_name .= $field;
          }
          elseif ($field == 'cat1') {
            $custom_fields_value .= "'$add_cat1'";
            $custom_fields_name .= $field;
          }
          elseif ($field == 'cat2') {
            $custom_fields_value .= "'$add_cat2'";
            $custom_fields_name .= $field;
          }
          elseif ($field == 'password') { }
          elseif ($field == 'last_updated') {
            $$field = "now()";
            $fields_value .= $$field;
            $custom_fields_name .= $field;
            $custom_fields_value .= $$field;
          }
          elseif($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
            $file_del = "{$field}_del";
            global $$file_del;
            if ($$file_del) {
              $custom_fields_name .= $field;
              $custom_fields_value .= "''";
            }
            else {
              $custom_fields_name .= $field;
              $custom_fields_value .= "'$old[$field]'";
            }
          }
          else {
            $custom_fields_name .= $field;
            if (!is_array($$field)) {
              $custom_fields_value .= "'".$$field."'";
            }
            else {
              $custom_fields_value .= "'".@implode(',', $$field)."'";
            }
          }

          $i++;
        }

        // compare password

        $query  = "select password from $this->table_name where link_id = '$id'";
        $result = $dbConn->Execute($query);
        $pwd    = $result->Fields("password");

        if ($password == $pwd || $pass_through_all) {
          $this->email_template_fields = str_replace(",", ",\$", $custom_fields_name);
          $this->email_template_fields = "\$category,\$" . $this->email_template_fields;

          // get category permission

          $add_permission              = $category_obj->GetAddLinkPermission($cat);

          // no need approval

          if ($add_permission == 0 || $pass_through_all) {

            // build query

            $query = "update $this->table_name set ";

            $i     = 1;

            $count_fields = @count($fields);
            while ($i < $count_fields) {
              $field = $fields[$i];
              global $$field;

              // process image/file field
              if($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
                $file_del = "{$field}_del";
                global $$file_del;
                if ($$file_del) {
                  $query .= "$field = '', ";
                  // delete file
                  @unlink($base_path . $old[$field]);
                }
                // copy file
                if ($file_queue[$field]) {
                  @unlink($base_path . $old[$field]);
                  $v = $file_queue[$field];
                  $k = $field;
                  $v['dst'] = str_replace('ID', $id, $v['dst']);
                  if (@copy($v['src'],$v['dst'])) {
                    $relatif_path = $folder. "/". $k ."_". $id .".". $file_ext[$k];
                    $query .= "$k = '$relatif_path', ";
                  }
                }
              }

              if ($field != "hits" && $field != "votes" && $field != "rating" && $field != "hot" && $field != "new"
                && $field != "pick" && $field != "top_rated" && $field != "password" && $field != "updated"
                && $field != "date" && $field != "avg_review" && $field != "reviews") {
                if ($field == 'category_id')
                  $value = "$cat";

                elseif ($field == 'cat1')
                  $value = "$add_cat1";

                elseif ($field == 'cat2')
                  $value = "$add_cat2";
                else
                  $value = $$field;

                if ($field == 'last_updated')
                  $query .= "$field = $value, ";
                elseif ($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") { }
                else {
                  if (!is_array($value)) {
                    $query .= "$field = '$value', ";
                  }
                  else {
                    $query .= "$field = '".@implode(',', $value)."', ";
                  }
                }

              }

              $i++;
            }

            $query = substr($query, 0, strlen($query) - 2); // delete last ', '

            $query .= " where link_id = '$id'";
            $result = $dbConn->Execute($query);

            if ($pass_through_all) {
              $query  = "update $this->table_name set
              password = '$password',
              pick = $pick
              where link_id = '$id'";
              $result = $dbConn->Execute($query);
            }

            if ($result)
              return 0;
            else
              return 3;
          }

          // need to approve

          elseif ($add_permission == 1) {

            //insert into temp db

            $this->table_name_temp = $this->table_name . "_temp";

            $query = "insert into $this->table_name_temp ($custom_fields_name) values ($custom_fields_value)";
            $result = $dbConn->Execute($query);

            $vid = $dbConn->InsertID();

            // add ownership if available
            if(!empty($_COOKIE['COOKIE_USERNAME'])) {
              $query  = "insert into idx_link_temp_user (vid, username)
                         values ('$vid','$_COOKIE[COOKIE_USERNAME]')";
              $result = $dbConn->Execute($query);
            }

            // copy file
            while (list($k, $v) = @each($file_queue)) {
              $file_del = "{$k}_del";
              global $$file_del;
              if ($$file_del) {
                continue;
              }
              $v['dst'] = str_replace('ID', 'temp'.$vid, $v['dst']);
              if (@copy($v['src'],$v['dst'])) {
                $relatif_path = $folder. "/". $k ."_temp". $vid .".". $file_ext[$k];
                $query = "update $this->table_name_temp set $k = '$relatif_path' where vid = '$vid'";
                $dbConn->Execute($query);
              }
            }

            return 1;
          }
        }
        else
          return 2;
      }
    }


    // method to delete link
    // return :   0: success
    //            1: sql error
    // ------------------------------------------

    function Delete($id) {
      global $dbConn, $base_path;

      // get values
      $sql_old = "select * from $this->table_name where link_id = '$id'";
      $result_old = $dbConn->Execute($sql_old);
      $old = $result_old->FetchRow();
      $old = $old[$id];

      $fields = $this->GetFields();
      while (list($k, $v) = @each($fields)) {
        if($this->fields_type[$k]=="IMAGE" || $this->fields_type[$k]=="FILE") {
          $file_queue[] = $old[$v];
        }
      }

      // delete link
      $query  = "delete from $this->table_name where link_id = '$id'";
      $result = $dbConn->Execute($query);

      if ($result) {

        // delete related tables:
        //      idx_bad_link, idx_favorites_detail, idx_link_temp, idx_review, idx_votes

        $query  = "delete from idx_bad_link where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from idx_favorites_detail where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from idx_link_temp where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from idx_review where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from idx_votes where link_id = '$id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from idx_link_user where link_id = '$id'";
        $result = $dbConn->Execute($query);

        // delete file
        while (list($k, $v) = @each($file_queue)) {
          @unlink($base_path . $v);
        }

        return 0;
      }
      else
        return 1;
    }


    // method to approve link
    // input :    $vid : validation_id
    //            $flag : 0: new link
    //                    1: modify link
    // return :   0: success
    //            1: sql error
    // ------------------------------------------

    function ApproveLink($vid, $flag) {
      global $dbConn, $base_path;

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // get field's value

      $fields                        = $this->GetFields();
      $this->table_name_temp         = $this->table_name . "_temp";

      $query                         = "select * from $this->table_name_temp where vid = '$vid'";
      $result                        = $dbConn->Execute($query);


      // if new link
      if ($flag == 0) {
        $i = 1; // skip vid and link_id

        $count_fields = @count($fields);
        while ($i < $count_fields) {
          $field = $fields[$i];
          global $$field;

          if ($i != 1) {
            $fields_name .= ",";
            $fields_value .= ",";
          }

          if ($field == 'password') {

            // generate pwd
            mt_srand ((double)microtime() * 1000000);
            $pwd    = mt_rand();
            $pwd    = substr($pwd, -4, 4);

            $$field = $pwd;
            $fields_value .= "'" . $pwd . "'";
          }
          elseif ($field == 'date') {
            $fields_value .= "now()";
          }
          else {
            if($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
              // put file in queue
              if ($result->Fields("$field")) {
                $file_queue[$field] = $result->Fields("$field");
              }
            }
            $$field = $result->Fields("$field");
            $fields_value .= "'" . addslashes($$field) . "'";
          }

          $fields_name .= $field;

          $i++;
        }

        $query   = "insert into $this->table_name ($fields_name) values ($fields_value)";
        $result  = $dbConn->Execute($query);
        // get link_id
        global $link_id;
        $link_id = $dbConn->InsertID();

        // add ownership if available
        global $dbConn;

        // get username
        $query    = "select username from idx_link_temp_user where vid = '$vid'";
        $result   = $dbConn->Execute($query);
        $username = $result->Fields("username");

        if(!empty($username)) {
          $query  = "insert into idx_link_user (link_id, username)
                     values ('$link_id','$username')";
          $result = $dbConn->Execute($query);

          // delete
          $query  = "delete from idx_link_temp_user where vid = '$vid'";
          $result = $dbConn->Execute($query);
        }

        if ($result)
          $return = 0;
        else
          $return = 1;

        // get category path
        global $category;
        $category                    = $category_obj->GetCategoryPath($category_id);

        // rename file
        while (list($k, $v) = @each($file_queue)) {
          $vv = preg_replace("|temp.*\.|", "{$link_id}.", $v);
          @rename($base_path . $v, $base_path . $vv);
          $relatif_path = $vv;
          $query = "update idx_link set $k = '$relatif_path' where link_id = '$link_id'";
          $dbConn->Execute($query);
        }

        $this->email_template_fields = str_replace(",", ",\$", $fields_name);
        $this->email_template_fields = "\$link_id,\$category,\$" . $this->email_template_fields;
      }


      // if modify link
      if ($flag == 1) {


        // build query
        $query = "update $this->table_name set ";

        $i     = 0; // skip vid and link_id

        $count_fields = @count($fields);
        while ($i < $count_fields) {
          $field = $fields[$i];
          global $$field;

          // get image/file field -> prevent it from updated
          if ($this->fields_type[$i] == 'IMAGE' || $this->fields_type[$i] == 'FILE')
            $file_field = $field;
          else
            $file_field = "";

          if ($i != 0) {
            $fields_name .= ",";
          }

          if ($field == 'last_updated') {
            $value = "now()";
          }
          else {
            $value = $$field = $result->Fields("$field");
          }

          $fields_name .= $field;

          if ($field != "link_id" && $field != "hits" && $field != "votes" && $field != "rating" && $field != "hot"
            && $field != "new" && $field != "pick" && $field != "top_rated" && $field != "password"
            && $field != "updated" && $field != "date" && $field != "reviews" && $field != "avg_review") {
            if ($field == 'last_updated')
              $query .= "$field = $value, ";
            elseif ($field == $file_field) {
              // put file in queue
              if ($result->Fields("$field")) {
                $file_queue[$field] = $result->Fields("$field");
              }
              $query .= "$field = '" . addslashes($value) . "', ";
            }
            else
              $query .= "$field = '" . addslashes($value) . "', ";

          }

          $i++;
        }

        $query = substr($query, 0, strlen($query) - 2); // delete last ', '

        $query .= " where link_id = '$link_id'";
        $result2 = $dbConn->Execute($query);

        if ($result)
          $return = 0;
        else
          $return = 1;

        // get category path
        global $category;
        $category                    = $category_obj->GetCategoryPath($category_id);

        // rename file
        while (list($k, $v) = @each($file_queue)) {
          $vv = preg_replace("|temp.*\.|", "{$link_id}.", $v);
          if ($vv != $v) {
            @unlink($base_path . $vv);
            @rename($base_path . $v, $base_path . $vv);
          }
          $relatif_path = $vv;
          $query = "update idx_link set $k = '$relatif_path' where link_id = '$link_id'";
          $dbConn->Execute($query);
        }

        $this->email_template_fields = str_replace(",", ",\$", $fields_name);
        $this->email_template_fields = "\$link_id,\$category,\$" . $this->email_template_fields;

      }

      // delete temporary record
      $query  = "delete from $this->table_name_temp where vid = '$vid'";
      $result = $dbConn->Execute($query);

      return $return;
    }


    // method to reject link
    // input :    $vid : validation_id
    // return :   0: success
    //            1: sql error
    // ------------------------------------------

    function RejectLink($vid) {
      global $dbConn, $base_path;

      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      // get field's value

      $fields                        = $this->GetFields();
      $this->table_name_temp         = $this->table_name . "_temp";

      $query                         = "select * from $this->table_name_temp where vid = '$vid'";
      $result                        = $dbConn->Execute($query);

      $sql_old                       = "select * from $this->table_name where link_id='".$result->Fields("link_id")."'";
      $result_old                    = $dbConn->Execute($sql_old);

      // get value

      $i                             = 1; // skip vid and link_id

      $count_fields = @count($fields);
      while ($i < $count_fields) {
        $field = $fields[$i];
        global $$field;

        if ($i != 1) {
          $fields_name .= ",";
          $fields_value .= ",";
        }

        if($this->fields_type[$i]=="IMAGE" || $this->fields_type[$i]=="FILE") {
          // put file in queue
          if ($result->Fields("$field")) {
            // if the file same with previous, then do not delete it
            if ($result->Fields("$field") != $result_old->Fields("$field")) {
              $file_queue[$field] = $result->Fields("$field");
            }
          }
        }

        $$field = $result->Fields("$field");
        $fields_value .= "'" . $$field . "'";
        $fields_name .= $field;

        $i++;
      }

      // get category path
      global $category;
      $category                    = $category_obj->GetCategoryPath($category_id);

      $this->email_template_fields = str_replace(",", ",\$", $fields_name);
      $this->email_template_fields = "\$link_id,\$category,\$" . $this->email_template_fields;

      // delete file
      while (list($k, $v) = @each($file_queue)) {
        @unlink($base_path . $v);
      }

      // delete temporary record
      $query                       = "delete from $this->table_name_temp where vid = '$vid'";
      $result                      = $dbConn->Execute($query);

      // delete ownership if available
      global $dbConn;
      $query  = "delete from idx_link_temp_user where vid = '$vid'";
      $result = $dbConn->Execute($query);

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to get all editors email address
    // input :    $cat
    // return :   array that contain email addr.
    // -----------------------------------------

    function GetEditorEmail($cat, $with_username = FALSE, $query_filter = "") {
      global $dbConn;

      if ($cat == 'all') {
        $query = "select distinct username
                  from $this->editor_table_name
                  where status = 1
                        $query_filter";
      }
      else {
        $query = "select username
                  from $this->editor_table_name
                  where category_id = '$cat'
                        and status = 1
                        $query_filter";
      }

      $result   = $dbConn->Execute($query);

      $user_obj = new clsUsers;
      $user_obj->table_name = $this->user_table_name;

      while (!$result->EOF) {
        $username = $result->Fields("username");
        if ($with_username) {
          $email[] = $user_obj->GetEmailAddress($username) . "|" . $username;
        }
        else {
          $email[] = $user_obj->GetEmailAddress($username);
        }
        $result->MoveNext();
      }

      return $email;
    }


    // method to get editors's username
    // input :    $cat
    // return :   array that contain username
    // ----------------------------------------

    function GetEditor($cat) {
      global $dbConn;
      $query  = "select username from $this->editor_table_name where category_id = '$cat' and status = 1";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $username = $result->Fields("username");
        $editor[] = $username;
        $result->MoveNext();
      }

      return $editor;
    }


    // method to handle new editor subscription
    // input :    $status = "process_form"
    // return :   0: success
    //            1: pending
    //            2: sql error
    // set var :  $email_template_fields
    // ------------------------------------------

    function BecomeEditor($status, $username, $cat, $admin = false) {
      global $dbConn;
      $category_obj = new clsCategory;
      $category_obj->table_name      = $this->category_table_name;
      $category_obj->link_table_name = $this->table_name;
      $category_obj->separator       = $this->category_separator;

      if ($status == "process_form") {

        if ($admin)
          $query
            = "insert into $this->editor_table_name
               (username,category_id,category,link,review,pick,status,date)
               values ('$username',$cat,1,1,1,1,1,now())";
        else
          $query
            = "insert into $this->editor_table_name
               (username,category_id,category,link,review,pick,status,date)
               values ('$username',$cat,1,1,1,1,0,now())";

        $result = $dbConn->Execute($query);

        // change group id
        if ($admin) {
          $users_obj = new clsUsers;
          $users_obj->table_name = "idx_users";
          $gid                   = $users_obj->GetGroupId($username);

          // if not administrator, then change to editor
          if ($gid != 0) {
            $query  = "update $this->user_table_name set
                       group_id = 1 where username = '$username'";
            $result = $dbConn->Execute($query);
          }
        }


        // email

        global $username, $name, $email, $category;

        $query  = "select name, email from $this->user_table_name where username = '$username'";
        $result = $dbConn->Execute($query);
        $name   = $result->Fields("name");
        $email  = $result->Fields("email");

        $category = $category_obj->GetCategoryPath($cat);
        $this->email_template_fields = "\$username,\$name,\$email,\$category";

        return 1;
      }
    }


    // method to display editor
    // input :    $query
    // return :   list of editor
    // --------------------------------

    function DisplayEditor($query = "") {
      global $dbConn, $pg_which, $editor_icon, $admin_template_path;

      $tpl         = new Template();

      $editor_icon = "../admin_tpl/images/people.gif";
      $editor_icon = "<img src=\"$editor_icon\" border=\"0\" alt=\"\" /> ";

      if (empty($query))
        $query = "select * from idx_editor where status = 0";

      if (empty($pg_which)) {
        $pg_which = 1;
      }

      $result          = $dbConn->PageExecute($query, $pg_which, $this->pg_size);
      $num_rows        = $result->RecordCount();

      // prepare pagination

      $nav             = new navigator;
      $nav->pg_size    = $this->pg_size;
      $nav->href       = $this->href;
      $nav->more_param = $this->more_param;
      $nav->pg_which   = $pg_which;
      $nav->rec_count  = $num_rows;
      $nav->init();
      $this->pagination = $nav->print_all();
      $i                = $nav->rec_start;

      // fetch data

      $chk_num          = 1;
      $this->num_rows   = 0;

      while (!$result->EOF) {
        $username    = $result->Fields("username");
        $category_id = $result->Fields("category_id");
        $date        = $result->Fields("date");
        $date        = date($this->date_format, @strtotime($date));

        $number      = $i + 1;
        $chk_box     = "<input type=checkbox name=chkbox_$chk_num value=$username&$category_id>";
        $chk_num++;

        // get more info about editor

        $query        = "select email, name from $this->user_table_name where username = '$username'";
        $result2      = $dbConn->Execute($query);
        $name         = $result2->Fields("name");
        $email        = $result2->Fields("email");

        $category_obj = new clsCategory;
        $category_obj->table_name      = $this->category_table_name;
        $category_obj->link_table_name = $this->table_name;
        $category_obj->separator       = $this->category_separator;
        $category_path                 = $category_obj->GetCategoryPath($category_id);
        $category_path_with_link       = $category_obj->GetCategoryPath($category_id, TRUE);

        $this->num_rows++;

        // write template

        $tpl->assign("username", $username);
        $tpl->assign("date", $date);
        $tpl->assign("category_path", $category_path);
        $tpl->assign("category_path_with_link", $category_path_with_link);
        $tpl->assign("chk_box", $chk_box);
        $tpl->assign("name", $name);
        $tpl->assign("email", $email);

        if ($number % 2)
          $tbl_class = "tbl_light";
        else
          $tbl_class = "tbl_light2";

        $tpl->assign("tbl_class", $tbl_class);

        $tpl->assign("editor_icon", $editor_icon);

        $line .= $tpl->fetch($this->template_file);

        $i++;

        $result->MoveNext();
      }

      return $line;
    }


    // method to approve editor
    // input :    $username
    //            $cat_id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function ApproveEditor($username, $cat_id) {
      global $dbConn;
      $query  = "update idx_users set group_id = 1 where username = '$username'";
      $result = $dbConn->Execute($query);

      // update status to 1
      $query  = "update $this->editor_table_name set status = 1 where username = '$username' and category_id = '$cat_id'";
      $result = $dbConn->Execute($query);

      global $username, $name, $email, $category;

      $query  = "select name, email from $this->user_table_name where username = '$username'";
      $result = $dbConn->Execute($query);
      $name   = $result->Fields("name");
      $email  = $result->Fields("email");

      $category_obj = new clsCategory;
      $category = $category_obj->GetCategoryPath($cat_id);
      $this->email_template_fields = "\$username,\$name,\$email,\$category";

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to reject editor
    // input :    $username
    //            $cat_id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function RejectEditor($username, $cat_id) {
      global $dbConn;

      // delete editor
      $query = "delete from $this->editor_table_name
                where username = '$username'
                      and category_id = '$cat_id'
                      and status = 0";
      $result = $dbConn->Execute($query);

      global $username, $name, $email, $category;

      $query  = "select name, email from $this->user_table_name where username = '$username'";
      $result = $dbConn->Execute($query);
      $name   = $result->Fields("name");
      $email  = $result->Fields("email");

      $category_obj = new clsCategory;
      $category = $category_obj->GetCategoryPath($cat_id);
      $this->email_template_fields = "\$username,\$name,\$email,\$category";

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to delete editor
    // input :    $username
    //            $cat_id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function DeleteEditor($username, $cat_id) {
      global $dbConn;

      // delete editor
      $query
              =
        "delete from $this->editor_table_name where username = '$username' and category_id = '$cat_id' and status = 1";
      $result = $dbConn->Execute($query);

      // change group_id if necessary

      $query  = "select category_id from $this->editor_table_name where username = '$username' and status = 1";
      $result = $dbConn->Execute($query);
      $total  = $result->RecordCount();

      if ($total < 1) {
        $query  = "update $this->user_table_name set group_id = 2 where username = '$username' and status = 1";
        $result = $dbConn->Execute($query);
      }

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to get editor's category
    // input :    $username
    // return :   array of category
    // --------------------------------

    function GetEditorCategory($username) {
      global $dbConn;
      $query  = "select category_id from $this->editor_table_name where username = '$username' and status = 1";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $category[] = $result->Fields("category_id");
        $result->MoveNext();
      }

      return $category;
    }


    // method to evaluate template file
    // input :    $templatefile
    //            $vars
    // return :   html
    // --------------------------------

    function EvalTemplate($templatefile, $vars) {
      $line     = implode(file($templatefile), "");
      eval ("global $vars;");
      $vars     = str_replace(",", "", $vars);
      $var_list = explode("\$", $vars);
      $i        = 0;

      while ($i <= sizeof($var_list)) {
        $line = str_replace("<%$var_list[$i]%>", $$var_list[$i], $line);
        $i++;
      }

      return $line;
    }


    // method to rate a link
    // input :    $id
    //            $value
    // return :   0: success
    //            1: ip already exist
    //            2: sql error
    // --------------------------------

    function RateLink($id, $value) {
      global $dbConn;

      $ip     = $_SERVER["REMOTE_ADDR"];

      // is the ip already exist

      $query  = "select ip from $this->votes_table_name where link_id = '$id' and ip = '$ip'";
      $result = $dbConn->Execute($query);
      $total  = $result->RecordCount();

      if ($total == 0 && $value >= 1 && $value <= 5) {

        // insert into votes table
        $query  = "insert into $this->votes_table_name values ($id,'$ip',$value)";
        $result = $dbConn->Execute($query);

        // get avg value
        $query  = "select avg(value) as avg from $this->votes_table_name where link_id = '$id'";
        $result = $dbConn->Execute($query);
        $avg    = $result->Fields("avg");

        // count votes
        $query  = "select count(value) as c from $this->votes_table_name where link_id = '$id'";
        $result = $dbConn->Execute($query);
        $count  = $result->Fields("c");

        // update avg value in link table
        $query  = "update $this->table_name set rating = $avg, votes = $count where link_id = '$id'";
        $result = $dbConn->Execute($query);

        return 0;
      }
      elseif ($total > 0)
        return 1;
      else
        return 2;
    }


    // method to review link
    // input :    $status      = "process_form"
    //                           "validate review"
    //            $id          = link_id
    //            $username    = username
    //            $rev_subject = review's subject
    //            $rev_rating  = review's rating
    //            $rev_review  = review
    // return :   0: success
    //            1: sql error
    // set var :  $email_template_fields
    // ------------------------------------------

    function Review($status, $id, $username, $rev_subject, $rev_rating, $rev_review, $rev_name, $rev_email) {
      global $dbConn;

      // get link value


      $fields = $this->GetFields();

      $query  = "select * from $this->table_name where link_id = '$id'";
      $result = $dbConn->Execute($query);

      $i      = 0;

      $count_fields = @count($fields);
      while ($i < $count_fields) {
        $field       = $fields[$i];
        global $$field;

        $$fields[$i] = $result->Fields("$fields[$i]");

        if ($i != 0)
          $fields_name .= ",";

        $fields_name .= $field;

        $i++;
      }

      $this->email_template_fields = str_replace(",", ",\$", $fields_name);
      $this->email_template_fields
                                   =
        "\$category,\$username,\$rev_subject,\$rev_rating,\$rev_review,\$" . $this->email_template_fields;

      if ($status == 'process_form') {

        //insert into db
        $query  = "insert into $this->review_table_name
        (link_id, username, subject, rating, review, date, status, name, email)
        values ($id,'$username','$rev_subject','$rev_rating','$rev_review',now(),0,'$rev_name','$rev_email')";
        $result = $dbConn->Execute($query);

        if ($result)
          return 0;
        else
          return 1;
      }
    }


    // method to display review
    // input :    $id
    //            $query
    // return :   list of review
    // --------------------------------

    function DisplayReview($id, $query = "", $show_link_detail = false) {
      global $dbConn, $pg_which, $review_icon, $admin_template_path;

      $tpl         = new Template();

      $review_icon = "../admin_tpl/images/review.gif";
      $review_icon = "<img src=\"$review_icon\" border=\"0\" alt=\"\" /> ";

      if (empty($query))
        $query = "select * from $this->review_table_name where link_id = '$id' and status = 1 order by date desc";

      if (empty($pg_which)) {
        $pg_which = 1;
      }
      $result       = $dbConn->PageExecute($query, $pg_which, $this->pg_size);
      $num_rows     = $result->RecordCount();

      // prepare pagination

      $nav             = new navigator;
      $nav->pg_size    = $this->pg_size;
      $nav->href       = $this->href;
      $nav->more_param = $this->more_param;

      $nav->pg_which  = $pg_which;
      $nav->rec_count = $num_rows;
      $nav->init();

      $this->pagination = $nav->print_all();

      $i                = $nav->rec_start;

      if (!$show_link_detail) { // not in admin area

        // get avg_review

        $query      = "select reviews, avg_review from $this->table_name where link_id = '$id'";
        $result2    = $dbConn->Execute($query);
        $avg_review = $result2->Fields("avg_review");
        $num_review = $result2->Fields("reviews");

        $avgr       = $avg_review * 2;

        if (round($avgr) == 1)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "0half.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 2)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "0.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 3)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "1half.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 4)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "2.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 5)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "2half.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 6)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "3.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 7)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "3half.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 8)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "4.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 9)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "4half.gif\"" . " alt=\"\" />";
        elseif (round($avgr) == 10)
          $avg_review_image = "<img src=\"" . $this->rev_rating_image_path . "5.gif\"" . " alt=\"\" />";

        //$line = $this->header;
        $tpl->assign('avg_review', $avg_review);
        $tpl->assign('num_review', $num_review);
        $tpl->assign('avg_review_image', $avg_review_image);
      }


      // fetch data

      $chk_num = 1;

      while (!$result->EOF) {
        $review_id = $result->Fields("review_id");
        $username  = $result->Fields("username");
        $link_id   = $result->Fields("link_id");
        $date      = $result->Fields("date");
        $rating    = $result->Fields("rating");
        $review    = $result->Fields("review");
        $subject   = $result->Fields("subject");
        $name      = $result->Fields("name");
        $email     = $result->Fields("email");

        $date      = date($this->date_format, @strtotime($date));
        $number    = $i + 1;

        global $rating_image;

        if ($rating == 1)
          $rating_image = "<img src=\"" . $this->rev_rating_image_path . "1.gif\"" . " alt=\"\" />";
        elseif ($rating == 2)
          $rating_image = "<img src=\"" . $this->rev_rating_image_path . "2.gif\"" . " alt=\"\" />";
        elseif ($rating == 3)
          $rating_image = "<img src=\"" . $this->rev_rating_image_path . "3.gif\"" . " alt=\"\" />";
        elseif ($rating == 4)
          $rating_image = "<img src=\"" . $this->rev_rating_image_path . "4.gif\"" . " alt=\"\" />";
        elseif ($rating == 5)
          $rating_image = "<img src=\"" . $this->rev_rating_image_path . "5.gif\"" . " alt=\"\" />";

        $chk_box = "<input type=\"checkbox\" name=\"chkbox_$chk_num\" value=\"$review_id\">";
        $chk_num++;

        if ($show_link_detail) {
          $query        = "select title, url, cat1, cat2, category_id from $this->table_name where link_id = '$link_id'";
          $result2      = $dbConn->Execute($query);
          $title        = $result2->Fields("title");
          $url          = $result2->Fields("url");
          $category_id  = $result2->Fields("category_id");
          $cat1         = $result2->Fields("cat1");
          $cat2         = $result2->Fields("cat2");

          $category_obj = new clsCategory;
          $category_obj->table_name      = $this->category_table_name;
          $category_obj->link_table_name = $this->table_name;
          $category_obj->separator       = $this->category_separator;

          $category_path                 = $category_obj->GetCategoryPath($category_id);
          $category_path_with_link       = $category_obj->GetCategoryPath($category_id, TRUE);

          // category's path

          $category_path                 = $category_obj->GetCategoryPath($category_id);
          $category_path_with_link       = $category_obj->GetCategoryPath($category_id, TRUE);

          // if it has additional category
          if ($cat1 != 0 or !empty($cat1)) {
            $cpath2                  = $category_obj->GetCategoryPath($cat1);
            $cpath2_link             = $category_obj->GetCategoryPath($cat1, TRUE);

            $category_path           = $category_path . "<br /> " . $cpath2;
            $category_path_with_link = $category_path_with_link . "<br /> " . $cpath2_link;
          }

          if ($cat2 != 0 or !empty($cat2)) {
            $cpath2                  = $category_obj->GetCategoryPath($cat2);
            $cpath2_link             = $category_obj->GetCategoryPath($cat2, TRUE);

            $category_path           = $category_path . "<br /> " . $cpath2;
            $category_path_with_link = $category_path_with_link . "<br /> " . $cpath2_link;
          }
        }

        $this->num_rows++;

        // write template

        $tpl->assign('number', $number);
        $tpl->assign('username', $username);
        $tpl->assign('name', $name);
        $tpl->assign('email', $email);
        $tpl->assign('date', $date);
        $tpl->assign('rating', $rating);
        $tpl->assign('rating_image', $rating_image);
        $tpl->assign('review', $review);
        $tpl->assign('subject', $subject);
        $tpl->assign('review_id', $review_id);
        $tpl->assign('chk_box', $chk_box);
        $tpl->assign('title', $title);
        $tpl->assign('url', $url);
        $tpl->assign('category_path', $category_path);
        $tpl->assign('category_path_with_link', $category_path_with_link);

        $number = $chk_num;

        if ($number % 2)
          $tbl_class = "tbl_light";
        else
          $tbl_class = "tbl_light2";

        $tpl->assign('tbl_class', $tbl_class);
        $tpl->assign('review_icon', $review_icon);

        if (empty($this->template)) {
          $line .= $tpl->fetch($this->template_file);
        }
        else {
          $line .= $tpl->fetch('var:' . $this->template);
        }

        $i++;

        $result->MoveNext();

      }

      return $line;
    }


    // method to get number of review
    // input :    $id
    // return :   number of review
    // --------------------------------

    function GetNumberOfReview($id) {
      global $dbConn;
      $query  = "select * from $this->review_table_name where link_id = '$id' and status = 1 order by date desc";
      $result = $dbConn->Execute($query);
      return $result->RecordCount();
    }


    // method to approve review
    // input :    $id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function ApproveReview($id) {
      global $dbConn;

      // update status to 1
      $query  = "update $this->review_table_name set status = 1 where review_id = '$id'";
      $result = $dbConn->Execute($query);

      // get link id
      $query  = "select link_id from $this->review_table_name where review_id = '$id'";
      $result = $dbConn->Execute($query);
      $lid    = $result->Fields("link_id");

      // get avg review
      $query  = "select avg(rating) as avg from $this->review_table_name where link_id = '$lid' and status = 1";
      $result = $dbConn->Execute($query);
      $avg    = $result->Fields("avg");

      // count review
      $query  = "select count(rating) as c from $this->review_table_name where link_id = '$lid' and status = 1";
      $result = $dbConn->Execute($query);
      $count  = $result->Fields("c");

      // update avg value in link table
      $query  = "update $this->table_name set avg_review = $avg, reviews = $count where link_id = '$lid'";
      $result = $dbConn->Execute($query);

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to reject review
    // input :    $id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function RejectReview($id) {
      global $dbConn;

      // delete review
      $query  = "delete from $this->review_table_name where review_id = '$id'";
      $result = $dbConn->Execute($query);

      if ($result)
        return 0;
      else
        return 1;
    }


    // method to get link's title
    // input :    $id
    // return :   title
    // --------------------------------

    function GetLinkTitle($id) {
      global $dbConn;
      $query  = "select title from $this->table_name where link_id = '$id'";
      $result = $dbConn->Execute($query);
      return $result->Fields("title");
    }


    // method to get link's category_id
    // input :    $id
    // return :   category_id
    // --------------------------------

    function GetLinkCategoryId($id) {
      global $dbConn;
      $query  = "select category_id from $this->table_name where link_id = '$id'";
      $result = $dbConn->Execute($query);
      return $result->Fields("category_id");
    }


    // method to display drop down menu of available favorites
    // output :    html
    // --------------------------------

    function GetFavoritesDropDown($username) {
      global $dbConn;
      $fav    = "<select name=favorite>\n";

      $query  = "select * from $this->favorite_table_name where username = '$username' order by title asc";
      $result = $dbConn->Execute($query);

      while (!$result->EOF) {
        $fav_id = $result->Fields("favorite_id");
        $title  = $result->Fields("title");

        $fav .= "<option value=\"$fav_id\">$title</option>\n";
        $result->MoveNext();
      }

      $fav .= "</select>";
      return $fav;
    }


    // method to add new link into favorites
    // input :     $favorite
    //             $id
    // output :    0: success
    //             1: link already exist
    // -------------------------------------

    function AddToFavorite($favorite, $id) {
      global $dbConn;
      $query  = "select * from $this->favorite_detail_table_name
                 where favorite_id = '$favorite' and link_id = '$id'";
      $result = $dbConn->Execute($query);

      if ($result->RecordCount() == 0) {
        $query  = "insert into $this->favorite_detail_table_name
                   (favorite_id, link_id) values ('$favorite', '$id')";
        $result = $dbConn->Execute($query);

        // update date
        $query  = "update $this->favorite_table_name
                   set date = now()
                   where favorite_id = '$favorite'";
        $result = $dbConn->Execute($query);

        return 0;
      }
      else
        return 1;
    }


    // method to display favorites
    // input :     $username
    // output :    html
    // -------------------------------------

    function DisplayFavorites() {
      global $dbConn;
      $tpl    = new Template();

      $result = $dbConn->Execute($this->query);

      while (!$result->EOF && $i < $this->max_rows) {
        $favorite_id = $result->Fields("favorite_id");
        $date        = $result->Fields("date");
        $username    = $result->Fields("username");
        $title       = $result->Fields("title");
        $description = $result->Fields("description");

        $date        = date($this->date_format, @strtotime($date));

        $tpl->assign('favorite_id', $favorite_id);
        $tpl->assign('date', $date);
        $tpl->assign('username', $username);
        $tpl->assign('title', $title);
        $tpl->assign('description', $description);
        $line .= $tpl->fetch($this->template_file);

        $result->MoveNext();
      }

      return $line;
    }


    // method to edit favorite
    // input :    $status = "display_form"
    //                      "process_form"
    //            $username
    //            $fav_id
    // output :   0 : success
    //            1 : user is not the owner
    // ------------------------------------------

    function EditFavorite($status, $username, $fav_id) {
      global $dbConn, $error_msg, $pflag, $title, $description, $id;

      $tpl    = new Template();

      $query  = "select username from $this->favorite_table_name where favorite_id = '$fav_id'";
      $result = $dbConn->Execute($query);

      if ($username == $result->Fields("username")) {
        $title       = stripslashes($title);
        $description = stripslashes($description);

        if ($status == 'display_form') {
          if ($pflag != "edit") {
            $query  = "select * from $this->favorite_table_name where favorite_id = '$fav_id'";
            $result = $dbConn->Execute($query);

            if ($result) {
              $title       = $result->Fields("title");
              $description = $result->Fields("description");
            }
          }
          else
            $title = $_POST["title"];

          // replace strings

          $tpl->assign('id', $id);
          $tpl->assign('title', $title);
          $tpl->assign('description', $description);
          $tpl->assign('error_msg', $error_msg);
          $line = $tpl->fetch($this->template_file);

          print $line;
          return 0;
        }
        elseif ($status == 'process_form') {
          $title  = $_POST["title"];

          $query  = "update $this->favorite_table_name set
          title = '$title',
          description = '$description'
          where favorite_id = '$fav_id'";
          $result = $dbConn->Execute($query);

          $line = $tpl->fetch($this->template_file);

          print $line;
          return 0;
        }
      }
      else
        return 1;
    }


    // method to create new favorite
    // input :    $username
    //            $title
    //            $description
    // output :   0 : success
    //            1 : sql error
    // ------------------------------------------

    function CreateFavorite($username, $title, $description) {
      global $dbConn;
      $query  = "insert into $this->favorite_table_name
                (username, title, description, date) values
                ('$username', '$title', '$description', now())";
      $result = $dbConn->Execute($query);
      if ($result)
        return 0;
      else
        return 1;
    }


    // method to delete favorite
    // input :    $username
    //            $fav_id
    // output :   0 : success
    //            1 : user is not the owner
    // ------------------------------------------

    function DeleteFavorite($username, $fav_id) {
      global $dbConn;
      $query  = "select username from $this->favorite_table_name where favorite_id = '$fav_id'";
      $result = $dbConn->Execute($query);

      if ($username == $result->Fields("username")) {
        $query  = "delete from $this->favorite_table_name where favorite_id = '$fav_id'";
        $result = $dbConn->Execute($query);

        $query  = "delete from $this->favorite_detail_table_name where favorite_id = '$fav_id'";
        $result = $dbConn->Execute($query);

        return 0;
      }
      else
        return 1;
    }


    // method to view detail favorite
    // input :    $fav_id
    // output :   0 : success
    //            1 : there's no favorite
    // ------------------------------------------

    function ViewFavorite($fav_id) {
      global $dbConn;
      $query  = "select username from $this->favorite_table_name where favorite_id = '$fav_id'";
      $result = $dbConn->Execute($query);

      if ($result)
        $username = $result->Fields("username");

      if (!empty($username)) {
        $query          = "select link_id from $this->favorite_detail_table_name where favorite_id = '$fav_id'";
        $result         = $dbConn->Execute($query);

        $this->max_rows = 100;

        if ($result) {
          while (!$result->EOF) {
            $link_id     = $result->Fields("link_id");
            $this->query = "select * from $this->table_name where link_id = '$link_id'";
            $line .= $this->Display();
            $result->MoveNext();
          }
        }

        return $line;
      }
      else
        return 1;
    }


    // method to remove detail favorite
    // input :    $username
    //            $fav_id
    //            $link_id
    // output :   0 : success
    //            1 : user is not the owner
    // ------------------------------------------

    function RemoveDetailFavorite($username, $fav_id, $link_id) {
      global $dbConn;
      $query  = "select username from $this->favorite_table_name where favorite_id = '$fav_id'";
      $result = $dbConn->Execute($query);

      if ($username == $result->Fields("username")) {
        $query  = "delete from $this->favorite_detail_table_name where link_id = '$link_id'";
        $result = $dbConn->Execute($query);

        // update date
        $query  = "update $this->favorite_table_name
                   set date = now()
                   where favorite_id = '$fav_id'";
        $result = $dbConn->Execute($query);

        return 0;
      }
      else
        return 1;
    }


    // method to report bad link
    // input :    $status      = "display_form"
    //                           "process_form"
    //                           "view_all"
    //            $link_id     = link id
    //            $r_name      = name
    //            $r_email     = email
    //            $type        = 1 DNS: Name Not Found
    //                           2 No Reply (Cannot Connect)
    //                           3 Moved
    //                           4 401 Authorization Required
    //                           5 404 Not Found
    //                           6 500 Server Error
    //                           0 Other
    //            $editor      = is in editor panel
    // return :   dispay_form = html
    //            process_form = 0: success
    //                           1: sql error
    // set var :  $email_template_fields
    // ------------------------------------------

    function BadLinkReport($status, $link_id = "", $r_name = "", $r_email = "", $type = "", $editor = false) {
      global $dbConn, $error_msg, $r_name, $r_email, $category, $type_val, $admin_template_path, $pg_which;

      $tpl       = new Template();

      $link_icon = $admin_template_path . "/images/tree_node.gif";
      $link_icon = "<img src=\"$link_icon\" border=\"0\" alt=\"\" /> ";

      // get link value

      if (!empty($link_id)) {
        $fields = $this->GetFields();

        $query  = "select * from $this->table_name where link_id = '$link_id'";
        $result = $dbConn->Execute($query);

        $i      = 0;

        $count_fields = @count($fields);
        while ($i < $count_fields) {
          $field       = $fields[$i];
          global $$field;

          $$fields[$i] = $result->Fields("$fields[$i]");

          if ($i != 0)
            $fields_name .= ",";

          $fields_name .= $field;

          $i++;
        }

        $category_obj = new clsCategory;
        $category_obj->table_name      = $this->category_table_name;
        $category_obj->link_table_name = $this->table_name;
        $category_obj->separator       = $this->category_separator;

        $category                      = $category_obj->GetCategoryPath($category_id);
        $category_with_link            = $category_obj->GetCategoryPath($category_id, TRUE);

        $this->email_template_fields   = str_replace(",", ",\$", $fields_name);
        $this->email_template_fields   = "\$category,\$r_name,\$r_email,\$type_val,\$" . $this->email_template_fields;
      }

      if ($type == 0)
        $type_val = "Other";
      elseif ($type == 1)
        $type_val = "DNS: Name Not Found";
      elseif ($type == 2)
        $type_val = "No Reply (Cannot Connect)";
      elseif ($type == 3)
        $type_val = "Moved";
      elseif ($type == 4)
        $type_val = "401 Authorization Required";
      elseif ($type == 5)
        $type_val = "404 Not Found";
      elseif ($type == 6)
        $type_val = "500 Server Error";

      if ($status == 'display_form') {
        // replace strings

        $tpl->assign('title', $title);
        $tpl->assign('url', $url);
        $tpl->assign('link_id', $link_id);
        $tpl->assign('error_msg', $error_msg);
        $tpl->assign('r_name', $r_name);
        $tpl->assign('r_email', $r_email);
        $tpl->assign('category_path', $category_path);
        $tpl->assign('category_path_with_link', $category_path_with_link);
        $line = $tpl->fetch($this->template_file);

        return $line;
      }
      elseif ($status == 'process_form') {
        $query  = "insert into $this->bad_link_table_name
                   (link_id, name, email, type, date) values
                   ($link_id, '$r_name', '$r_email', $type, now())";
        $result = $dbConn->Execute($query);

        if ($result)
          return 0;
        else
          return 1;
      }
      elseif ($status == 'view_all') {

        // query
        if (empty($this->query))
          $this->query = "select * from $this->bad_link_table_name order by date desc";

        if (empty($pg_which)) {
          $pg_which = 1;
        }

        $result           = $dbConn->PageExecute($this->query, $pg_which, $this->pg_size);
        $num_rows         = $result->RecordCount();

        // prepare pagination

        $nav             = new navigator;
        $nav->pg_size    = $this->pg_size;
        $nav->href       = $this->href;
        $nav->more_param = $this->more_param;

        $nav->pg_which   = $pg_which;
        $nav->rec_count  = $num_rows;
        $nav->init();

        $this->pagination = $nav->print_all();

        $i                = $nav->rec_start;

        // fetch data

        $chk_num          = 1;

        while (!$result->EOF) {
          $bad_link_id = $result->Fields("bad_link_id");
          $link_id     = $result->Fields("link_id");
          $name        = $result->Fields("name");
          $email       = $result->Fields("email");
          $date        = $result->Fields("date");
          $type        = $result->Fields("type");

          if ($type == 0)
            $type_val = "Other";
          elseif ($type == 1)
            $type_val = "DNS: Name Not Found";
          elseif ($type == 2)
            $type_val = "No Reply (Cannot Connect)";
          elseif ($type == 3)
            $type_val = "Moved";
          elseif ($type == 4)
            $type_val = "401 Authorization Required";
          elseif ($type == 5)
            $type_val = "404 Not Found";
          elseif ($type == 6)
            $type_val = "500 Server Error";

          $date         = date($this->date_format, @strtotime($date));
          $number       = $i + 1;

          // show link's detail
          $query        = "select title, url, category_id from $this->table_name where link_id = '$link_id'";
          $result2      = $dbConn->Execute($query);
          $title        = $result2->Fields("title");
          $url          = $result2->Fields("url");
          $category_id  = $result2->Fields("category_id");

          $category_obj = new clsCategory;
          $category_obj->table_name      = $this->category_table_name;
          $category_obj->link_table_name = $this->table_name;
          $category_obj->separator       = $this->category_separator;

          $category_path                 = $category_obj->GetCategoryPath($category_id);
          $category_path_with_link       = $category_obj->GetCategoryPath($category_id, TRUE);

          if ($editor) {

            // get editor category
            $categories = $this->GetEditorCategory($_COOKIE['COOKIE_USERNAME']);

            if (in_array($category_id, $categories)) {
              $this->num_rows++;
              $chk_box = "<input type=checkbox name=chkbox_$chk_num value=$bad_link_id>";
              $chk_num++;

              // write template

              $tpl->assign('number', $number);
              $tpl->assign('link_id', $link_id);
              $tpl->assign('name', $name);
              $tpl->assign('date', $date);
              $tpl->assign('email', $email);
              $tpl->assign('type_val', $type_val);

              $tpl->assign('chk_box', $chk_box);

              $tpl->assign('title', $title);
              $tpl->assign('url', $url);
              $tpl->assign('category_path', $category_path);
              $tpl->assign('category_path_with_link', $category_path_with_link);
              $line .= $tpl->fetch($this->template_file);
            }
          }
          else {
            $this->num_rows++;
            $chk_box = "<input type=checkbox name=chkbox_$chk_num value=$bad_link_id>";
            $chk_num++;

            // write template

            $tpl->assign('number', $number);
            $tpl->assign('link_id', $link_id);
            $tpl->assign('name', $name);
            $tpl->assign('date', $date);
            $tpl->assign('email', $email);
            $tpl->assign('type_val', $type_val);

            $tpl->assign('chk_box', $chk_box);

            $tpl->assign('title', $title);
            $tpl->assign('url', $url);
            $tpl->assign('category_path', $category_path);
            $tpl->assign('category_path_with_link', $category_path_with_link);

            if ($number % 2)
              $tbl_class = "tbl_light";
            else
              $tbl_class = "tbl_light2";

            $tpl->assign('tbl_class', $tbl_class);

            $tpl->assign('link_icon', $link_icon);

            $line .= $tpl->fetch($this->template_file);
          }

          $i++;

          $result->MoveNext();

        }

        return $line;
      }
    }


    // method to delete broken link
    // input :    $op : "delete report"
    //                  "delete link"
    //            $id : broken_link_id
    // return :   0 : success
    //            1 : sql error
    // --------------------------------

    function DeleteBadLinkReport($op, $id) {
      global $dbConn;
      if ($op == "delete_report") {

        // delete report
        $query  = "delete from $this->bad_link_table_name where bad_link_id = '$id'";
        $result = $dbConn->Execute($query);

        if ($result)
          return 0;
        else
          return 1;
      }
      elseif ($op == "delete_link") {

        // get link_id
        $query   = "select link_id from $this->bad_link_table_name where bad_link_id = '$id'";
        $result  = $dbConn->Execute($query);
        $link_id = $result->Fields("link_id");

        // delete link
        $query   = "delete from $this->table_name where link_id = '$link_id'";
        $result  = $dbConn->Execute($query);

        // delete all report associated with link_id
        $query   = "delete from $this->bad_link_table_name where link_id = '$link_id'";
        $result  = $dbConn->Execute($query);

        if ($result)
          return 0;
        else
          return 1;
      }
    }


    // method to view duplicate links
    // return :   html
    // --------------------------------

    function ViewDuplicateLinks() {
      global $dbConn;
      $query  = "select distinct url, count(url) as cu from $this->table_name
                 group by url
                 having cu > 1
                 order by url";
      $result = $dbConn->Execute($query);
      while (!$result->EOF) {
        $dup_url   = $result->Fields("url");
        $url_count = $result->Fields("cu");
        $this->query = "select * from $this->table_name where url = '$dup_url'";
        $html .= $this->Display();
        $result->MoveNext();
      }
      return $html;
    }


    // method to update new flag
    // ------------------------------------------

    function UpdateNewFlag() {
      global $dbConn;

      // reset new flag
      $query        = "update $this->table_name set new = 0";
      $result       = $dbConn->Execute($query);

      //update

      $expired_date = date("Y-m-d H:i:s", time() - (86400 * $this->new_limit));

      $query        = "select link_id from $this->table_name
                       where date >= '$expired_date' or last_updated >= '$expired_date'
                       order by date desc";
      $result       = $dbConn->Execute($query);
      while (!$result->EOF) {
        $link_id = $result->Fields('link_id');
        $query   = "update $this->table_name set new = 1 where link_id = '$link_id'";
        $result2 = $dbConn->Execute($query);
        $result->MoveNext();
      }
    }

    // method to update updated flag
    // ------------------------------------------

    function UpdateUpdatedFlag() {
      global $dbConn;

      // update new flag first
      $this->UpdateNewFlag();

      // reset updated flag
      $query        = "update $this->table_name set updated = 0";
      $result       = $dbConn->Execute($query);

      //update

      $expired_date = date("Y-m-d H:i:s", time() - (86400 * $this->updated_limit));

      $query        = "select link_id from $this->table_name where last_updated >= '$expired_date' order by date desc";
      $result       = $dbConn->Execute($query);
      while (!$result->EOF) {
        $link_id = $result->Fields('link_id');
        $query   = "update $this->table_name set new = 1, updated = 1 where link_id = '$link_id'";
        $result2 = $dbConn->Execute($query);
        $result->MoveNext();
      }
    }


    // method to avg review
    // input : $id : link_id
    // ------------------------------------------

    function UpdateAvgReview($id) {
      global $dbConn;

      // get avg value
      $query  = "select avg(rating) as avg from $this->review_table_name where link_id = '$id'";
      $result = $dbConn->Execute($query);
      $avg    = $result->Fields("avg");

      // update avg value in link table
      $query  = "update $this->table_name set avg_review = $avg where link_id = '$id'";
      $result = $dbConn->Execute($query);
    }


    // method to get webmaster's email address
    // return : array that contain email addr and link ID.
    // -------------------------------------------

    function GetWebmasterEmail($type = 'all', $with_link_id = FALSE, $query_filter = "") {
      global $dbConn;
      if ($type == 'all') {
        $query  = "select idx_link.email, idx_link.link_id
                   from idx_link
                   where email <> ''
                         $query_filter";
      }
      if ($type == 'basic') {
        $query  = "select idx_link.email, idx_link.link_id
                   from idx_link
                        left join idx_paid_listing on (idx_link.link_id = idx_paid_listing.link_id)
                   where suspended = 0
                         and email <> ''
                         and if (isnull(premium) || expire < now() || paid != 1, 0, premium) = 0
                         and if (isnull(sponsored) || expire < now() || paid != 1, 0, sponsored) = 0
                         $query_filter";
      }
      if ($type == 'premium') {
        $query  = "select idx_link.email, idx_link.link_id
                   from idx_link
                        left join idx_paid_listing on (idx_link.link_id = idx_paid_listing.link_id)
                   where suspended = 0
                         and email <> ''
                         and if (isnull(premium) || expire < now() || paid != 1, 0, premium) = 1
                         $query_filter";
      }
      if ($type == 'sponsored') {
        $query  = "select idx_link.email, idx_link.link_id
                   from idx_link
                        left join idx_paid_listing on (idx_link.link_id = idx_paid_listing.link_id)
                   where suspended = 0
                         and email <> ''
                         and if (isnull(sponsored) || expire < now() || paid != 1, 0, sponsored) = 1
                         $query_filter";
      }
      if ($type == 'suspended') {
        $query  = "select idx_link.email, idx_link.link_id
                   from idx_link
                   where suspended = 1
                         and email <> ''
                         $query_filter";
      }
      $result = $dbConn->Execute($query);
      while (!$result->EOF) {
        if ($with_link_id) {
          $email[] = $result->Fields("email") . "|" . $result->Fields("link_id");
        }
        else {
          $email[] = $result->Fields("email");
        }
        $result->MoveNext();
      }
      return $email;
    }

  }

?>