<?php
/*************************
  Coppermine Photo Gallery
  ************************
  Copyright (c) 2003-2007 Coppermine Dev Team
  v1.1 originally written by Gregory DEMAR

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  ********************************************
  Coppermine version: 1.4.12
**********************************************/

if (!defined('IN_COPPERMINE')) die('Not in Coppermine...');

// Switch that allows overriding the bridge manager with hard-coded values
define('USE_BRIDGEMGR', 1);

// include base class
require_once 'bridge/udb_base.inc.php';

//-----------------------------------------------------------------------------
/** return relative path to 'target_file' up from 'source_file'
*/
//-----------------------------------------------------------------------------
function relative_paths($source_file, $target_file)
{
  
  $_cpg = dirname(realpath($source_file));
  $_bb = dirname(realpath($target_file));
  $sep = strpos($_cpg, '\\') !== false ? '\\' : '/'; // for IIS

  $_cpg = explode($sep, $_cpg);
  $_bb = explode($sep, $_bb);

  if (count($_cpg) > count($_bb))
  {
    // $_cpg is below $_bb
    $npath = '';
    foreach($_bb as $key=>$path)
    {
      if ($path == $_cpg[$key])
        continue;
      $npath.=$_cpg[$key].'/';
    }
    $npath.=implode('/', array_slice($_cpg, $key+1));
  }
  elseif (count($_bb) > count($_cpg))
  {
    // $_bb is below $cpg
    $npath = '';
    foreach($_cpg as $key=>$path)
    {
      if ($path == $_bb[$key])
        continue;
      $npath.='../';
    }
    $npath.=str_repeat('../', count($_bb) - ($key+1));
  }
  else
  {
    // both on same level
    $npath = '';
    foreach($_cpg as $key=>$path)
    {
      if ($path == $_bb[$key])
        continue;
      $npath.='../'.$_cpg[$key];
    }
  }

  return $npath;
}
//-----------------------------------------------------------------------------
/** bridge class for phpbb3 (RC3)
*/
//-----------------------------------------------------------------------------
class phpbb3_udb extends core_udb {
  //---------------------------------------------------------------------------
  /** construct bridge
  */
  function phpbb3_udb()
  {
    global $BRIDGE;
    if (!USE_BRIDGEMGR) 
    { 
      // the vars that are used when bridgemgr is disabled
      // change them for your needs
      // URL of your phpbb3
      $this->boardurl = 'http://muvipix.com/phpBB3/';
      // local path to your phpbb3 config file
      require_once('../config.php');
    } 
    else 
    { // the vars from the bridgemgr
      $this->boardurl = $BRIDGE['full_forum_url'];
      require_once($BRIDGE['relative_path_to_config_file'] . 'config.php');
      $this->use_post_based_groups = $BRIDGE['use_post_based_groups'];
    }

    // phpbb3 uses multigroups
    $this->multigroups = 1;
    
    // Database connection settings from phpbb3's config file
    $this->db = array(
      'name' => $dbname,
      'host' => $dbhost ? $dbhost : 'localhost',
      'user' => $dbuser,
      'password' => $dbpasswd,
      'prefix' =>$table_prefix
    );
    
    // Board table names
    $this->table = array(
      'users' => 'users',
      'groups' => 'groups',
      'sessions' => 'sessions',
      'usergroups' => 'user_group',
      'sessionskeys' => 'sessions_keys'
    );

    // Derived full table names
    $this->usertable = '`' . $this->db['name'] . '`.' . $this->db['prefix'] . $this->table['users'];
    $this->groupstable =  '`' . $this->db['name'] . '`.' . $this->db['prefix'] . $this->table['groups'];
    $this->sessionstable =  '`' . $this->db['name'] . '`.' . $this->db['prefix'] . $this->table['sessions'];
    $this->usergroupstable = '`' . $this->db['name'] . '`.' . $this->db['prefix'] . $this->table['usergroups'];
    $this->sessionskeystable = '`' . $this->db['name'] . '`.' . $this->db['prefix'] . $this->table['sessionskeys'];
    
    // Table field names
    $this->field = array(
      'username' => 'username', // name of 'username' field in users table
      'user_id' => 'user_id', // name of 'id' field in users table
      'password' => 'user_password', // name of 'password' field in users table
      'email' => 'user_email', // name of 'email' field in users table
      'regdate' => 'user_regdate', // name of 'registered' field in users table
      'active' => 'user_active', // is user account active?
      'lastvisit' => 'user_lastvisit', // name of 'location' field in users table
      'location' => 'user_from', // name of 'location' field in users table
      'website' => 'user_website', // name of 'website' field in users table
      'usertbl_group_id' => 'group_id', // name of 'group id' field in users table
      'grouptbl_group_id' => 'group_id', // name of 'group id' field in groups table
      'grouptbl_group_name' => 'group_name' // name of 'group name' field in groups table
    );
    
    // Pages to redirect to
    $this->page = array(
      'register' => '/ucp.php?mode=register',
      'editusers' => '/memberlist.php',
      'edituserprofile' => "/memberlist.php?mode=viewprofile&u=",
    );

    // Group ids - admin and guest only.
    $this->admingroups = array($BRIDGE['admin_group']);
    $this->guestgroup = 1;
    $this->botgroup = 6;

    // Use a special function to collect groups for cpg groups table
    $this->group_overrride = 1;

    // get path for redirection
    $this->redirect_url = relative_paths(basename($_SERVER['PHP_SELF']), $BRIDGE['relative_path_to_config_file'].'config.php');
    // Cookie settings - used in following functions only
    $this->cookie_name = $BRIDGE['cookie_prefix'];
    // Connect to db
    $this->connect();
  }

