Your IP : 52.14.244.213


Current Path : /var/www/axolotl/data/www/arhangelsk.axolotls.ru/a537b/
Upload File :
Current File : /var/www/axolotl/data/www/arhangelsk.axolotls.ru/a537b/copy.tar

implement/iblock.php000066400000005561147744171310010534 0ustar00<?php
namespace Bitrix\Lists\Copy\Implement;

use Bitrix\Iblock\Copy\Implement\Iblock as IblockImplementer;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Copy\Container;

class Iblock extends IblockImplementer
{
	public function add(Container $container, array $fields)
	{
		$iblockId = parent::add($container, $fields);

		if ($iblockId)
		{
			$this->setUrlTemplate($container, $iblockId, $fields);
		}

		return $iblockId;
	}

	public function copyChildren(Container $container, $iblockId, $copiedIblockId)
	{
		$this->copyLockFeature($iblockId, $copiedIblockId);

		return parent::copyChildren($container, $iblockId, $copiedIblockId);
	}

	protected function cleanCache(int $iblockId): void
	{
		parent::cleanCache($iblockId);

		if ($this->cacheManager)
		{
			$this->cacheManager->clearByTag("lists_list_".$iblockId);
			$this->cacheManager->clearByTag("lists_list_any");
		}
	}

	protected function getSocnetPermission($iblockId, $socnetGroupId): array
	{
		$rights = [];
		$i = 0;
		$socnetPerm = \CLists::getSocnetPermission($iblockId);
		foreach ($socnetPerm as $role => $permission)
		{
			if ($permission > "W")
			{
				$permission = "W";
			}
			switch ($role)
			{
				case "A":
				case "E":
				case "K":
					$rights["n" . ($i++)] = [
						"GROUP_CODE" => "SG" . $socnetGroupId . "_" . $role,
						"IS_INHERITED" => "N",
						"TASK_ID" => \CIBlockRights::letterToTask($permission),
					];
					break;
				case "L":
					$rights["n" . ($i++)] = [
						"GROUP_CODE" => "AU",
						"IS_INHERITED" => "N",
						"TASK_ID" => \CIBlockRights::letterToTask($permission),
					];
					break;
				case "N":
					$rights["n" . ($i++)] = [
						"GROUP_CODE" => "G2",
						"IS_INHERITED" => "N",
						"TASK_ID" => \CIBlockRights::letterToTask($permission),
					];
					break;
			}
		}
		return $rights;
	}

	private function copyLockFeature(int $iblockId, int $copiedIblockId): void
	{
		$option = Option::get("lists", "iblock_lock_feature");
		$iblockIdsWithLockFeature = ($option !== "" ? unserialize($option) : []);
		if (isset($iblockIdsWithLockFeature[$iblockId]))
		{
			$iblockIdsWithLockFeature[$copiedIblockId] = $copiedIblockId;
			Option::set("lists", "iblock_lock_feature", serialize($iblockIdsWithLockFeature));
		}
	}

	private function setUrlTemplate(Container $container, int $iblockId, array $fields)
	{
		$list = new \CList($iblockId);

		$dictionary = $container->getDictionary();

		if (!empty($dictionary["LIST_ELEMENT_URL"]))
		{
			$listElementUrl = $dictionary["LIST_ELEMENT_URL"];
		}
		else
		{
			$listElementUrl = $list->getUrlByIblockId($container->getEntityId());
			$listElementUrl = str_replace($container->getEntityId(), $iblockId, $listElementUrl);
		}

		$socnetGroupId = ($fields["SOCNET_GROUP_ID"] ? $fields["SOCNET_GROUP_ID"] : 0);

		$list->actualizeDocumentAdminPage(str_replace(
			["#list_id#", "#group_id#"],
			[$iblockId, $socnetGroupId],
			$listElementUrl
		));
	}
}implement/children/field.php000066400000004747147744171310012151 0ustar00<?php
namespace Bitrix\Lists\Copy\Implement\Children;

use Bitrix\Iblock\Copy\Implement\Children\Field as BaseField;
use Bitrix\Main\Error;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Result;

Loc::loadMessages(__FILE__);

