Esempio n. 1
0
 /**
  * Получить число сущностей по связанной таблице
  *
  * @param array  $aJoinData      Фильтр
  * @param string $sEntityFull    Название класса сущности
  *
  * @return int
  */
 public function GetCountItemsByJoinTable($aJoinData = array(), $sEntityFull = null)
 {
     if (is_null($sEntityFull)) {
         $sEntityFull = E::GetPluginPrefix($this) . 'Module' . E::GetModuleName($this) . '_Entity' . E::GetModuleName(get_class($this));
     } elseif (!substr_count($sEntityFull, '_')) {
         $sEntityFull = E::GetPluginPrefix($this) . 'Module' . E::GetModuleName($this) . '_Entity' . $sEntityFull;
     }
     // Если параметр #cache указан и пуст, значит игнорируем кэширование для запроса
     if (array_key_exists('#cache', $aJoinData) && !$aJoinData['#cache']) {
         $iCount = $this->oMapper->GetCountItemsByJoinTable($aJoinData, $sEntityFull);
     } else {
         $sEntityFullRoot = E::ModulePlugin()->GetRootDelegater('entity', $sEntityFull);
         $sCacheKey = $sEntityFullRoot . '_count_items_by_join_table_' . serialize($aJoinData);
         $aCacheTags = array();
         $iCacheTime = 60 * 60 * 24;
         // скорее лучше хранить в свойстве сущности, для возможности выборочного переопределения
         // переопределяем из параметров
         if (isset($aJoinData['#cache'][0])) {
             $sCacheKey = $aJoinData['#cache'][0];
         }
         if (isset($aJoinData['#cache'][1])) {
             $aCacheTags = $aJoinData['#cache'][1];
         }
         if (isset($aJoinData['#cache'][2])) {
             $iCacheTime = $aJoinData['#cache'][2];
         }
         $aCacheTags[] = 'm2m_' . $aJoinData['#relation_key'] . $aJoinData['#by_key'] . $aJoinData['#by_value'];
         if (false === ($iCount = E::ModuleCache()->Get($sCacheKey))) {
             $iCount = $this->oMapper->GetCountItemsByJoinTable($aJoinData, $sEntityFull);
             E::ModuleCache()->Set($iCount, $sCacheKey, $aCacheTags, $iCacheTime);
         }
     }
     return $iCount;
 }
Esempio n. 2
0
 /**
  * Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
  * Также производит обработку методов set* и get*
  * Учитывает связи и может возвращать связанные данные
  *
  * @see Engine::_CallModule
  *
  * @param string $sName Имя метода
  * @param array  $aArgs Аргументы
  *
  * @return mixed
  */
 public function __call($sName, $aArgs)
 {
     $sType = substr($sName, 0, strpos(F::StrUnderscore($sName), '_'));
     if (!strpos($sName, '_') && in_array($sType, array('get', 'set', 'reload'))) {
         $sKey = F::StrUnderscore(preg_replace('/' . $sType . '/', '', $sName, 1));
         if ($sType == 'get') {
             if (isset($this->_aData[$sKey])) {
                 return $this->_aData[$sKey];
             } else {
                 $sField = $this->_getField($sKey);
                 if ($sField != $sKey && isset($this->_aData[$sField])) {
                     return $this->_aData[$sField];
                 }
             }
             /**
              * Проверяем на связи
              */
             if (array_key_exists($sKey, $this->aRelations)) {
                 $sEntityRel = $this->aRelations[$sKey][1];
                 $sRelationType = $this->aRelations[$sKey][0];
                 $sRelationKey = $this->aRelations[$sKey][2];
                 $sRelationJoinTable = null;
                 $sRelationJoinTableKey = 0;
                 // foreign key в join-таблице для текущей сущности
                 if ($sRelationType == self::RELATION_TYPE_MANY_TO_MANY && array_key_exists(3, $this->aRelations[$sKey])) {
                     $sRelationJoinTable = $this->aRelations[$sKey][3];
                     $sRelationJoinTableKey = isset($this->aRelations[$sKey][4]) ? $this->aRelations[$sKey][4] : $this->_getPrimaryKey();
                 }
                 /**
                  * Если связь уже загруженна, то возвращаем сразу результат
                  */
                 if (array_key_exists($sKey, $this->aRelationsData)) {
                     return $this->aRelationsData[$sKey];
                 }
                 $sRelModuleName = E::GetModuleName($sEntityRel);
                 $sRelEntityName = E::GetEntityName($sEntityRel);
                 $sRelPluginPrefix = E::GetPluginPrefix($sEntityRel);
                 $sRelPrimaryKey = 'id';
                 if ($oRelEntity = E::GetEntity($sEntityRel)) {
                     $sRelPrimaryKey = $oRelEntity->_getPrimaryKey();
                 }
                 $iPrimaryKeyValue = $this->getProp($this->_getPrimaryKey());
                 $sCmd = '';
                 $mCmdArgs = array();
                 switch ($sRelationType) {
                     case self::RELATION_TYPE_BELONGS_TO:
                         $sCmd = "{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}By" . F::StrCamelize($sRelPrimaryKey);
                         $mCmdArgs = $this->getProp($sRelationKey);
                         break;
                     case self::RELATION_TYPE_HAS_ONE:
                         $sCmd = "{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}By" . F::StrCamelize($sRelationKey);
                         $mCmdArgs = $iPrimaryKeyValue;
                         break;
                     case self::RELATION_TYPE_HAS_MANY:
                         $sCmd = "{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ItemsByFilter";
                         $mCmdArgs = array($sRelationKey => $iPrimaryKeyValue);
                         break;
                     case self::RELATION_TYPE_MANY_TO_MANY:
                         $sCmd = "{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
                         $mCmdArgs = array('#join_table' => Config::Get($sRelationJoinTable), '#relation_key' => $sRelationKey, '#by_key' => $sRelationJoinTableKey, '#by_value' => $iPrimaryKeyValue, '#index-from-primary' => true);
                         break;
                     default:
                         break;
                 }
                 // Нужно ли учитывать дополнительный фильтр
                 $bUseFilter = is_array($mCmdArgs) && array_key_exists(0, $aArgs) && is_array($aArgs[0]);
                 if ($bUseFilter) {
                     $mCmdArgs = array_merge($mCmdArgs, $aArgs[0]);
                 }
                 $aCallArgs = array($mCmdArgs);
                 $res = E::GetInstance()->_CallModule($sCmd, $aCallArgs);
                 // Сохраняем данные только в случае "чистой" выборки
                 if (!$bUseFilter) {
                     $this->aRelationsData[$sKey] = $res;
                 }
                 // Создаём объекты-обёртки для связей MANY_TO_MANY
                 if ($sRelationType == self::RELATION_TYPE_MANY_TO_MANY) {
                     $this->_aManyToManyRelations[$sKey] = new LS_ManyToManyRelation($res);
                 }
                 return $res;
             }
             return null;
         } elseif ($sType == 'set' && array_key_exists(0, $aArgs)) {
             if (array_key_exists($sKey, $this->aRelations)) {
                 $this->aRelationsData[$sKey] = $aArgs[0];
             } else {
                 $this->_aData[$this->_getField($sKey)] = $aArgs[0];
             }
         } elseif ($sType == 'reload') {
             if (array_key_exists($sKey, $this->aRelationsData)) {
                 unset($this->aRelationsData[$sKey]);
                 return $this->__call('get' . F::StrCamelize($sKey), $aArgs);
             }
         }
     } else {
         return E::getInstance()->_CallModule($sName, $aArgs);
     }
 }