Вход Регистрация
Файл: library/XenForo/Model/Ip.php
Строк: 440
<?php

/**
 * Model for logging IPs and querying them.
 *
 * @package XenForo_Ip
 */
class XenForo_Model_Ip extends XenForo_Model
{
    
/**
     * Stores resolved host names from IPs
     *
     * @var array
     */
    
protected $_hostCache = array();

    
/**
     * Logs an IP for an action.
     *
     * @param integer $userId User causing action
     * @param string $contentType Type of content (user, post)
     * @param integer $contentId ID of content
     * @param string $action Action (insert, login)
     * @param string|null $ipAddress IP address or null to pull from request
     * @param integer|null $date Timestamp to tag IP with
     *
     * @return integer ID of inserted IP; 0 if no insert
     */
    
public function logIp($userId$contentType$contentId$action$ipAddress null$date null)
    {
        
$ipAddress XenForo_Helper_Ip::getBinaryIp(null$ipAddress);
        if (!
$ipAddress)
        {
            return 
0;
        }

        if (
$date === null)
        {
            
$date XenForo_Application::$time;
        }

        
$this->_getDb()->insert('xf_ip', array(
            
'user_id' => $userId,
            
'content_type' => $contentType,
            
'content_id' => $contentId,
            
'action' => $action,
            
'ip' => $ipAddress,
            
'log_date' => max(0$date)
        ));

        return 
$this->_getDb()->lastInsertId();
    }

    
/**
     * Static helper to log IPs without creating the model first.
     *
     * @see XenForo_Model_Ip::logIp()
     */
    
public static function log($userId$contentType$contentId$action$ipAddress null$date null)
    {
        return 
XenForo_Model::create(__CLASS__)->logIp(
            
$userId$contentType$contentId$action$ipAddress$date
        
);
    }

    
/**
     * Fetches an IP record by its id
     *
     * @param integer $ipId
     *
     * @return array
     */
    
public function getIpById($ipId)
    {
        
$ip $this->_getDb()->fetchRow('
            SELECT * FROM xf_ip
            WHERE ip_id = ?
        '
$ipId);

        
$ip['ip_address'] = XenForo_Helper_Ip::convertIpBinaryToString($ip['ip']);

        return 
$ip;
    }

    
/**
     * Static version of getIpById
     *
     * @see XenForo_Model_Ip::getIpById()
     */
    
public static function getById($ipId)
    {
        return 
XenForo_Model::create(__CLASS__)->getIpById($ipId);
    }

    
/**
     * Returns the first IP logged for the given parameters
     *
     * @param integer $userId
     * @param string $contentType
     * @param integer $contentId
     *
     * @return string IP binary/empty string
     */
    
public function getIp($userId$contentType$contentId)
    {
        
$ip $this->_getDb()->fetchOne('
            SELECT ip
            FROM xf_ip
            WHERE user_id = ?
            AND content_type = ?
            AND content_id = ?
        '
, array($userId$contentType$contentId));

        return (
$ip XenForo_Helper_Ip::convertIpBinaryToString($ip) : '');
    }

    
/**
     * Static helper to get a logged ip wihtout creating the model first
     *
     * @see XenForo_Model_Ip::getIp()
     */
    
public static function get($userId$contentType$contentId)
    {
        return 
XenForo_Model::create(__CLASS__)->getIp(
            
$userId$contentType$contentId
        
);
    }

    
/**
     * Deletes all IPs that belong to the specified content.
     *
     * @param string $contentType
     * @param int|array $contentIds One or more content Ids to delete from
     */
    
public function deleteByContent($contentType$contentIds)
    {
        if (!
is_array($contentIds))
        {
            
$contentIds = array($contentIds);
        }
        if (!
$contentIds)
        {
            return;
        }

        
$db $this->_getDb();

        
$db->delete('xf_ip',
            
'content_type = ' $db->quote($contentType) . ' AND content_id IN (' $db->quote($contentIds) . ')'
        
);
    }

