Просмотр исходного кода

#5176 Speed improvements: cache for checkAllowedView calls

Alex Trofimov 1 год назад
Родитель
Сommit
dbca4bdf47

+ 17 - 0
inc/utils.inc.php

@@ -2861,4 +2861,21 @@ function bx_content_cache_obj()
     return $GLOBALS['bxCacheContentObj'] = $oCacheObject;
 }
 
+function bx_mem_cache_get($sKey)
+{
+    if(isset($GLOBALS['glMemCache']) && array_key_exists($sKey, $GLOBALS['glMemCache']) && !defined('BX_DOL_INSTALL') && !defined('BX_DOL_CRON_EXECUTE'))
+        return $GLOBALS['glMemCache'][$sKey];
+
+    return null;
+}
+
+function bx_mem_cache_set($sKey, $mixedData)
+{
+    if(!isset($GLOBALS['glMemCache']))
+        $GLOBALS['glMemCache'] = [];
+
+    return $GLOBALS['glMemCache'][$sKey] = $mixedData;
+}
+
+
 /** @} */

+ 24 - 13
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -20,6 +20,8 @@ bx_import('BxDolAcl');
  */
 class BxBaseModGeneralModule extends BxDolModule
 {
+    protected static $_aMemCacheData = [];
+
     protected $_bIsApi;
     protected $_iProfileId;
     protected $_aSearchableNamesExcept;
@@ -3663,7 +3665,7 @@ class BxBaseModGeneralModule extends BxDolModule
     }
 
     protected function _serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction, $iProfileId)
-    {
+    {        
         $CNF = &$this->_oConfig->CNF;
 
         if(!$iProfileId)
@@ -3672,23 +3674,32 @@ class BxBaseModGeneralModule extends BxDolModule
         if(empty($aDataEntry) || !is_array($aDataEntry))
             return _t('_sys_txt_not_found');
 
-        // moderator and owner always have access
-        if(!empty($iProfileId) && (abs($aDataEntry[$CNF['FIELD_AUTHOR']]) == (int)$iProfileId || $this->_isModeratorForProfile($isPerformAction, $iProfileId)))
+        if(!empty($iProfileId) && abs($aDataEntry[$CNF['FIELD_AUTHOR']]) == (int)$iProfileId)
             return CHECK_ACTION_RESULT_ALLOWED;
 
-        // check ACL
-        $aCheck = checkActionModule($iProfileId, 'view entry', $this->getName(), $isPerformAction);
-        if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
-            return $aCheck[CHECK_ACTION_MESSAGE];
+        // below goes mem cached response for current page load
 
-        // check privacy
-        if(!empty($CNF['OBJECT_PRIVACY_VIEW'])) {
-            $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
-            if ($oPrivacy && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']], $iProfileId))
-                return _t('_sys_access_denied_to_private_content');
+        $sCacheKey = $this->getName() . ':' . __CLASS__ . ':_checkAllowedViewForProfile:' . $aDataEntry[$CNF['FIELD_ID']] . ':' . $iProfileId;        
+        $mixedRet = bx_mem_cache_get($sCacheKey);
+        if (null !== $mixedRet)
+            return $mixedRet;
+
+        $mixedRet = CHECK_ACTION_RESULT_ALLOWED;
+
+        if (empty($iProfileId) || !$this->_isModeratorForProfile($isPerformAction, $iProfileId)) { // skip checking if moderator
+            $aCheck = checkActionModule($iProfileId, 'view entry', $this->getName(), $isPerformAction); 
+            if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED) { // check ACL
+                $mixedRet = $aCheck[CHECK_ACTION_MESSAGE];
+            } elseif(!empty($CNF['OBJECT_PRIVACY_VIEW'])) { // check privacy
+                $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
+                if ($oPrivacy && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']], $iProfileId))
+                    $mixedRet = _t('_sys_access_denied_to_private_content');
+            }
         }
 
-        return CHECK_ACTION_RESULT_ALLOWED;
+        bx_mem_cache_set($sCacheKey, $mixedRet);
+
+        return $mixedRet;
     }
 
     public function _serviceBrowse ($sMode, $aParams = false, $iDesignBox = BX_DB_PADDING_DEF, $bDisplayEmptyMsg = false, $bAjaxPaginate = true, $sClassSearchResult = 'SearchResult')

+ 29 - 9
modules/base/profile/classes/BxBaseModProfileModule.php

@@ -1639,11 +1639,20 @@ class BxBaseModProfileModule extends BxBaseModGeneralModule implements iBxDolCon
         if(empty($aDataEntry) || !is_array($aDataEntry))
             return _t('_sys_txt_not_found');
 
+        $sCacheKey = $this->getName() . ':' . __CLASS__ . ':serviceCheckAllowedViewForProfile:' . $aDataEntry['id'] . ':' . $iProfileId;
+        $mixedRet = bx_mem_cache_get($sCacheKey);
+        if (null !== $mixedRet)
+            return $mixedRet;
+        
         $oProfile = BxDolProfile::getInstanceByContentAndType($aDataEntry[$this->_oConfig->CNF['FIELD_ID']], $this->getName());
         if ($oProfile && $oProfile->id() == $iProfileId)
-            return CHECK_ACTION_RESULT_ALLOWED;
+            $mixedRet = CHECK_ACTION_RESULT_ALLOWED;
+        else
+            $mixedRet = parent::serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction, $iProfileId);
+
+        bx_mem_cache_set($sCacheKey, $mixedRet);
 
-        return parent::serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction, $iProfileId);
+        return $mixedRet;
     }
 
     /**
@@ -1780,18 +1789,29 @@ class BxBaseModProfileModule extends BxBaseModGeneralModule implements iBxDolCon
      * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden.
      */
     public function checkAllowedViewProfileImage ($aDataEntry, $isPerformAction = false)
-    {
+    {        
         $CNF = &$this->_oConfig->CNF;
 
+        $sCacheKey = $this->getName() . ':' . __CLASS__ . ':checkAllowedViewProfileImage:' . $aDataEntry[$CNF['FIELD_ID']];
+        $mixedRet = bx_mem_cache_get($sCacheKey);
+        if (null !== $mixedRet)
+            return $mixedRet;
+
         // check privacy
-        if (empty($CNF['OBJECT_PRIVACY_VIEW']) || isAdmin() || CHECK_ACTION_RESULT_ALLOWED === $this->checkAllowedEditAnyEntry())
-            return CHECK_ACTION_RESULT_ALLOWED;
+        
+        if (empty($CNF['OBJECT_PRIVACY_VIEW']) || isAdmin() || CHECK_ACTION_RESULT_ALLOWED === $this->checkAllowedEditAnyEntry()) {
+            $mixedRet = CHECK_ACTION_RESULT_ALLOWED;
+        } 
+        elseif (($oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW'])) && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']]) && !$oPrivacy->isPartiallyVisible($aDataEntry[$CNF['FIELD_ALLOW_VIEW_TO']])) {
+            $mixedRet = _t('_sys_access_denied_to_private_content');
+        }
+        else {
+            $mixedRet = CHECK_ACTION_RESULT_ALLOWED;
+        }
 
-        $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
-        if ($oPrivacy && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']]) && !$oPrivacy->isPartiallyVisible($aDataEntry[$CNF['FIELD_ALLOW_VIEW_TO']]))
-            return _t('_sys_access_denied_to_private_content');
+        bx_mem_cache_set($sCacheKey, $mixedRet);
 
-        return CHECK_ACTION_RESULT_ALLOWED;
+        return $mixedRet;
     }
 
     /**