%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/components/bitrix/lists.export.excel/
Upload File :
Create Path :
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;
	}
}

Zerion Mini Shell 1.0