PageRenderTime 77ms CodeModel.GetById 19ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 1ms

/webapp/lib/util/util.php

https://github.com/openpne/OpenPNE2
PHP | 1143 lines | 847 code | 127 blank | 169 comment | 131 complexity | 8cb7fadd7842373c50c6b9f3e21893e7 MD5 | raw file
   1<?php
   2/**
   3 * @copyright 2005-2008 OpenPNE Project
   4 * @license   http://www.php.net/license/3_01.txt PHP License 3.01
   5 */
   6
   7/**
   8 * リダイレクト
   9 *
  10 * @param string $module
  11 * @param string $action
  12 * @param array  $params
  13 */
  14function openpne_redirect($module, $action = '', $params = array())
  15{
  16    if ($module == 'ktai') {
  17        if (session_id()) {
  18            $params['ksid'] = session_id();
  19        }
  20    }
  21    $url = openpne_gen_url($module, $action, $params);
  22    client_redirect_absolute($url);
  23}
  24
  25/**
  26 * クライアントリダイレクト
  27 *
  28 * @param   string  $dest ジャンプ先URI(絶対パス)
  29 */
  30function client_redirect_absolute($dest)
  31{
  32    // 改行文字を削除
  33    $dest = str_replace(array("\r", "\n"), '', $dest);
  34    header('Location: '. $dest);
  35    exit;
  36}
  37
  38/**
  39 * クライアントリダイレクト(ログインページ)
  40 */
  41function client_redirect_login()
  42{
  43    client_redirect_absolute(get_login_url());
  44}
  45
  46/**
  47 * ログインページを取得
  48 *
  49 * @return string ログインページURL
  50 */
  51function get_login_url()
  52{
  53    if (LOGIN_URL_PC) {
  54        return LOGIN_URL_PC;
  55    } else {
  56        return openpne_gen_url('pc', 'page_o_login');
  57    }
  58}
  59
  60//---
  61
  62/**
  63 * URLを生成
  64 */
  65function openpne_gen_url($module, $action = '', $params = array(), $absolute = true, $force = false)
  66{
  67    switch ($force) {
  68    case 'ssl':
  69        $url = OPENPNE_SSL_URL;
  70        break;
  71    case 'nonssl':
  72        $url = OPENPNE_URL;
  73        break;
  74    default:
  75        $url = openpne_gen_url_head($module, $action, $absolute);
  76        break;
  77    }
  78
  79    $p = array('m' => $module, 'a' => $action) + (array)$params;
  80    if (need_ssl_param($module, $action, $force)) {
  81        $p['ssl_param'] = 1;
  82    } else {
  83        unset($p['ssl_param']);
  84    }
  85    if ($p['m'] == 'admin') {
  86        $p['m'] = ADMIN_MODULE_NAME;
  87    }
  88    if ($q = http_build_query($p)) {
  89        $url .= '?' . $q;
  90    }
  91    return $url;
  92}
  93
  94function openpne_gen_url_head($module, $action = '', $absolute = true)
  95{
  96    if (OPENPNE_USE_PARTIAL_SSL) {
  97        switch (openpne_ssl_type($module, $action)) {
  98        case 'SSL_REQUIRED':
  99            $head = ($absolute || !is_ssl()) ? OPENPNE_SSL_URL : './';
 100            break;
 101        case 'SSL_SELECTABLE':
 102            if ($absolute) {
 103                $head = (is_ssl()) ? OPENPNE_SSL_URL : OPENPNE_URL;
 104            } else {
 105                $head = './';
 106            }
 107            break;
 108        case 'SSL_DISABLED':
 109            $head = ($absolute || is_ssl()) ? OPENPNE_URL : './';
 110            break;
 111        }
 112    } else {
 113        $head = ($absolute) ? OPENPNE_URL : './';
 114    }
 115    return $head;
 116}
 117
 118//---
 119
 120/**
 121 * module / action が部分SSL対象かどうかを判別する
 122 */
 123function openpne_ssl_type($m, $a)
 124{
 125    if (in_array($a, (array)$GLOBALS['_OPENPNE_SSL_REQUIRED'][$m]) ||
 126        in_array($m, (array)$GLOBALS['_OPENPNE_SSL_REQUIRED_MODULES'])
 127    ) {
 128        $type = 'SSL_REQUIRED';
 129    } elseif (in_array($a, (array)$GLOBALS['_OPENPNE_SSL_SELECTABLE'][$m])) {
 130        $type = 'SSL_SELECTABLE';
 131    } else {
 132        $type = 'SSL_DISABLED';
 133    }
 134    return $type;
 135}
 136
 137/**
 138 * 現在のリクエストがSSL通信であるかどうかを判別
 139 */
 140function is_ssl()
 141{
 142    static $is_ssl;
 143    if (!isset($is_ssl)) {
 144        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
 145            $is_ssl = true;
 146        } elseif (OPENPNE_USE_SSL_PARAM && !empty($_REQUEST['ssl_param'])) {
 147            $is_ssl = true;
 148        } else {
 149            $is_ssl = false;
 150        }
 151    }
 152    return $is_ssl;
 153}
 154
 155function need_ssl_param($module, $action = '', $force = false)
 156{
 157    $need = false;
 158    if (OPENPNE_USE_PARTIAL_SSL && OPENPNE_USE_SSL_PARAM) {
 159        switch ($force) {
 160        case 'ssl':
 161            $need = true;
 162            break;
 163        case 'nonssl':
 164            $need = false;
 165            break;
 166        default:
 167            switch (openpne_ssl_type($module, $action)) {
 168            case 'SSL_REQUIRED':
 169                $need = true;
 170                break;
 171            case 'SSL_SELECTABLE':
 172                $need = is_ssl();
 173                break;
 174            case 'SSL_DISABLED':
 175                break;
 176            }
 177            break;
 178        }
 179    }
 180    return $need;
 181}
 182
 183//---
 184
 185function is_ktai_mail_address($mail)
 186{
 187    $pieces = explode('@', $mail);
 188    $domain = array_pop($pieces);
 189
 190    return in_array($domain, $GLOBALS['OpenPNE']['KTAI_DOMAINS']);
 191}
 192
 193function db_common_is_mailaddress($value)
 194{
 195    if (preg_match('/^[^:;@,\s\x80-\xFF]+@\w[\w\-.]*\.[a-zA-Z]+$/', $value)) {
 196        return true;
 197    } else {
 198        return false;
 199    }
 200}
 201
 202//---
 203
 204function _mt_srand()
 205{
 206    if (version_compare(phpversion(), '4.2.0', '<')) {
 207        list($usec, $sec) = explode(' ', microtime());
 208        $seed = (float)$sec + ((float)$usec * 100000);
 209
 210        mt_srand($seed);
 211    }
 212}
 213
 214function do_common_create_password($length = 8)
 215{
 216    // パスワードに使用する文字
 217    $elem = 'abcdefghkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ2345679';
 218    $max = strlen($elem) - 1;
 219
 220    _mt_srand();
 221    $password = '';
 222    for ($i = 0; $i < $length; $i++) {
 223        $password .= substr($elem, mt_rand(0, $max), 1);
 224    }
 225    return $password;
 226}
 227
 228function create_hash()
 229{
 230    _mt_srand();
 231    return md5(uniqid(mt_rand(), true));
 232}
 233
 234//---
 235
 236function &get_crypt_blowfish()
 237{
 238    static $singleton;
 239    if (empty($singleton)) {
 240        if (OPENPNE_USE_OLD_CRYPT_BLOWFISH) {
 241            include_once 'Crypt/BlowfishOld.php';
 242            $singleton = new Crypt_BlowfishOld(ENCRYPT_KEY);
 243        } else {
 244            include_once 'Crypt/Blowfish.php';
 245            $singleton = new Crypt_Blowfish(ENCRYPT_KEY);
 246        }
 247    }
 248    return $singleton;
 249}
 250
 251/**
 252 * 可逆的な暗号化をする
 253 *
 254 * @param string $str 平文
 255 * @return string 暗号文
 256 */
 257function t_encrypt($str)
 258{
 259    if (!$str) return '';
 260
 261    $bf =& get_crypt_blowfish();
 262    $str = $bf->encrypt($str);
 263
 264    //base64
 265    $str = base64_encode($str);
 266
 267    return $str;
 268}
 269
 270/**
 271 * 可逆的な暗号を復号化する
 272 *
 273 * @param string $str 暗号文
 274 * @return string 平文
 275 */
 276function t_decrypt($str)
 277{
 278    if (!$str) return '';
 279
 280    //base64
 281    $str = base64_decode($str);
 282
 283    $bf =& get_crypt_blowfish();
 284    return rtrim($bf->decrypt($str));
 285}
 286
 287function t_wordwrap($str, $width = 80, $break = "\n")
 288{
 289    if (!$width) {
 290        return $str;
 291    }
 292
 293    $lines = explode($break, $str);
 294    foreach ($lines as $key => $line) {
 295        if (mb_strwidth($line) > $width) {
 296            $new_line = '';
 297            do {
 298                if ($new_line) {
 299                    $new_line .= $break;
 300                }
 301                $tmp = mb_strimwidth($line, 0, $width);
 302                $new_line .= $tmp;
 303                $line = substr($line, strlen($tmp));
 304            } while (strlen($line) > 0);
 305            $lines[$key] = $new_line;
 306        }
 307    }
 308    return implode($break, $lines);
 309}
 310
 311function util_is_unused_mail($name)
 312{
 313    $unused = explode(',', UNUSED_MAILS);
 314    return in_array($name, $unused);
 315}
 316
 317function util_get_c_navi($navi_type = 'h')
 318{
 319    switch ($navi_type) {
 320    case 'global':
 321        $navi_type = 'global';
 322        $navi = array(
 323            array('url' => '?m=pc&a=page_h_search', 'caption' => 'メンバー検索'),
 324            array('url' => '?m=pc&a=page_h_com_find_all', 'caption' => WORD_COMMUNITY . '検索'),
 325            array('url' => '?m=pc&a=page_h_review_search', 'caption' => 'レビュー検索'),
 326            array('url' => '?m=pc&a=page_h_home', 'caption' => 'マイホーム'),
 327            array('url' => '?m=pc&a=page_h_invite', 'caption' => '友人を誘う'),
 328            array('url' => '?m=pc&a=page_h_diary_list_all', 'caption' => '最新' . WORD_DIARY),
 329            array('url' => '?m=pc&a=page_h_ranking', 'caption' => 'ランキング'),
 330            array('url' => '?m=pc&a=page_h_config', 'caption' => '設定変更'),
 331        );
 332        break;
 333    case 'h':
 334    default:
 335        $navi_type = 'h';
 336        $navi = array(
 337            array('url' => '?m=pc&a=page_h_home', 'caption' => 'ホーム'),
 338            array('url' => '?m=pc&a=page_fh_friend_list', 'caption' => WORD_MY_FRIEND),
 339            array('url' => '?m=pc&a=page_fh_diary_list', 'caption' => WORD_DIARY),
 340            array('url' => '?m=pc&a=page_h_message_box', 'caption' => 'メッセージ'),
 341            array('url' => '?m=pc&a=page_h_ashiato', 'caption' => 'あしあと'),
 342            array('url' => '?m=pc&a=page_h_bookmark_list', 'caption' => 'お気に入り'),
 343            array('url' => '?m=pc&a=page_fh_review_list_member', 'caption' => 'マイレビュー'),
 344            array('url' => '?m=pc&a=page_h_prof', 'caption' => 'マイページ確認'),
 345            array('url' => '?m=pc&a=page_h_config_prof', 'caption' => 'プロフィール変更'),
 346        );
 347        break;
 348    case 'f':
 349        $navi = array(
 350            array('url' => '?m=pc&a=page_f_home', 'caption' => 'ホーム'),
 351            array('url' => '?m=pc&a=page_fh_friend_list', 'caption' => WORD_FRIEND),
 352            array('url' => '?m=pc&a=page_fh_diary_list', 'caption' => WORD_DIARY . 'を読む'),
 353            array('url' => '?m=pc&a=page_f_message_send', 'caption' => 'メッセージを送る'),
 354            array('url' => '?m=pc&a=page_f_bookmark_add', 'caption' => 'お気に入りに追加'),
 355            array('url' => '?m=pc&a=page_fh_review_list_member', 'caption' => 'レビュー'),
 356            array('url' => '?m=pc&a=page_f_invite', 'caption' => WORD_MY_FRIEND.'に紹介'),
 357            array('url' => '?m=pc&a=page_f_link_request', 'caption' => WORD_MY_FRIEND.'に追加'),
 358            array('url' => '?m=pc&a=page_f_intro_edit', 'caption' => '紹介文を書く'),
 359        );
 360        break;
 361    case 'c':
 362        $navi = array(
 363            array('url' => '?m=pc&a=page_c_home', 'caption' => WORD_COMMUNITY . 'トップ'),
 364            array('url' => '?m=pc&a=page_c_topic_list', 'caption' => '掲示板'),
 365            array('url' => '?m=pc&a=page_c_member_review', 'caption' => 'おすすめレビュー'),
 366            array('url' => '?m=pc&a=page_c_join_commu', 'caption' => WORD_COMMUNITY . 'に参加'),
 367            array('url' => '?m=pc&a=page_c_invite', 'caption' => WORD_MY_FRIEND.'に紹介'),
 368            array('url' => '?m=pc&a=page_c_leave_commu', 'caption' => WORD_COMMUNITY . 'を退会'),
 369        );
 370        break;
 371    }
 372    $db = db_get_c_navi($navi_type);
 373    foreach ($db as $value) {
 374        $i = $value['sort_order'] - 1;
 375        $navi[$i] = array('url' => $value['url'], 'caption' => $value['caption']);
 376    }
 377    return $navi;
 378}
 379
 380/**
 381 * checkdate の wrapper function
 382 * Warning 対策
 383 */
 384function t_checkdate($month, $day, $year)
 385{
 386    return checkdate(intval($month), intval($day), intval($year));
 387}
 388
 389/**
 390 * Date_Calc::isFutureDate の wrapper function
 391 */
 392function t_isFutureDate($day, $month, $year)
 393{
 394    include_once 'Date/Calc.php';
 395    return Date_Calc::isFutureDate(intval($day), intval($month), intval($year));
 396}
 397
 398//---
 399
 400/**
 401 * Check c_diary.public_flag
 402 *
 403 * @param int $c_diary_id
 404 * @param int $c_member_id
 405 * @return bool allowed or not
 406 */
 407function pne_check_diary_public_flag($c_diary_id, $c_member_id)
 408{
 409    $c_diary = db_diary_get_c_diary4id($c_diary_id);
 410    if ($c_diary['c_member_id'] == $c_member_id) {
 411        return true;
 412    }
 413
 414    switch ($c_diary['public_flag']) {
 415    case 'public':
 416        $allowed = true;
 417        break;
 418    case 'friend':
 419        $allowed = db_friend_is_friend($c_diary['c_member_id'], $c_member_id);
 420        break;
 421    case 'private':
 422    default:
 423        $allowed = false;
 424        break;
 425    }
 426
 427    return $allowed;
 428}
 429
 430function pne_url2a($url, $target = '_blank')
 431{
 432    $length = 60;
 433    $etc = '...';
 434
 435    if (strlen($url) > $length) {
 436        $length -= strlen($etc);
 437        $urlstr = substr($url, 0, $length) . $etc;
 438    } else {
 439        $urlstr = $url;
 440    }
 441    if ($target) {
 442        $target = sprintf(' target="%s"', $target);
 443    }
 444
 445    $url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
 446    $urlstr = htmlspecialchars($urlstr, ENT_QUOTES, 'UTF-8');
 447
 448    return sprintf('<a href="%s"%s>%s</a>', $url, $target, $urlstr);
 449}
 450
 451function get_auth_config($is_ktai = false)
 452{
 453    if (OPENPNE_AUTH_MODE == 'slavepne') {
 454        $config = $GLOBALS['_OPENPNE_AUTH_CONFIG'];
 455    } elseif (OPENPNE_AUTH_MODE == 'pneid') {
 456        $config['storage'] = 'DB';
 457        $config['is_lowercase_username'] = true;
 458        $config['options'] = array(
 459            'dsn'         => db_get_dsn(),
 460            'auto_quote'  => false,
 461            'table'       => 'c_member_secure AS cms INNER JOIN c_username AS cu USING (c_member_id)',
 462            'db_fields'   => 'cms.hashed_password AS hashed_password, cu.username AS username',
 463            'usernamecol' => 'username',
 464            'passwordcol' => 'hashed_password',
 465            'cryptType'   => 'md5',
 466        );
 467    } else {
 468        $config['storage'] = 'DB';
 469        $config['is_encrypt_username'] = true;
 470        if ($is_ktai) {
 471            $config['options'] = array(
 472                'dsn'         => db_get_dsn(),
 473                'table'       => 'c_member_secure',
 474                'usernamecol' => 'ktai_address',
 475                'passwordcol' => 'hashed_password',
 476                'cryptType'   => 'md5',
 477            );
 478        } else {
 479            $config['options'] = array(
 480                'dsn'         => db_get_dsn(),
 481                'table'       => 'c_member_secure',
 482                'usernamecol' => 'pc_address',
 483                'passwordcol' => 'hashed_password',
 484                'cryptType'   => 'md5',
 485            );
 486        }
 487    }
 488    $config['is_ktai'] = $is_ktai;
 489
 490    if ($is_ktai) {
 491        $config['is_check_user_agent'] = OPENPNE_SESSION_CHECK_KTAI_USER_AGENT;
 492    } else {
 493        $config['is_check_user_agent'] = OPENPNE_SESSION_CHECK_PC_USER_AGENT;
 494    }
 495
 496    return $config;
 497}
 498
 499function crypt_func($raw_value,$cryptType)
 500{
 501    if (   isset($cryptType)
 502        && $cryptType == 'none') {
 503        $cryptFunction = 'strval';
 504    } elseif (   isset($cryptType)
 505              && function_exists($cryptType)) {
 506        $cryptFunction = $cryptType;
 507    } else {
 508        $cryptFunction = 'md5';
 509    }
 510
 511    return $cryptFunction($raw_value);
 512}
 513
 514function check_action4pne_slave($is_ktai = false)
 515{
 516    if (OPENPNE_AUTH_MODE == 'slavepne') {
 517        if ($is_ktai) {
 518            openpne_redirect('ktai');
 519        } else {
 520            openpne_redirect('pc');
 521        }
 522    }
 523}
 524
 525function util_include_php_files($dir)
 526{
 527    if (!is_dir($dir)) {
 528        return;
 529    }
 530    if ($dh = opendir($dir)) {
 531        while (($file = readdir($dh)) !== false) {
 532            if ($file[0] === '.') {
 533                continue;
 534            }
 535            $path = realpath($dir . '/' . $file);
 536            if (is_dir($path)) {
 537                util_include_php_files($path);
 538            } else {
 539                if (substr($file, -4, 4) === '.php') {
 540                    include_once $path;
 541                }
 542            }
 543        }
 544        closedir($dh);
 545    }
 546}
 547
 548function util_cast_public_flag_diary($public_flag, $default = 'public')
 549{
 550    switch ($public_flag) {
 551    case 'public':
 552    case 'friend':
 553    case 'private':
 554        break;
 555    default:
 556        $public_flag = $default;
 557        break;
 558    }
 559    return $public_flag;
 560}
 561
 562/**
 563 * 登録してもよいメールアドレスかどうか
 564 */
 565function util_is_regist_mail_address($mail_address, $c_member_id = 0)
 566{
 567    if (!db_common_is_mailaddress($mail_address)) {
 568        return false;
 569    }
 570
 571    if (!db_member_is_limit_domain4mail_address($mail_address)) {
 572        return false;
 573    }
 574
 575    if (db_member_is_sns_join4mail_address($mail_address, $c_member_id)) {
 576        return false;
 577    }
 578
 579    return true;
 580}
 581
 582/**
 583 * アップロード可能な拡張子のリストを取得
 584 */
 585function util_get_file_allowed_extensions($format = null)
 586{
 587    $list = array();
 588    if (FILE_ALLOWED_EXTENTIONS) {
 589        $exts = explode(',', FILE_ALLOWED_EXTENTIONS);
 590        foreach ((array)$exts as $ext) {
 591            if (trim($ext) !== '') {
 592                $list[] = trim($ext);
 593            }
 594        }
 595    }
 596    if ($format === 'string') {
 597        if ($list) {
 598            foreach ($list as $key => $value) {
 599                $list[$key] = '*.' . $value;
 600            }
 601            $list = implode('; ', $list);
 602        } else {
 603            $list = '';
 604        }
 605    }
 606    return $list;
 607}
 608
 609/**
 610 * アップロード可能な拡張子かどうか
 611 */
 612function util_check_file_extention($filename)
 613{
 614    $extension = pathinfo($filename, PATHINFO_EXTENSION);
 615    $list = util_get_file_allowed_extensions();
 616    return (!$list || in_array($extension, $list));
 617}
 618
 619/**
 620 * 参照可能なメッセージかどうか
 621 *
 622 * ・指定メンバーが送信者で、完全削除済でない
 623 * ・指定メンバーが受信者で、送信済であり完全削除済でない
 624 *
 625 * @param int $c_member_id
 626 * @param int $c_message_id
 627 * @return bool
 628 */
 629function util_is_readable_message($c_member_id, $c_message_id)
 630{
 631    $c_message = db_message_c_message4c_message_id($c_message_id);
 632
 633    if ($c_message['c_member_id_from'] == $c_member_id) {  // 自分が送信者
 634        if (!$c_message['is_kanzen_sakujo_from']) {  // 完全削除済でない
 635            return true;
 636        }
 637    } elseif ($c_message['c_member_id_to'] == $c_member_id)  { // 自分が受信者
 638        if ($c_message['is_send'] && !$c_message['is_kanzen_sakujo_to']) {  // 送信済であり完全削除済でない
 639            return true;
 640        }
 641    }
 642
 643    return false;
 644}
 645
 646/**
 647 * DB内配色設定の未設定項目をデフォルトの配色設定で埋める
 648 *
 649 * @param array $c_config_color    DB内配色設定
 650 * @param string $mode
 651 * @return array
 652 */
 653function util_apply_color_default2current($c_config_color, $mode = 'pc')
 654{
 655    if ($mode == 'ktai') {
 656        $default_color['color_23'] = $c_config_color['color_1'];
 657        $default_color['color_24'] = $c_config_color['color_14'];
 658        $default_color['color_25'] = $c_config_color['color_14'];
 659        $default_color['color_26'] = $c_config_color['color_14'];
 660        $default_color['color_27'] = $c_config_color['color_3'];
 661        $default_color['color_28'] = $c_config_color['color_14'];
 662    } else {
 663        $default_color['color_19'] = $c_config_color['color_13'];
 664    }
 665
 666    $c_config_color = array_map('trim', $c_config_color);
 667    $empty_keys = array_keys($c_config_color, '');
 668    foreach ($empty_keys as $key) {
 669        if (array_key_exists($key, $default_color)) {
 670            $c_config_color[$key] = $default_color[$key];
 671        }
 672    }
 673
 674    return $c_config_color;
 675}
 676
 677function util_get_color_config()
 678{
 679    $c_config_color = db_etc_c_config_color();
 680    $c_config_color = util_apply_color_default2current($c_config_color);
 681
 682    $color_config = array(
 683        'border_01' => $c_config_color['color_1'],
 684        'border_07' => $c_config_color['color_2'],
 685        'border_10' => $c_config_color['color_3'],
 686        'bg_00' => $c_config_color['color_4'],
 687        'bg_01' => $c_config_color['color_5'],
 688        'bg_02' => $c_config_color['color_6'],
 689        'bg_03' => $c_config_color['color_7'],
 690        'bg_04' => $c_config_color['color_8'],
 691        'bg_05' => $c_config_color['color_9'],
 692        'bg_06' => $c_config_color['color_10'],
 693        'bg_07' => $c_config_color['color_11'],
 694        'bg_08' => $c_config_color['color_12'],
 695        'bg_09' => $c_config_color['color_13'],
 696        'bg_10' => $c_config_color['color_14'],
 697        'bg_11' => $c_config_color['color_15'],
 698        'bg_12' => $c_config_color['color_16'],
 699        'bg_13' => $c_config_color['color_17'],
 700        'bg_14' => $c_config_color['color_18'],
 701        'color_19' => $c_config_color['color_19'],
 702    );
 703    return $color_config;
 704}
 705
 706function util_get_color_config_ktai()
 707{
 708    $c_config_color = db_etc_c_config_color_ktai();
 709    $c_config_color = util_apply_color_default2current($c_config_color, 'ktai');
 710
 711    $color_config = array(
 712        'bg_01' => $c_config_color['color_1'],
 713        'bg_02' => $c_config_color['color_2'],
 714        'bg_03' => $c_config_color['color_3'],
 715        'bg_04' => $c_config_color['color_4'],
 716        'bg_05' => $c_config_color['color_5'],
 717        'bg_06' => $c_config_color['color_6'],
 718        'bg_07' => $c_config_color['color_7'],
 719        'bg_08' => $c_config_color['color_8'],
 720        'bg_09' => $c_config_color['color_9'],
 721        'bg_10' => $c_config_color['color_10'],
 722        'border_01' => $c_config_color['color_11'],
 723        'border_02' => $c_config_color['color_12'],
 724        'border_03' => $c_config_color['color_13'],
 725        'font_01' => $c_config_color['color_14'],
 726        'font_02' => $c_config_color['color_15'],
 727        'font_03' => $c_config_color['color_23'],
 728        'font_04' => $c_config_color['color_17'],
 729        'font_05' => $c_config_color['color_18'],
 730        'font_06' => $c_config_color['color_19'],
 731        'font_07' => $c_config_color['color_20'],
 732        'font_08' => $c_config_color['color_21'],
 733        'font_09' => $c_config_color['color_22'],
 734        'color_24' => $c_config_color['color_24'],
 735        'color_25' => $c_config_color['color_25'],
 736        'color_26' => $c_config_color['color_26'],
 737        'color_27' => $c_config_color['color_27'],
 738        'color_28' => $c_config_color['color_28'],
 739    );
 740    return $color_config;
 741}
 742
 743/**
 744 * メンバー登録を行う
 745 *
 746 * @param array $c_member
 747 * @param array $c_member_secure
 748 * @param array $c_member_profile_list
 749 * @param bool $is_password_encrypted    パスワードが既に暗号化済みかどうか
 750 * @return int
 751 */
 752function util_regist_c_member($c_member, $c_member_secure, $c_member_profile_list = array(), $is_password_encrypted = false)
 753{
 754    // メール受信設定をデフォルト値に
 755    $c_member['is_receive_mail'] = 1;
 756    $c_member['is_receive_ktai_mail'] = 1;
 757    $c_member['is_receive_daily_news'] = 1;
 758
 759    // メンバー登録
 760    $u = db_member_insert_c_member($c_member, $c_member_secure, $is_password_encrypted);
 761    if ($u === false) {  // メンバー登録に失敗した場合
 762        return false;
 763    }
 764
 765    if (OPENPNE_USE_POINT_RANK) {
 766        //入会者にポイント加算
 767        $point = db_action_get_point4c_action_id(1);
 768        db_point_add_point($u, $point);
 769
 770        //メンバー招待をした人にポイント加算
 771        $point = db_action_get_point4c_action_id(7);
 772        db_point_add_point($c_member['c_member_id_invite'], $point);
 773    }
 774
 775    // c_member_profile
 776    db_member_update_c_member_profile($u, $c_member_profile_list);
 777
 778    // 招待者とフレンドリンク
 779    db_friend_insert_c_friend($u, $c_member['c_member_id_invite']);
 780
 781    //管理画面で指定したコミュニティに強制参加
 782    $c_commu_id_list = db_commu_regist_join_list();
 783    foreach ($c_commu_id_list as $c_commu_id) {
 784        db_commu_join_c_commu($c_commu_id, $u);
 785    }
 786
 787    // ログインIDを登録
 788    if (OPENPNE_AUTH_MODE == 'pneid') {
 789        $login_id = strtolower($c_member['login_id']);
 790        db_member_insert_username($u, $login_id);
 791    }
 792
 793    return $u;
 794}
 795
 796function util_get_preset_color_list($dir = 'pc')
 797{
 798    $color_list_dir = OPENPNE_WEBAPP_DIR . '/lib/color/' . $dir . '/';
 799    $color_list = array();
 800
 801    if ($dh = opendir($color_list_dir)) {
 802        while (($file = readdir($dh)) !== false) {
 803            if (array_pop(explode('.', $file)) == 'ini') {
 804                $color_list[$file] = parse_ini_file($color_list_dir . $file);
 805            }
 806        }
 807        closedir($dh);
 808    }
 809
 810    ksort($color_list);
 811
 812    return array_values($color_list);
 813}
 814
 815function util_get_module_config($module)
 816{
 817    $config = array();
 818
 819    if ($file = openpne_ext_search($module . '/config.ini')) {
 820        $config = parse_ini_file($file, true);
 821    }
 822
 823    return $config;
 824}
 825
 826function util_get_validate_rules_profile($disp = 'config')
 827{
 828    $disp_key = 'disp_' . $disp;
 829
 830    $rules = array();
 831    $profile_list = db_member_c_profile_list4null();
 832    foreach ($profile_list as $profile) {
 833        if ($profile[$disp_key]) {
 834            $rule = array(
 835                'type' => 'int',
 836                'required' => $profile['is_required'],
 837                'caption' => $profile['caption'],
 838            );
 839            switch ($profile['form_type']) {
 840            case 'text':
 841            case 'textlong':
 842            case 'textarea':
 843                $rule['type'] = $profile['val_type'];
 844                $rule['regexp'] = $profile['val_regexp'];
 845                $rule['min'] = $profile['val_min'];
 846                if ($profile['val_max']) {
 847                    $rule['max'] = $profile['val_max'];
 848                }
 849                break;
 850            case 'checkbox':
 851                $rule['is_array'] = '1';
 852                break;
 853            }
 854            $rules[$profile['name']] = $rule;
 855        }
 856    }
 857    return $rules;
 858}
 859
 860function util_send_header_internal_server_error()
 861{
 862    header('HTTP/1.0 500 Internal Server Error');
 863    exit;
 864}
 865
 866function util_output_xml4array($data, $root, $is_escape = true)
 867{
 868    require_once 'XML/Serializer.php';
 869    $option = array(
 870        'rootName' => $root,
 871    );
 872    $serializer = new XML_Serializer($option);
 873
 874    if ($is_escape) {
 875        $data = util_escape4output_xml($data);
 876    }
 877
 878    $result = $serializer->serialize($data);
 879
 880    if ($result === true) {
 881        $xml = $serializer->getSerializedData();
 882        header('Content-Type: application/xml');
 883        echo $xml;
 884        exit;
 885    }
 886
 887    util_send_header_internal_server_error();
 888}
 889
 890function util_escape4output_xml($data)
 891{
 892    if (is_array($data)) {
 893        foreach ($data as $key => $value) {
 894            $data[$key] = util_escape4output_xml($value);
 895        }
 896        return $data;
 897    } elseif (is_string($data)) {
 898        return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
 899    } else {
 900        return $data;
 901    }
 902}
 903
 904function util_get_img_url($filename, $width, $height)
 905{
 906    require_once 'smarty_plugins/function.t_img_url.php';
 907    $params = array(
 908        'filename' => $filename,
 909        'w' => $width,
 910        'h' => $height,
 911    );
 912    return smarty_function_t_img_url($params, $dummy);
 913}
 914
 915function util_get_c_member_config_default()
 916{
 917    $default_config = array(
 918        'SEND_DIARY_COMMENT_MAIL_KTAI' => 0,
 919        'IS_DISPLAY_NEWDIARY_HOME' => 1,
 920        'IS_DISPLAY_NEWTOPIC_HOME' => 1,
 921        'IS_DISPLAY_NEWDIARY_HOME_KTAI' => 1,
 922        'IS_DISPLAY_NEWTOPIC_HOME_KTAI' => 1,
 923        'IS_DISPLAY_BOOKMARK_DIARY_HOME' => 1,
 924        'IS_DISPLAY_BOOKMARK_BLOG_HOME' => 1,
 925        'IS_DISPLAY_SCHEDULE_HOME' => 1,
 926        'SEND_RANK_UP_MAIL_PC' => 1,
 927        'SEND_RANK_UP_MAIL_KTAI' => 1,
 928        'IS_SEARCH_RESULT' => 1,
 929    );
 930
 931    return $default_config;
 932}
 933
 934function util_get_c_member_config($c_member_id)
 935{
 936    $default_config = util_get_c_member_config_default();
 937    $member_config = array_merge($default_config, db_member_c_member_config4c_member_id($c_member_id));
 938
 939    return $member_config;
 940}
 941
 942/**
 943 * ページャの作成
 944 *
 945 * @param  int   $page
 946 * @param  int   $page_size
 947 * @param  int   $total_num
 948 * @return mixed $total_num が 0 の場合は null、それ以外の場合はページャ用の連想配列
 949 */
 950function util_make_pager($page, $page_size, $total_num)
 951{
 952    if ($total_num == 0) {
 953        return;
 954    }
 955    $pager = array(
 956        'page' => $page,
 957        'page_size' => $page_size,
 958        'total_num' => $total_num,
 959        'start_num' => ($page - 1) * $page_size + 1,
 960        'end_num' => $page * $page_size,
 961        'total_page' => ceil($total_num / $page_size),
 962        'prev_page' => 0,
 963        'next_page' => 0,
 964    );
 965
 966    // 表示している最後の番号
 967    if ($pager['end_num'] > $pager['total_num'])
 968        $pager['end_num'] = $pager['total_num'];
 969
 970    // 前ページ
 971    if ($pager['page'] > 1)
 972        $pager['prev_page'] = $page - 1;
 973
 974    // 次ページ
 975    if ($pager['end_num'] < $pager['total_num'])
 976        $pager['next_page'] = $page + 1;
 977
 978    $disp_first = max(($page - 10), 1);
 979    $disp_last = min(($page + 9), $pager['total_page']);
 980    for (; $disp_first <= $disp_last; $disp_first++) {
 981        $pager['disp_pages'][] = $disp_first;
 982    }
 983
 984    return $pager;
 985}
 986
 987/**
 988 * debug_backtrace() の結果を、出力用にフィルタリングする
 989 *
 990 * @param  array $backtrace
 991 * @return array
 992 */
 993function util_filter_backtrace($backtrace)
 994{
 995    $result = $backtrace;
 996
 997    $base_regex = '/^' . preg_quote(OPENPNE_DIR, '/') . '/';
 998
 999    foreach ($backtrace as $key => $value) {
1000        // 関数・メソッドの引数
1001        if (!empty($value['args'])) {
1002            foreach ($value['args'] as $arg_num => $arg) {
1003                if (is_object($arg)) {
1004                    $result[$key]['args'][$arg_num] = 'object(' . get_class($arg) . ')';
1005                } elseif (is_array($arg)) {
1006                    $result[$key]['args'][$arg_num] = 'Array(' . count($arg) . ')';
1007                }
1008            }
1009        }
1010
1011        // メソッドが所属しているクラス
1012        if (isset($value['object'])) {
1013            unset($result[$key]['object']);
1014        }
1015
1016        // 関数・メソッドが定義されているファイル名を相対パスに変更
1017        $result[$key]['file'] = preg_replace($base_regex, '.', $value['file']);
1018    }
1019
1020    return $result;
1021}
1022
1023/**
1024 * マッチングした文字列を一時的に退避する
1025 *
1026 * $patterns に指定された正規表現のパターンにマッチするものをマーカーに置換し、
1027 * 置換後の文字列、マーカーと元の文字列の対応テーブルを返す。
1028 *
1029 * @param string $subject
1030 * @param array  $patterns
1031 * @return array
1032 */
1033function util_replace_patterns_to_marker($subject, $patterns = array())
1034{
1035    $i = 0;
1036    $list = array();
1037
1038    if (empty($patterns)) {
1039        $patterns = array(
1040            '/<input[^>]+>/is',
1041            '/<textarea.*?<\/textarea>/is',
1042            '/<option.*?<\/option>/is',
1043            '/<img[^>]+>/is',
1044            '/<head.*?<\/head>/is',
1045            '/response_comment_format\(\'.*?\'\)/is',
1046        );
1047    }
1048
1049    foreach ($patterns as $pattern) {
1050        if (preg_match_all($pattern, $subject, $matches)) {
1051            foreach ($matches[0] as $match) {
1052                $replacement = '<<<MARKER:'.$i.'>>>';
1053                $list[$replacement] = $match;
1054                $i++;
1055            }
1056        }
1057    }
1058
1059    $subject = str_replace(array_values($list), array_keys($list), $subject);
1060
1061    return array($list, $subject);
1062}
1063
1064/**
1065 * 連続投稿チェック用の情報を取得する
1066 *
1067 * @param  int   $u
1068 * @return array
1069 */
1070function util_get_post_info($u)
1071{
1072    $last_post_time = '';
1073    $post_count = 0;
1074
1075    if (OPENPNE_POST_USE_DB) {
1076        list($last_post_time, $post_count) = db_etc_get_post_info($u);
1077    } else {
1078        $last_post_time = $_SESSION['last_post_time'];
1079        $post_count = $_SESSION['post_count'];
1080    }
1081
1082    return array($last_post_time, $post_count);
1083}
1084
1085/**
1086 * 連続投稿チェック用の情報を設定する
1087 *
1088 * @param int $u
1089 * @param int $post_time
1090 * @param int $post_count
1091 */
1092function util_set_post_info($u, $post_time, $post_count)
1093{
1094    if (OPENPNE_POST_USE_DB) {
1095        db_etc_set_post_info($u, $post_time, $post_count);
1096    } else {
1097        $_SESSION['last_post_time'] = $post_time;
1098        $_SESSION['post_count'] = $post_count;
1099    }
1100}
1101
1102/**
1103 * 連続投稿確認用
1104 *
1105 * @param  string $module
1106 * @param  string $action
1107 * @param  int    $u
1108 * @return bool   true  : post OK
1109 *                false : post NG
1110 */
1111function util_do_post_interval_ok($module, $action, $u)
1112{
1113    // チェックしない
1114    if (!OPENPNE_POST_INTERVAL_UNFAIR_SECOND || !isset($GLOBALS['CHECK_POST_ACTIONS'])) {
1115        return true;
1116    }
1117
1118    if (in_array($action, $GLOBALS['CHECK_POST_ACTIONS'][$module])) {
1119        // 最終投稿時間と投稿回数を取得
1120        list($last_post_time, $post_count) = util_get_post_info($u);
1121
1122        $now_time = time();
1123        $interval = $now_time - (int)$last_post_time;
1124
1125        if (!$last_post_time || $interval > OPENPNE_POST_INTERVAL_UNFAIR_COUNT_RESET_SECOND) {
1126            // 最終投稿時間が不明か、前回投稿から一定時間経過しているためカウントをリセットする
1127            $post_count = 1;
1128        } elseif ($interval < OPENPNE_POST_INTERVAL_UNFAIR_SECOND) {
1129            $post_count++;
1130        }
1131        // 情報更新
1132        util_set_post_info($u, $now_time, $post_count);
1133
1134        // 投稿回数が一定数以上のため、連続投稿であるとみなす
1135        if ($post_count > OPENPNE_POST_INTERVAL_UNFAIR_COUNT) {
1136            return false;
1137        }
1138    }
1139
1140    return true;
1141}
1142
1143?>