class Field extends BaseField
{
	/**
	 * Copies lists fields.
	 * @param int $iblockId Iblock id.
	 * @param int $copiedIblockId Copied iblock id.
	 * @return Result
	 */
	public function copy($iblockId, $copiedIblockId): Result
	{
		$fields = $this->getFieldsToCopy($iblockId, $copiedIblockId);
		$this->addListsFields($iblockId, $copiedIblockId, $fields);

		return $this->result;
	}

	private function getFieldsToCopy($iblockId, $copiedIblockId)
	{
		$fields = [];

		$object = new \CList($iblockId);

		foreach($object->getFields() as $fieldId => $field)
		{
			$copiedField = [
				"ID" => $fieldId,
				"NAME" => $field["NAME"],
				"SORT" => $field["SORT"],
				"MULTIPLE" => $field["MULTIPLE"],
				"IS_REQUIRED" => $field["IS_REQUIRED"],
				"IBLOCK_ID" => $copiedIblockId,
				"SETTINGS" => $field["SETTINGS"],
				"DEFAULT_VALUE" => $field["DEFAULT_VALUE"],
				"TYPE" => $field["TYPE"],
				"PROPERTY_TYPE" => $field["PROPERTY_TYPE"],
			];

			if (!$object->is_field($fieldId))
			{
				if ($field["TYPE"] == "L")
				{
					$copiedField["VALUES"] = $this->getEnumValues($fieldId);
				}

				$copiedField["CODE"] = $field["CODE"];
				$copiedField["LINK_IBLOCK_ID"] = $field["LINK_IBLOCK_ID"];
				if (!empty($field["PROPERTY_USER_TYPE"]["USER_TYPE"]))
					$copiedField["USER_TYPE"] = $field["PROPERTY_USER_TYPE"]["USER_TYPE"];
				if (!empty($field["ROW_COUNT"]))
					$copiedField["ROW_COUNT"] = $field["ROW_COUNT"];
				if (!empty($field["COL_COUNT"]))
					$copiedField["COL_COUNT"] = $field["COL_COUNT"];
				if (!empty($field["USER_TYPE_SETTINGS"]))
					$copiedField["USER_TYPE_SETTINGS"] = $field["USER_TYPE_SETTINGS"];
			}
			$fields[] = $copiedField;
		}

		return $fields;
	}

	private function addListsFields($iblockId, $copiedIblockId, array $fields)
	{
		$object = new \CList($copiedIblockId);

		foreach ($fields as $field)
		{
			if ($field["ID"] == "NAME")
			{
				$result = $object->updateField("NAME", $field);
			}
			else
			{
				$result = $object->addField($field);
			}

			if ($result)
			{
				$object->save();

				$this->setEnumRatio($iblockId, $field["ID"], $result);
			}
			else
			{
				$this->result->addError(
					new Error(
						Loc::getMessage("COPY_FIELD_ERROR", ["#NAME#" => $field["NAME"]]),
						self::FIELD_COPY_ERROR
					)
				);
			}
		}
	}
}implement/children/workflow.php000066400000000661147744171310012727 0ustar00<?php
namespace Bitrix\Lists\Copy\Implement\Children;

use Bitrix\Iblock\Copy\Implement\Children\Workflow as IblockWorkflow;
use Bitrix\Lists\BizprocDocumentLists;

class Workflow extends IblockWorkflow
{
	protected function getDocumentType(int $iblockId): array
	{
		$entity = ($this->iblockTypeId == "bitrix_processes" ? \BizprocDocument::class : BizprocDocumentLists::class);
		return ["lists", $entity, "iblock_".$iblockId];
	}
}integration/group.php000066400000004314147744171310010751 0ustar00<?php
namespace Bitrix\Lists\Copy\Integration;

use Bitrix\Main\Config\Option;
use Bitrix\Socialnetwork\Copy\Integration\Feature;

class Group implements Feature
{
	private $executiveUserId;
	private $features = [];

	const MODULE_ID = "lists";
	const QUEUE_OPTION = "ListsGroupQueue";
	const CHECKER_OPTION = "ListsGroupChecker_";
	const STEPPER_OPTION = "ListsGroupStepper_";
	const STEPPER_CLASS = GroupStepper::class;
	const ERROR_OPTION = "ListsGroupError_";

	public function __construct($executiveUserId = 0, array $features = [])
	{
		$this->executiveUserId = $executiveUserId;
		$this->features = $features;
	}

