%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/components/bitrix/lists.export.excel/ |
Current File : /home/bitrix/www/bitrix/components/bitrix/lists.export.excel/class.php |
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); use Bitrix\Main\Localization\Loc; use Bitrix\Main\Loader; use Bitrix\Main\SystemException; class ListExportExcelComponent extends CBitrixComponent { protected $listsPerm; protected $arIBlock = array(); public function onIncludeComponentLang() { $this->includeComponentLang(basename(__FILE__)); Loc::loadMessages(__FILE__); } protected function checkModules() { if(!Loader::includeModule('lists')) throw new SystemException(Loc::getMessage('CC_BLL_MODULE_NOT_INSTALLED')); $this->arResult['BIZPROC'] = (bool)Loader::includeModule('bizproc') && CBPRuntime::isFeatureEnabled(); $this->arResult['DISK'] = (bool)Loader::includeModule('disk'); } public function onPrepareComponentParams($params) { if(!Loader::includeModule('lists')) return $params; $this->arIBlock = CIBlock::GetArrayByID($params["IBLOCK_ID"]); $this->arResult["IBLOCK"] = $this->arIBlock; $this->arResult["IBLOCK_ID"] = $this->arIBlock["ID"]; $this->arResult["GRID_ID"] = "lists_list_elements_".$this->arResult["IBLOCK_ID"]; $this->arResult["FILTER_ID"] = "lists_list_elements_".$this->arResult["IBLOCK_ID"]; $this->arResult["ANY_SECTION"] = isset($_GET["list_section_id"]) && strlen($_GET["list_section_id"]) == 0; $sectionUpperUrl = CHTTP::urlAddParams(str_replace(array("#list_id#", "#section_id#", "#group_id#"), array($this->arResult["IBLOCK_ID"], 0, $params["SOCNET_GROUP_ID"]), $params['LIST_URL']), array('list_section_id' => "")); $this->arResult["SECTIONS"] = array( array( "NAME" => GetMessage("CC_BLL_UPPER_LEVEL"), "NAME_HTML" => '<a href="'.$sectionUpperUrl .'">'.GetMessage("CC_BLL_UPPER_LEVEL").'</a>', ) ); $this->arResult["SECTION_ID"] = false; $this->arResult["PARENT_SECTION_ID"] = false; $this->arResult["LIST_SECTIONS"] = array(); $this->arResult["SECTION_PATH"] = array(); if (isset($_GET["list_section_id"])) $sectionId = intval($_GET["list_section_id"]); else $sectionId = intval($params["SECTION_ID"]); $rsSections = CIBlockSection::GetList( array("left_margin" => "asc"), array("IBLOCK_ID" => $this->arIBlock["ID"], "GLOBAL_ACTIVE" => "Y", "CHECK_PERMISSIONS" => "Y") ); while ($arSection = $rsSections->GetNext()) { if($sectionId && !$this->arResult["SECTION"]) { while(count($this->arResult["SECTION_PATH"]) && $arSection["DEPTH_LEVEL"] <= $this->arResult["SECTION_PATH"] [count($this->arResult["SECTION_PATH"])-1]["DEPTH_LEVEL"]) array_pop($this->arResult["SECTION_PATH"]); if(!count($this->arResult["SECTION_PATH"])|| $arSection["DEPTH_LEVEL"] > $this->arResult["SECTION_PATH"] [count($this->arResult["SECTION_PATH"])-1]["DEPTH_LEVEL"]) array_push($this->arResult["SECTION_PATH"], $arSection); } if($arSection["ID"] == $sectionId) { $this->arResult["SECTION"] = $arSection; $this->arResult["SECTION_ID"] = intval($arSection["ID"]); $this->arResult["PARENT_SECTION_ID"] = $arSection["IBLOCK_SECTION_ID"]; } $this->arResult["LIST_SECTIONS"][$arSection["ID"]] = str_repeat(" . ", $arSection["DEPTH_LEVEL"]).$arSection["NAME"]; $this->arResult["~LIST_SECTIONS"][$arSection["ID"]] = str_repeat(" . ", $arSection["DEPTH_LEVEL"]).$arSection["~NAME"]; $sectionUrl = CHTTP::URN2URI(CHTTP::urlAddParams(str_replace(array("#list_id#", "#section_id#", "#group_id#"), array($this->arResult["IBLOCK_ID"], 0, $params["SOCNET_GROUP_ID"]), $params['LIST_URL']), array('list_section_id' => $arSection["ID"]))); $this->arResult["SECTIONS"][$arSection["ID"]] = array( "ID" => $arSection["ID"], "NAME" => $arSection["NAME"], "LIST_URL" => str_replace( array("#list_id#", "#section_id#", "#group_id#"), array($arSection["IBLOCK_ID"], $arSection["ID"], $params["SOCNET_GROUP_ID"]), $params['LIST_URL'] ), "PARENT_ID" => intval($arSection["IBLOCK_SECTION_ID"]), "SECTION_URL" => $sectionUrl, "NAME_HTML_LABLE" => '<a href="'.$sectionUrl .'">'.htmlspecialcharsbx($arSection["~NAME"]).'</a>', "NAME_HTML" => '<a href="'.$sectionUrl .'">'.htmlspecialcharsbx(str_repeat( " . ", ($arSection["DEPTH_LEVEL"])).$arSection["~NAME"]).'</a>', "DEPTH_LEVEL" => intval($arSection["DEPTH_LEVEL"]) ); } $this->arResult["IS_SOCNET_GROUP_CLOSED"] = false; if ( intval($params["~SOCNET_GROUP_ID"]) > 0 && CModule::IncludeModule("socialnetwork") ) { $arSonetGroup = CSocNetGroup::GetByID(intval($params["~SOCNET_GROUP_ID"])); if ( is_array($arSonetGroup) && $arSonetGroup["CLOSED"] == "Y" && !CSocNetUser::IsCurrentUserModuleAdmin() && ( $arSonetGroup["OWNER_ID"] != $GLOBALS["USER"]->GetID() || COption::GetOptionString("socialnetwork", "work_with_closed_groups", "N") != "Y" ) ) { $this->arResult["IS_SOCNET_GROUP_CLOSED"] = true; } } return $params; } public function executeComponent() { try { $this->checkModules(); $this->checkPermissions(); $this->setFrameMode(false); global $APPLICATION; $this->createDataExcel(); $APPLICATION->RestartBuffer(); header("Content-Type: application/vnd.ms-excel"); header("Content-Disposition: filename=list_".$this->arIBlock["ID"].".xls"); $this->IncludeComponentTemplate(); $r = $APPLICATION->EndBufferContentMan(); echo $r; include($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php"); die(); } catch (SystemException $exception) { ShowError($exception->getMessage()); } } protected function checkPermissions() { global $USER; $this->listsPerm = CListPermissions::checkAccess( $USER, $this->arParams['IBLOCK_TYPE_ID'], $this->arResult['IBLOCK_ID'], $this->arParams['SOCNET_GROUP_ID'] ); if($this->listsPerm < 0) { switch($this->listsPerm) { case CListPermissions::WRONG_IBLOCK_TYPE: throw new SystemException(Loc::getMessage('CC_BLL_WRONG_IBLOCK_TYPE')); case CListPermissions::WRONG_IBLOCK: throw new SystemException(Loc::getMessage('CC_BLL_WRONG_IBLOCK')); case CListPermissions::LISTS_FOR_SONET_GROUP_DISABLED: throw new SystemException(Loc::getMessage('CC_BLL_LISTS_FOR_SONET_GROUP_DISABLED')); default: throw new SystemException(Loc::getMessage('CC_BLL_UNKNOWN_ERROR')); } } elseif( $this->listsPerm < CListPermissions::CAN_READ && !( CIBlockRights::UserHasRightTo($this->arResult['IBLOCK_ID'],$this->arResult['IBLOCK_ID'],'element_read') || CIBlockSectionRights::UserHasRightTo( $this->arResult["IBLOCK_ID"], $this->arResult["SECTION_ID"], "section_element_bind") ) ) { throw new SystemException(Loc::getMessage("CC_BLL_ACCESS_DENIED")); } if(!( !$this->arResult["IS_SOCNET_GROUP_CLOSED"] && ($this->listsPerm > CListPermissions::CAN_READ || CIBlockSectionRights::UserHasRightTo($this->arResult["IBLOCK_ID"], $this->arResult["SECTION_ID"], "element_read") || CIBlockSectionRights::UserHasRightTo($this->arResult["IBLOCK_ID"], $this->arResult["SECTION_ID"], "section_element_bind") ) )) { throw new SystemException(Loc::getMessage("CC_BLL_ACCESS_DENIED")); } } protected function createDataExcel() { $obList = new CList($this->arIBlock["ID"]); $gridOptions = new CGridOptions($this->arResult["GRID_ID"]); $gridColumns = $gridOptions->GetVisibleColumns(); $gridSort = $gridOptions->GetSorting(array("sort" => array("name" => "asc"))); $this->arResult["ELEMENTS_HEADERS"] = array(); $arSelect = array("ID", "IBLOCK_ID"); $arProperties = array(); $this->arResult["FIELDS"] = $arListFields = $obList->GetFields(); $filterable = array(); $dateFilter = array(); $customFilter = array(); foreach ($arListFields as $fieldId => $arField) { if (!count($gridColumns) || in_array($fieldId, $gridColumns)) { if (substr($fieldId, 0, 9) == "PROPERTY_") $arProperties[] = $fieldId; else $arSelect[] = $fieldId; } if ($fieldId == "CREATED_BY") $arSelect[] = "CREATED_USER_NAME"; if ($fieldId == "MODIFIED_BY") $arSelect[] = "USER_NAME"; $this->arResult["ELEMENTS_HEADERS"][$fieldId] = $arField["NAME"]; $preparedField = Bitrix\Lists\Field::prepareFieldDataForFilter($arField); $filterable[$preparedField["id"]] = $preparedField["filterable"]; if(!empty($preparedField["dateFilter"])) $dateFilter[$preparedField["id"]] = true; if(!empty($preparedField["customFilter"])) $customFilter[$preparedField["id"]] = $preparedField["customFilter"]; } if (!count($gridColumns) || in_array("IBLOCK_SECTION_ID", $gridColumns)) { $arSelect[] = "IBLOCK_SECTION_ID"; $this->arResult["ELEMENTS_HEADERS"]["IBLOCK_SECTION_ID"] = Loc::getMessage("CC_BLL_COLUMN_SECTION"); } $arFilter = array(); $filterOption = new \Bitrix\Main\UI\Filter\Options($this->arResult["FILTER_ID"]); $filterData = $filterOption->getFilter(); global $DB; foreach($filterData as $key => $value) { if (is_array($value)) { if (empty($value)) continue; } elseif(strlen($value) <= 0) continue; if(substr($key, -5) == "_from") { $new_key = substr($key, 0, -5); $op = (!empty($filterData[$new_key."_numsel"]) && $filterData[$new_key."_numsel"] == "more") ? ">" : ">="; } elseif(substr($key, -3) == "_to") { $new_key = substr($key, 0, -3); $op = (!empty($filterData[$new_key."_numsel"]) && $filterData[$new_key."_numsel"] == "less") ? "<" : "<="; if(array_key_exists($new_key, $dateFilter)) { $dateFormat = $DB->dateFormatToPHP(Csite::getDateFormat()); $dateParse = date_parse_from_format($dateFormat, $value); if(!strlen($dateParse["hour"]) && !strlen($dateParse["minute"]) && !strlen($dateParse["second"])) { $timeFormat = $DB->dateFormatToPHP(CSite::getTimeFormat()); $value .= " ".date($timeFormat, mktime(23, 59, 59, 0, 0, 0)); } } } elseif($key == 'list_section_id') { $this->arResult["ANY_SECTION"] = false; $this->arResult["SECTION_ID"] = $value; } else { $op = ""; $new_key = $key; } if($key == "CREATED_BY" || $key == "MODIFIED_BY") { if(!intval($value)) { $userId = array(); $userQuery = CUser::GetList( $by = "ID", $order = "ASC", array("NAME" => $value), array("FIELDS" => array("ID")) ); while($user = $userQuery->fetch()) $userId[] = $user["ID"]; if(!empty($userId)) $value = $userId; } } if(array_key_exists($new_key, $filterable)) { if($op == "") $op = $filterable[$new_key]; $arFilter[$op.$new_key] = $value; } if($key == "FIND") { $op = "?"; $arFilter[$op."SEARCHABLE_CONTENT"] = $value; } } foreach($customFilter as $fieldId => $callback) { $filtered = false; call_user_func_array($callback, array( $this->arResult["FIELDS"][$fieldId], array( "VALUE" => $fieldId, "FILTER_ID" => $this->arResult["FILTER_ID"], ), &$arFilter, &$filtered, )); } $arFilter["IBLOCK_ID"] = $this->arIBlock["ID"]; if($this->arParams["CAN_EDIT"]) $arFilter["SHOW_NEW"] = "Y"; $arFilter["CHECK_PERMISSIONS"] = $this->listsPerm >= CListPermissions::CAN_READ ? "N" : "Y"; if(!$this->arResult["ANY_SECTION"]) { $listChildSection = array(); CLists::getChildSection($this->arResult["SECTION_ID"], $this->arResult["SECTIONS"], $listChildSection); $arFilter["SECTION_ID"] = $listChildSection; } $this->arResult["EXCEL_COLUMN_NAME"] = array(); $this->arResult["EXCEL_CELL_VALUE"] = array(); $count = 0; $comments = in_array("COMMENTS", $gridColumns) && CModule::includeModule("forum"); $listValues = array(); $rsElements = CIBlockElement::GetList( $gridSort["sort"], $arFilter, false, false, $arSelect); $regexp = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/'; while($obElement = $rsElements->GetNextElement()) { $data = $obElement->GetFields(); if(!is_array($data)) continue; if(!is_array($listValues[$data["ID"]])) $listValues[$data["ID"]] = array(); foreach($data as $fieldId => $fieldValue) $listValues[$data["ID"]][$fieldId] = $fieldValue; if(!empty($arProperties)) { $propertyValuesObject = \CIblockElement::getPropertyValues( $data["IBLOCK_ID"], array("ID" => $data["ID"], "SHOW_NEW" => "Y")); while($propertyValues = $propertyValuesObject->fetch()) { foreach($propertyValues as $propertyId => $propertyValue) { if($propertyId == "IBLOCK_ELEMENT_ID") continue; $listValues[$data["ID"]]['PROPERTY_'.$propertyId] = $propertyValue; } } } foreach($this->arResult["FIELDS"] as $fieldId => $field) { switch($field["TYPE"]) { case "S:DiskFile": $field["CONTROL_SETTINGS"]["MODE"] = "EXCEL_EXPORT"; break; case "S:map_yandex": $field["CONTROL_SETTINGS"]["MODE"] = "CSV_EXPORT"; break; case "S:ECrm": $field["CONTROL_SETTINGS"]["MODE"] = "EXCEL_EXPORT"; break; } $valueKey = (substr($fieldId, 0, 9) == "PROPERTY_") ? $fieldId : "~".$fieldId; $field["VALUE"] = $listValues[$data["ID"]][$valueKey]; $data[$fieldId] = \Bitrix\Lists\Field::renderField($field); } if(!empty($data["IBLOCK_SECTION_ID"]) && array_key_exists($data["IBLOCK_SECTION_ID"], $this->arResult["SECTIONS"])) { $iblockSectionId = $data["IBLOCK_SECTION_ID"]; $sectionName = array(); $data["IBLOCK_SECTION_ID"] = $this->arResult["SECTIONS"][0]["NAME_HTML"]; $parentId = $this->arResult["SECTIONS"][$iblockSectionId]["PARENT_ID"]; if($parentId) { for($count = 1; $count < $this->arResult["SECTIONS"][$iblockSectionId]["DEPTH_LEVEL"]; $count++) { foreach($this->arResult["SECTIONS"] as $sectionId => $sectionData) { if($sectionId == $parentId) { $sectionName[] = $sectionData["NAME_HTML"]; if($sectionData["PARENT_ID"]) $parentId = $sectionData["PARENT_ID"]; } } } krsort($sectionName); foreach($sectionName as $name) $data["IBLOCK_SECTION_ID"] .= "<br>".$name; } $data["IBLOCK_SECTION_ID"] .= "<br>".$this->arResult["SECTIONS"][$iblockSectionId]["NAME_HTML"]; } if(in_array("BIZPROC", $gridColumns)) $data["BIZPROC"] = $this->getArrayBizproc($data); if($comments) $countComments = $this->getCommentsProcess($data["ID"]); if (empty($gridColumns)) { $gridColumns = array_keys($arListFields); } if (in_array("IBLOCK_SECTION_ID", $arSelect) && !in_array("IBLOCK_SECTION_ID", $gridColumns)) { $gridColumns[] = "IBLOCK_SECTION_ID"; } foreach ($gridColumns as $position => $id) { if($id == "COMMENTS") { if($comments) $data[$id] = $countComments; else continue; } if(is_array($data[$id])) continue; if(preg_match_all($regexp, $data[$id], $matches, PREG_SET_ORDER)) { foreach($matches as $match) { $fullLink = CHTTP::URN2URI($match[1]); $data[$id] = str_replace($match[1], $fullLink, $data[$id]); } } $this->arResult["EXCEL_CELL_VALUE"][$count][$position] = is_array($data[$id]) ? implode('/', $data[$id]) : $data[$id]; $this->arResult["EXCEL_COLUMN_NAME"][$position] = $this->arResult["ELEMENTS_HEADERS"][$id]; } $count++; } } protected function getArrayBizproc($data = array()) { if(!$this->arResult["BIZPROC"]) return ''; $currentUserId = $GLOBALS["USER"]->GetID(); $html = ""; if ($this->arResult["IBLOCK"]["BIZPROC"] == "Y") { $this->arResult["ELEMENTS_HEADERS"]["BIZPROC"] = Loc::getMessage("CC_BLL_COLUMN_BIZPROC"); $arDocumentStates = CBPDocument::GetDocumentStates( BizprocDocument::generateDocumentComplexType( $this->arParams["IBLOCK_TYPE_ID"], $this->arResult["IBLOCK_ID"]), BizprocDocument::getDocumentComplexId($this->arParams["IBLOCK_TYPE_ID"], $data["ID"]) ); $userGroups = $GLOBALS["USER"]->GetUserGroupArray(); if ($data["~CREATED_BY"] == $currentUserId) $userGroups[] = "Author"; $arUserGroupsForBP = CUser::GetUserGroup($currentUserId); $ii = 0; foreach ($arDocumentStates as $workflowId => $workflowState) { $canViewWorkflow = BizprocDocument::canUserOperateDocument( CBPCanUserOperateOperation::ViewWorkflow, $currentUserId, $data["ID"], array( "IBlockPermission" => $this->listsPerm, "AllUserGroups" => $arUserGroupsForBP, "DocumentStates" => $arDocumentStates, "WorkflowId" => $workflowId, ) ); if (!$canViewWorkflow) continue; if (strlen($workflowState["TEMPLATE_NAME"]) > 0) $html .= "".$workflowState["TEMPLATE_NAME"].":\r\n"; else $html .= "".(++$ii).":\r\n"; $html .= "".(strlen($workflowState["STATE_TITLE"]) > 0 ? $workflowState["STATE_TITLE"] : $workflowState["STATE_NAME"])."\r\n"; } } return $html; } protected function getCommentsProcess($elementId) { $countComments = 0; $this->arResult["ELEMENTS_HEADERS"]["COMMENTS"] = Loc::getMessage("CC_BLL_COMMENTS"); if(!$this->arResult["BIZPROC"] || !$elementId) return $countComments; $documentStates = CBPDocument::GetDocumentStates( BizprocDocument::generateDocumentComplexType( $this->arParams["IBLOCK_TYPE_ID"], $this->arResult["IBLOCK_ID"]), BizprocDocument::getDocumentComplexId($this->arParams["IBLOCK_TYPE_ID"], $elementId) ); if(!empty($documentStates)) $state = current($documentStates); else return $countComments; $query = CForumTopic::getList(array(), array("@XML_ID" => 'WF_'.$state["ID"])); while ($row = $query->fetch()) $countComments = $row["POSTS"]; return $countComments; } }