text: <?php
  /*---------------------------------------------------------------------------
   * @Project: Alto CMS
   * @Project URI: http://altocms.com
   * @Description: Advanced Community Engine
   * @Copyright: Alto CMS Team
   * @License: GNU GPL v2 & MIT
   *----------------------------------------------------------------------------
   * Based on
   *   LiveStreet Engine Social Networking by Mzhelskiy Maxim
   *   Site: www.livestreet.ru
   *   E-mail: rus.engine@gmail.com
   *----------------------------------------------------------------------------
   */
  
  /**
   * Маппер для работы с БД
   *
   * @package modules.userfeed
   * @since   1.0
   */
  class ModuleUserfeed_MapperUserfeed extends Mapper {
  
      /**
       * Подписать пользователя
       *
       * @param int $iUserId        ID подписываемого пользователя
       * @param int $iSubscribeType Тип подписки (см. константы класса)
       * @param int $iTargetId      ID цели подписки
       *
       * @return bool
       */
      public function SubscribeUser($iUserId, $iSubscribeType, $iTargetId) {
  
          $sql = "
              SELECT *
              FROM ?_userfeed_subscribe
              WHERE
                  user_id = ?d AND subscribe_type = ?d AND target_id = ?d
              LIMIT 1
              ";
          if (!$this->oDb->select($sql, $iUserId, $iSubscribeType, $iTargetId)) {
              $sql = "
                  INSERT INTO ?_userfeed_subscribe
                  (
                      user_id, subscribe_type, target_id
                  )
                  VALUES (
                      ?d, ?d, ?d
                  )
                  ";
              $this->oDb->query($sql, $iUserId, $iSubscribeType, $iTargetId);
              return true;
          }
          return false;
      }
  
      /**
       * Отписать пользователя
       *
       * @param int $iUserId        ID подписываемого пользователя
       * @param int $iSubscribeType Тип подписки (см. константы класса)
       * @param int $iTargetId      ID цели подписки
       *
       * @return bool
       */
      public function UnsubscribeUser($iUserId, $iSubscribeType, $iTargetId) {
  
          $sql = '
              DELETE FROM ?_userfeed_subscribe
              WHERE
                  user_id = ?d AND subscribe_type = ?d AND target_id = ?d';
          $this->oDb->query($sql, $iUserId, $iSubscribeType, $iTargetId);
          return true;
      }
  
      /**
       * Gets list of subscribtion
       *
       * @param int        $iUserId
       * @param string|int $xTargetType
       * @param array      $aTargetsId
       *
       * @return array
       */
      public function GetUserSubscribes($iUserId, $xTargetType = null, $aTargetsId = array()) {
  
          $aResult = array(
              'blogs' => array(),
              'blog' => array(),
              'users' => array(),
              'user' => array(),
          );
          if (!is_null($xTargetType)) {
              if (!is_array($xTargetType)) {
                  $xTargetType = array($xTargetType);
              }
              if (is_array($xTargetType)) {
                  foreach ($xTargetType as $iKey => $iTargetType) {
                      if (!is_integer($iTargetType)) {
                          switch ($iTargetType) {
                              case 'blog':
                              case 'blogs':
                                  $xTargetType[$iKey] = ModuleUserfeed::SUBSCRIBE_TYPE_BLOG;
                                  break;
                              case 'user':
                              case 'users':
                                  $xTargetType[$iKey] = ModuleUserfeed::SUBSCRIBE_TYPE_USER;
                                  break;
                              default:
                                  $xTargetType[$iKey] = 0;
                          }
                      }
                  }
              }
              $xTargetType = array_unique($xTargetType);
              if (sizeof($xTargetType) == 0) {
                  return $aResult;
              } elseif (sizeof($xTargetType) == 1) {
                  $xTargetType = reset($xTargetType);
              }
          } else {
              $xTargetType = null;
          }
  
          $sql = '
              SELECT subscribe_type, target_id
              FROM ?_userfeed_subscribe
              WHERE
                  user_id = ?d
                  {AND subscribe_type=?d}
                  {AND subscribe_type IN (?a)}
                  {AND target_id=?d}
                  {AND target_id IN (?a)}
              ';
          $aSubscribes = $this->oDb->select(
              $sql,
              $iUserId,
              ($xTargetType && !is_array($xTargetType)) ? $xTargetType : DBSIMPLE_SKIP,
              ($xTargetType && is_array($xTargetType)) ? $xTargetType : DBSIMPLE_SKIP,
              ($aTargetsId && !is_array($aTargetsId)) ? $aTargetsId : DBSIMPLE_SKIP,
              ($aTargetsId && is_array($aTargetsId)) ? $aTargetsId : DBSIMPLE_SKIP
          );
  
          if (!count($aSubscribes)) {
              return $aResult;
          }
  
          foreach ($aSubscribes as $aSubscribe) {
              if ($aSubscribe['subscribe_type'] == ModuleUserfeed::SUBSCRIBE_TYPE_BLOG) {
                  $aResult['blogs'][$aSubscribe['target_id']] = $aSubscribe['target_id'];
                  $aResult['blog'][$aSubscribe['target_id']] = $aSubscribe['target_id'];
              } elseif ($aSubscribe['subscribe_type'] == ModuleUserfeed::SUBSCRIBE_TYPE_USER) {
                  $aResult['users'][$aSubscribe['target_id']] = $aSubscribe['target_id'];
                  $aResult['user'][$aSubscribe['target_id']] = $aSubscribe['target_id'];
              }
          }
          return $aResult;
      }
  
      /**
       * Получить ленту топиков по подписке
       *
       * @param array $aUserSubscribes Список подписок пользователя
       * @param int   $iCount          Число получаемых записей (если null, из конфига)
       * @param int   $iFromId         Получить записи, начиная с указанной
       * @param array $aFilter         Дополнительные фильтры
       *
       * @return array
       */
      public function ReadFeed($aUserSubscribes, $iCount, $iFromId, $aFilter) {
  
          $sql
              = "
  				SELECT
  					t.topic_id
  				FROM
  					?_topic as t,
  					?_blog as b
  				WHERE
  					t.topic_publish = 1
  					AND (t.topic_date_show IS NULL OR t.topic_date_show <= ?)
  					AND t.blog_id=b.blog_id
  					{ AND b.blog_type=? }
  					{ AND b.blog_type IN (?a) }
  					{ AND b.blog_type!=? }
  					{ AND b.blog_type NOT IN (?a) }
  					{ AND t.topic_id < ?d }
  					AND ( 1=0 { OR t.blog_id IN (?a) } { OR t.user_id IN (?a) } )
                  ORDER BY t.topic_id DESC
                  { LIMIT 0, ?d }";
  
          $aTopics = $aTopics = $this->oDb->selectCol(
              $sql,
              F::Now(),
              (isset($aFilter['include_types']) && !is_array($aFilter['include_types'])) ? $aFilter['include_types'] : DBSIMPLE_SKIP,
              (isset($aFilter['include_types']) && is_array($aFilter['include_types'])) ? $aFilter['include_types'] : DBSIMPLE_SKIP,
              (isset($aFilter['exclude_types']) && !is_array($aFilter['exclude_types'])) ? $aFilter['exclude_types'] : DBSIMPLE_SKIP,
              (isset($aFilter['exclude_types']) && is_array($aFilter['exclude_types'])) ? $aFilter['exclude_types'] : DBSIMPLE_SKIP,
              $iFromId ? $iFromId : DBSIMPLE_SKIP,
              count($aUserSubscribes['blogs']) ? $aUserSubscribes['blogs'] : DBSIMPLE_SKIP,
              count($aUserSubscribes['users']) ? $aUserSubscribes['users'] : DBSIMPLE_SKIP,
              $iCount ? $iCount : DBSIMPLE_SKIP
          );
          return $aTopics;
      }
  
  
      /**
       * Возвращает количество новых комментариев
       *
       * @param $sUserId
       *
       * @return bool
       */
      public function GetCountTrackNew($sUserId) {
  
          $sql
              = "
  				SELECT
  					SUM(
  					    CASE
  					      WHEN t.topic_count_comment > tr.comment_count_last
  					      THEN t.topic_count_comment - tr.comment_count_last
  					      ELSE 0
  					    END
  					) as count_new
  				FROM
   					?_topic_read as tr,
  					?_topic as t
  				WHERE
  					t.topic_id=tr.topic_id
  					AND
  					tr.user_id=?d
  					AND
  					t.topic_id IN (
  						SELECT target_id FROM ?_track WHERE
  							target_type = ?
  							AND
  							user_id = ?d
  							AND
  							status=?d
  						)
  		";
          if ($aRow = $this->oDb->selectRow($sql, $sUserId, 'topic_new_comment', $sUserId, 1)) {
              return $aRow['count_new'];
          }
          return false;
      }
  
  }
  
  // EOF