	/**
	 * Starts the copy process.
	 * @param int $groupId Origin group id.
	 * @param int $copiedGroupId Copied group id.
	 * @throws \Bitrix\Main\ArgumentOutOfRangeException
	 */
	public function copy($groupId, $copiedGroupId)
	{
		$iblockTypeId = "lists_socnet";

		$iblockIds = $this->getIblockIdsToCopy($iblockTypeId, $groupId);
		if (!$iblockIds)
		{
			return;
		}

		$this->addToQueue($copiedGroupId);

		Option::set(self::MODULE_ID, self::CHECKER_OPTION.$copiedGroupId, "Y");

		$queueOption = [
			"iblockTypeId" => $iblockTypeId,
			"groupId" => $groupId,
			"copiedGroupId" => $copiedGroupId,
			"features" => $this->features
		];
		Option::set(self::MODULE_ID, self::STEPPER_OPTION.$copiedGroupId, serialize($queueOption));

		$agent = \CAgent::getList([], [
			"MODULE_ID" => self::MODULE_ID,
			"NAME" => GroupStepper::class."::execAgent();"
		])->fetch();
		if (!$agent)
		{
			GroupStepper::bind(1);
		}
	}

	private function getIblockIdsToCopy($iblockTypeId, $groupId)
	{
		$iblockIds = [];

		$filter = [
			"ACTIVE" => "Y",
			"TYPE" => $iblockTypeId,
			"CHECK_PERMISSIONS" => "N",
			"=SOCNET_GROUP_ID" => $groupId
		];

		$queryObject = \CIBlock::getList([], $filter);
		while ($iblock = $queryObject->fetch())
		{
			$iblockIds[] = $iblock["ID"];
		}

		return $iblockIds;
	}

	private function addToQueue(int $copiedGroupId)
	{
		$option = Option::get(self::MODULE_ID, self::QUEUE_OPTION, "");
		$option = ($option !== "" ? unserialize($option) : []);
		$option = (is_array($option) ? $option : []);

		$option[] = $copiedGroupId;
		Option::set(self::MODULE_ID, self::QUEUE_OPTION, serialize($option));
	}
}integration/groupstepper.php000066400000013024147744171310012352 0ustar00<?php
namespace Bitrix\Lists\Copy\Integration;

use Bitrix\Iblock\Copy\Manager;
use Bitrix\Lists\Copy\Implement\Children\Field;
use Bitrix\Lists\Copy\Implement\Children\Workflow;
use Bitrix\Lists\Copy\Implement\Iblock;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Loader;
use Bitrix\Main\Update\Stepper;

class GroupStepper extends Stepper
{
	protected static $moduleId = "lists";

	protected $queueName = "ListsGroupQueue";
	protected $checkerName = "ListsGroupChecker_";
	protected $baseName = "ListsGroupStepper_";
	protected $errorName = "ListsGroupError_";

	/**
	 * Executes some action, and if return value is false, agent will be deleted.
	 * @param array $option Array with main data to show if it is necessary like {steps : 35, count : 7},
	 * where steps is an amount of iterations, count - current position.
	 * @return boolean
	 * @throws \Bitrix\Main\ArgumentNullException
	 * @throws \Bitrix\Main\LoaderException
	 * @throws \Bitrix\Main\SystemException
	 */
	public function execute(array &$option)
	{
		if (!Loader::includeModule(self::$moduleId))
		{
			return false;
		}

		try
		{
			$queue = $this->getQueue();
			$this->setQueue($queue);
			$queueOption = $this->getQueueOption();
			if (empty($queueOption))
			{
				$this->deleteQueueOption();
				return !$this->isQueueEmpty();
			}

			$groupId = ($queueOption["groupId"] ?: 0);
			$copiedGroupId = ($queueOption["copiedGroupId"] ?: 0);
			$iblockTypeId = ($queueOption["iblockTypeId"] ?: "");
			$errorOffset = ($queueOption["errorOffset"] ?: 0);

			$limit = 5;
			$offset = $this->getOffset($iblockTypeId, $copiedGroupId) + $errorOffset;

			$iblockIds = $this->getIblockIdsToCopy($iblockTypeId, $groupId);
			$count = count($iblockIds);
			$iblockIds = array_slice($iblockIds, $offset, $limit);
			$features = ($queueOption["features"] ?: []);

			if ($iblockIds)
			{
				$option["count"] = $count;

				$copyManager = new Manager($iblockTypeId, $iblockIds, $groupId);
				$copyManager->setTargetLocation($iblockTypeId, $copiedGroupId);
				$copyManager->setIblockImplementer(new Iblock());
				$copyManager->setFieldImplementer(new Field());
				$copyManager->setWorkflowImplementer(new Workflow($iblockTypeId));

				if (!in_array("field", $features))
				{
					$copyManager->removeFeature("field");
				}
				if (!in_array("section", $features))
				{
					$copyManager->removeFeature("section");
				}
				if (!in_array("element", $features))
				{
					$copyManager->removeFeature("element");
				}
				if (!in_array("workflow", $features))
				{
					$copyManager->removeFeature("workflow");
				}

				$result = $copyManager->startCopy();
				if (!$result->isSuccess())
				{
					$queueOption["errorOffset"] += $this->getErrorOffset($copyManager);
					$this->saveQueueOption($queueOption);
				}

				$option["steps"] = $offset;

				return true;
			}
			else
			{
				$this->deleteQueueOption();
				return !$this->isQueueEmpty();
			}
		}
		catch (\Exception $exception)
		{
			$this->writeToLog($exception);
			$this->deleteQueueOption();
			return false;
		}
	}

