public function measure(array $collectData = []): self
{
if (!$this->isMeasureAvailable())
{
$this->addError(new BitrixMainError('', self::ERROR_MEASURE_UNAVAILABLE));
return $this;
}
$connection = BitrixMainApplication::getConnection();
$indicatorType = $connection->getSqlHelper()->forSql(static::className());
$ownerId = (string)$this->getOwner();
$tableName = VolumeTable::getTableName();
$stageId = $this->getStage();
if (empty($stageId))
{
$stageId = 'UserFields';
$this->setStage($stageId);
}
switch($stageId)
{
case 'UserFields':
{
// Scan User fields specific to module
$entityUserFieldSource = $this->prepareUserFieldSourceSql(null, [CUserTypeFile::USER_TYPE_ID]);
if ($entityUserFieldSource != '')
{
$querySql = "
INSERT INTO {$tableName}
(
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
FILE_SIZE,
FILE_COUNT,
DISK_SIZE,
DISK_COUNT,
VERSION_COUNT
)
SELECT
'{$indicatorType}' as INDICATOR_TYPE,
{$ownerId} as OWNER_ID,
". $connection->getSqlHelper()->getCurrentDateTimeFunction(). " as CREATE_TIME,
'UserFields',
SUM(src.FILE_SIZE) as FILE_SIZE,
SUM(src.FILE_COUNT) as FILE_COUNT,
SUM(src.DISK_SIZE) as DISK_SIZE,
SUM(src.DISK_COUNT) as DISK_COUNT,
SUM(src.VERSION_COUNT) as VERSION_COUNT
FROM
(
{$entityUserFieldSource}
) src
";
$connection->queryExecute($querySql);
}
unset($querySql);
$this->setStage('ActElemFile');// go next
if (!$this->checkTimeEnd())
{
break;
}
}
case 'ActElemFile':
{
$crmActivityElememtTable = CCrmActivity::ELEMENT_TABLE_NAME;
$querySql = "
INSERT INTO {$tableName}
(
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
FILE_SIZE,
FILE_COUNT,
DISK_SIZE,
DISK_COUNT,
VERSION_COUNT
)
SELECT
'{$indicatorType}' as INDICATOR_TYPE,
{$ownerId} as OWNER_ID,
". $connection->getSqlHelper()->getCurrentDateTimeFunction(). " as CREATE_TIME,
'ActElemFile' as TITLE,
SUM(f.FILE_SIZE) as FILE_SIZE,
COUNT(f.id) as FILE_COUNT,
0 as DISK_SIZE,
0 as DISK_COUNT,
0 as VERSION_COUNT
FROM
b_file f
INNER JOIN (
SELECT ELEMENT_ID
FROM {$crmActivityElememtTable}
WHERE STORAGE_TYPE_ID = '".BitrixCrmIntegrationStorageType::File."'
GROUP BY ELEMENT_ID
ORDER BY NULL
) elem
ON elem.ELEMENT_ID = f.ID
";
$connection->queryExecute($querySql);
unset($querySql);
$this->setStage('ActElemDisk');// go next
if (!$this->checkTimeEnd())
{
break;
}
}
case 'ActElemDisk':
{
/**
* @param VolumeIVolumeIndicatorModule $indicator
* @return int[]
*/
$getExcludeFolderId = function ($indicator)
{
$folderIds = [];
$storageList = $indicator->getStorageList();
foreach ($storageList as $storage)
{
$folderList = $indicator->getFolderList($storage);
foreach ($folderList as $folder)
{
$folderIds[] = $folder->getId();
$childFolders = DiskInternalsFolderTable::getList([
'select' => ['ID'],
'filter' => [
'=TYPE' => DiskInternalsObjectTable::TYPE_FOLDER,
'=PATH_CHILD.PARENT_ID' => $folder->getId()
]
]);
foreach ($childFolders as $row)
{
$folderIds[] = $row['ID'];
}
}
}
return $folderIds;
};
// exclude CRM regular folders content
$excludeFolderIds = $getExcludeFolderId($this);
// exclude voximplant folders content
$vox = new VolumeModuleVoximplant();
$excludeFolderIds = array_merge($excludeFolderIds, $getExcludeFolderId($vox));
$excludeFolderSql = '';
if (count($excludeFolderIds) > 0)
{
$excludeFolderSql = '
AND files.PARENT_ID NOT IN(
SELECT object_id FROM b_disk_object_path
WHERE PARENT_id IN('. implode(',', $excludeFolderIds). ')
)
';
}
$crmActivityElememtTable = CCrmActivity::ELEMENT_TABLE_NAME;
$querySql = "
INSERT INTO {$tableName}
(
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
FILE_SIZE,
FILE_COUNT,
DISK_SIZE,
DISK_COUNT,
VERSION_COUNT
)
SELECT
'{$indicatorType}' as INDICATOR_TYPE,
{$ownerId} as OWNER_ID,
". $connection->getSqlHelper()->getCurrentDateTimeFunction(). " as CREATE_TIME,
'ActElemDisk' as TITLE,
SUM(f.FILE_SIZE) as FILE_SIZE,
COUNT(f.id) as FILE_COUNT,
SUM(f.FILE_SIZE) as DISK_SIZE,
COUNT(f.id) as DISK_COUNT,
COUNT(f.id) as VERSION_COUNT
FROM
b_disk_object files
INNER JOIN b_file f
ON files.FILE_ID = f.ID
INNER JOIN
(
SELECT ELEMENT_ID
FROM {$crmActivityElememtTable}
WHERE STORAGE_TYPE_ID = '".BitrixCrmIntegrationStorageType::Disk."'
GROUP BY ELEMENT_ID
ORDER BY NULL
) elem
ON files.ID = elem.ELEMENT_ID
WHERE
files.TYPE = '".DiskInternalsObjectTable::TYPE_FILE."'
AND files.ID = files.REAL_OBJECT_ID
{$excludeFolderSql}
";
$connection->queryExecute($querySql);
unset($querySql);
$this->setStage('CrmEvent');// go next
if (!$this->checkTimeEnd())
{
break;
}
}
case 'CrmEvent':
{
$crmEventTable = BitrixCrmEventTable::getTableName();
// analise b_crm_event with non empty field FILES
$querySql = "
INSERT INTO {$tableName}
(
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
FILE_SIZE,
FILE_COUNT,
DISK_SIZE,
DISK_COUNT,
VERSION_COUNT
)
SELECT
'{$indicatorType}' as INDICATOR_TYPE,
{$ownerId} as OWNER_ID,
". $connection->getSqlHelper()->getCurrentDateTimeFunction(). " as CREATE_TIME,
'CrmEvent' as TITLE,
SUM(f.FILE_SIZE) as FILE_SIZE,
count(f.ID) as FILE_COUNT,
0 as DISK_SIZE,
0 as DISK_COUNT,
0 as VERSION_COUNT
FROM
(
select
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(src.fids, ' ', NS.n), ' ', -1) AS UNSIGNED) as ID
from (
select 1 as n union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10 union
select 11 union
select 12 union
select 13 union
select 14 union
select 15 union
select 16 union
select 17 union
select 18 union
select 19 union
select 20
) NS
inner join
(
select
@xml := replace(
replace(
replace(
replace(
e.FILES,
'a:',''
),
';}',''
),
':{i:',''
),
';i:',''
) as xml,
CAST(ExtractValue(@xml, '/a/len') AS UNSIGNED) as len,
ExtractValue(@xml, '/a/i[position() mod 2 = 0]') as fids
from
{$crmEventTable} e
where
e.FILES is not null
and e.FILES <> ''
and e.FILES <> 'a:0:{}'
) src
ON NS.n <= src.len
) file_ids
INNER JOIN b_file f
ON file_ids.ID = f.ID
";
$connection->queryExecute($querySql);
unset($querySql);
$this->setStage('CrmFolder');// go next
if (!$this->checkTimeEnd())
{
break;
}
}
case 'CrmFolder':
{
// Scan specific folder list in a storage
VolumeTable::createTemporally();
$temporallyTableName = VolumeTable::getTemporallyName();
$storageList = $this->getStorageList();
foreach ($storageList as $storage)
{
$storageId = $storage->getId();
$parentId = $storage->getRootObjectId();
$folderIds = [];
$folders = $this->getFolderList($storage);
foreach ($folders as $folder)
{
$folderIds[] = $folder->getId();
}
if (count($folderIds) > 0)
{
$agr = new VolumeFolderTree;
$agr
->setOwner($this->getOwner())
->addFilter('STORAGE_ID', $storageId)
->addFilter('@FOLDER_ID', $folderIds)
->purify()
->measure([self::DISK_FILE]);
$indicatorTypeFolder = $connection->getSqlHelper()->forSql(VolumeFolder::className());
$folderIdSql = implode(',', $folderIds);
$querySql = "
INSERT INTO {$temporallyTableName}
(
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
FILE_SIZE,
FILE_COUNT,
DISK_SIZE,
DISK_COUNT,
VERSION_COUNT,
ATTACHED_COUNT,
LINK_COUNT,
SHARING_COUNT,
UNNECESSARY_VERSION_SIZE,
UNNECESSARY_VERSION_COUNT
)
SELECT
'{$indicatorType}',
{$ownerId},
".$connection->getSqlHelper()->getCurrentDateTimeFunction()." as CREATE_TIME,
'CrmFolder' as TITLE,
SUM(FILE_SIZE),
SUM(FILE_COUNT),
SUM(DISK_SIZE),
SUM(DISK_COUNT),
SUM(VERSION_COUNT),
SUM(ATTACHED_COUNT),
SUM(LINK_COUNT),
SUM(SHARING_COUNT),
SUM(UNNECESSARY_VERSION_SIZE),
SUM(UNNECESSARY_VERSION_COUNT)
FROM
b_disk_volume
WHERE
INDICATOR_TYPE = '{$indicatorTypeFolder}'
and OWNER_ID = {$ownerId}
and STORAGE_ID = '{$storageId}'
and FOLDER_ID IN( {$folderIdSql} )
and PARENT_ID = '{$parentId}'
";
$connection->queryExecute($querySql);
unset($querySql);
}
}
$querySql = "
SELECT
INDICATOR_TYPE,
OWNER_ID,
CREATE_TIME,
TITLE,
SUM(FILE_SIZE),
SUM(FILE_COUNT),
SUM(DISK_SIZE),
SUM(DISK_COUNT),
SUM(VERSION_COUNT),
SUM(ATTACHED_COUNT),
SUM(LINK_COUNT),
SUM(SHARING_COUNT),
SUM(UNNECESSARY_VERSION_SIZE),
SUM(UNNECESSARY_VERSION_COUNT)
FROM
{$temporallyTableName}
WHERE
INDICATOR_TYPE = '{$indicatorType}'
GROUP BY
INDICATOR_TYPE
ORDER BY NULL
";
$columnList = VolumeQueryHelper::prepareInsert(
[
'INDICATOR_TYPE',
'OWNER_ID',
'CREATE_TIME',
'TITLE',
'FILE_SIZE',
'FILE_COUNT',
'DISK_SIZE',
'DISK_COUNT',
'VERSION_COUNT',
'ATTACHED_COUNT',
'LINK_COUNT',
'SHARING_COUNT',
'UNNECESSARY_VERSION_SIZE',
'UNNECESSARY_VERSION_COUNT',
],
$this->getSelect()
);
$connection->queryExecute("INSERT INTO {$tableName} ({$columnList}) {$querySql}");
VolumeTable::clearTemporally();
$this->setStage(null);
}
}
return $this;
}