  //---------------------------------------------------------------------------
  /** get group definitions from phpbb3
  */
  function collect_groups()
  {
    if (!$this->use_post_based_groups)
    {
    // add initial groups for non post-based groups
      $udb_groups = array(1 =>'Administrators', 2=> 'Registered', 3=>'Guests', 4=> 'Banned');
    }
    else
    {
      // select all groups instead of bots' group
      $sql ="SELECT * FROM {$this->groupstable} WHERE group_id != {$this->botgroup} ORDER BY group_id DESC";
    
      $result = cpg_db_query($sql, $this->link_id);
      while ($row = mysql_fetch_assoc($result))
      {
        // offset all phpbb3 defined groups by 100
        $udb_groups[$row[$this->field['grouptbl_group_id']]+100] = utf_ucfirst(utf_strtolower($row[$this->field['grouptbl_group_name']]));
      }
      mysql_free_result($result);
    }
    return $udb_groups;
  }
  //---------------------------------------------------------------------------
  /** definition of how to extract id, name from a session
      NOTICE: normally called cookie_extraction, but had to change this because
              session_extraction is called first
  */
  function session_extraction()
  {
    $this->sid=FALSE;
    // check if cookie is set
    if (isset($_COOKIE[$this->cookie_name . '_sid'])) 
    {
      // extract session id
      $this->sid = addslashes($_COOKIE[$this->cookie_name . '_sid']);
      // select user_id and password, except session belongs to a bot or a guest
      $sql = "SELECT u.{$this->field['user_id']} AS user_id, u.{$this->field['password']} AS password FROM {$this->usertable} AS u, {$this->sessionstable} AS s WHERE u.{$this->field['user_id']}=s.session_user_id ".
        "AND s.session_id = '{$this->sid}' ".
        "AND u.group_id != {$this->botgroup} ".
        "AND u.group_id != {$this->guestgroup}";
      $result = cpg_db_query($sql, $this->link_id);
      
      if (mysql_num_rows($result))
      {
        $row = mysql_fetch_array($result);
      }
      mysql_free_result($result);
    }
    return isset($row) ? $row : false;
  }
  //---------------------------------------------------------------------------
  /** extract id and password information from a session (cookies not available?)
      WARNING: since I didn't found how to force coppermine to hand over the 
               session id in links, it won't work without cookies!
  */
  function cookie_extraction()
  {
    $id = 0;
    $pass = '';
    if (!isset($this->sid)) $this->sid = FALSE;
    if (!$this->sid)
    {
      if (!($this->sid = $GLOBALS['value']))
      {
        global $_REQUEST;
        if (isset($_REQUEST['sid']))
        {
          $this->sid = $_REQUEST['sid'];
        }
        else
        {
          global $_SERVER;
          $url = parse_url($_SERVER['HTTP_REFERER']);
          parse_str($url['query'], $query);
          if (isset($query['sid']))
          {
            $this->sid = $query['sid'];
          }
        }
      }
    }
    if ($this->sid) 
    {
      $sql = "SELECT u.user_id, u.user_password ".
             "FROM {$this->sessionstable} AS s ".
             "  INNER JOIN {$this->usertable} AS u ".
             "  ON s.session_user_id = u.user_id ".
             "WHERE s.session_id = '".mysql_real_escape_string($this->sid, $this->linkid)."'".
             "  AND ".
             "u.user_inactive_reason = 0 ".
             "  AND u.group_id != {$this->botgroup} ".
             "  AND u.group_id != {$this->guestgroup} ".
             "LIMIT 1";

      $result = cpg_db_query($sql, $this->link_id);
      list($id, $pass) = mysql_fetch_row($result);
      mysql_free_result($result);
    }
    return ($id) ? array($id, $pass) : false;
  }
  //---------------------------------------------------------------------------
  /** get users groups
  */
  function get_groups($row)
  {
    global $BRIDGE, $USER_DATA;
    $data = array();
    $user_id = $USER_DATA['user_id'];
    // select all groups of user, for easier handling the maingroup of user is placed in every row
    $sql = "SELECT ug.group_id AS group_id, u.group_id AS maingroup ".
           "FROM {$this->usergroupstable} ug ".
           "LEFT JOIN {$this->usertable} u ON u.user_id = ug.user_id ".
           "WHERE u.user_id = $user_id ".
           "AND u.group_id != {$this->botgroup}";

    $result = cpg_db_query($sql, $this->link_id);
    
    $first = true;
    $maingroup = -1;

    while ($row=mysql_fetch_assoc($result))
    {
      if ($first)
      {
        // in first iteration step we have to place the maingroup of request into result array
        if (in_array($row['maingroup'], $this->admingroups))
        {
          $data[] = 100 + $BRIDGE['admin_group'];
        }
        // store it for later use
        $maingroup = $row['maingroup'];
        // add maingroup
        $data[] = 100 + $maingroup;
        $first = false;
      }
      // add the rest, if not already in (maingroup is already in)
      if ($row['group_id'] != $maingroup)
      {
        $data[] = 100 + $row['group_id'];
      }
    }

    mysql_free_result($result);

    // if a maingroup was set and not using post-based groups, place main group as first value
    if (!$this->use_post_based_groups && ($maingroup >= 0))
    {
      if ( in_array($maingroup, $this->admingroups) )
      {
        array_unshift($data, 1);
      }
      else
      {
        array_unshift($data, 2);
      }
    }

    return $data;
  }
  //---------------------------------------------------------------------------
  /** definition of actions required to convert a password from user database form to cookie form
  */
  function udb_hash_db($password)
  {
    return $password; // unused
  }
  //---------------------------------------------------------------------------
  /** redirect to login page
  */
  function login_page()
  {
    $this->redirect("ucp.php?mode=login&redirect={$this->redirect_url}");
  }
  //---------------------------------------------------------------------------
  /** redirect to logout page
  */
  function logout_page()
  {
    $this->redirect("ucp.php?mode=logout&sid={$this->sid}&redirect={$this->redirect_url}");
  }
  //---------------------------------------------------------------------------
  /** redirect to user list (available for admins only)
  */
  function view_users() 
  {
    // uncomment the next line if you want to see phpbb3's user list instead of coppermine's one
    // $this->redirect("memberlist.php?sid={$this->sid}");
  }
  //---------------------------------------------------------------------------
  /** redirect to user's profile
  */
  function view_profile() 
  {
    global $USER_DATA;
    $this->redirect("memberlist.php?mode=viewprofile&sid={$this->sid}&u={$USER_DATA[user_id]}");
  }
  //---------------------------------------------------------------------------
  /** get full user list
  */
  function get_users($options = array())
  {
      global $CONFIG;
    
    // Copy UDB fields and config variables (just to make it easier to read)
      $f =& $this->field;
      $C =& $CONFIG;
    
    // Sort codes - global this in usermgr.php in 1.5
        $sort_codes = array('name_a' => 'user_name ASC',
                            'name_d' => 'user_name DESC',
                            'group_a' => 'group_name ASC',
                            'group_d' => 'group_name DESC',
                            'reg_a' => 'user_regdate ASC',
                            'reg_d' => 'user_regdate DESC',
                            'pic_a' => 'pic_count ASC',
                            'pic_d' => 'pic_count DESC',
                            'disku_a' => 'disk_usage ASC',
                            'disku_d' => 'disk_usage DESC',
                            'lv_a' => 'user_lastvisit ASC',
                            'lv_d' => 'user_lastvisit DESC',
                           );
        
    $sql = "SELECT group_id, group_name, group_quota FROM {$C['TABLE_USERGROUPS']}";

    $result = cpg_db_query($sql, $this->link_id);
    
    $groups = $quotas = array();
  
    while ($row = mysql_fetch_assoc($result)) {
      $groups[$row['group_id']] = $row['group_name'];
      $quotas[$row['group_id']] = $row['group_quota'];
    }

    mysql_free_result($result);
    
    if (in_array($options['sort'], array('group_a', 'group_d', 'pic_a', 'pic_d', 'disku_a', 'disku_d'))){
      
      $sort = '';
      list($this->sortfield, $this->sortdir) = explode(' ', $sort_codes[$options['sort']]);
      $this->adv_sort = true;
      
    } else {
      
      $sort = "ORDER BY " . $sort_codes[$options['sort']];
      $this->adv_sort = false;
    }

    // Build WHERE clause, if this is a username search
        if ($options['search']) {
            $options['search'] = 'AND u.'.$f['username'].' LIKE "'.$options['search'].'" ';
        }
    
    // Main array to hold our user data
    $userlist = array();
    
    // These sorting methods need the cpg pics table, do that first
    if (in_array($options['sort'], array('pic_a', 'pic_d', 'disku_a', 'disku_d'))){
      
      $sql = "SELECT owner_id, COUNT(pid) as pic_count, ROUND(SUM(total_filesize)/1024) as disk_usage FROM {$C['TABLE_PICTURES']} WHERE owner_id <> 0 GROUP BY owner_id ORDER BY {$sort_codes[$options['sort']]} LIMIT {$options['lower_limit']}, {$options['users_per_page']}";
      $result = cpg_db_query($sql, $this->link_id);
      
      // If no records, return empty value
      if (!mysql_num_rows($result)) {
        return array();
      }
    
      while ($row = mysql_fetch_assoc($result)) $userlist[$row['owner_id']] = $row;
      mysql_free_result($result);

      $user_list_string = implode(', ', array_keys($userlist));

      $sql = "SELECT u.{$f['user_id']} as user_id, u.group_id, {$f['username']} as user_name, {$f['email']} as user_email, {$f['regdate']} as user_regdate, {$f['lastvisit']} as user_lastvisit ".
               "FROM {$this->usertable} AS u ".
               "WHERE u.{$f['user_id']} IN ($user_list_string) GROUP BY u.{$f['user_id']}";
      $result = cpg_db_query($sql, $this->link_id);
    
      // If no records, return empty value
      if (!mysql_num_rows($result)) {
        return array();
      }
    
      while ($row = mysql_fetch_assoc($result)) $userlist[$row['user_id']] = array_merge($userlist[$row['user_id']], $row);
      mysql_free_result($result);

    } else {
    
      $sql = "SELECT u.{$f['user_id']} as user_id, u.group_id, {$f['username']} as user_name, {$f['email']} as user_email, {$f['regdate']} as user_regdate, {$f['lastvisit']} as user_lastvisit, 0 as pic_count ".
               "FROM {$this->usertable} AS u ".
               "WHERE u.group_id != {$this->guestgroup} " . // no guests
               "AND u.group_id != {$this->botgroup} ". // no bots
               $options['search'].
               "GROUP BY u.{$f['user_id']} " . $sort . 
         " LIMIT {$options['lower_limit']}, {$options['users_per_page']}";

      $result = cpg_db_query($sql, $this->link_id);
    
      // If no records, return empty value
      if (!mysql_num_rows($result)) {
        return array();
      }
    
      while ($row = mysql_fetch_assoc($result)) $userlist[$row['user_id']] = $row;
      mysql_free_result($result);
      
      $user_list_string = implode(', ', array_keys($userlist));
    
      $sql = "SELECT owner_id, COUNT(pid) as pic_count, ROUND(SUM(total_filesize)/1024) as disk_usage FROM {$C['TABLE_PICTURES']} WHERE owner_id IN ($user_list_string) GROUP BY owner_id";

      $result = cpg_db_query($sql, $this->link_id);

      while ($owner = mysql_fetch_assoc($result)) $userlist[$owner['owner_id']] = array_merge($userlist[$owner['owner_id']], $owner);

      mysql_free_result($result);
    }
    
    foreach ($userlist as $uid => $user){
      
      $grps = array();
      if ($this->use_post_based_groups)
      {
        $sql = "SELECT ug.{$this->field['usertbl_group_id']}+100 AS group_id FROM 
          {$this->usertable} AS u, 
          {$this->usergroupstable} AS ug, 
          {$this->groupstable} as g 
          WHERE u.{$this->field['user_id']}=ug.{$this->field['user_id']} 
          AND u.user_id = '$uid' 
          AND g.{$this->field['grouptbl_group_id']} = ug.{$this->field['grouptbl_group_id']}";

        $result = cpg_db_query($sql, $this->link_id);
  
        while ($row2 = mysql_fetch_array($result)) {
          $grps[] = $row2['group_id'];
        }

        mysql_free_result($result);
  
      } else {
        $grps[0] = in_array($user['group_id'], $this->admingroups) ? 1 : 2;
      }
  
      $groupnames = $q = array();

      foreach ($grps as $gid){
        if ($this->use_post_based_groups && $gid == ($user['group_id'] + 100))
          $groupnames[] = '<b>'.$groups[$gid].'</b>';
        else
          $groupnames[] = $groups[$gid];
        $q[] = $quotas[$gid];
      }

      sort($groupnames);

      $userlist[$uid]['group_name'] = implode('<br />' ,$groupnames); 
      $userlist[$uid]['group_quota'] = max($q);
    }
    
    foreach ($userlist as $uid => $user) if (!isset($user['user_name'])) unset($userlist[$uid]);

    if ($this->adv_sort) usort($userlist, array('core_udb', 'adv_sort'));

        return $userlist;
    }
    //---------------------------------------------------------------------------
    function session_update()
    {
      if (isset($this->sid) && $this->sid)
      {
        $sql = "update {$this->sessionstable} set session_time='".time()."' where session_id='{$this->sid}';";
        cpg_db_query($sql, $this->link_id);
      }
    }
    //---------------------------------------------------------------------------
}
//-------------------------------------------------------------------------------
// and go !
$cpg_udb = new phpbb3_udb;
?>