	private function getIblockIdsToCopy($iblockTypeId, $groupId)
	{
		$iblockIds = [];

		$filter = [
			"ACTIVE" => "Y",
			"TYPE" => $iblockTypeId,
			"CHECK_PERMISSIONS" => "N",
			"=SOCNET_GROUP_ID" => $groupId
		];

		$queryObject = \CIBlock::getList([], $filter);
		while ($iblock = $queryObject->fetch())
		{
			$iblockIds[] = $iblock["ID"];
		}

		return $iblockIds;
	}

	private function getOffset(string $iblockTypeId, int $copiedGroupId): int
	{
		$iblockIds = $this->getIblockIdsToCopy($iblockTypeId, $copiedGroupId);
		return count($iblockIds);
	}

	private function getErrorOffset(Manager $copyManager): int
	{
		$numberIds = count($copyManager->getMapIdsCopiedEntity());
		$numberSuccessIds = count(array_filter($copyManager->getMapIdsCopiedEntity()));
		return $numberIds - $numberSuccessIds;
	}

	protected function getQueue(): array
	{
		return $this->getOptionData($this->queueName);
	}

	protected function setQueue(array $queue): void
	{
		$queueId = (string) current($queue);
		$this->checkerName = (mb_strpos($this->checkerName, $queueId) === false ?
			$this->checkerName.$queueId : $this->checkerName);
		$this->baseName = (mb_strpos($this->baseName, $queueId) === false ?
			$this->baseName.$queueId : $this->baseName);
		$this->errorName = (mb_strpos($this->errorName, $queueId) === false ?
			$this->errorName.$queueId : $this->errorName);
	}

	protected function getQueueOption()
	{
		return $this->getOptionData($this->baseName);
	}

	protected function saveQueueOption(array $data)
	{
		Option::set(static::$moduleId, $this->baseName, serialize($data));
	}

	protected function deleteQueueOption()
	{
		$queue = $this->getQueue();
		$this->setQueue($queue);
		$this->deleteCurrentQueue($queue);
		Option::delete(static::$moduleId, ["name" => $this->checkerName]);
		Option::delete(static::$moduleId, ["name" => $this->baseName]);
	}

	protected function deleteCurrentQueue(array $queue): void
	{
		$queueId = current($queue);
		$currentPos = array_search($queueId, $queue);
		if ($currentPos !== false)
		{
			unset($queue[$currentPos]);
			Option::set(static::$moduleId, $this->queueName, serialize($queue));
		}
	}

	protected function isQueueEmpty()
	{
		$queue = $this->getOptionData($this->queueName);
		return empty($queue);
	}

	protected function getOptionData($optionName)
	{
		$option = Option::get(static::$moduleId, $optionName);
		$option = ($option !== "" ? unserialize($option) : []);
		return (is_array($option) ? $option : []);
	}

	protected function deleteOption($optionName)
	{
		Option::delete(static::$moduleId, ["name" => $optionName]);
	}
}