    protected static 
$_lookupCache = array();

    
/**
     * Resolves the host name of an IP address
     *
     * @param string $ip
     *
     * @return string
     */
    
protected function _getHost($ip)
    {
        if (isset(
self::$_lookupCache[$ip]))
        {
            return 
self::$_lookupCache[$ip];
        }

        if (
strpos($ip':') !== false)
        {
            
// we need to uncompress the hex address to split this up
            
$binary XenForo_Helper_Ip::convertIpStringToBinary($ip);
            if (!
$binary)
            {
                return 
'';
            }
            
$checkIp XenForo_Helper_Ip::convertIpBinaryToString($binaryfalse);
            if (!
$checkIp)
            {
                return 
false;
            }

            
$checkIp str_replace(':'''$checkIp);
            
$parts str_split($checkIp);
            
$dnsRecord implode('.'array_reverse($parts)) . '.ip6.arpa';
        }
        else
        {
            
$parts explode('.'$ip);
            if (
count($parts) != 4)
            {
                return 
'';
            }

            
$dnsRecord implode('.'array_reverse($parts)) . '.in-addr.arpa';
        }

        
$lookup false;

        try
        {
            if (
function_exists('dns_get_record'))
            {
                
$host dns_get_record($dnsRecordDNS_PTR);
                if (isset(
$host[0]['target']))
                {
                    
$lookup $host[0]['target'];
                }
            }
            else
            {
                
$lookup gethostbyaddr($ip);
            }
        }
        catch (
Exception $e) {} // bad lookup

        
if (!$lookup)
        {
            
$lookup $ip;
        }

        
self::$_lookupCache[$ip] = $lookup;
        return 
$lookup;
    }

    
/**
     * Resolves the host name of an IP address
     *
     * @param string $ip
     *
     * @return string
     */
    
public static function getHost($ip)
    {
        return 
XenForo_Model::create(__CLASS__)->_getHost($ip);
    }

    
/**
     * Gets IP info for a content item and the member who created it
     *
     * @param array $content
     * @param boolean $resolveHosts
     *
     * @return array (contentIp, contentHost, registrationIp, registrationHost, confirmationIp, confirmationHost)
     */
    
public function getContentIpInfo(array $content)
    {
        if (
$content['ip_id'])
        {
            
$ip $this->getIpById($content['ip_id']);
            
$contentIp $ip['ip_address'];
            
$contentHost $this->_getHost($contentIp);
        }

        return 
$this->getRegistrationIps($content['user_id']) + array(
            
'contentIp'    => (empty($contentIp) ? false $contentIp),
            
'contentHost'  => (empty($contentHost) ? false $contentHost),
        );
    }

    
/**
     * Gets IP info for an online user
     *
     * @param array $onlineUser
     *
     * @return array (contentIp, contentHost, registrationIp, registrationHost, confirmationIp, confirmationHost)
     */
    
public function getOnlineUserIp($onlineUser)
    {
        if (
$onlineUser['ip'])
        {
            
$contentIp XenForo_Helper_Ip::convertIpBinaryToString($onlineUser['ip']);
            
$contentHost $this->_getHost($contentIp);
        }

        return 
$this->getRegistrationIps($onlineUser['user_id']) + array(
            
'contentIp'   => (empty($contentIp) ? false $contentIp),
            
'contentHost' => (empty($contentHost) ? false $contentHost),
        );
    }

    
/**
     * Fetches an array containing IP info for the registration and confirmation IPs of the given user
     *
     * @param integer $userId
     *
     * @return array (registrationIp, registrationHost, confirmationIp, confirmationHost)
     */
    
protected function getRegistrationIps($userId)
    {
        
$userIps $this->getModelFromCache('XenForo_Model_User')->getRegistrationIps($userId);

        return array(
            
'registrationIp'   => (empty($userIps['register']) ? false $userIps['register']),
            
'registrationHost' => (empty($userIps['register']) ? false $this->_getHost($userIps['register'])),

            
'confirmationIp'   => (empty($userIps['account-confirmation']) ? false $userIps['account-confirmation']),
            
'confirmationHost' => (empty($userIps['account-confirmation']) ? false $this->_getHost($userIps['account-confirmation'])),
        );
    }

    
/**
     * Returns an array all IPs used by a user, keyed by the most recent date recorded for that IP
     *
     * @param integer $userId
     *
     * @return array [$unixDate => $ip]
     */
    
public function getIpsByUserId($userId)
    {
        
$ips $this->_getDb()->fetchPairs('
            SELECT MAX(log_date), ip
            FROM xf_ip
            WHERE user_id = ?
            GROUP BY ip
            ORDER BY log_date DESC
        '
$userId);

        foreach (
$ips AS &$ip)
        {
            
$ip XenForo_Helper_Ip::convertIpBinaryToString($ip);
        }

        return 
$ips;
    }

    
/**
     * Searches for records of users using any of the IP addresses logged by the specified user
     *
     * @param integer ID of the user to check against
     * @param integer Number of days to look back in the logs
     *
     * @return array
     */
    
public function getSharedIpUsers($userId$logDays)
    {
        
$db $this->_getDb();

        
// written this way due to mysql's ridiculous sub-query performance
        
$recentIps $db->fetchCol($db->limit(
            
'
                SELECT DISTINCT ip
                FROM xf_ip
                WHERE user_id = ?
                    AND log_date > ?
            '
500
        
), array($userIdXenForo_Application::$time $logDays 86400));
        if (!
$recentIps)
        {
            return array();
        }

        
$ipLogs $db->fetchAll($db->limit(
            
'
                SELECT *
                FROM xf_ip
                WHERE ip IN (' 
$db->quote($recentIps) . ')
                    AND user_id <> ?
                    AND user_id > 0
                    AND log_date > ?
                ORDER BY log_date DESC
            '
1000
        
), array($userIdXenForo_Application::$time $logDays 86400));

        
$userIpLogs = array();
        foreach (
$ipLogs AS $ipLog)
        {
            
$ipLog['ip_address'] = XenForo_Helper_Ip::convertIpBinaryToString($ipLog['ip']);

            
$userIpLogs[$ipLog['user_id']][] = $ipLog;
        }

        
$userRecords $this->getModelFromCache('XenForo_Model_User')->getUsersByIds(
            
array_keys($userIpLogs),
            array(
'join' => XenForo_Model_User::FETCH_LAST_ACTIVITY)
        );

        
$visitor XenForo_Visitor::getInstance();

        
$users = array();

        foreach (
$userIpLogs AS $userId => $ipLog)
        {
            if (!isset(
$userRecords[$userId]))
            {
                continue;
            }

            
$users[$userId] = $userRecords[$userId];
            
$users[$userId]['ipLogs'] = $ipLog;
        }

        return 
$users;
    }

    public function 
pruneIps($cutOff null)
    {
        if (
$cutOff === null)
        {
            if (!
XenForo_Application::get('options')->ipLogCleanUp['enabled'])
            {
                return 
0;
            }

            
$cutOff XenForo_Application::$time 86400 XenForo_Application::get('options')->ipLogCleanUp['delay'];
        }

        
$db $this->_getDb();
        return 
$db->delete('xf_ip''log_date < ' $db->quote($cutOff));
    }
}
Онлайн: 1
Реклама