Преглед изворни кода

#4 - connections: common content (for ex: mutual friends between two profiles)

Alex Trofimov пре 12 година
родитељ
комит
8d91c2d24a

+ 83 - 0
inc/classes/BxDolConnection.php

@@ -262,6 +262,17 @@ class BxDolConnection extends BxDol implements iBxDolFactoryObject {
         return true;
     }
 
+    /**
+     * Get common content IDs between two initiators
+     * @param $iInitiator1 one initiator
+     * @param $iInitiator2 second initiator 
+     * @param $isMutual get mutual connections only
+     * @return array of available connections
+     */    
+    public function getCommonContent ($iInitiator1, $iInitiator2, $isMutual = false, $iStart = 0, $iLimit = BX_CONNECTIONS_LIST_LIMIT, $iOrder = BX_CONNECTIONS_ORDER_NONE) {
+        return $this->_oQuery->getCommonContent($iInitiator1, $iInitiator2, $isMutual, $iStart, $iLimit, $iOrder);
+    }
+
     /**
      * Get connected content IDs
      * @param $iInitiator initiator of the connection
@@ -282,6 +293,18 @@ class BxDolConnection extends BxDol implements iBxDolFactoryObject {
         return $this->_oQuery->getConnectedInitiators($iContent, $isMutual, $iStart, $iLimit, $iOrder);
     }
 
+    /**
+     * Get necessary parts of SQL query to use connections in other queries
+     * @param $sContentTable content table or alias
+     * @param $sContentField content table field or field alias
+     * @param $iInitiator initiator of the connection
+     * @param $isMutual get mutual connections only
+     * @return array of SQL string parts, for now 'join' part only is returned
+     */
+    public function getCommonContentAsSQLParts ($sContentTable, $sContentField, $iInitiator1, $iInitiator2, $isMutual = false) {
+        return $this->_oQuery->getCommonContentSQLParts($sContentTable, $sContentField, $iInitiator1, $iInitiator2, $isMutual);
+    }
+
     /**
      * Get necessary parts of SQL query to use connections in other queries
      * @param $sContentTable content table or alias
@@ -306,6 +329,66 @@ class BxDolConnection extends BxDol implements iBxDolFactoryObject {
         return $this->_oQuery->getConnectedInitiatorsSQLParts($sContentTable, $sContentField, $iContent, $isMutual);
     }
 
+    /**
+     * Get necessary condition array to use connections in search classes
+     * @param $sContentField content table field name
+     * @param $iInitiator initiator of the connection
+     * @param $iMutual get mutual connections only
+     * @return array of conditions, for now with 'restriction' and 'join' parts
+     */
+    public function getCommonContentAsCondition ($sContentField, $iInitiator1, $iInitiator2, $iMutual = false) {
+        return array(
+
+            'restriction' => array (
+                'connections_' . $this->_sObject => array(
+                    'value' => $iInitiator1,
+                    'field' => 'initiator',
+                    'operator' => '=',
+                    'table' => 'c',
+                ),
+                'connections_mutual_' . $this->_sObject => array(
+                    'value' => $iMutual,
+                    'field' => 'mutual',
+                    'operator' => '=',
+                    'table' => 'c',
+                ),
+                'connections2_' . $this->_sObject => array(
+                    'value' => $iInitiator2,
+                    'field' => 'initiator',
+                    'operator' => '=',
+                    'table' => 'c2',
+                ),
+                'connections2_mutual_' . $this->_sObject => array(
+                    'value' => $iMutual,
+                    'field' => 'mutual',
+                    'operator' => '=',
+                    'table' => 'c2',
+                ),
+            ),
+
+            'join' => array (
+                'connections_' . $this->_sObject => array(
+                    'type' => 'INNER',
+                    'table' => $this->_aObject['table'],
+                    'table_alias' => 'c',
+                    'mainField' => $sContentField,
+                    'onField' => 'content',
+                    'joinFields' => array(),
+                ),
+                'connections2_' . $this->_sObject => array(
+                    'type' => 'INNER',
+                    'table' => $this->_aObject['table'],
+                    'table_alias' => 'c2',
+                    'mainTable' => 'c',
+                    'mainField' => 'content',
+                    'onField' => 'content',
+                    'joinFields' => array(),
+                ),
+            ),
+
+        );
+    }
+
     /**
      * Get necessary condition array to use connections in search classes
      * @param $sContentField content table field name

+ 48 - 18
inc/classes/BxDolConnectionQuery.php

@@ -35,51 +35,81 @@ class BxDolConnectionQuery extends BxDolDb {
         return $aObject;
     }
 
+    public function getCommonContentSQLParts ($sContentTable, $sContentField, $iInitiator1, $iInitiator2, $isMutual = false) {
+        $sWhereJoin1 = $this->prepare(" AND `c`.`initiator` = ?", $iInitiator1);
+        $sWhereJoin2 = $this->prepare(" AND `c2`.`initiator` = ?", $iInitiator2);
+        if (false !== $isMutual) {
+            $sWhereJoin1 .= $this->prepare(" AND `c`.`mutual` = ?", $isMutual);
+            $sWhereJoin2 .= $this->prepare(" AND `c2`.`mutual` = ?", $isMutual);
+        }
+        return array(
+            'join' => "
+                INNER JOIN `{$this->_sTable}` AS `c` ON (`c`.`content` = `$sContentTable`.`$sContentField` $sWhereJoin1)
+                INNER JOIN `{$this->_sTable}` AS `c2` ON (`c2`.`content` = `c`.`content` $sWhereJoin2)",
+        );
+    }
+
     public function getConnectedContentSQLParts ($sContentTable, $sContentField, $iInitiator, $isMutual = false) {
-        $sWhere = $this->prepare(" AND `" . $this->_sTable . "`.`initiator` = ?", $iInitiator);
+        $sWhere = $this->prepare(" AND `c`.`initiator` = ?", $iInitiator);
         if (false !== $isMutual)
-            $sWhere .= $this->prepare(" AND `mutual` = ?", $isMutual);
+            $sWhere .= $this->prepare(" AND `c`.`mutual` = ?", $isMutual);
         return array(
-            'join' => "INNER JOIN `{$this->_sTable}` ON (`{$this->_sTable}`.`content` = `$sContentTable`.`$sContentField` $sWhere)",
+            'join' => "INNER JOIN `{$this->_sTable}` AS `c` ON (`c`.`content` = `$sContentTable`.`$sContentField` $sWhere)",
         );
     }
 
     public function getConnectedInitiatorsSQLParts ($sContentTable, $sContentField, $iInitiator, $isMutual = false) {
-        $sWhere = $this->prepare(" AND `" . $this->_sTable . "`.`content` = ?", $iInitiator);
+        $sWhere = $this->prepare(" AND `c`.`content` = ?", $iInitiator);
         if (false !== $isMutual)
-            $sWhere .= $this->prepare(" AND `mutual` = ?", $isMutual);
+            $sWhere .= $this->prepare(" AND `c`.`mutual` = ?", $isMutual);
         return array(
-            'join' => "INNER JOIN `{$this->_sTable}` ON (`{$this->_sTable}`.`initiator` = `$sContentTable`.`$sContentField` $sWhere)",
+            'join' => "INNER JOIN `{$this->_sTable}` AS `c` ON (`c`.`initiator` = `$sContentTable`.`$sContentField` $sWhere)",
         );
     }
 
+    public function getCommonContent($iInitiator1, $iInitiator2, $isMutual, $iStart, $iLimit, $iOrder) {        
+        $sWhereJoin = (false !== $isMutual) ? $this->prepare(" AND `c2`.`mutual` = ?", $isMutual) : '';
+        $sJoin = $this->prepare("INNER JOIN `" . $this->_sTable . "` AS `c2` ON (`c2`.`initiator` = ? AND `c`.`content` = `c2`.`content` $sWhereJoin)", $iInitiator2);
+
+        $sWhere = $this->prepare(" AND `c`.`initiator` = ?", $iInitiator1);
+        $sQuery = $this->_getConnectionsQuery($sWhere, $sJoin, '`c`.`content`', $isMutual, $iStart, $iLimit, $iOrder);
+
+        return $this->getColumn($sQuery);
+    }
+
     public function getConnectedContent ($iInitiator, $isMutual = false, $iStart = 0, $iLimit = BX_CONNECTIONS_LIST_LIMIT, $iOrder = BX_CONNECTIONS_ORDER_NONE) {
-        $sWhere = $this->prepare(" AND `initiator` = ?", $iInitiator);
-        $sQuery = $this->_getConnectionsQuery($sWhere, '`content`', $isMutual, $iStart, $iLimit, $iOrder);
+        $sWhere = $this->prepare(" AND `c`.`initiator` = ?", $iInitiator);
+        $sQuery = $this->_getConnectionsQuery($sWhere, '', '`c`.`content`', $isMutual, $iStart, $iLimit, $iOrder);
         return $this->getColumn($sQuery);
     }
 
     public function getConnectedInitiators ($iContent, $isMutual = false, $iStart = 0, $iLimit = BX_CONNECTIONS_LIST_LIMIT, $iOrder = BX_CONNECTIONS_ORDER_NONE) {
-        $sWhere = $this->prepare(" AND `content` = ?", $iContent);
-        $sQuery = $this->_getConnectionsQuery($sWhere, '`initiator`', $isMutual, $iStart, $iLimit, $iOrder);
+        $sWhere = $this->prepare(" AND `c`.`content` = ?", $iContent);
+        $sQuery = $this->_getConnectionsQuery($sWhere, '', '`c`.`initiator`', $isMutual, $iStart, $iLimit, $iOrder);
         return $this->getColumn($sQuery);
     }
 
-    protected function _getConnectionsQuery ($sWhere, $sFields = '*', $isMutual = false, $iStart = 0, $iLimit = BX_CONNECTIONS_LIST_LIMIT, $iOrder = BX_CONNECTIONS_ORDER_NONE) {
+    protected function _getConnectionsQuery ($sWhere, $sJoin = '', $sFields = '*', $isMutual = false, $iStart = 0, $iLimit = BX_CONNECTIONS_LIST_LIMIT, $iOrder = BX_CONNECTIONS_ORDER_NONE) {
+        $sOrder = $this->_getOrderClause($iOrder);
+
+        $sWhere .= (false !== $isMutual) ? $this->prepare(" AND `c`.`mutual` = ?", $isMutual) : '';
+
+        return $this->prepare("SELECT $sFields FROM `" . $this->_sTable . "` AS `c` $sJoin WHERE 1 $sWhere $sOrder LIMIT ?, ?", $iStart, $iLimit);
+    }
+
+    protected function _getOrderClause ($iOrder = BX_CONNECTIONS_ORDER_NONE, $sTable = '') {
+        if ($sTable)
+            $sTable .= '.';
         $sOrder = '';
         switch ($iOrder) {
         case BX_CONNECTIONS_ORDER_ADDED_ASC: 
-            $sOrder = 'ORDER BY `added` ASC';
+            $sOrder = "ORDER BY {$sTable}`added` ASC";
             break;
         case BX_CONNECTIONS_ORDER_ADDED_DESC: 
-            $sOrder = 'ORDER BY `added` DESC';
+            $sOrder = "ORDER BY {$sTable}`added` DESC";
             break;
         }
-
-        if (false !== $isMutual)
-            $sWhere .= $this->prepare(" AND `mutual` = ?", $isMutual);
-
-        return $this->prepare("SELECT $sFields FROM `" . $this->_sTable . "` WHERE 1 $sWhere $sOrder LIMIT ?, ?", $iStart, $iLimit);
+        return $sOrder;
     }
 
     public function getConnection ($iInitiator, $iContent) {

+ 5 - 2
inc/classes/BxDolSearch.php

@@ -411,16 +411,19 @@ class BxDolSearchResult implements iBxDolReplaceable
         if (isset($this->aCurrent['join']) && is_array($this->aCurrent['join'])) {
             $aSql = array('join'=>'', 'ownFields'=>'', 'joinFields'=>'', 'groupBy'=>'');
             foreach ($this->aCurrent['join'] as $sKey => $aValue) {
+                $sAlias = isset($aValue['table_alias']) ? $aValue['table_alias'] : $aValue['table'];
+                $sTableAlias = isset($aValue['table_alias']) ? " AS {$aValue['table_alias']} " : '';
+
                 if (is_array($aValue['joinFields'])) {
                     foreach ($aValue['joinFields'] as $sValue) {
-                        $aSql['joinFields'] .= $this->setFieldUnit($sValue, $aValue['table'], isset($aValue['operator']) ? $aValue['operator'] : null, $bRenameMode);
+                        $aSql['joinFields'] .= $this->setFieldUnit($sValue, $sAlias, isset($aValue['operator']) ? $aValue['operator'] : null, $bRenameMode);
                     }
                 }
                 // group by
                 if (isset($aValue['groupTable']))
                     $aSql['groupBy'] =  "GROUP BY `{$aValue['groupTable']}`.`{$aValue['groupField']}`, ";
                 $sOn = isset($aValue['mainTable']) ? $aValue['mainTable'] : $this->aCurrent['table'];
-                $aSql['join'] .= " {$aValue['type']} JOIN `{$aValue['table']}` ON `{$aValue['table']}`.`{$aValue['onField']}`=`$sOn`.`{$aValue['mainField']}`";
+                $aSql['join'] .= " {$aValue['type']} JOIN `{$aValue['table']}` $sTableAlias ON `{$sAlias}`.`{$aValue['onField']}`=`$sOn`.`{$aValue['mainField']}`";
                 $aSql['ownFields'] .= $this->setFieldUnit($aValue['mainField'], $sOn, '', $bRenameMode);
             }
             $aSql['joinFields'] = trim($aSql['joinFields'], ', ');

+ 3 - 2
modules/boonex/persons/classes/BxPersonsModule.php

@@ -86,14 +86,15 @@ class BxPersonsModule extends BxDolModule implements iBxDolProfileService {
         return $this->_serviceBrowse ('recent');
     }
 
-    public function serviceBrowseConnections ($iProfileId, $sObjectConnections = 'sys_profiles_friends', $sConnectionsType = 'content', $iMutual = false, $iDesignBox = BX_DB_PADDING_DEF) {
+    public function serviceBrowseConnections ($iProfileId, $sObjectConnections = 'sys_profiles_friends', $sConnectionsType = 'content', $iMutual = false, $iDesignBox = BX_DB_PADDING_DEF, $iProfileId2 = 0) {
         return $this->_serviceBrowse (
             'connections', 
             array(
                 'object' => $sObjectConnections,
                 'type' => $sConnectionsType,
                 'mutual' => $iMutual,
-                'profile' => (int)$iProfileId),  
+                'profile' => (int)$iProfileId,  
+                'profile2' => (int)$iProfileId2),
             $iDesignBox
         );
     }

+ 4 - 1
modules/boonex/persons/classes/BxPersonsSearchResult.php

@@ -68,7 +68,10 @@ class BxPersonsSearchResult extends BxTemplSearchResult {
                     if (isset($aParams['type']) && $aParams['type'] == 'initiators')
                         $sMethod = 'getConnectedInitiatorsAsCondition';
 
-                    $a = $oConnection->$sMethod('id', (int)$aParams['profile'], isset($aParams['mutual']) ? $aParams['mutual'] : false);
+                    if (isset($aParams['type']) && $aParams['type'] == 'common')
+                        $a = $oConnection->getCommonContentAsCondition('id', (int)$aParams['profile'], (int)$aParams['profile2'], isset($aParams['mutual']) ? $aParams['mutual'] : false);
+                    else
+                        $a = $oConnection->$sMethod('id', (int)$aParams['profile'], isset($aParams['mutual']) ? $aParams['mutual'] : false);
                     $this->aCurrent['restriction'] = array_merge($this->aCurrent['restriction'], $a['restriction']);
                     $this->aCurrent['join'] = array_merge($this->aCurrent['join'], $a['join']);
 

+ 17 - 1
samples/connections.php

@@ -75,12 +75,19 @@ function PageCompMainCode() {
         $iProfileId = $oDb->getOne($sQueryPrepared);
     }
 
+    $iProfileId2 = bx_get('id2');
+    if (!$iProfileId2) {
+        $sQueryOrig = "SELECT `id` FROM `sys_profiles` WHERE `type` = ? AND `status` = 'active' AND `id` != ? ORDER BY RAND() LIMIT 1";
+        $sQueryPrepared = $oDb->prepare($sQueryOrig, $sType, $iProfileId);
+        $iProfileId2 = $oDb->getOne($sQueryPrepared);
+    }
+
     bx_import('BxDolConnection');
     $oConnection = BxDolConnection::getObjectInstance($sObject);
     if (!$oConnection)
         die ("'$sObject' object is not defined.");
 
-    echo "<h1>Profile: $iProfileId</h1>";
+    echo "<h1>Profile: $iProfileId / another one: $iProfileId2 </h1>";
     echo '<hr class="bx-def-hr" />';
 
     switch($sMethod) {
@@ -88,6 +95,9 @@ function PageCompMainCode() {
         default:
         case 'array':
 
+            echo "<h2>Common Content (like mutual Friends between two initiators)</h2>";
+            echoDbg($oConnection->getCommonContent($iProfileId, $iProfileId2, 1));
+
             echo "<h2>Mutual Content (like Friends)</h2>";
             echoDbg($oConnection->getConnectedContent($iProfileId, 1));
     
@@ -119,6 +129,9 @@ function PageCompMainCode() {
                     echo "{$r['id']} - {$r['fullname']} <br />\n";
             };
 
+            echo "<h2>Common Content (like mutual Friends between two initiators)</h2>";
+            $f($oConnection->getCommonContentAsSQLParts('p', 'id', $iProfileId, $iProfileId2, 1));
+
             echo "<h2>Mutual Content (like Friends)</h2>";
             $f($oConnection->getConnectedContentAsSQLParts('p', 'id', $iProfileId, 1));
 
@@ -139,6 +152,9 @@ function PageCompMainCode() {
         break;
         case 'search-results':
 
+            echo "<h2>Common Content (like mutual Friends between two initiators)</h2>";
+            echo BxDolService::call('bx_persons', 'browse_connections', array($iProfileId, 'sys_profiles_friends', 'common', 1, BX_DB_CONTENT_ONLY, $iProfileId2));
+
             echo "<h2>Mutual Content (like Friends)</h2>";
             echo BxDolService::call('bx_persons', 'browse_connections', array($iProfileId, 'sys_profiles_friends', 'content', 1, BX_DB_CONTENT_ONLY));