uawdijnntqw1x1x1
IP : 18.188.93.255
Hostname : axolotl
Kernel : Linux axolotl 4.9.0-13-amd64 #1 SMP Debian 4.9.228-1 (2020-07-05) x86_64
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
OS : Linux
PATH:
/
var
/
www
/
axolotl
/
data
/
www
/
yar.axolotls.ru
/
bitrix
/
modules
/
webdav
/
classes
/
iblock.php
/
/
<? ############################################## # Bitrix Site Manager WebDav # # Copyright (c) 2002-2010 Bitrix # # http://www.bitrixsoft.com # # mailto:admin@bitrixsoft.com # ############################################## use Bitrix\Main\Config\Option; IncludeModuleLangFile(__FILE__); class CWebDavIblock extends CWebDavBase { var $IBLOCK_ID; var $IBLOCK_TYPE; var $Type = "iblock"; var $allow = array( "POST" => array("rights" => "U", "min_rights" => "R"), "HEAD" => array("rights" => "R", "min_rights" => "R"), "OPTIONS" => array("rights" => "A", "min_rights" => "A"), "PROPPATCH" => array("rights" => "U", "min_rights" => "U"), "PROPFIND" => array("rights" => "R", "min_rights" => "R"), "GET" => array("rights" => "R", "min_rights" => "R"), "PUT" => array("rights" => "U", "min_rights" => "U"), "LOCK" => array("rights" => "U", "min_rights" => "U"), "MOVE" => array("rights" => "W", "min_rights" => "U"), "COPY" => array("rights" => "W", "min_rights" => "U"), "UNLOCK" => array("rights" => "U", "min_rights" => "U"), "MKCOL" => array("rights" => "W", "min_rights" => "W"), "DELETE" => array("rights" => "W", "min_rights" => "U"), "DESTROY" => array("rights" => "X", "min_rights" => "X"), "UNDELETE" => array("rights" => "W", "min_rights" => "W"), ); var $preg_modif = "i"; var $iblock_permission = "D"; var $iblock_permission_real = "D"; var $check_creator = false; var $file_prop = "FILE"; var $permission_real = "D"; var $short_path_template = "/folder#SECTION_ID#/#ELEMENT_ID#"; var $attributes = array(); var $arMetaIDs = array(); var $e_rights = null; var $INT_MAX = 2147483647; // php < 5.0.5 var $FORUM_ID = null; var $UF_ENTITY = null; var $UF_FIELDS = null; var $withoutAuthorization = false; private static $first_run = true; private static $trashCache = array(); //new const OBJ_TYPE_IBLOCK = 'IBLOCK'; const OBJ_TYPE_SECTION = 'SECTION'; const OBJ_TYPE_ELEMENT = 'ELEMENT'; const GET_ALL_CACHED_SETTINGS = 'GET_ALL_CACHED_SETTINGS'; const TYPE = 'IBLOCK'; const PROPERTY_VERSION = 'WEBDAV_VERSION'; const UF_LINK_IBLOCK_ID = 'UF_LINK_IBLOCK_ID'; const UF_LINK_SECTION_ID = 'UF_LINK_SECTION_ID'; const UF_LINK_ROOT_SECTION_ID = 'UF_LINK_RSECTION_ID'; const UF_LINK_CAN_FORWARD = 'UF_LINK_CAN_FORWARD'; protected static $arSettingsCache = array(); protected static $arSectionCache = array(); public static $lastActionMoveWithSymlink = false; public static $possibleUseSymlinkByInternalSections = false; protected $_originalParams = array(); protected $_symlinkMode = false; protected $_symlinkSectionData = array(); protected $_symlinkRealRootSectionData = array(); var $CACHE_TIME = 0; protected $cacheType = "N"; protected $cachePathBase = ""; var $CACHE_PATH = ""; var $CACHE_OBJ = false; private static $_fetchUFSymlinkMode = true; private static $_metaSectionData = array(); //new end function CWebDavIblock($IBLOCK_ID, $base_url, $arParams = array()) { $arParams = (is_array($arParams) ? $arParams : array()); $this->_originalParams = $arParams; $this->_symlinkMode = !empty($arParams['symlinkMode']); $this->_symlinkSectionData = empty($arParams['symlinkSectionData'])? array() : $arParams['symlinkSectionData']; $this->_symlinkRealRootSectionData = empty($arParams['symlinkRealRootSectionData'])? array() : $arParams['symlinkRealRootSectionData']; $this->IBLOCK_ID = $IBLOCK_ID; $this->IBLOCK_TYPE = $arParams["IBLOCK_TYPE"]; $this->FORUM_ID = ((isset($arParams['FORUM_ID']) && (intval($arParams['FORUM_ID']) > 0)) ? intval($arParams['FORUM_ID']) : null); $this->cachePathBase = str_replace(array("///", "//"), "/", "/".SITE_ID."/webdav/".$this->IBLOCK_ID."/"); $this->CACHE_PATH = $this->cachePathBase; $this->CACHE_TIME = array_key_exists("CACHE_TIME", $arParams) ? $arParams["CACHE_TIME"] : 0; $this->cacheType = array_key_exists("CACHE_TYPE", $arParams) ? $arParams["CACHE_TYPE"] : "N"; if ($this->cacheType == "Y" || ( $this->cacheType == "A" && COption::GetOptionString("main", "component_cache_on", "Y") == "Y" ) ) { $this->CACHE_TIME = intval($arParams["CACHE_TIME"]); } else { $this->CACHE_TIME = 0; } $arParams["CACHE_TIME"] = $this->CACHE_TIME; if ($this->CACHE_TIME > 0) { $this->CACHE_OBJ = new CPHPCache(); } if (!$this->SetRootSection($arParams["ROOT_SECTION_ID"], false, empty($arParams['PLEASE_DO_NOT_MAKE_REDIRECT']))) // socnet { $this->arError[] = array( "id" => "root_section_is_not_found", "text" => GetMessage("WD_ROOT_SECTION_NOT_FOUND")); } else { if (self::$first_run) AddEventHandler("iblock", "OnAfterIBlockSectionAdd", array($this, "UpdateRootSection")); } if ( (COption::GetOptionString('webdav', 'webdav_socnet', 'Y') === 'Y') && (self::$first_run) && CModule::IncludeModule("socialnetwork") ) { $obDavEventHandler = CWebDavSocNetEvent::GetRuntime(); $obDavEventHandler->object = $this; AddEventHandler("webdav", "OnFileAdd", array($obDavEventHandler, "SocnetLogFileAdd")); AddEventHandler("webdav", "OnFileAdd", array($obDavEventHandler, "SocnetNotify")); AddEventHandler("webdav", "OnFileUpdate", array($obDavEventHandler, "SocnetLogFileUpdate")); AddEventHandler("webdav", "OnFileMoveFinished", array($obDavEventHandler, "SocnetLogFileMove")); AddEventHandler("webdav", "OnFileTrash", array($obDavEventHandler, "SocnetLogFileDelete")); AddEventHandler("webdav", "OnFileDelete", array($obDavEventHandler, "SocnetLogFileDelete")); if (CModule::IncludeModule('forum')) { AddEventHandler("forum", "onAfterMessageAdd", array($obDavEventHandler, "SocnetLogMessageAdd")); AddEventHandler("forum", "onAfterMessageDelete", array($obDavEventHandler, "SocnetLogMessageDelete")); AddEventHandler("forum", "onAfterMessageUpdate", array($obDavEventHandler, "SocnetLogMessageUpdate")); } } $this->CWebDavBase($base_url); if (!IsModuleInstalled("iblock")) { $this->arError[] = array( "id" => "module iblock is not installed. ", "text" => GetMessage("W_IBLOCK_IS_NOT_INSTALLED")); return false; } $this->e_rights = (CIBlock::GetArrayByID($IBLOCK_ID, "RIGHTS_MODE") === "E"); if ($this->e_rights) $this->permission_real = 'X'; else $this->permission_real = $this->GetPermission('IBLOCK', $this->IBLOCK_ID); $this->permission = (empty($arParams["PERMISSION"]) ? $this->permission_real : $arParams["PERMISSION"]); if ($GLOBALS['USER']->CanDoOperation('webdav_change_settings')) $this->permission = $this->permission_real = 'X'; $this->check_creator = false; if ($this->permission_real < "W" && $this->permission > $this->permission_real) $this->check_creator = ($arParams["CHECK_CREATOR"] == "Y" ? true : false); $this->USER["GROUPS"] = $GLOBALS["USER"]->GetUserGroupArray(); $this->workflow = false; if (CIBlock::GetArrayByID($IBLOCK_ID, "WORKFLOW") != "N" && IsModuleInstalled("workflow")) { CModule::IncludeModule("workflow"); $this->workflow = 'workflow'; $this->permission_wf_edit = true; if ($this->permission == "U" && !CWorkflow::IsAdmin()) { $this->permission_wf_edit = false; $db_res = CWorkflowStatus::GetDropDownList("Y", "desc"); if ($db_res && $res = $db_res->Fetch()) { do { if (CIBlockElement::WF_GetStatusPermission($res["REFERENCE_ID"]) >= 2) { $this->permission_wf_edit = true; break; } } while ($res = $db_res->Fetch()); } } } elseif (IsModuleInstalled("bizproc")) { CModule::IncludeModule("bizproc"); $this->workflow = (CIBlock::GetArrayByID($IBLOCK_ID, "BIZPROC") != "N" ? 'bizproc' : 'bizproc_limited'); $this->wfParams['AUTO_PUBLISH'] = "N"; if (isset($arParams['AUTO_PUBLISH'])) $this->wfParams['AUTO_PUBLISH'] = (($arParams['AUTO_PUBLISH'] == "Y") ? "Y" : "N"); if (isset($arParams['FILES_AUTO_PUBLISH'])) $this->wfParams['AUTO_PUBLISH'] = (($arParams['FILES_AUTO_PUBLISH'] == "Y") ? "Y" : "N"); $this->wfParams['DOCUMENT_TYPE'] = array("webdav", "CIBlockDocumentWebdav", "iblock_".$IBLOCK_ID); if (is_array($arParams["DOCUMENT_TYPE"])) { $this->wfParams['DOCUMENT_TYPE'][1] = $arParams["DOCUMENT_TYPE"][1]; $this->wfParams['DOCUMENT_TYPE'][2] = $arParams["DOCUMENT_TYPE"][2]; } if (self::$first_run) AddEventHandler('bizproc', 'OnBeforeDeleteFileFromHistory', array('CWebdavDocumentHistory', 'OnBeforeDeleteFileFromHistory')); if ($this->wfParams['DOCUMENT_TYPE'][1] == "CIBlockDocumentWebdavSocnet") { if ($this->workflow == 'bizproc') { $tmp = explode("_", $this->wfParams['DOCUMENT_TYPE'][2]); if (intval($tmp[3]) > 0) { $arFilter = array( "IBLOCK_ID" => $IBLOCK_ID, "SOCNET_GROUP_ID" => false, "SECTION_ID" => 0); if ($tmp[2] == "user") { $arFilter["CREATED_BY"] = $tmp[3]; //we don't use BP in user lib; $this->workflow = 'bizproc_limited'; } else { $arFilter["SOCNET_GROUP_ID"] = $tmp[3]; $db_res = CIBlockSection::GetList(array(), $arFilter, false, array("ID", "UF_USE_BP")); if ($db_res && $res = $db_res->Fetch()) { $this->workflow = ($res["UF_USE_BP"] == "N" ? 'bizproc_limited' : 'bizproc'); } } } } if (method_exists($this->wfParams['DOCUMENT_TYPE'][1], "GetUserGroups")) { $this->USER["GROUPS"] = call_user_func_array( array($this->wfParams['DOCUMENT_TYPE'][1], "GetUserGroups"), array($this->wfParams['DOCUMENT_TYPE'], null, $GLOBALS["USER"]->GetID())); } } if ($this->workflow == 'bizproc') { AddEventHandler('webdav', 'OnBizprocPublishDocument', array($this, 'OnBizprocPublishDocument')); } } $this->file_prop = strtoupper(isset($arParams["NAME_FILE_PROPERTY"]) ? $arParams["NAME_FILE_PROPERTY"] : "FILE"); if ($this->permission == "U" && $this->workflow != "workflow" && $this->workflow != "bizproc") $this->permission = "R"; if ($arParams["SHORT_PATH_TEMPLATE"]) $this->short_path_template = $arParams["SHORT_PATH_TEMPLATE"]; if ($arParams["ATTRIBUTES"]) $this->attributes = $arParams["ATTRIBUTES"]; $this->_check_iblock_prop(array( "WEBDAV_INFO" => array( "name" => GetMessage("WD_PROPERTY_WEBDAV_INFO"), "type" => "S" ), "WEBDAV_SIZE" => array( "name" => GetMessage("WD_PROPERTY_FILE_SIZE"), "type" => "N" ), static::PROPERTY_VERSION => array( "name" => GetMessage("WD_PROPERTY_VERSION"), "type" => "N" ), $this->file_prop => array( "name" => GetMessage("WD_PROPERTY_NAME_FILE"), "type" => "F", "properties" => array("SEARCHABLE" => "Y") ) )); $oIB = new CIBlock; $arIBlock = $oIB->GetArrayByID($this->IBLOCK_ID); if(!array_key_exists("NOT_SAVE_SUG_FILES", $arParams)) { if (strpos($arIBlock['CODE'], 'shared_files') !== false) { // without trailing slash redirects POST request to GET request if (strlen($this->base_url) > 0) $this->LibOptions('shared_files', false, SITE_ID, array('id' => $this->IBLOCK_ID, 'base_url' => $this->base_url.'/')); } elseif (strpos($arIBlock['CODE'], 'group_files') !== false) { $this->LibOptions('group_files', false, SITE_ID, array('id' => $this->IBLOCK_ID)); } elseif (strpos($arIBlock['CODE'], 'user_files') !== false) { $this->LibOptions('user_files', false, SITE_ID, array('id' => $this->IBLOCK_ID)); } } if ($arIBlock['INDEX_SECTION'] == 'Y' && strlen(trim($arIBlock['SECTION_PAGE_URL'])) == 0) { $arIBlock['SECTION_PAGE_URL'] = str_replace(array("///", "//"), "/", $arIBlock['LIST_PAGE_URL'] . "/folder/view/#SECTION_ID#/"); $oIB->Update($this->IBLOCK_ID, $arIBlock); } $this->GetUfEntity(); self::$first_run = false; } public static function GetULRsFromIBlockID($IBLOCK_ID, $params = array()) { $IBLOCK_ID = intval($IBLOCK_ID); if ($IBLOCK_ID <= 0) return false; $params = (is_array($params) ? $params : array()); $params["path"] = trim(!!$params["path"] ? $params["path"] : (!!$params["PATH"] ? $params["PATH"] : "")); if (empty($params["path"])) { $params["path"] = CIBlock::GetArrayByID($IBLOCK_ID, "DETAIL_PAGE_URL"); } // Params for socialnetwork static $arExtranetSite = false; static $defSite = false; $params["SECTION_ID"] = intval($params["SECTION_ID"]); // root section id $params["ELEMENT_ID"] = intval($params["ELEMENT_ID"]); $arSection = (is_array($params["SECTION"]) ? $params["SECTION"] : array()); // root section $arElement = (is_array($params["ELEMENT"]) ? $params["ELEMENT"] : array()); if (empty($arSection)) { if ($params["SECTION_ID"] > 0) { $arSection = CIBlockSection::GetList(array(), array( "ID" => $params["SECTION_ID"], 'CHECK_PERMISSIONS' => 'N' ), false, array('ID', 'IBLOCK_ID', 'SOCNET_GROUP_ID', 'CREATED_BY') )->fetch(); } else { if ($params["ELEMENT_ID"] > 0 && empty($arElement)) $arElement = CIBlockElement::GetList(array(), array('ID' => $params["ELEMENT_ID"]), false, false, array('ID', 'IBLOCK_SECTION_ID', 'IBLOCK_CODE', 'IBLOCK_ID'))->fetch(); if (!empty($arElement) && $arElement["IBLOCK_SECTION_ID"] > 0) { $res = CWebDavSymlinkHelper::getNavChain($IBLOCK_ID, $arElement["IBLOCK_SECTION_ID"]); if (!!$res) $arSection = reset($res); } } } if (empty($arSection) || $arSection["IBLOCK_ID"] != $IBLOCK_ID) { $arSection = array(); $arElement = array(); } // Params for socialnetwork / if (strpos($params["path"], "#SITE_DIR#") !== false) $params["path"] = str_replace("#SITE_DIR#", SITE_DIR, $params["path"]); else if (array_key_exists("SITE_ID", $params) && CModule::IncludeModule('extranet') && (CExtranet::GetExtranetSiteID() == $params["SITE_ID"])) { if($arExtranetSite === false) { $rsSites = CSite::GetByID(SITE_ID); $arExtranetSite = $rsSites->Fetch(); unset($rsSites); } if ( $arExtranetSite ) { if($defSite === false) { $defSite = CSite::GetDefSite(); } $params["path"] = $arExtranetSite["DIR"] . $params["path"]; } } $SEF_FOLDER = "/"; $SEF_URL_TEMPLATES = array(); $arUrlRewrite = CUrlRewriter::GetList(!empty($params["path"]) ? array("QUERY" => str_replace("//", "/", $params["path"])) : array()); $entity = false; foreach($arUrlRewrite as $arRule) { if (! in_array($arRule["ID"], array( "bitrix:webdav", "bitrix:socialnetwork", "bitrix:socialnetwork_user", "bitrix:socialnetwork_group"))) continue; $arComponents = WDGetComponentsOnPage($arRule["PATH"]); $firstMet = !empty($params["path"]); foreach ($arComponents as $arComponent) { if ($arComponent["COMPONENT_NAME"] == $arRule["ID"]) { $SEF_FOLDER = $arComponent["PARAMS"]["SEF_FOLDER"]; if (strpos($arRule["ID"], "bitrix:socialnetwork") === 0) { if ($arRule["ID"] == "bitrix:socialnetwork" && $arComponent["PARAMS"]["FILES_GROUP_IBLOCK_ID"] == $arComponent["PARAMS"]["FILES_USER_IBLOCK_ID"] && ($firstMet || $arComponent["PARAMS"]["FILES_USER_IBLOCK_ID"] == $IBLOCK_ID)) { $entity = ($arSection["SOCNET_GROUP_ID"] > 0 ? "group" : "user"); } else if ( ($firstMet || $arComponent["PARAMS"]["FILES_USER_IBLOCK_ID"] == $IBLOCK_ID) && ($arRule["ID"] == "bitrix:socialnetwork_user" || $arRule["ID"] == "bitrix:socialnetwork") ) { $entity = "user"; } else if ( ($firstMet || $arComponent["PARAMS"]["FILES_GROUP_IBLOCK_ID"] == $IBLOCK_ID) && ($arRule["ID"] == "bitrix:socialnetwork_group" || $arRule["ID"] == "bitrix:socialnetwork") ) { $entity = "group"; } if (!!$entity) { $SEF_URL_TEMPLATES = ($entity == "user" ? array( "path" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["user_files"], "view" => "user/#user_id#/files/element/view/#element_id#/", "edit" => "user/#user_id#/files/element/edit/#element_id#/#action#/", "history" => "user/#user_id#/files/element/history/#element_id#/", "history_get" => "user/#user_id#/files/element/historyget/#element_id#/#element_name#" ) : array( "path" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["group_files"], "view" => "group/#group_id#/files/element/view/#element_id#/", "edit" => "group/#group_id#/files/element/edit/#element_id#/#action#/", "history" => "group/#group_id#/files/element/history/#element_id#/", "history_get" => "group/#group_id#/files/element/historyget/#element_id#/#element_name#" ) ); } } else if ($arRule["ID"] == "bitrix:webdav" && ($firstMet || $arComponent["PARAMS"]["IBLOCK_ID"] == $IBLOCK_ID)) { $entity = "lib"; $SEF_URL_TEMPLATES = array( "path" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["sections"], "view" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["element"], "edit" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["element_edit"], "history" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["element_history"], "history_get" => $arComponent["PARAMS"]["SEF_URL_TEMPLATES"]["element_history_get"] ); } if (!!$entity) { $SEF_URL_TEMPLATES["component"] = $arRule["ID"]; break 2; } } } } $repl = array("#id#", "#ELEMENT_ID#", "#element_id#", "#name#", "#ELEMENT_NAME#", "#element_name#", "#action#", "//"); $patt = array("#ELEMENT_ID#", "#ELEMENT_ID#", "#ELEMENT_ID#", "#ELEMENT_NAME#", "#ELEMENT_NAME#", "#ELEMENT_NAME#", "#ACTION#", "/"); if ($entity != "lib") { $repl[] = "#SOCNET_USER_ID#"; $patt[] = "#USER_ID#"; $repl[] = "#socnet_user_id#"; $patt[] = "#USER_ID#"; $repl[] = "#user_id#"; $patt[] = "#USER_ID#"; $repl[] = "#SOCNET_GROUP_ID#"; $patt[] = "#GROUP_ID#"; $repl[] = "#socnet_group_id#"; $patt[] = "#GROUP_ID#"; $repl[] = "#group_id#"; $patt[] = "#GROUP_ID#"; $repl[] = "#SOCNET_OBJECT_ID#"; $patt[] = "#SOCNET_OBJECT#"; $repl[] = "#socnet_object_id#"; $patt[] = "#SOCNET_OBJECT#"; $repl[] = "#socnet_object#"; $patt[] = "#SOCNET_OBJECT#"; if (!empty($arSection)) { $repl[] = "#USER_ID#"; $patt[] = $arSection["CREATED_BY"]; $repl[] = "#GROUP_ID#"; $patt[] = $arSection["SOCNET_GROUP_ID"]; $patt[] = "#SOCNET_OBJECT#"; $patt[] = ($arSection["SOCNET_GROUP_ID"] > 0 ? "group" : "user"); } } if (!empty($arElement)) { $repl[] = "#ID#"; $patt[] = $arElement["ID"]; $repl[] = "#ELEMENT_ID#"; $patt[] = $arElement["ID"]; $repl[] = "#NAME#"; $patt[] = $arElement["NAME"]; $repl[] = "#ELEMENT_NAME#"; $patt[] = $arElement["NAME"]; } foreach($SEF_URL_TEMPLATES as $key => $val) $SEF_URL_TEMPLATES[$key] = str_replace($repl, $patt, $SEF_FOLDER ."/". $val); $SEF_URL_TEMPLATES["path"] = str_replace(array("#path#", "#PATH#"), "", $SEF_URL_TEMPLATES["path"]); $SEF_URL_TEMPLATES["delete_dropped"] = str_replace("#ACTION#", "delete_dropped", $SEF_URL_TEMPLATES["edit"]); $SEF_URL_TEMPLATES["edit"] = str_replace("#ACTION#", "edit", $SEF_URL_TEMPLATES["edit"]); $SEF_URL_TEMPLATES["entity"] = $entity; return $SEF_URL_TEMPLATES; } static function LibOptions($title, $user = true, $key = false, $value = false) { $arLibOptions = array(); $user = (!!$user); if ($user) { $arLibOptions = CUserOptions::GetOption('webdav', $title, ''); } else { $sLibOptions = COption::GetOptionString('webdav', $title, ''); if (CheckSerializedData($sLibOptions)) $arLibOptions = @unserialize($sLibOptions); } if (!is_array($arLibOptions)) $arLibOptions = array(); if (($key !== false) && ($value !== false)) { if (!isset($arLibOptions[$key]) || $arLibOptions[$key] != $value) { $arLibOptions[$key] = $value; if ($user) { CUserOptions::SetOption('webdav', $title, $arLibOptions); } else { $sLibOptions = serialize($arLibOptions); COption::SetOptionString('webdav', $title, $sLibOptions); } } } $result = ((!! $key ) ? ( isset($arLibOptions[$key]) ? $arLibOptions[$key] : false ) : $arLibOptions); return $result; } /*static*/ function _get_ib_rights_object($type, $id, $IBLOCK_ID=null) { if ($type !== 'SECTION' && $type !== 'ELEMENT' && $type !== 'IBLOCK') throw new Exception("_get_ib_rights_object invalid type \"".htmlspecialcharsbx($type)."\""); $ibRights = null; if ($IBLOCK_ID === null && isset($this)) $IBLOCK_ID = $this->IBLOCK_ID; if ($IBLOCK_ID === null) throw new Exception("_get_ib_rights_object called statically, but no IBLOCK_ID is set"); if ($type == 'SECTION') $ibRights = new CIBlockSectionRights($IBLOCK_ID, $id); elseif ($type == 'ELEMENT') $ibRights = new CIBlockElementRights($IBLOCK_ID, $id); else $ibRights = new CIBlockRights($IBLOCK_ID); return $ibRights; } function GetERights($type, $id) { $ibRights = $this->_get_ib_rights_object($type, $id); return $ibRights->GetRights(); } //function SetERights() //{ //} static function CheckRight($IBlockPermission, $permission) { if ($GLOBALS['USER']->CanDoOperation('webdav_change_settings')) return 'Z'; if (is_array($IBlockPermission)) return (isset($IBlockPermission[trim($permission)]) ? 'Z' : 'A'); else return $IBlockPermission; } function GetPermissionRules($type, $arID) { if ($this->e_rights) { $id = 0; $arResult = array(); $ibRights = $this->_get_ib_rights_object($type, $id); $dbRules = $ibRights->GetList(array("=IBLOCK_ID" => $this->IBLOCK_ID, "=ITEM_ID" => $arID)); if (!$dbRules) return false; while ($arRule = $dbRules->Fetch()) $arResult[$arRule['ITEM_ID']][] = $arRule; return $arResult; } else return false; } /*static*/ function GetPermissions($type, $arID, $IBLOCK_ID=null) { static $cache = array(); if ($IBLOCK_ID === null && isset($this)) $IBLOCK_ID = $this->IBLOCK_ID; if ($IBLOCK_ID === null) throw new Exception("GetPermissions called statically, but no IBLOCK_ID is set"); if (!isset($cache[$IBLOCK_ID])) $cache[$IBLOCK_ID] = array(); if (!is_array($arID) && ($type=='ELEMENT')) { if (isset($cache[$IBLOCK_ID][$arID])) return $cache[$IBLOCK_ID][$arID]; } if($type == 'SECTION' && !is_array($arID) && isset($this) && is_object($this) && $this instanceof CWebDavBase) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($arID); //if this element is link. if($sectionData && $sectionData['ID'] != $arID) { return self::GetPermissions($type, $sectionData['ID'], $sectionData['IBLOCK_ID']); } } $ibRights = CWebDavIblock::_get_ib_rights_object($type, 0, $IBLOCK_ID); $result = $ibRights->GetUserOperations($arID); if ($type=='ELEMENT') { if (is_array($arID)) $cache[$IBLOCK_ID] = array_merge($cache[$IBLOCK_ID], $result); else $cache[$IBLOCK_ID][$arID] = $result; } return $result; } function GetPermission($type, $id, $op='', $runSymlinkProxy = true) { if ($this->e_rights) { if ($op === '') return $this->GetPermissions($type, $id, $this->IBLOCK_ID); else { if($type == 'SECTION') { if($runSymlinkProxy) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($id); //if this element is link. if($sectionData && $sectionData['ID'] != $id) { return self::GetPermission($type, $sectionData['ID'], $op); } } } $ibRights = $this->_get_ib_rights_object($type, $id); $result = $ibRights->UserHasRightTo($this->IBLOCK_ID, $id, trim($op)); return $result; } } else { return CIBlock::GetPermission($this->IBLOCK_ID); } } function PROPPATCH(&$options) { $ID = 0; $strProps = ""; $is_dir = false; $object = $this->GetObject($options); if ($object["not_found"] === true) { return "404 Not Found"; } elseif (!$this->CheckWebRights("", array("action" => "proppatch", "arElement" => $object))) { return $this->ThrowAccessDenied(__LINE__); } elseif ($object["is_dir"] === true) { $strProps = $object["dir_array"]["DESCRIPTION"]; $is_dir = true; } else { $strProps = $object["element_array"]["PROPERTY_WEBDAV_INFO_VALUE"]; } $ID = $object["item_id"]; $arProps = @unserialize($strProps); $arProps = (!is_array($arProps) ? array() : $arProps); foreach ($options["props"] as $key => $prop) { if ($prop["ns"] == "DAV:") $options["props"][$key]["status"] = "403 Forbidden"; else { if (isset($prop["val"])) $arProps["PROPS"][$prop["ns"]][$prop["name"]] = $prop["val"]; else unset($arProps["PROPS"][$prop["ns"]][$prop["name"]]); } } foreach ($arProps["PROPS"] as $nsName => $arNs) if (sizeof($arNs) < 1) unset($arProps["PROPS"][$nsName]); if (sizeof($arProps['PROPS']) < 1) unset($arProps['PROPS']); if (sizeof($arProps) > 0) $strProps = serialize($arProps); else $strProps = ''; if ($is_dir) { $se = new CIBlockSection(); $se->Update($ID, array("DESCRIPTION" => $strProps)); } else { CIBlockElement::SetPropertyValues($ID, $this->IBLOCK_ID, $strProps, "WEBDAV_INFO"); } $this->_clear_cache_for_object($options); return ""; } function PROPFIND(&$options, &$files, $arParams = array()) { global $DB; if(empty($files)) { $files = array(); } $files["files"] = array(); $arParams = (is_array($arParams) ? $arParams : array()); if ($this->e_rights) $options['check_permissions'] = false; $this->IsDir($options); $arParamsIsDir = $this->arParams; $arResult = array("NAV_RESULT" => false, "RESULT" => array()); if ($arParamsIsDir["not_found"] === true) { $msg = (($arParamsIsDir['parent_id'] === false) ? GetMessage("WD_FOLDER_NOT_FOUND") : GetMessage("WD_FILE_NOT_FOUND")); return $this->ThrowError( "404 Not Found", "DESTINATION_FILE_OR_FOLDER_IS_NOT_FOUND", $msg, __LINE__); } elseif($arParamsIsDir["is_dir"] != true) { $db_res = $this->_get_mixed_list(intVal($arParamsIsDir["parent_id"]), $arParams, intVal($arParamsIsDir["item_id"])); if ($db_res && $res = $db_res->Fetch()) { if ($this->MetaNames($res)) { $files["files"]["F".$res["ID"]] = $this->_get_file_info_arr($res, $arParams); if ($arParams["return"] == "array") $files["files"]["F".$res["ID"]] = $res; $arResult["RESULT"]["E".$res["ID"]] = $res; // dummy } } } else { if(!empty($arParamsIsDir['dir_array'][self::UF_LINK_SECTION_ID])) { $linkWebdav = new self($arParamsIsDir['dir_array'][self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array_merge($this->_originalParams, array( 'ROOT_SECTION_ID' => $arParamsIsDir['dir_array'][self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $arParamsIsDir['dir_array'], 'symlinkRealRootSectionData' => $this->arRootSection, ))); $options = array( 'path' => '/', 'depth' => 1, 'check_permissions' => false, ); $params = array_merge($arParams, array('PARENT_ID' => $arParamsIsDir['dir_array'][self::UF_LINK_SECTION_ID])); $linkWebdav->_path = $this->_path; return $linkWebdav->PROPFIND($options, $files, $params); } //simple detect symlink list($contextType, $contextEntityId) = $this->getContextData(); if($arParamsIsDir['dir_array']) { $sectionData = $this->getSectionDataForLinkAnalyze($arParamsIsDir['dir_array']['ID'], array( 'IBLOCK_ID' => $arParamsIsDir['dir_array']['IBLOCK_ID'], 'ID' => $arParamsIsDir['dir_array']['ID'], )); if(!$this->_symlinkMode && CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $symlinkSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); } } if(!empty($symlinkSectionData)) { $linkWebdav = new self($symlinkSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array_merge($this->_originalParams, array( 'ROOT_SECTION_ID' => $symlinkSectionData[self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $symlinkSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, ))); $options = array( 'path' => '/', 'depth' => 1, 'check_permissions' => false, ); $params = array_merge($arParams, array('PARENT_ID' => $arParamsIsDir['dir_array']['ID'])); $linkWebdav->_path = $this->_path; return $linkWebdav->PROPFIND($options, $files, $params); } if ($arParamsIsDir["item_id"] <= 0 || $this->arRootSection["ID"] == $arParamsIsDir["item_id"]) { $files["files"]["iblock"] = $this->get_iblock_info($arr); if($this->_symlinkMode) { $files["files"]["iblock"]['path'] = $this->_path; if (SITE_CHARSET != "UTF-8") $files["files"]["iblock"]['path'] = $GLOBALS["APPLICATION"]->ConvertCharset($this->_path, SITE_CHARSET, "UTF-8"); } $arResult["IBLOCK"] = $arr; } else { $arResult["SECTION"] = $this->arParams["dir_array"]; if ($this->MetaNames($arResult["SECTION"])) $files["files"]["section"] = $this->_get_section_info_arr($arResult["SECTION"]); else unset($arResult["SECTION"]); } if (!empty($options["depth"])) { if (intVal($arParamsIsDir["item_id"]) <= 0) $arParamsIsDir["item_id"] = ($this->arRootSection ? $this->arRootSection["ID"] : $arParamsIsDir["item_id"]); // content search $arSearchResults = array(); if (isset($arParams["FILTER"]["content"]) && strlen($arParams["FILTER"]["content"])>0 && IsModuleInstalled('search') && CModule::IncludeModule('search')) { $obSearch = new CSearch; if (preg_match("/\\.[a-zA-Z]{3,4}$/", $arParams["FILTER"]["content"])) // search by file name? { $arParams["FILTER"]["content"] = '"'.$arParams["FILTER"]["content"].'"'; } $arSearchParams = array( "QUERY" => $arParams["FILTER"]["content"]); if (!$this->arRootSection) { $arSearchParams += array( "MODULE_ID" => "iblock", "PARAM_2" => $this->IBLOCK_ID); } else { if (isset($this->attributes['user_id'])) { $arSearchParams += array( "PARAMS" => array("socnet_user" => $this->attributes['user_id'])); } elseif (isset($this->attributes['group_id'])) { $arSearchParams += array( "PARAMS" => array("socnet_group" => $this->attributes['group_id'])); } } $obSearch->Search($arSearchParams); if ($obSearch->errorno != 0) { $arResult["ERROR_MESSAGE"] = $obSearch->error; } else { while($arSearchResultItem = $obSearch->GetNext()) { $arSearchResults[$arSearchResultItem['ITEM_ID']] = true; } } } $arSearchOptParams = array_flip(array("SHOW_NEW", "SHOW_HISTORY", "FILE_SIZE_multiply")); $arParams["function"] = "propfind"; $parentID = isset($arParams["FILTER"]) ? ((sizeof(array_diff_key($arParams["FILTER"], $arSearchOptParams))==0) ? $arParamsIsDir["item_id"] : null ) : $arParamsIsDir["item_id"]; if (isset($arParams["PARENT_ID"]) && intval($arParams["PARENT_ID"]) > 0) $parentID = $arParams["PARENT_ID"]; if (!empty($arParams["FILTER"])) { $arParams["FILTER"]["SHOW_NEW"] = "Y"; } if ($this->meta_state == "TRASH" && $this->workflow == "bizproc") { $arParams["FILTER"]["SHOW_HISTORY"] = "Y"; } if (isset($arParams["FILTER"]["doctype"])) { $arFileTypes = @unserialize(COption::GetOptionString("webdav", "file_types")); if ($arFileTypes !== false) { foreach ($arFileTypes as $arFileType) { if ($arParams["FILTER"]["doctype"] == $arFileType["ID"]) $arParams["FILTER"]["extension"] = str_replace(".","",$arFileType["EXTENSIONS"]); } } unset($arParams["FILTER"]["doctype"]); } if (isset($arParams["FILTER"]["extension"])) { $arFltExtensions = array_map('strtoupper', explode(" ", $arParams["FILTER"]["extension"])); } //$arResult["NAV_RESULT"] = $db_res; if (isset($arParams["FILTER"]["content"]) && (sizeof(array_diff_key($arParams["FILTER"], $arSearchOptParams)) === 1)) { // there is only content search unset($arParams["FILTER"]["content"]); unset($arParams["FILTER"]["FILE_SIZE_multiply"]); foreach ($arSearchResults as $itemID => $nopValue) { $arParams["FILTER"]["ID"] = $itemID; $db_res = $this->_get_mixed_list(null, $arParams); if ($db_res && $res = $db_res->Fetch()) { if ($this->MetaNames($res)) { if ($res["TYPE"] == "S") { if (!$this->MetaSectionHide($res)) { $files["files"]["S".$res["ID"]] = $this->_get_section_info_arr($res); $arResult["RESULT"]["S".$res["ID"]] = $res; } } else { $files["files"]["F".$res["ID"]] = $this->_get_file_info_arr($res, $arParams); $arResult["RESULT"]["E".$res["ID"]] = $res; } } } } } else { // there are some other fields to search $db_res = $this->_get_mixed_list($parentID, $arParams); if ($db_res && $res = $db_res->Fetch()) { do { if (!empty($arSearchResults) && !isset($arSearchResults[$res["ID"]])) continue; $this->_parse_webdav_info($res); if ($this->meta_state != 'TRASH' && isset($res['PROPS']['BX:']['UNDELETE'])) continue; if ($this->MetaNames($res)) { if ($res["TYPE"] == "S") { if (!$this->MetaSectionHide($res)) { if (empty($arParams["FILTER"]) || $this->meta_state == "TRASH" || !empty($arParams['FILTER']['SHOW_SECTIONS'])) { $files["files"]["S".$res["ID"]] = $this->_get_section_info_arr($res); $arResult["RESULT"]["S".$res["ID"]] = $res; } } } else { if (isset($arFltExtensions)) { $ext = GetFileExtension($res["NAME"]); if (! in_array(strtoupper($ext), $arFltExtensions)) continue; } $files["files"]["F".$res["ID"]] = $this->_get_file_info_arr($res, $arParams); $arResult["RESULT"]["E".$res["ID"]] = $res; } } } while ($res = $db_res->Fetch()); } } } } if ($this->e_rights && (sizeof($arResult['RESULT']) <= 0) && (!$this->GetPermission('SECTION', $arParamsIsDir['item_id'], 'section_read'))) // prevent path disclosure { $options['check_permissions'] = true; $arParamsIsDir = $this->GetObject($options); if ($arParamsIsDir["not_found"] === true) { return $this->ThrowError( "404 Not Found", "DESTINATION_FILE_OR_FOLDER_IS_NOT_FOUND", GetMessage("WD_FOLDER_NOT_FOUND"), __LINE__); } } if ($arParams["return"] == "array") { return $arResult; } elseif ($arParams["return"] == "nav_result") { $arResult["NAV_RESULT"] = new CDBResult; $arResult["NAV_RESULT"]->InitFromArray($arResult["RESULT"]); return $arResult; } return true; } function GET(&$options) { if (count($this->arParams) <= 0) { $this->IsDir($options); } $arParams = $this->arParams; $this->_get_file_info_arr($arParams); if ($this->arParams["not_found"]) { return false; } elseif($this->withoutAuthorization !== true) { if (!$this->CheckWebRights("", array('action' => 'read', 'arElement' => $arParams), false)) { return $this->ThrowAccessDenied(__LINE__); } elseif ($this->arParams["element_array"]["WF_NEW"] == "Y" || (intVal($this->arParams["element_array"]["WF_PARENT_ELEMENT_ID"]) > 0 && $this->arParams["element_array"]["WF_PARENT_ELEMENT_ID"] != $this->arParams["element_array"]["ID"]) || $this->arParams["element_array"]["BP_PUBLISHED"] != "Y") { $res = $this->arParams["element_array"]; $this->_get_file_info_arr($res); if ($this->CheckRight($res["PERMISSION"], 'element_read') <= "D") { return false; } } } $arElement = $this->arParams['element_array']; if ($this->workflow == 'workflow' && $this->permission < "W" && $res["STATUS_PERMISSION"] < 2) // permissions are not enouph to edit { $arElement = $this->arParams['original']; //$arParams["fullpath"] = CFile::GetPath($arElement["PROPERTY_".$this->file_prop."_VALUE"]); } $options["mimetype"] = $arParams["file_mimetype"]; $options["mtime"] = MakeTimeStamp($arElement["TIMESTAMP_X"]); $options["size"] = $arParams["file_size"]; $options["name"] = $arElement["NAME"]; $arTmpFile = CFile::MakeFileArray($arParams['file_id']); if (!(is_array($arTmpFile) && is_set($arTmpFile, 'tmp_name'))) { return false; } $io = self::GetIo(); if(!empty($options['getContent'])) { if(file_exists($io->GetPhysicalName($arTmpFile['tmp_name']))) { $options['content'] = $io->GetFile($io->GetPhysicalName($arTmpFile['tmp_name']))->GetContents(); } elseif(file_exists($arTmpFile['tmp_name'])) { $options['content'] = file_get_contents($arTmpFile['tmp_name']); } else { $options['content'] = null; } } else { if(file_exists($io->GetPhysicalName($arTmpFile['tmp_name']))) { $options['stream'] = fopen($io->GetPhysicalName($arTmpFile['tmp_name']), 'rb'); } elseif(file_exists($arTmpFile['tmp_name'])) { $options['stream'] = fopen($arTmpFile['tmp_name'], 'rb'); } else { return false; } } if (empty($options["mimetype"]) || $options["mimetype"] == "unknown" || $options["mimetype"] == "application/octet-stream") { $options["mimetype"] = $this->get_mime_type($arParams["file_name"]); } return true; } function PUT(&$options) { WDUnpackCookie(); $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] = (is_string($_SESSION["WEBDAV_DATA"]["PUT_EMPTY"]) ? $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] : ""); $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] = (is_string($_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"]) ? $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] : ""); $this->IsDir($options, true); if ($this->arParams["is_dir"] === true) return "409 Conflict"; if ($this->arParams["parent_id"] === false) return false; $options["new"] = ($this->arParams["not_found"] === true); $options["ELEMENT_ID"] = $this->arParams["item_id"]; if (!$this->CheckWebRights("PUT", array('arElement' => $this->arParams))) { $this->ThrowAccessDenied(__LINE__); return false; } $options["FILE_NAME"] = (!empty($this->arParams["file_name"]) ? $this->arParams["file_name"] : $this->arParams["basename"]); $options["FILE_NAME"] = $this->CorrectName($options["FILE_NAME"]); $options["~path"] = $this->_udecode($options["path"]); $options["set_now"] = false; if (($_SERVER['REQUEST_METHOD'] == "PUT" || $_SERVER['REQUEST_METHOD'] == "LOCK") && /*empty($_SESSION["WEBDAV_DATA"]["PUT_EMPTY"]) && */ intVal($options["content_length"]) <= 0) { // Sometimes file is uploaded in 2 steps: 1) PUT with content_length == 0, when PUT with content_length >= 0. $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] = $options["~path"]; $options["set_now"] = true; } if (!empty($_SESSION["WEBDAV_DATA"]["PUT_EMPTY"]) && $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] != $options["~path"]) { if ($_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] == $options["~path"]) { } elseif (substr($options["FILE_NAME"], 0, 2) == "._" && $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] == str_replace($options["FILE_NAME"], substr($options["FILE_NAME"], 2), $options["~path"])) { // Mac OS uploads in 4 PUT: <br> // 1. PUT with content_length == 0; // 2. PUT with content_length == 0 && file_name == "._".file_name; // 3. PUT with content_length >= 0 && file_name == "._".file_name; // 4. PUT with content_length >= 0. $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] = $options["~path"]; } else { $_SESSION["WEBDAV_DATA"] = array(); } } WDPackCookie(); if (!empty($_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"]) && $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] == $options["~path"]) { "no need to check data"; } elseif (!$options["set_now"] && !empty($_SESSION["WEBDAV_DATA"]["PUT_EMPTY"]) && $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] == $options["~path"]) { "no need to check data"; } elseif (!$this->CheckWebRights("", $options = array_merge($options, array( "action" => ($this->arParams["not_found"] ? "create" : "edit"), "arElement" => $this->arParams)), false)) { $this->ThrowAccessDenied(__LINE__); return false; } elseif ($this->check_creator && $this->arParams["is_file"] === true && $this->arParams["element_array"]["CREATED_BY"] != $GLOBALS["USER"]->GetID()) { $this->ThrowAccessDenied(__LINE__); return false; } $options["IBLOCK_SECTION_ID"] = $this->arParams["parent_id"]; if ($this->arParams["parent_id"] <= 0 && $this->arRootSection) $options["IBLOCK_SECTION_ID"] = $this->arRootSection["ID"]; $options["TMP_FILE"] = CTempFile::GetFileName($options["FILE_NAME"]); CheckDirPath($options["TMP_FILE"]); $fp = fopen($options["TMP_FILE"], "w"); return $fp; } function _ib_elm_update($id, $arFields, $workflow=false) { global $APPLICATION; global $USER_FIELD_MANAGER; if (is_string($workflow)) $workflow = ($workflow == 'workflow'); $id = intval($id); if ($id <= 0) return false; $bUF = (isset($arFields['USER_FIELDS'])); if ($bUF) { $UF_ENTITY = $this->GetUfEntity(); if ( ! $USER_FIELD_MANAGER->CheckFields($UF_ENTITY, $id, $arFields['USER_FIELDS'])) { if(is_object($APPLICATION) && $APPLICATION->GetException()) { $e = $APPLICATION->GetException(); $this->LAST_ERROR .= $e->GetString(); return false; } } } $el = new CIBlockElement; if ($workflow) { if ($bUF) $handlerID = AddEventHandler('search', 'BeforeIndex', array($this, 'IndexUfValues')); $result = $el->Update($id, $arFields, $workflow); if ($bUF) RemoveEventHandler('search', 'BeforeIndex', $handlerID); if(!$result) { $this->LAST_ERROR = $el->LAST_ERROR; return false; } else { if (isset($arFields['USER_FIELDS'])) { $USER_FIELD_MANAGER->Update($UF_ENTITY, $id, $arFields['USER_FIELDS']); } } } else { $arFields['WF_STATUS_ID'] = 1; $arProperties = (isset($arFields['PROPERTY_VALUES']) ? $arFields['PROPERTY_VALUES'] : false); unset($arFields['PROPERTY_VALUES']); if ($bUF) $handlerID = AddEventHandler('search', 'BeforeIndex', array($this, 'IndexUfValues')); if ($arProperties !== false) { if( isset($this->arParams['element_array']['ID']) && isset($this->arParams['element_array']['IBLOCK_ID']) && $this->arParams['element_array']['ID'] == $id ) { $iblockId = $this->arParams['element_array']['IBLOCK_ID']; } else { $iblockId = $this->IBLOCK_ID; } foreach ($arProperties as $code => $value) { if($code === 'FILE') { $el->SetPropertyValuesEx($id, $iblockId, array($code => $value)); } else { $el->SetPropertyValues($id, $iblockId, $value, $code); } } if (! $this->ValidatePropertyValues($id, $arProperties, $iblockId)) // as SetPropertyValues doesn't handle SaveFile errors { $this->LAST_ERROR = GetMessage("WD_FILE_ERROR111"); return false; } } if (isset($arFields['USER_FIELDS']) && !empty($arFields['USER_FIELDS']) ) { $USER_FIELD_MANAGER->Update($UF_ENTITY, $id, $arFields['USER_FIELDS']); } $result = $el->Update($id, $arFields, $workflow, true); if(!$result) { if ($bUF) RemoveEventHandler('search', 'BeforeIndex', $handlerID); $this->LAST_ERROR = $el->LAST_ERROR; return false; } if ($bUF) RemoveEventHandler('search', 'BeforeIndex', $handlerID); } $element = CIBlockElement::GetList(array(), array('ID' => $id), false, false, array('ID', 'IBLOCK_SECTION_ID', 'IBLOCK_CODE', 'IBLOCK_ID'))->fetch(); CWebDavDiskDispatcher::sendEventToOwners($element, null, 'update'); return $result; } function put_commit(&$options) { if(!empty($options["IBLOCK_SECTION_ID"])) { $sectionData = $this->getSectionDataForLinkAnalyze($options["IBLOCK_SECTION_ID"], $this->getObject(array('section_id' => $options["IBLOCK_SECTION_ID"]))); //simple detect link list($contextType, $contextEntityId) = $this->getContextData(); $isSymlink = !$this->_symlinkMode && CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData); if($isSymlink) { $symlinkSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($symlinkSectionData) { $linkWebdav = new self($symlinkSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array_merge($this->_originalParams, array( 'ROOT_SECTION_ID' => $symlinkSectionData[self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $symlinkSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, ))); $options = array_merge($options, array( 'IBLOCK_ID' => $symlinkSectionData[self::UF_LINK_IBLOCK_ID], 'IBLOCK_SECTION_ID' => $sectionData['ID'], )); return $linkWebdav->put_commit($options); } } } $ID = intVal($options["ELEMENT_ID"]); $arError = array(); $arFile = array( "name" => $options["FILE_NAME"], "size" => $options["content_length"], "tmp_name" => $options["TMP_FILE"], "type" => "", "error" => 0); if(!empty($options['HEIGHT'])) { $arFile['HEIGHT'] = $options['HEIGHT']; } if(!empty($options['WIDTH'])) { $arFile['WIDTH'] = $options['WIDTH']; } if (is_set($options, "arFile")) $arFile = $options["arFile"]; if (isset($arFile['tmp_name']) && is_file($arFile['tmp_name'])) { if (intval($arFile["size"]) <= 0) $arFile["size"] = filesize($arFile["tmp_name"]); if (($arFile['type'] == '') && ($arFile["size"] > 0)) { $arFile["type"] = CFile::GetContentType($arFile['tmp_name'], true); } if (($arFile['type'] == '') || ($arFile['type'] == 'application/zip') // fix old magic.mime ) $arFile['type'] = $this->get_mime_type($arFile['name']); } if (isset($arFile['tmp_name']) && strlen($arFile["type"])<=0) $arFile["type"] = $this->get_mime_type($options["FILE_NAME"]); $bDropped = isset($options['dropped']) ? $options['dropped'] : false; @set_time_limit(1000); if (is_set($options, "~path") && $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] == $options["~path"]) { // "For Mac OS"; if ($options["new"]) { $arr = array( "ACTIVE" => "N", "IBLOCK_ID" => $this->IBLOCK_ID, "IBLOCK_SECTION_ID" => $options["IBLOCK_SECTION_ID"], "NAME" => $options["FILE_NAME"], "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "PROPERTY_VALUES" => array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'] )); if ($arFile["size"] <= 0) unset($arr["PROPERTY_VALUES"]); $ID = $this->_ib_elm_add($arr, false, false, false); if (!$ID) { return false; } else { $this->arParams["changed_element_id"] = $ID; } } else { $arr = array( "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "PROPERTY_VALUES" => array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'] )); $res = $this->_ib_elm_update($options["ELEMENT_ID"], $arr, false); if(!$res) return false; } } elseif (is_set($options, "~path") && $this->workflow && !$options["set_now"] && $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] == $options["~path"]) { $arr = array( "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "PROPERTY_VALUES" => array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'] )); $res = $this->_ib_elm_update($options["ELEMENT_ID"], $arr, ($this->workflow == 'workflow')); if(!$res) return false; //if ($this->workflow == 'bizproc_limited' || $this->workflow == 'bizproc') //{ /** * Update history comments */ //$documentId = array($this->wfParams['DOCUMENT_TYPE'][0], $this->wfParams['DOCUMENT_TYPE'][1], $options["ELEMENT_ID"]); //$history = new CBPHistoryService(); //$db_res = $history->GetHistoryList( //array("ID" => "DESC"), //array("DOCUMENT_ID" => $documentId), //false, //false, //array("ID", "DOCUMENT", "NAME") //); //if ($db_res && $arr = $db_res->Fetch()) //{ //$fullpath = $_SERVER["DOCUMENT_ROOT"].$arr["DOCUMENT"]["PROPERTIES"][$this->file_prop]["VALUE"]; //if (!file_exists($fullpath) || filesize($fullpath) <= 0) //CBPHistoryService::Delete($arr["ID"], $documentId); //CBPDocument::AddDocumentToHistory($documentId, $arr["NAME"], $GLOBALS["USER"]->GetID()); //} //} $_SESSION["WEBDAV_DATA"] = array(); WDPackCookie(); } else { if ($this->workflow == "workflow" && $this->permission < "W") // && (is_set($options, "WF_STATUS_ID") || $options["ELEMENT_ID"] <= 0)) { $fw_status_id = (is_set($options, "WF_STATUS_ID") ? $options["WF_STATUS_ID"] : false); $arStatusesPermission = array(); $db_res = CWorkflowStatus::GetDropDownList("N", "desc"); while ($db_res && $res = $db_res->Fetch()) { $perm = CIBlockElement::WF_GetStatusPermission($res["REFERENCE_ID"]); if ($perm < 1) continue; $arStatusesPermission[intVal($res["REFERENCE_ID"])] = $perm; if ((($fw_status_id === false) && $perm >= 2) || $fw_status_id == $res["REFERENCE_ID"]) { $fw_status_id = $res["REFERENCE_ID"]; break; } } if (empty($arStatusesPermission)) { $this->LAST_ERROR = GetMessage("WD_FILE_ERROR_EMPTY_STATUSES"); return false; } elseif ($options["WF_STATUS_ID"] == $fw_status_id && !array_key_exists($fw_status_id, $arStatusesPermission)) { $res = array_flip($arStatusesPermission); $fw_status_id = (isset($res[2]) ? $res[2] : reset($res)); } $options["WF_STATUS_ID"] = $fw_status_id; } /** * Validate bizproc input parameters for begining BP */ elseif ( ($this->workflow == 'bizproc') && (! $bDropped) ) { $arDocumentStates = array(); if (is_set($options, "arDocumentStates")) { $arDocumentStates = $options["arDocumentStates"]; } elseif (is_set($this->wfParams, "arDocumentStates")) { $arDocumentStates = $this->wfParams["arDocumentStates"]; } else { $arDocumentStates = CBPDocument::GetDocumentStates( $this->wfParams['DOCUMENT_TYPE'], ( $options["ELEMENT_ID"] > 0 ? array( $this->wfParams['DOCUMENT_TYPE'][0], $this->wfParams['DOCUMENT_TYPE'][1], $options["ELEMENT_ID"]) : null ) ); } foreach ($arDocumentStates as $key => $arDocumentState) { if (strlen($arDocumentState["ID"]) <= 0 && is_array($arDocumentState["TEMPLATE_PARAMETERS"])) { $templateId = $arDocumentState["TEMPLATE_ID"]; foreach ($arDocumentState["TEMPLATE_PARAMETERS"] as $key => $arWorkflowParameters) $_REQUEST["bizproc".$templateId."_".$key] = (array_key_exists("bizproc".$templateId."_".$key, $_REQUEST) ? $_REQUEST["bizproc".$templateId."_".$key] : $arWorkflowParameters["Default_printable"]); } } $arBizProcParametersValues = $arErrors = array(); if (!CIBlockDocumentWebdav::StartWorkflowsParametersValidate($this->wfParams["DOCUMENT_TYPE"], $arDocumentStates, $arBizProcParametersValues, $arErrors)) { $e = new CAdminException($arErrors); $this->LAST_ERROR = $e->GetString(); return false; } } /** * Add or update or clone elements */ if ($options["clone"]) { $arr = array( "CREATED_BY" => $GLOBALS["USER"]->GetID(), "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "PROPERTY_VALUES" => array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'], static::PROPERTY_VERSION => 1, )); foreach (array("NAME", "TAGS", "PREVIEW_TEXT", "PREVIEW_TEXT_TYPE", "ACTIVE", "WF_COMMENTS", "WF_STATUS_ID") as $key) if (is_set($options, $key)) $arr[$key] = $options[$key]; if ($arFile["size"] <= 0) unset($arr["PROPERTY_VALUES"]); $options["ELEMENT_ID"] = $ID = call_user_func_array( array($this->wfParams['DOCUMENT_TYPE'][1], "CloneElement"), array($options["PARENT_ELEMENT_ID"], $arr)); CIBlockElement::SetPropertyValues($options["ELEMENT_ID"], $this->IBLOCK_ID, array(0), "FORUM_MESSAGE_CNT"); CIBlockElement::SetPropertyValues($options["ELEMENT_ID"], $this->IBLOCK_ID, array(0), "FORUM_TOPIC_ID"); } elseif ($options["new"]) { $arr = array( "ACTIVE" => "Y", "IBLOCK_ID" => $this->IBLOCK_ID, "IBLOCK_SECTION_ID" => $options["IBLOCK_SECTION_ID"], "NAME" => $options["FILE_NAME"], "TAGS" => $options["TAGS"], "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "PREVIEW_TEXT_TYPE" => "html", "PREVIEW_TEXT" => $options["PREVIEW_TEXT"], "WF_COMMENTS" => (!empty($options["WF_COMMENTS"]) ? $options["WF_COMMENTS"] : GetMessage("WD_FILE_IS_CREATED")), "PROPERTY_VALUES" => array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'], static::PROPERTY_VERSION => 1, ), ); if (isset($options['USER_FIELDS'])) $arr["USER_FIELDS"] = $options['USER_FIELDS']; if ( ($this->workflow == 'workflow') && isset($options["WF_STATUS_ID"]) ) $arr["WF_STATUS_ID"] = $options["WF_STATUS_ID"]; else $arr["WF_STATUS_ID"] = 1; if ($this->workflow == 'bizproc') $arr["BP_PUBLISHED"] = (($this->wfParams["AUTO_PUBLISH"] == "Y") || $bDropped) ? "Y" : "N"; $options["ELEMENT_ID"] = $ID = $this->_ib_elm_add( $arr, (($_SERVER['REQUEST_METHOD'] != "LOCK" || $this->workflow != "workflow") && $this->workflow != false), ($arFile['size'] > 0), false ); if (!$ID) { return false; } else { $this->arParams["changed_element_id"] = $ID; } } else // update { $arUpdateType = array(); $arr = array( "MODIFIED_BY" => $GLOBALS["USER"]->GetID(), "WF_COMMENTS" => GetMessage("WD_FILE_IS_MODIFIED") ); if (isset($options['USER_FIELDS'])) $arr["USER_FIELDS"] = $options['USER_FIELDS']; if (!empty($arFile)) { $arr["PROPERTY_VALUES"] = array( $this->file_prop => $arFile, "WEBDAV_SIZE" => $arFile['size'], ); $arUpdateType[] = 'FILE'; } $element = $this->GetObject(array('element_id' => $options["ELEMENT_ID"])); foreach (array("NAME", "TAGS", "PREVIEW_TEXT", "ACTIVE", "IBLOCK_SECTION_ID", "WF_COMMENTS", "WF_STATUS_ID") as $key) { if (is_set($options, $key)) { $arr[$key] = $options[$key]; if ( isset($element['element_array'][$key]) && ($element['element_array'][$key] != $options[$key]) ) { $arUpdateType[] = $key; } } } //if ($arFile["size"] <= 0) //unset($arr["PROPERTY_VALUES"]); if (is_set($arr, "PREVIEW_TEXT")) $arr["PREVIEW_TEXT_TYPE"] = 'html'; if (is_set($arr, "IBLOCK_SECTION_ID")) { $arr["IBLOCK_SECTION_ID"] = intval($arr["IBLOCK_SECTION_ID"]); if ($this->arRootSection && $arr["IBLOCK_SECTION_ID"] <= 0) $arr["IBLOCK_SECTION_ID"] = $this->arRootSection["ID"]; } if ($_SERVER['REQUEST_METHOD'] != "LOCK" && !$options["clone"] && ($this->workflow == 'bizproc_limited' || $this->workflow == 'bizproc')) { if(empty($arr["PROPERTY_VALUES"])) { $arr["PROPERTY_VALUES"] = array(); } if(empty($element['element_array']['PROPERTY_' . static::PROPERTY_VERSION . '_VALUE'])) { //+1 - version from HEAD $countAlreadyInHistory = (int)$this->countHistoryDocumentByFileId($options["ELEMENT_ID"]) + 1; } else { $countAlreadyInHistory = $element['element_array']['PROPERTY_' . static::PROPERTY_VERSION . '_VALUE']; } $arr["PROPERTY_VALUES"][static::PROPERTY_VERSION] = $countAlreadyInHistory + 1; $options['THROUGH_VERSION'] = $arr["PROPERTY_VALUES"][static::PROPERTY_VERSION]; $this->AddDocumentToHistory($ID, $options['FILE_NAME']); } $res = $this->_ib_elm_update($options["ELEMENT_ID"], $arr, ($this->workflow == "workflow")); if(!$res) { return false; } $ID = $options["ELEMENT_ID"]; $this->_onEvent('Update', $ID, 'FILE', array('UPDATE_TYPE' => $arUpdateType)); if ($this->workflow == 'bizproc' && is_set($arr, "IBLOCK_SECTION_ID")) { $db_res2 = CIBlockElement::GetList(array(), array("WF_PARENT_ELEMENT_ID" => $options["ELEMENT_ID"], "SHOW_HISTORY" => "Y"), false, false, array("ID")); if ($db_res2 && $res2 = $db_res2->Fetch()) { do { $ar = array("IBLOCK_SECTION_ID" => $arr["IBLOCK_SECTION_ID"]); $res = $this->_ib_elm_update($res2["ID"], $ar, false); } while ($res2 = $db_res2->Fetch()); } } } $documentId = $this->wfParams["DOCUMENT_TYPE"]; $documentId[2] = $ID; if ( ($this->workflow == 'bizproc') && (! $bDropped) ) { if (!CIBlockDocumentWebdav::StartWorkflowsExecuting($documentId, $arDocumentStates, $arBizProcParametersValues, $options["arUserGroups"], $arErrors, $this->wfParams)) { $e = new CAdminException($arErrors); $this->LAST_ERROR = $e->GetString(); } } } $this->CACHE['CWebDavIblock::GetObject'] = array(); return true; } function AddDocumentToHistory($docID, $fileName) { global $USER; $documentId = $this->wfParams["DOCUMENT_TYPE"]; $documentId[2] = $docID; $userID = $USER->GetID(); $rDoc = CIBlockElement::GetList( array(), array( 'ID' => $docID, ), false, false, array('MODIFIED_BY') ); if ($rDoc && $arDoc = $rDoc->Fetch()) { $userID = $arDoc['MODIFIED_BY']; } $historyDoc = CWebdavDocumentHistory::IsHistoryUpdate($documentId); $historyIndex = false; if ($historyDoc) { $historyIndex = CWebdavDocumentHistory::UpdateDocumentHistory($documentId, $historyDoc['ID']); } else { $historyIndex = CBPDocument::AddDocumentToHistory($documentId, $fileName, $userID); } return $historyIndex; } function _get_lock(&$options, array $element = array()) { $strProps = ""; if($element) { $strProps = $element["PROPERTY_WEBDAV_INFO_VALUE"]; $arProps = @unserialize($strProps); $arProps = (!is_array($arProps) ? array() : $arProps); return $arProps; } $this->IsDir($options, true); if ($this->arParams["not_found"] === true) { return "404 Not Found"; } elseif ($this->arParams["is_dir"] === true) { $strProps = $this->arParams["dir_array"]["DESCRIPTION"]; } else { $strProps = $this->arParams["element_array"]["PROPERTY_WEBDAV_INFO_VALUE"]; } $arProps = @unserialize($strProps); $arProps = (!is_array($arProps) ? array() : $arProps); return $arProps; } function _set_lock(&$options, $op) { $lock = ($op == 'LOCK'); $is_dir = false; $ID = 0; $bFirstElement = false; $arProps = $this->_get_lock($options); if(!$this->CheckWebRights("", array('action' => 'lock', 'arElement' => $this->arParams))) return $this->ThrowAccessDenied(__LINE__); if (!is_array($arProps)) // arProps == 404 not found { if ($lock && $this->arParams['not_found'] === true) // create file by lock { if (!$this->CheckName($this->arParams["basename"])) { return "400 bad request"; } elseif ($this->check_creator && $this->arParams["is_file"] === true && $this->arParams["element_array"]["CREATED_BY"] != $GLOBALS["USER"]->GetID()) { return $this->ThrowAccessDenied(__LINE__); } elseif ($this->arParams["parent_id"] !== false) { $options1 = array( 'path' => $options["path"], 'content_length' => 0, 'content_type' => "", 'WF_COMMENTS' => GetMessage("WD_FILE_IS_CREATED_BY_LOCK")); $stat = $this->PUT($options1); if ($stat === false) { return $this->ThrowAccessDenied(__LINE__); } elseif (is_string($stat)) { return $stat; } else { if ( is_resource($stat) && get_resource_type($stat) == 'stream' ) fclose($stat); if ( !$this->CheckWebRights( "", array( "action" => "create", "arElement" => $this->arParams ) ) ) return $this->ThrowAccessDenied(__LINE__); $this->put_commit($options1); } $ID = intVal($options1["ELEMENT_ID"]); if ($ID <= 0) return "409 Conflict"; else return "200 OK"; } else { return $arProps; // 404 not found } } return $arProps; // error in _get_lock } $ID = $this->arParams['item_id']; $is_dir = $this->arParams["is_dir"]; if ($lock) { if ($is_dir && !empty($options["depth"])) { return "409 Conflict"; } elseif (!$is_dir && CIBlockElement::WF_IsLocked($ID, $locked_by, $date_lock)) { return false; } $options["timeout"] = time() + 300; // 5min. hardcoded if (isset($options["update"]) ) { $token = $options["update"]; $arProps["LOCK"] = (is_array($arProps["LOCK"]) ? $arProps["LOCK"] : array()); if (array_key_exists($token, $arProps["LOCK"]) && strlen($arProps["LOCK"][$token]["exclusivelock"]) > 0) { $arProps["LOCK"][$token]["expires"] = $options["timeout"]; $arProps["LOCK"][$token]["modified"] = time(); if (array_key_exists("owner", $arProps["LOCK"][$token])) { $options["owner"] = $arProps["LOCK"][$token]["owner"]; } $options["scope"] = $arProps["LOCK"][$token]["exclusivelock"] ? "exclusive" : "shared"; $options["type"] = $arProps["LOCK"][$token]["exclusivelock"] ? "write" : "read"; if ($bFirstElement) { $arProps["FIRST"] = "Y"; } CIBlockElement::SetPropertyValues($ID, $this->IBLOCK_ID, serialize($arProps), "WEBDAV_INFO"); CIBlockElement::WF_Lock($ID); $this->_onEvent('Lock', $ID); return true; } else { return false; } } $arProps["LOCK"][$options["locktoken"]] = array( "created" => time(), "modified" => time(), "owner" => $options["owner"], "expires" => $options["timeout"], "locktoken" => $options["locktoken"], "exclusivelock" => ($options["scope"] === "exclusive" ? 1 : 0) ); } else { if (!empty($options["token"])) { $token = $options["token"]; unset($arProps["LOCK"][$token]); } else { unset($arProps["LOCK"]); } if ($this->workflow == 'bizproc' && $GLOBALS['USER']->CanDoOperation('webdav_change_settings')) // admin can remove bizproc locks { $arDocId = $this->wfParams["DOCUMENT_TYPE"]; $arDocId[2] = $ID; $arStates = CBPDocument::GetDocumentStates($this->wfParams["DOCUMENT_TYPE"], $arDocId); foreach ($arStates as $workflowId => $arState) { CIBlockDocumentWebdav::UnlockDocument($ID, $workflowId); } } } if ($is_dir) { $se = new CIBlockSection(); $x = $se->Update($ID, array("DESCRIPTION" => serialize($arProps))); } else { if ($lock && $bFirstElement) $arProps["FIRST"] = "Y"; CIBlockElement::SetPropertyValues($ID, $this->IBLOCK_ID, serialize($arProps), "WEBDAV_INFO"); if ($lock) CIBlockElement::WF_Lock($ID, ($this->workflow == "workflow")); else CIBlockElement::WF_UnLock($ID, ($this->workflow == "workflow")); $this->_onEvent(($lock ? 'Lock' : 'Unlock'), $ID); $x = true; } return $x ? ($lock ? "200 OK" : "204 No Content") : "409 Conflict"; } function LOCK(&$options) { return $this->_set_lock($options, 'LOCK'); } function UNLOCK(&$options) { return $this->_set_lock($options, 'UNLOCK'); } function MOVE($options) { return $this->COPY($options, true); } function _move_form_section_to_section($arData = array(), $iFromSectionID = 0, $iToSectionID = 0, $arParams = array()) // out of date { } static function _move_from_iblock_to_iblock($elementId, $targetIblockId, $targetSectionId = 0, $delete = true, $setNewNameIfNonUnique = false) { $elementId = intval($elementId); $targetIblockId = intval($targetIblockId); $targetSectionId = intval($targetSectionId); if (($elementId <= 0) || ($targetIblockId <= 0)) return false; $dbElement = CIBlockElement::GetList(array(), array("ID"=>$elementId, "SHOW_HISTORY"=>"Y"), false, false, array( "ID", "MODIFIED_BY", "DATE_CREATE", "CREATED_BY", "IBLOCK_ID", "ACTIVE", "ACTIVE_FROM", "ACTIVE_TO", "SORT", "NAME", "PREVIEW_PICTURE", "PREVIEW_TEXT", "PREVIEW_TEXT_TYPE", "DETAIL_PICTURE", "DETAIL_TEXT", "DETAIL_TEXT_TYPE", "WF_STATUS_ID", "WF_PARENT_ELEMENT_ID", "WF_COMMENTS", "IN_SECTIONS", "CODE", "TAGS", "XML_ID", "TMP_ID", ) ); if($element = $dbElement->Fetch()) { $IBLOCK_ID = $element["IBLOCK_ID"]; if($element["WF_PARENT_ELEMENT_ID"] > 0) { return false; } else { //public doc. $element["WF_STATUS_ID"] = 1; unset($element["WF_NEW"]); if($element["PREVIEW_PICTURE"]) $element["PREVIEW_PICTURE"] = CFile::MakeFileArray($element["PREVIEW_PICTURE"]); if($element["DETAIL_PICTURE"]) $element["DETAIL_PICTURE"] = CFile::MakeFileArray($element["DETAIL_PICTURE"]); $element["IBLOCK_SECTION_ID"] = $targetSectionId; $element["IN_SECTIONS"] = "N"; $element["PROPERTY_VALUES"] = array(); $arProps = &$element["PROPERTY_VALUES"]; //Add new property values $rsProps = CIBlockElement::GetProperty($element["IBLOCK_ID"], $element["ID"], array("value_id" => "asc")); $i = 0; while($arProp = $rsProps->Fetch()) { $i++; if(!array_key_exists($arProp["CODE"], $arProps)) $arProps[$arProp["CODE"]] = array(); if($arProp["PROPERTY_VALUE_ID"]) { if($arProp["PROPERTY_TYPE"] == "F") $arPropValue = array( "VALUE" => CFile::MakeFileArray($arProp["VALUE"]), "DESCRIPTION" => $arProp["DESCRIPTION"], ); else { if ($arProp["VALUE_XML_ID"] != null) { $arPropValue = array( "VALUE_XML_ID" => $arProp["VALUE_XML_ID"], "DESCRIPTION" => $arProp["DESCRIPTION"], ); } else { $arPropValue = array( "VALUE" => $arProp["VALUE"], "DESCRIPTION" => $arProp["DESCRIPTION"], ); } } $arProps[$arProp["CODE"]]["n".$i] = $arPropValue; } } $element["IBLOCK_ID"] = $targetIblockId; if($setNewNameIfNonUnique) { $mainPartName = $element['NAME']; $newName = $mainPartName; $count = 0; while(!self::sCheckUniqueName($targetIblockId, $targetSectionId, '', $newName, $res)) { $count++; $newName = strstr($mainPartName, '.', true) . " ({$count})" . strstr($mainPartName, '.'); } $element['NAME'] = $newName; } $newElement = new CIBlockElement; $newId = $newElement->Add($element); if(!$newId) { return false; } else { $element['ID'] = $newId; CWebDavDiskDispatcher::sendEventToOwners($element, null, 'move_from_block_to_block'); if ($delete === true) { $ibe = new CIBlockElement(); $result = $ibe->Delete($elementId); } return $newId; } } } else { return false; } } function COPY($options, $drop = false) { $statusSymlinkDelete = false; $arCacheCleanID = array(); if(!$this->CheckWebRights("", array("action" => "create"), true)) { return $this->ThrowAccessDenied(__LINE__); } elseif($_SERVER['REQUEST_METHOD'] == "MOVE" && !empty($_SERVER["CONTENT_LENGTH"])) { return "415 Unsupported media type"; } elseif($options["path"] == $options["dest_url"]) { return "204 No Content"; } elseif(empty($options["dest_url"])) { return $this->ThrowError("502 bad gateway", "EMPTY_DESTINATION_URL", GetMessage("WD_FILE_ERROR2"), __LINE__); } $destUrl = $options["dest_url"]; if(substr($destUrl, -1) === "/") { $destUrl = substr($destUrl, 0, -1); } $destName = GetFileName($destUrl); if($destUrl !== "" && $destName !== "") { $destParentDir = GetDirPath($destUrl); $destParentDir = (count($destParentDir) > 0 ? $destParentDir : "/"); $o = array("path" => $destParentDir, "depth" => 1); $result = $this->PROPFIND($o, $files, array("COLUMNS" => array("ID", "NAME"), "return" => "array")); if (!empty($result["RESULT"])) { foreach ($result["RESULT"] as $key => $res) { if($res["NAME"] === $destName) { if(strlen(GetFileExtension($destName)) > 0) { return $this->ThrowError("400 Bad Request", "FOLDER_IS_EXISTS", str_replace("#FILE#", '"' .$res["NAME"] . '"', GetMessage("WD_FILE_ERROR8")), __LINE__); } elseif(isset($options['section_id']) && $res['ID'] == $options['section_id']) { return $this->ThrowError("400 Bad Request", "SAME_FOLDER_IS_EXISTS", str_replace("#FOLDER#", '"' .$res["NAME"] . '"', GetMessage("WD_FILE_ERROR5")), __LINE__); } else { return $this->ThrowError("400 Bad Request", "FOLDER_IS_EXISTS", str_replace("#FOLDER#", '"' .$res["NAME"] . '"', GetMessage("WD_FILE_ERROR5")), __LINE__); } } } } } //$this->CheckUniqueName($basename, $section_id, &$res) //GetFileName() $arFrom = array(); $arTo = array(); $is_dir = false; ////////////// CHECK FROM $this->IsDir($options); $arFrom = $this->arParams; if($this->arParams["not_found"]) { return $this->ThrowError("404 Not Found", "DESTINATION_FILE_OR_FOLDER_IS_NOT_FOUND", GetMessage("WD_FILE_ERROR3"), __LINE__); } elseif($this->arParams["is_dir"] === true) { $is_dir = true; if ($_SERVER['REQUEST_METHOD'] == "MOVE" && ($options["depth"] != "infinity")) { return "400 Bad request"; } elseif($this->check_creator) { return $this->ThrowAccessDenied("USER_IS_NOT_CREATOR", __LINE__); } elseif(empty($options["path"])) { $options["path"] = $this->_get_path($arFrom["item_id"], false); } $res = $this->_udecode($options["dest_url"]); $res2 = str_replace("//", "/", $res."/"); $res1 = str_replace("//", "/", $options["path"]."/"); if ($res1 === $res2) { return "204 No Content"; } elseif ( strtolower(substr($res2, 0, strlen($res1))) == strtolower($res1) && (strlen($res1) != strlen($res2)) // is not the same dir rename ) { return $this->ThrowError("400 Bad Request", "SECTION_IS_NOT_UPDATED", GetMessage("WD_FILE_ERROR100"), __LINE__); } } else { // found and is_file } if(!empty($arFrom['parent_id'])) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($arFrom['parent_id']); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $arFrom['is_symlink'] = true; $arFrom['symlink_section_data'] = $sectionData; $arFrom['symlink_section_data_link'] = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); } } ////////////// CHECK TO $arToParams = array("path" => $options['dest_url']); if (strpos($options['dest_url'], '.Trash') !== false) { $arToParams['check_permissions'] = false; } $this->IsDir($arToParams); $arTo = $this->arParams; if(!empty($arTo['parent_id'])) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($arTo['parent_id']); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $arTo['is_symlink'] = true; $arTo['symlink_section_data'] = $sectionData; $arTo['symlink_section_data_link'] = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); } } if($this->arParams["not_found"] == true) { if ( $this->e_rights && (strpos($options['dest_url'], '.Trash') === false) && !$this->CheckWebRights( "COPY", array( 'action' => ($drop?'move':'copy'), 'from' => array($arFrom), 'to' => array($arTo) ), false ) ) { return $this->ThrowAccessDenied(__LINE__); } //$arTo = false; } elseif ( $arFrom["is_dir"] === true && $arTo["is_file"] === true || $arFrom["is_file"] === true && $arTo["is_dir"] === true ) { return $this->ThrowError("400 Bad Request", "FOLDER_IS_EXISTS", str_replace("#FOLDER#", $this->arParams["item_id"], GetMessage("WD_FILE_ERROR5")), __LINE__); } elseif ( !$this->CheckWebRights( "COPY", array( 'action' => ($drop?'move':'copy'), 'from' => array($arFrom), 'to' => array($arTo) ), false) ) { return $this->ThrowAccessDenied(__LINE__); } elseif(($arFrom["item_id"] == $arTo["item_id"]) && ($arFrom['basename'] == $arTo['basename'])) { // else - trying to change case in name return "204 No Content"; } elseif($arFrom["element_array"]["WF_PARENT_ELEMENT_ID"] > 0) { unset($arTo["item_id"]); } elseif(isset($options['rename']) && $options['rename'] === true) { // fix fast delete to trash from different folders with the same file name $nameSuffix = 1; do { $tmpName = $options["dest_url"]." (". $nameSuffix++ .")"; $this->IsDir(array("path" => $tmpName)); $arTo = $this->arParams; } while ($arTo["not_found"] !== true); $options['dest_url'] = $tmpName; } elseif(!$options["overwrite"]) { return $this->ThrowError('412 Precondition failed', "FILE_OR_FOLDER_ALREADY_EXISTS", GetMessage("WD_FILE_ERROR4"), __LINE__); } elseif(!$this->CheckName($arTo["basename"])) { return $this->ThrowError("400 bad request", "BAD_NAME", GetMessage("WD_FILE_ERROR101"), __LINE__); } elseif( $arTo["is_file"] && $this->check_creator && $arTo["element_array"]["CREATED_BY"] != $GLOBALS["USER"]->GetID() ) { return $this->ThrowAccessDenied("USER_IS_NOT_CREATOR", __LINE__); } if( ($this->workflow == 'workflow') && $arFrom["is_file"] && (! CWorkflow::IsAdmin()) && (! $GLOBALS['USER']->CanDoOperation('webdav_change_settings')) ) { $bNeedCheckWfRights = false; if ($this->e_rights) { $arToParent = $this->GetObject(array('section_id' => $arTo['parent_id'])); if ($arToParent['is_dir']) { $bNeedCheckWfRights = ! $this->GetPermission('SECTION', $arToParent['item_id'], 'element_edit_any_wf_status'); } } else { $bNeedCheckWfRights = ($this->permission < 'W'); } if ( $bNeedCheckWfRights && (CIBlockElement::WF_GetStatusPermission($arFrom["element_array"]["WF_STATUS_ID"]) != 2) ) { return $this->ThrowError("400 bad request", "BAD_WF_RIGHTS", GetMessage("WD_FILE_ERROR110"), __LINE__); } } if ($arTo['parent_id'] == $this->GetMetaID('TRASH')) { $arCheckTrashElement = $arFrom[($arFrom['is_dir']?'dir_array':'element_array')]; if ( $this->_parse_webdav_info($arCheckTrashElement) && (! isset($arCheckTrashElement['PROPS']['BX:']['UNDELETE']))) { return $this->ThrowAccessDenied("BAD_NAME", __LINE__); } } if ($arFrom["is_file"]) { $el = new CIBlockElement(); if ( $arTo["item_id"] && ($arTo['item_id'] !== $arFrom['item_id']) // rename ) { $this->_ib_elm_delete($arTo['item_id']); // TODO: need to check permissions ? } //drop == true if this action is @move@ //is file if ($drop) { $actionRename = $arFrom['parent_id'] == $arTo['parent_id']; $arFields = array( "NAME" => $arTo["basename"], "MODIFIED_BY" => $GLOBALS['USER']->GetID(), "IBLOCK_SECTION_ID" => $arTo["parent_id"]); $this->_onEvent( (($arFrom['parent_id'] != $arTo['parent_id'])?'Move':'Rename'), $arFrom['element_id'], 'FILE', array( 'TO' => ( ($arFrom['parent_id'] != $arTo['parent_id']) ? $arTo["parent_id"] : $arTo["basename"] )) ); //from symlink move. Not rename!!!! if(!$actionRename && (!empty($arFrom['is_symlink']) || !empty($arTo['is_symlink']))) { $targetIblockId = $this->IBLOCK_ID; if(!empty($arTo['is_symlink'])) { $targetIblockId = $arTo['symlink_section_data']['IBLOCK_ID']; } //move and don't delete item if(self::_move_from_iblock_to_iblock($arFrom['item_id'], $targetIblockId, $arTo['parent_id'], false, true)) { $statusSymlinkDelete = $this->DELETE(array("element_id" => $arFrom['item_id'])); } } else { if ($this->workflow == 'workflow') { if ($arTo["parent_id"] != $arFrom["parent_id"]) { $arFields["WF_COMMENTS"] = GetMessage("WD_FILE_IS_MOVED"); $el->SetElementSection($arFrom["item_id"], $arTo["parent_id"]); // TODO: need to check permissions ??? } else { $arFields["WF_COMMENTS"] = GetMessage("WD_FILE_IS_RENAMED"); } if ($arTo["parent_id"] != $arFrom["parent_id"] && $arTo["basename"] != $arFrom["element_name"]) $arFields["WF_COMMENTS"] = GetMessage("WD_FILE_IS_MOVED_AND_RENAMED"); } if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') { $this->AddDocumentToHistory($arFrom['item_id'], $arFrom['element_name']); } $el->Update($arFrom["item_id"], $arFields, $this->workflow == 'workflow', true, false, false); // TODO: need to check permissions ??? $arCacheCleanID[] = 'element'.$arFrom["item_id"]; if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') { $db_res2 = CIBlockElement::GetList(array(), array("WF_PARENT_ELEMENT_ID" => $arFrom["item_id"], "SHOW_HISTORY" => "Y"), false, false, array("ID")); if ($db_res2 && $res2 = $db_res2->Fetch()) { do { $res = $el->Update($res2["ID"], array("IBLOCK_SECTION_ID" => $arFields["IBLOCK_SECTION_ID"]), false, true, false, false); $arCacheCleanID[] = 'element'.$res2["ID"]; } while ($res2 = $db_res2->Fetch()); } } } } else { //from symlink copy if(!empty($arFrom['is_symlink']) || !empty($arTo['is_symlink'])) { $targetIblockId = $this->IBLOCK_ID; if(!empty($arTo['is_symlink'])) { $targetIblockId = $arTo['symlink_section_data']['IBLOCK_ID']; } //move and don't delete item if(!self::_move_from_iblock_to_iblock($arFrom['item_id'], $targetIblockId, $arTo['parent_id'], false, true)) { return '403 Forbidden'; } } else { $options = array( 'path' => $options["dest_url"], 'content_length' => $arFrom["file_array"]['FILE_SIZE'], 'content_type' => $arFrom["file_array"]['CONTENT_TYPE']); $stat = $this->PUT($options); if ($stat === false) { return '403 Forbidden'; } elseif (is_resource($stat) && get_resource_type($stat) == 'stream') { fclose($stat); $arTmpFile = CFile::MakeFileArray($arFrom['element_array']['PROPERTY_FILE_VALUE']); // since CopyDirFiles doesn't support clouds if (!(is_array($arTmpFile) && is_set($arTmpFile, 'tmp_name'))) return false; CopyDirFiles($arTmpFile['tmp_name'], $options["TMP_FILE"]); clearstatcache(); $options['USER_FIELDS'] = $this->GetUfFieldsSimpleArray($arFrom['item_id']); if (!$this->put_commit($options)) { return $this->ThrowError('409 Conflict', "BAD_BP_PERMISSIONS", GetMessage("WD_FILE_ERROR110"), __LINE__); } } } } $this->_onEvent( (($arFrom['parent_id'] != $arTo['parent_id'])?'Move':'Rename').'Finished', $arFrom['element_id'], 'FILE' ); } else { $se = new CIBlockSection(); $actionRename = $arFrom['parent_id'] == $arTo['parent_id']; $actionWithSymlink = !empty($arFrom['is_symlink']) || !empty($arTo['is_symlink']); $actionMoveInSymlink = false; if($actionWithSymlink) { $actionMoveInSymlink = $arFrom['symlink_section_data_link'] == $arTo['symlink_section_data_link']; } //drop == true if this action is @move@ //not symlink and move! but if action rename in symlink - run this code block if (!$actionWithSymlink && $drop || $actionWithSymlink && $actionRename || $actionMoveInSymlink) { $this->_onEvent( (($arFrom['parent_id'] != $arTo['parent_id'])?'Move':'Rename'), $arFrom['item_id'], 'FOLDER', array('TO' => ( ($arFrom['parent_id'] != $arTo['parent_id']) ? $arTo["parent_id"] : $arTo["basename"]) ) ); $GLOBALS['DB']->StartTransaction(); if ( isset($options['overwrite']) && ($arTo['is_dir'] === true) && ($arTo['item_id'] !== $arFrom['item_id']) // rename ) { $se->Delete($arTo['item_id']); } $result = $se->Update($arFrom["item_id"], array("NAME" => $arTo["basename"], "IBLOCK_SECTION_ID" => $arTo["parent_id"])); // TODO: need to check permissions ??? if ($result == false) { $GLOBALS['DB']->Rollback(); return $this->ThrowError("409 Conflict", "SECTION_IS_NOT_UPDATED", ($se->LAST_ERROR ? $se->LAST_ERROR : GetMessage("WD_FILE_ERROR102")), __LINE__); } else { $arCacheCleanID[] = 'section'.$arFrom["item_id"]; $this->ClearCache("section"); $GLOBALS['DB']->Commit(); } } else { if (isset($options['overwrite']) && ($arTo['is_dir'] === true)) $se->Delete($arTo['item_id']); if ($arTo["item_id"] === false) { $arPath = explode("/", $options["dest_url"]); $this->IsDir(array('path' => "/".implode("/", array_slice($arPath, 0, -1)))); if ($this->arParams["not_found"] === false) { if ($this->arParams["item_id"] == 0) // root $arTo["dir_array"] = array("LEFT_MARGIN" => 0, "RIGHT_MARGIN" => $this->INT_MAX); if (($arTo["dir_array"]["LEFT_MARGIN"] - 1) < $arFrom["dir_array"]["LEFT_MARGIN"] && $arFrom["dir_array"]["RIGHT_MARGIN"] < ($arTo["dir_array"]["RIGHT_MARGIN"] + 1)) { // If folder moved to upper folder } elseif ( $arTo["dir_array"]["RIGHT_MARGIN"] < $arFrom["dir_array"]["LEFT_MARGIN"] || $arFrom["dir_array"]["RIGHT_MARGIN"] < $arTo["dir_array"]["LEFT_MARGIN"]) { // if folder moved to neighbourhood folder } elseif ( ( (($arFrom["dir_array"]["LEFT_MARGIN"] - 1) <= $arTo["dir_array"]["LEFT_MARGIN"]) && ($arTo["dir_array"]["RIGHT_MARGIN"] <= ($arFrom["dir_array"]["RIGHT_MARGIN"] + 1)) ) || ( $arTo["dir_array"]["ID"] == $arFrom["dir_array"]["ID"] ) ) { return $this->ThrowError( "400 Bad Request", "SECTION_IS_NOT_UPDATED", GetMessage("WD_FILE_ERROR100"), __LINE__); } if(!empty($arTo['is_symlink'])) { $parentSectionId = $this->arParams["item_id"]; if($this->arParams["item_id"] == $arTo['symlink_section_data_link']['ID']) { $parentSectionId = $arTo['symlink_section_data_link'][self::UF_LINK_SECTION_ID]; } $arTo["dir_array"]["ID"] = $se->Add(array( "IBLOCK_ID" => $arTo['symlink_section_data']['IBLOCK_ID'], "IBLOCK_SECTION_ID" => $parentSectionId, "NAME" => end(array_slice($arPath, -1, 1)) )); $arTo["dir_array"]['IBLOCK_ID'] = $arTo['symlink_section_data']['IBLOCK_ID']; } else { $arTo["dir_array"]["ID"] = $se->Add(array( "IBLOCK_ID" => $this->IBLOCK_ID, "IBLOCK_SECTION_ID" => $this->arParams["item_id"], "NAME" => end(array_slice($arPath, -1, 1)) )); } if ($arTo["dir_array"]["ID"] === false) { return $this->ThrowError("409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace(array( "#FOLDER#", "#TEXT_ERROR#" ), array( "/" . implode("/", $arPath), $se->LAST_ERROR ), GetMessage("WD_FILE_ERROR103")), __LINE__); } else { $returnSection = $arTo["dir_array"]["ID"]; $this->_onEvent('Add', $returnSection, 'FOLDER'); } } } else { return $this->ThrowError( "409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace( array("#FOLDER#", "#TEXT_ERROR#"), array($options["dest_url"], $se->LAST_ERROR), GetMessage("WD_FILE_ERROR103")), __LINE__); } $arFrom["dir_array"]['is_symlink'] = !empty($arFrom['is_symlink']); $arFrom["dir_array"]['symlink_section_data'] = empty($arFrom['symlink_section_data'])? array() : $arFrom['symlink_section_data']; $arTo["dir_array"]['is_symlink'] = !empty($arTo['is_symlink']); $arTo["dir_array"]['symlink_section_data'] = empty($arTo['symlink_section_data'])? array() : $arTo['symlink_section_data']; $result = $this->copy_commit($arFrom["dir_array"], $arTo["dir_array"], $options, $drop); if ($result === true && $drop === true) { if($actionWithSymlink) { $this::$lastActionMoveWithSymlink = true; $this->DELETE(array("section_id" => $arFrom["item_id"])); } else { CIBlockSection::Delete($arFrom["item_id"]); } $this->ClearCache("section"); } elseif (is_string($result) && strpos($result, "403")!==false) return $this->ThrowAccessDenied(__LINE__); } if ($result !== true) return $result; } if($arFrom['element_id']) { CWebDavDiskDispatcher::sendEventToOwners($arFrom['element_array'], null, 'copy'); } elseif($arFrom['is_dir']) { CWebDavDiskDispatcher::sendEventToOwners(null, $arFrom['dir_array'], 'copy'); } $this->ClearCache($arCacheCleanID, 'local'); if (isset($returnSection)) { $this->arParams["changed_section_id"] = $returnSection; } if($statusSymlinkDelete !== false) { return $statusSymlinkDelete; } return ($arTo["not_found"]) ? "201 Created" : "204 No Content"; } function copy_commit($arFrom, $arTo, $options, $drop = false) { $result = true; $actionWithSymlink = !empty($arFrom['is_symlink']) || !empty($arTo['is_symlink']); $action = ($drop ? 'move' : 'copy'); if (!$this->CheckWebRights("", array('action' => $action, 'from' => $arFrom, 'to' => $arTo))) // warning: array param return $this->ThrowAccessDenied(__LINE__); $toIblockId = $this->IBLOCK_ID; if(!empty($arTo['IBLOCK_ID'])) { $toIblockId = $arTo['IBLOCK_ID']; } $fromIblockId = $this->IBLOCK_ID; if(!empty($arFrom['IBLOCK_ID'])) { $fromIblockId = $arFrom['IBLOCK_ID']; } $arFromSections = $this->GetSectionsTree(array("section_id" => $arFrom["ID"])); $arToSections = $this->GetSectionsTree(array("section_id" => $arTo["ID"], 'not_check_permissions' => true)); $res = array(); foreach ($arToSections as $key => $val) $res[$val["PATH"]] = $val; $arToSections = $res; $arSectionsToCopyElements[$arFrom["ID"]] = array("TO_ID" => $arTo["ID"], "NEED_CHECK_NAME" => true); $result = true; $bSectionsWasUpdated = false; $res = reset($arFromSections); $arParentId = array(intVal($arTo["ID"]), $res["ID"]); $iParentDeep = intVal($res["DEPTH_LEVEL"]); if (!empty($arFromSections)) { $se = new CIBlockSection(); do { $res["DEPTH_LEVEL"] = intVal($res["DEPTH_LEVEL"]); while ($res["DEPTH_LEVEL"] <= $iParentDeep) { array_pop($arParentId); $iParentDeep--; } if (!array_key_exists($res["PATH"], $arToSections)) { if (!$actionWithSymlink && $drop === true) // Moving folders { $GLOBALS['DB']->StartTransaction(); $se_result = $se->Update($res["ID"], array("IBLOCK_SECTION_ID" => end($arParentId))); if (!$se_result) { $GLOBALS['DB']->Rollback(); $result = $this->ThrowError("409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace( array("#FOLDER#", "#TEXT_ERROR#"), array($res["PATH"], $se->LAST_ERROR), GetMessage("WD_FILE_ERROR103")), __LINE__); break; } else { $GLOBALS['DB']->Commit(); } $this->_onEvent( 'Move', $res["ID"], "FOLDER", array( 'TO' => end($arParentId))); $bSectionsWasUpdated = true; // Remove brunch elements as we move all the brunch $deep = intVal($res["DEPTH_LEVEL"]); while ($res = next($arFromSections)) { $res["DEPTH_LEVEL"] = intVal($res["DEPTH_LEVEL"]); if ($deep <= $res["DEPTH_LEVEL"]) { prev($arFromSections); break; } } } else // Copy folders { $se_result = $se->Add(array("IBLOCK_ID" => $toIblockId, "IBLOCK_SECTION_ID" => end($arParentId), "NAME" => $res["NAME"])); if (!$se_result) { $result = $this->ThrowError("409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace( array("#FOLDER#", "#TEXT_ERROR#"), array($res["PATH"], $se->LAST_ERROR), GetMessage("WD_FILE_ERROR104")), __LINE__); break; } $this->_onEvent('Add', $se_result, 'FOLDER'); $bSectionsWasUpdated = true; $arSectionsToCopyElements[$res["ID"]] = array("TO_ID" => $se_result, "NEED_CHECK_NAME" => false); $arParentId[] = $se_result; $iParentDeep++; } } else { $arParentId[] = $arToSections[$res["PATH"]]["ID"]; $iParentDeep++; if (!$options["overwrite"]) { $result = $this->ThrowError("409 Conflict", "FOLDER_ALREADY_EXISTS", str_replace("#FOLDER#", $res["PATH"], GetMessage("WD_FILE_ERROR5")), __LINE__); break; } else { $arSectionsToCopyElements[$res["ID"]] = array("TO_ID" => $arToSections[$res["PATH"]]["ID"], "NEED_CHECK_NAME" => true); } } } while ($res = next($arFromSections)); if ($bSectionsWasUpdated) { $this->ClearCache("section"); } } if ($result === true) { $el = new CIBlockElement(); foreach ($arSectionsToCopyElements as $iFromSectionID => $arElement) { $arToElements = array(); if ($arElement["NEED_CHECK_NAME"] != false) { $db_res = CIBlockElement::GetList( array("NAME" => "ASC"), array("IBLOCK_ID" => $toIblockId, "SECTION_ID" => $arElement["TO_ID"], "SHOW_NEW" => "Y", "CHECK_PERMISSIONS" => "N"), false, false, array("ID", "NAME")); if ($db_res && $res = $db_res->Fetch()) { do { $arToElements[strtolower($res["NAME"])] = $res; } while ($res = $db_res->Fetch()); } } $db_res = CIBlockElement::GetList( array("NAME" => "ASC"), array("IBLOCK_ID" => $fromIblockId, "SECTION_ID" => $iFromSectionID, "SHOW_NEW" => "Y"), false, false, array("ID", "NAME", "IBLOCK_SECTION_ID", "PROPERTY_".$this->file_prop)); if ($db_res && $res = $db_res->Fetch()) { do { $res["NAME"] = strtolower($res["NAME"]); if (array_key_exists($res["NAME"], $arToElements)) { if (!$options["overwrite"]) { $result = $this->ThrowError( "409 Conflict", "FILE_ALREADY_EXISTS", str_replace("#FILE#", $res["NAME"], GetMessage("WD_FILE_ERROR8")), __LINE__); break; } else { // TODO: check permission to destroy elements $tmp = $arToElements[$res["NAME"]]; $this->_onEvent('Delete', $tmp["ID"]); $this->_ib_elm_delete($tmp["ID"]); } } if (!$actionWithSymlink && $drop == true) { if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') { $this->AddDocumentToHistory($res['ID'], $res['NAME']); } $el->Update( $res["ID"], array("IBLOCK_SECTION_ID" => $arElement["TO_ID"], "WF_COMMENTS" => GetMessage("WD_FILE_IS_MOVED")), ($this->workflow == 'workflow')); $this->_onEvent( 'Move', $res["ID"], "FILE", array( 'TO' => $arElement["TO_ID"])); if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') { $db_res2 = CIBlockElement::GetList(array(), array("WF_PARENT_ELEMENT_ID" => $res["ID"], "SHOW_HISTORY" => "Y"), false, false, array("ID")); if ($db_res2 && $res2 = $db_res2->Fetch()) { do { $res = $el->Update($res2["ID"], array("IBLOCK_SECTION_ID" => $arElement["TO_ID"]), false, true, false, false); } while ($res2 = $db_res2->Fetch()); } } } else { if($actionWithSymlink) { //move and don't delete item if(!self::_move_from_iblock_to_iblock($res["ID"], $toIblockId, $arElement["TO_ID"], false, true)) { return '409 Conflict'; } elseif($drop) //move action { //$this->DELETE(array("element_id" => $res["ID"])); //delete section in method COPY } } else { $arFile = CFile::GetFileArray($res["PROPERTY_".$this->file_prop."_VALUE"]); $optionsPut = array( 'path' => $this->_udecode($this->_get_path($arElement["TO_ID"]))."/".$res["NAME"], 'content_length' => $arFile['FILE_SIZE'], 'content_type' => $arFile['CONTENT_TYPE']); $stat = $this->PUT($optionsPut); if ($stat === false) { return '403 Forbidden'; } elseif (is_resource($stat) && get_resource_type($stat) == 'stream') { fclose($stat); $arTmpFile = CFile::MakeFileArray($arFile['ID']); // since CopyDirFiles doesn't support clouds if (!(is_array($arTmpFile) && is_set($arTmpFile, 'tmp_name'))) return '409 Conflict'; CopyDirFiles($arTmpFile['tmp_name'], $optionsPut["TMP_FILE"]); clearstatcache(); $optionsPut['USER_FIELDS'] = $this->GetUfFields($res["ID"]); if (!$this->put_commit($optionsPut)) { return '409 Conflict'; } } } } } while ($res = $db_res->Fetch()); } if ($result !== true) { break; } } } return $result; } function MKCOL($options) { $this->IsDir($options, true); if ($this->check_creator || !$this->CheckWebRights("", array('action' => 'mkcol', 'arElement' => $this->arParams), false)) { return $this->ThrowAccessDenied(__LINE__); } elseif ($_SERVER['REQUEST_METHOD'] == "MKCOL" && !empty($_SERVER["CONTENT_LENGTH"])) { return "415 Unsupported media type"; } if ($this->arParams["is_dir"] == true) { return $this->ThrowError( "405 Method not allowed", "FOLDER_IS_EXISTS", str_replace("#FOLDER#", $this->arParams["basename"], GetMessage("WD_FILE_ERROR5")), __LINE__); } elseif ($this->arParams["is_file"] === true) { return $this->ThrowError( "405 Method not allowed", "FILE_ALREADY_EXISTS", str_replace("#FILE#", $this->arParams["basename"], GetMessage("WD_FILE_ERROR8")), __LINE__); } elseif ($this->arParams["parent_id"] === false) return $this->ThrowError("409 Conflict" , "NO_PARENT_FOLDER", __LINE__); $iblockId = $this->IBLOCK_ID; if($this->arParams["parent_id"]) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($this->arParams["parent_id"]); $iblockId = $sectionData['IBLOCK_ID']; if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $parentSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($parentSectionData) { $iblockId = $parentSectionData[self::UF_LINK_IBLOCK_ID]; } } } $se = new CIBlockSection(); $b = $se->Add(array( "IBLOCK_SECTION_ID" => $this->arParams["parent_id"], "NAME" => $this->CorrectName($this->arParams["basename"]), "IBLOCK_ID" => $iblockId, "ACTIVE" => "Y")); if (!$b) { return "403 Forbidden"; } else { $this->arParams["changed_element_id"] = $b; $this->_onEvent('Add', $b, 'FOLDER'); CWebDavDiskDispatcher::sendEventToOwners(null, array( 'IBLOCK_ID' => (int)$iblockId, 'ID' => (int)$b, ), 'mkcol'); } $this->ClearCache("section"); return "201 Created"; } function Undelete($options) { $this->IsDir($options); if(!$this->CheckWebRights("UNDELETE", array('action' => 'undelete', 'arElement' => $this->arParams))) return $this->ThrowAccessDenied(__LINE__); $bIsDir = ($this->arParams['is_dir']); if ($this->arParams["not_found"] === true) return "404 Not Found"; if (!isset($options['dest_url'])) { $arElement = $this->arParams[($this->arParams['dir_array']?'dir_array':'element_array')]; if ( $this->_parse_webdav_info($arElement) && isset($arElement['PROPS']['BX:']['UNDELETE'])) $options['dest_url'] = $arElement['PROPS']['BX:']['UNDELETE']; } if (!isset($options['dest_url'])) return "404 Not Found"; $this->events_enabled = false; $result = $this->MOVE($options); $this->events_enabled = true; if (in_array(intval($result), array(201, 204))) // remove the "UNDELETE" in WEBDAV_INFO { $options["props"] = array(array("ns"=>"BX:","name"=>"UNDELETE")); $this->PROPPATCH($options); if ($bIsDir) { $this->_onEvent('Restore', $options["section_id"], 'FOLDER'); $arUndeleteSections = array($options["section_id"]); reset($arUndeleteSections); while($sectionID = current($arUndeleteSections)) { $dbUndeleteItems = $this->_get_mixed_list($sectionID); while ($arUndeleteItem = $dbUndeleteItems->Fetch()) { if ($arUndeleteItem["TYPE"] == "S") { $arUndeleteSections[] = $arUndeleteItem["ID"]; } $arUndeleteOptions = array("props" => array( array("ns"=>"BX:", "name"=>"UNDELETE"))); if ($arUndeleteItem["TYPE"] == "S") $arUndeleteOptions["section_id"] = $arUndeleteItem["ID"]; else $arUndeleteOptions["element_id"] = $arUndeleteItem["ID"]; $this->PROPPATCH($arUndeleteOptions); if ($arUndeleteItem["TYPE"] == "S") $this->_onEvent('Restore', $arUndeleteItem["ID"], 'FOLDER'); else { $this->_onEvent('Restore', $arUndeleteItem["ID"]); $el = new CIBlockElement; $el->Update($arUndeleteItem["ID"], array('TIMESTAMP_X' => true), false, false); } } next($arUndeleteSections); } } else { $this->_onEvent('Restore', $options['element_id']); } $this->ClearCache("section"); return "204 No Content"; } else { return "404 Not Found"; } } function _move_to_trash(&$options) { self::$trashCache = array(); $this->IsDir($options); $bIsDir = $this->arParams["is_dir"]; if ($bIsDir) $arElement = $this->arParams['dir_array']; else $arElement = $this->arParams['element_array']; if ($arElement['IBLOCK_SECTION_ID'] === null) $arElement['IBLOCK_SECTION_ID'] = 0; $sOriginalName = str_replace(array('///', '//'), '/', $this->_get_path($arElement['IBLOCK_SECTION_ID'], false) .'/'.$arElement['NAME']); // false in _get_path - for correct ru names in trash recovery param $arUndeleteOptions = $options; $arUndeleteOptions["props"][] = array("ns"=>"BX:", "name"=>"UNDELETE", "val"=>$sOriginalName); $this->PROPPATCH($arUndeleteOptions); $this->CACHE['CWebDavIblock::GetObject'] = array(); if ($bIsDir) { $arDeleteSections = array($options["section_id"]); $this->_onEvent('Trash', $arElement["ID"], 'FOLDER'); $markDeleteSection = null; $markDeleteSection = CWebDavDiskDispatcher::addElementForDeletingMark($arElement, $arElement); reset($arDeleteSections); while($sectionID = current($arDeleteSections)) { $dbDeleteItems = $this->_get_mixed_list($sectionID); while ($arDeleteItem = $dbDeleteItems->Fetch()) { $sOriginalName = str_replace(array('///', '//'), '/', $this->_get_path($arDeleteItem["IBLOCK_SECTION_ID"], false) .'/'.$arDeleteItem['NAME']); $arUndeleteOptions = array("props" => array( array("ns"=>"BX:", "name"=>"UNDELETE", "val"=>$sOriginalName))); if ($arDeleteItem["TYPE"] == "S") { $arUndeleteOptions["section_id"] = $arDeleteItem["ID"]; $arDeleteSections[] = $arDeleteItem["ID"]; if($markDeleteSection) { CWebDavDiskDispatcher::addElementForDeletingMark($arDeleteItem, $arElement); } $this->_onEvent('Trash', $arDeleteItem['ID'], 'FOLDER'); } else { $arUndeleteOptions["element_id"] = $arDeleteItem["ID"]; if($markDeleteSection) { CWebDavDiskDispatcher::addElementForDeletingMark($arDeleteItem, $arElement, false); } $this->_onEvent('Trash', $arDeleteItem['ID']); } $this->PROPPATCH($arUndeleteOptions); } next($arDeleteSections); } } else { CWebDavDiskDispatcher::addElementForDeletingMark($arElement, null, false); $this->_onEvent('Trash', $this->arParams['element_id']); } if ($bIsDir) { CWebDavSymlinkHelper::setSectionOriginalName($this->arParams['dir_array']['ID'], $this->arParams['dir_array']['NAME']); $destName = $this->arParams['dir_array']['NAME'] . " " . $this->CorrectName(ConvertTimeStamp(time(), "FULL")); } else { if (strlen($this->arParams['file_extention']) > 1) { $destName = substr($this->arParams['element_name'], 0, -strlen($this->arParams['file_extention'])) . " " . $this->CorrectName(ConvertTimeStamp(time(), "FULL")) . $this->arParams['file_extention']; } else { $destName = $this->arParams['element_name'] . " " . $this->CorrectName(ConvertTimeStamp(time(), "FULL")) . ".noext"; } } $destName = str_replace("/", "_", $destName); $options['dest_url'] = "/".$this->meta_names['TRASH']['name']."/".$destName; $options['rename'] = true; $this->events_enabled = false; $status = $this->MOVE($options); $this->events_enabled = true; if(intval($status) > 200 && intval($status) < 300) { CWebDavDiskDispatcher::markDeleteBatch(); } else { CWebDavDiskDispatcher::clearDeleteBatch(); } if (intval($status) == 201) { return "204 No Content"; } else { $GLOBALS["APPLICATION"]->ResetException(); $GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR16"), "FILE_OR_FOLDER_TRASH_ERROR"); return $status; } } function _isInMeta($id, $metaId, $type = 'FILE') { if($type == 'FILE') { $elementData = $this->GetObject(array('element_id' => intval($id))); if ($elementData['not_found']) { return false; } $sectionId = $elementData['parent_id']; } else { $sectionData = $this->GetObject(array('section_id' => intval($id))); $sectionId = $sectionData['item_id']; } list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($sectionId, array(), false); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $parentSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($parentSectionData) { $linkWebdav = new self($parentSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array( 'ROOT_SECTION_ID' => $parentSectionData[self::UF_LINK_ROOT_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $parentSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, )); return $linkWebdav->_isInMeta($id, $metaId, $type); } } $sectionMetaId = $this->GetMetaID($metaId, false); foreach (CWebDavSymlinkHelper::getNavChain($this->IBLOCK_ID, $sectionId) as $res) { if($sectionMetaId == $res['ID']) { return true; } } unset($res); return false; } function DeleteDroppedFile($fileId) { $fileId = (int)$fileId; if($this->_isInMeta($fileId, "DROPPED")) { $this->DELETE(array( 'element_id' => $fileId, 'force' => true, )); } } function CleanUpDropped() { $dropTargetID = $this->GetMetaID("DROPPED"); // remove empty 'dropped' folders $ise = new CIBlockSection; //if (!$checked) //{ $rsParentSection = $ise->GetByID($dropTargetID); if ($arParentSection = $rsParentSection->GetNext()) { $arFilter = array('IBLOCK_ID' => $this->IBLOCK_ID, '>LEFT_MARGIN' => $arParentSection['LEFT_MARGIN'], '<RIGHT_MARGIN' => $arParentSection['RIGHT_MARGIN'], '>DEPTH_LEVEL' => $arParentSection['DEPTH_LEVEL'], 'CHECK_PERMISSIONS' => 'N' ); $dbFolders = $ise->GetList(array(),$arFilter, false, array('ID', 'IBLOCK_ID')); while($arFolder = $dbFolders->Fetch()) { $count = CIBlockElement::GetList(array(), array( 'IBLOCK_SECTION_ID' => $arFolder['ID'], 'IBLOCK_ID' => $arFolder['IBLOCK_ID'], 'INCLUDE_SUBSECTIONS' => 'Y'), array(), false, array('ID')); if(intval($count) < 1) { $ise->Delete($arFolder['ID']); } } } //} } function InTrash($arElement) { static $trashID = false; if($trashID === false) { $trashID = $this->GetMetaID("TRASH"); } $id = ( isset($arElement['ID']) ? intval($arElement['ID']) : (isset($arElement['item_id']) ? intval($arElement['item_id']) : null ) ); $parentID = ( isset($arElement['parent_id']) ? intval($arElement['parent_id']) : (isset($arElement['IBLOCK_SECTION_ID']) ? intval($arElement['IBLOCK_SECTION_ID']) : null ) ); if($id === null) { return false; } $isDir = isset($arElement['is_dir']) ? $arElement['is_dir'] : false; if (($id === $trashID && $isDir === true) || $parentID === $trashID) { return true; } if($parentID === null) { return false; } if(array_key_exists($parentID, self::$trashCache)) { return self::$trashCache[$parentID]; } $result = false; foreach (CWebDavSymlinkHelper::getNavChain($this->IBLOCK_ID, $parentID) as $res) { if($res["ID"] == $trashID) { $result = true; break; } } self::$trashCache[$parentID] = $result; return $result; } function DELETE($options) { $options["~path"] = $this->_udecode($options["path"]); WDUnpackCookie(); if (isset($options['path'])) { $arPath = explode('/', $options['path']); // ms excel tries to create and delete ~\$FileName.xls $basename = array_pop($arPath); $basename = $this->CorrectName($this->_udecode($basename)); array_push($arPath, $basename); $options['path'] = implode('/', $arPath); } if (!empty($options["~path"]) && $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] == $options["~path"]) { $this->IsDir($options); $_SESSION["WEBDAV_DATA"]["PUT_MAC_OS"] = ""; WDPackCookie(); if (intVal($this->arParams["element_id"]) > 0) { $this->_ib_elm_delete($this->arParams["element_id"]); return "204 No Content"; } return "404 Not Found"; } else { $this->IsDir($options); //symlink logic list($contextType, $contextEntityId) = $this->getContextData(); //we can't forward delete symlink. Only delete symlink section. $sectionData = $this->getSectionDataForLinkAnalyze($this->arParams['is_dir']? $this->arParams['dir_array']['ID'] : $this->arParams['element_array']['IBLOCK_SECTION_ID'], array(), false); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { //we don't enable symlink mode, because we move to real trash $parentSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($parentSectionData) { $linkWebdav = new self($parentSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array( 'ROOT_SECTION_ID' => $parentSectionData[self::UF_LINK_ROOT_SECTION_ID], )); return $linkWebdav->DELETE($options); } else { return "404 Not Found"; } } if(!$this->CheckWebRights("DELETE", array('action' => 'delete', 'arElement' => $this->arParams), false)) return $this->ThrowAccessDenied(__LINE__); $resLock = array(); $lockedBy = $lockedDate = null; $resLock["LOCK_STATUS"] = CIBlockElement::WF_GetLockStatus($this->arParams["item_id"], $lockedBy, $lockedDate); if ($resLock['LOCK_STATUS'] == 'red' && !$GLOBALS['USER']->CanDoOperation('webdav_change_settings')) return $this->ThrowAccessDenied(__LINE__); //delete symlink. Not move to trash if(!empty($this->arParams['dir_array'][self::UF_LINK_SECTION_ID])) { $options['force'] = true; } if (!isset($options['force']) && ($this->arParams["is_dir"] === true || intval($this->arParams["element_id"]) > 0)) { if ($trashID = $this->GetMetaID("TRASH")) { $item_id = $this->arParams['item_id']; $arSectionsChain = array(); $bRootFounded = (empty($this->arRootSection) ? true : false); foreach (CWebDavSymlinkHelper::getNavChain($this->IBLOCK_ID, $this->arParams['parent_id']) as $res) { if (!$bRootFounded && $res["ID"] == $this->arRootSection["ID"]) { $bRootFounded = true; continue; } if (!$bRootFounded) continue; $arSectionsChain[] = $res["ID"]; } if ($item_id == $trashID && $this->arParams["is_dir"]) // empty trash { if($this->CheckWebRights("DESTROY", array('action' => 'destroy', 'arElement' => $this->arParams), false)) { if(isset($this->attributes['user_id']) && ($this->attributes['user_id'] == $GLOBALS['USER']->GetID())) { //now we clean own bin so simple, so fast $this->runCleaningTrash($trashID); } else { //old cleaning. So-so $this->_delete_section($options["section_id"]); } $this->GetMetaID('TRASH'); // create return "204 No Content"; } else { return $this->ThrowAccessDenied(__LINE__); } } elseif ( (!in_array($trashID, $arSectionsChain)) && (strpos($this->arParams['file_name'], "_$") !== 0) // ms office special files ) // move to trash { return $this->_move_to_trash($options); } } else { return "404 Not Found"; } } $this->IsDir($options); if(!$this->CheckWebRights("DESTROY", array('action' => 'destroy', 'arElement' => $this->arParams), false)) return $this->ThrowAccessDenied(__LINE__); if ($this->arParams["is_dir"] === true) { if ($this->check_creator) return $this->ThrowAccessDenied(__LINE__); if($this->_delete_section($options["section_id"]) === true && !empty($this->arParams['dir_array'][self::UF_LINK_SECTION_ID]) && $this->attributes['user_id']) { if(!empty($this->attributes['user_id'])) { CWebDavDiskDispatcher::sendChangeStatus($this->attributes['user_id'], 'delete_symlink'); } \Bitrix\Webdav\FolderInviteTable::deleteByFilter(array( '=INVITE_USER_ID' => $this->attributes['user_id'], '=IS_APPROVED' => true, '=IBLOCK_ID' => $this->arParams['dir_array'][self::UF_LINK_IBLOCK_ID], '=SECTION_ID' => $this->arParams['dir_array'][self::UF_LINK_SECTION_ID], )); } } elseif (intVal($this->arParams["element_id"]) > 0) { CWebDavDiskDispatcher::addElementForDeletingMark($this->arParams['element_array'], null, false); $el = new CIBlockElement(); $this->_onEvent('Delete', $this->arParams["element_id"]); if($this->_ib_elm_delete($this->arParams["element_id"])) { CWebDavDiskDispatcher::markDeleteBatch(); CWebDavDiskDispatcher::sendEventToOwners($this->arParams['element_array'], null, 'force_delete_element'); } else { CWebDavDiskDispatcher::clearDeleteBatch(); } } else { return "404 Not Found"; } if ($_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] == $options["~path"]) { $_SESSION["WEBDAV_DATA"]["PUT_EMPTY"] = ""; } } return "204 No Content"; } function _eventObjectParams() { $res = array( "TYPE" => $this->Type, "IBLOCK_ID" => $this->IBLOCK_ID, "SECTION_ID" => null,//$arElement["IBLOCK_SECTION_ID"], "ATTRIBUTES" => $this->attributes ); if(is_array($this->arRootSection) && array_key_exists("ID", $this->arRootSection)) { $res["SECTION_ID"] = $this->arRootSection["ID"]; } return $res; } function _eventElementParams($elementID, $elementType) { $result = null; if ($elementType == 'FILE') $options = array('element_id' => $elementID); else $options = array('section_id' => $elementID); $arElement = $this->GetObject($options); $sFileName = ''; if (isset($arElement['element_array']['NAME'])) $sFileName = $arElement['element_array']['NAME']; elseif (isset($arElement['dir_array']['NAME'])) $sFileName = $arElement['dir_array']['NAME']; if ($sFileName !== '.Trash') { $result = array( "name" => $sFileName, "id" => $elementID, "element" => $arElement ); if (isset($arElement['element_array'])) $result['hidden'] = !$this->MetaNames($arElement['element_array'], true); if (isset($arElement['dir_array'])) $result['hidden'] = !$this->MetaNames($arElement['dir_array'], true); if ($this->_isInMeta($arElement['item_id'], 'DROPPED', $elementType)) $result['dropped'] = true; $result['url'] = $this->GetPath($options); } return $result; } function _eventParams($operation, $elementID, $elementType, $arParams) { $arEventParams = null; if ($arElement = $this->_eventElementParams($elementID, $elementType)) { $arEventParams = array( 'OPERATION' => $arParams + array('NAME' => $operation), 'OBJECT' => $this->_eventObjectParams($operation), 'ELEMENT' => $arElement, ); } return $arEventParams; } function _onEvent($eventTitle, $elementID, $elementType = 'FILE', $arParams = array()) { if (!in_array($eventTitle, array('Delete', 'Trash', 'Lock', 'Unlock', 'Restore', 'Rename', 'Move', 'MoveFinished', 'Add', 'Update'))) return; if (!$this->events_enabled) return; $objectTitle = ($elementType=='FILE'?'File':'Folder'); $eventName = 'On'.$objectTitle.$eventTitle; //$rsEvents = GetModuleEvents("webdav", $eventName); $arEventAll = GetModuleEvents("webdav", $eventName, true); $arEventParams = $this->_eventParams(strtoupper($eventTitle), $elementID, $elementType, $arParams); if (count($arEventAll) > 0 && ($arEventParams)) { $cMethod = '_onBefore'.$objectTitle.$eventTitle.'Event'; if (method_exists($this, $cMethod)) call_user_func_array(array($this, $cMethod), array($elementID, &$arEventParams)); //while ($arEvent = $rsEvents->Fetch()) foreach($arEventAll as $arEvent) { ExecuteModuleEventEx($arEvent, array($arEventParams)); } } $cMethod = '_onAfter'.$objectTitle.$eventTitle.'Event'; if (method_exists($this, $cMethod)) call_user_func_array(array($this, $cMethod), array($elementID, &$arEventParams)); } function _onBeforeFileDeleteEvent($elementID, &$arEventParams) { $io = self::GetIo(); $arElement = $arEventParams['ELEMENT']['element']; $this->_parse_webdav_info($arElement['element_array']); if (isset($arElement['element_array']['PROPS']['BX:']['UNDELETE'])) { $sFileName = $arElement['element_array']['PROPS']['BX:']['UNDELETE']; $sFileName = $io->ExtractNameFromPath($sFileName); $arElement['element_array']["~NAME"] = $arElement['element_array']["NAME"]; $arElement['element_array']["NAME"] = $sFileName; $arEventParams['ELEMENT']['element'] = $arElement; $arEventParams['ELEMENT']['~name'] = $arEventParams['ELEMENT']['name']; $arEventParams['ELEMENT']['name'] = $sFileName; } } function _onBeforeFolderDeleteEvent($elementID, &$arEventParams) { $io = self::GetIo(); $arElement = $arEventParams['ELEMENT']['element']; $this->_parse_webdav_info($arElement['dir_array']); if (isset($arElement['dir_array']['PROPS']['BX:']['UNDELETE'])) { $sFileName = $arElement['dir_array']['PROPS']['BX:']['UNDELETE']; $sFileName = $io->ExtractNameFromPath($sFileName); $arElement['dir_array']["~NAME"] = $arElement['dir_array']["NAME"]; $arElement['dir_array']["NAME"] = $sFileName; $arEventParams['ELEMENT']['element'] = $arElement; $arEventParams['ELEMENT']['~name'] = $arEventParams['ELEMENT']['name']; $arEventParams['ELEMENT']['name'] = $sFileName; } } function _onDeleteElement($elementID) { global $USER_FIELD_MANAGER; $USER_FIELD_MANAGER->Delete($this->GetUfEntity(), $elementID); $this->_onEvent('Delete', $elementID); } function _onDeleteSection($sectionID) { $this->_onEvent('Delete', $sectionID, 'FOLDER'); } /** * Clean own trash. Check rights only on root (bin folder) * Without transaction * @param $sectionId * @return bool */ private function runCleaningTrash($sectionId) { //copy-past from _delete_section() if($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') { AddEventHandler("iblock", "OnBeforeIBlockElementDelete", Array($this, "_onDeleteElement")); AddEventHandler("iblock", "OnBeforeIBlockSectionDelete", Array($this, "_onDeleteSection")); } $se = new CIBlockSection(); if(!$se->Delete($sectionId, false)) { return $this->ThrowError("423 Locked", "423", GetMessage('WD_FILE_ERROR16')); } return true; } function _delete_section($sectionID) { static $onDeleteEventSet = false; $result = true; if ($onDeleteEventSet == false && ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited')) { AddEventHandler("iblock", "OnBeforeIBlockElementDelete", Array($this, "_onDeleteElement")); AddEventHandler("iblock", "OnBeforeIBlockSectionDelete", Array($this, "_onDeleteSection")); } $arSections = array(); $sectionID = intval($sectionID); $s = CIBlockSection::GetList(array(), array( "ID" => $sectionID, 'CHECK_PERMISSIONS' => 'N' ), false, array('ID', 'NAME', 'LEFT_MARGIN', 'RIGHT_MARGIN', 'DEPTH_LEVEL', 'IBLOCK_ID') ); if ($arParentSection = $s->Fetch()) { CWebDavSymlinkHelper::setSectionOriginalName($sectionID, $arParentSection['NAME']); if (! $this->GetPermission('SECTION', $sectionID, 'section_delete', false)) // check perms on target folder { $result = GetMessage('WD_ERR_DELETE_FOLDER_NO_PERMS', array( 'ID' => $sectionID, //$arSection['ID'], 'NAME' => "", //htmlspecialcharsbx($arSection['NAME']) )); } else { $arSections[] = $sectionID; $rSection = CIBlockSection::GetList( // get all subsections array('LEFT_MARGIN' => 'DESC'), array( 'CHECK_PERMISSIONS' => 'N', 'IBLOCK_ID' => $arParentSection['IBLOCK_ID'], '>LEFT_MARGIN' => $arParentSection['LEFT_MARGIN'], '<RIGHT_MARGIN' => $arParentSection['RIGHT_MARGIN'], '>DEPTH_LEVEL' => $arParentSection['DEPTH_LEVEL'] ), false, array('ID', 'NAME') ); if ($rSection) { while ($arSection = $rSection->Fetch()) { if (! $this->GetPermission('SECTION', $arSection['ID'], 'section_delete')) // check perms on subsection { $result = GetMessage('WD_ERR_DELETE_FOLDER_NO_PERMS', array( 'ID' => $arSection['ID'], 'NAME' => htmlspecialcharsbx($arSection['NAME']) )); break; } else { $arSections[] = $arSection['ID']; } } } } if ($result === true) // no errors { $se = new CIBlockSection(); if (!$se->Delete($arParentSection['ID'], false)) // delete each section in separate transaction { $result = GetMessage('WD_FILE_ERROR16'); } } } return (($result === true) ? $result : $this->ThrowError("423 Locked", "423", $result)); } function get_iblock_info(&$arr) { $info = array(); $info["path"] = "/"; $info["props"] = array(); $info["props"][] = CWebDavBase::_mkprop("resourcetype", "collection"); $info["props"][] = CWebDavBase::_mkprop("getcontenttype", "httpd/unix-directory"); $arr = CIBlock::GetArrayByID($this->IBLOCK_ID); $time = MakeTimeStamp($arr["TIMESTAMP_X"]); $year = date("Y"); $info["props"][] = CWebDavBase::_mkprop("creationdate", mktime(0, 0, 0, 1, 1, $year)); $info["props"][] = CWebDavBase::_mkprop("getlastmodified", $time); $info["props"][] = CWebDavBase::_mkprop("iscollection", 1); return $info; } function getDocCount($arFilter = array()) { static $dataType = 'DocCount'; $itemsCount = $this->_dataCache($dataType); if ($itemsCount === false) { if ($this->arRootSection) $arFilter['SECTION_ID'] = $this->arRootSection['ID']; $arFilter = $arFilter + Array("IBLOCK_ID" => $this->IBLOCK_ID, "INCLUDE_SUBSECTIONS" => "Y", "ACTIVE" => "Y"); $itemsCount = 0; $res = CIBlockElement::GetList(array(), $arFilter, false, false, array('ID')); if ($res) { $res->NavStart(); $itemsCount = $res->NavRecordCount; $arFilter["SECTION_ID"] = $this->GetMetaID("TRASH"); $res = CIBlockElement::GetList( array(), $arFilter, false, false, array('ID')); if ($res) { $res->NavStart(); $trashItemsCount = $res->NavRecordCount; $itemsCount -= $trashItemsCount; } } $this->_dataCache($dataType, $itemsCount); } return $itemsCount; } function checkLock($path, array $element = array()) { $result = false; $options = array("path" => $path); $arProps = $this->_get_lock($options, $element); if (!is_array($arProps)) return $arProps; // error in _get_lock if (array_key_exists("LOCK", $arProps) && is_array($arProps["LOCK"]) && count($arProps["LOCK"]) > 0) { $k = reset(array_keys($arProps["LOCK"])); $row = $arProps["LOCK"][$k]; $result = array( "type" => "write", "scope" => $row["exclusivelock"] ? "exclusive" : "shared", "depth" => 0, "owner" => $row["owner"], "token" => $k, "created" => $row["created"], "modified" => $row["modified"], "expires" => $row["expires"]); } return $result; } function GetProperties() { static $dataType = 'GetIblockProperties'; $arProps = $this->_dataCache($dataType); if (!$arProps) { $rIBProps = CIBlockProperty::GetList( Array( "SORT" => "ASC", "NAME" => "ASC" ), Array( "ACTIVE" => "Y", "IBLOCK_ID" => $this->IBLOCK_ID ) ); if (!$rIBProps) return false; $arProps = array(); while ($arIBProp = $rIBProps->Fetch()) { $arProps[$arIBProp['CODE']] = $arIBProp; } $this->_dataCache($dataType, $arProps); } return $arProps; } function _check_iblock_prop($arProperty = false) { static $dataType = 'IblockProperties'; $checked = $this->_dataCache($dataType); if (!$checked) { $arProps = $this->GetProperties(); foreach ($arProps as $code => &$arIBProp) { if (!isset($arProperty[$code])) continue; if (($arIBProp['PROPERTY_TYPE'] != $arProperty[$code]['type']) || ($arIBProp['USER_TYPE'] != null)) continue; unset($arProperty[$code]); } $prp = new CIBlockProperty(); foreach ($arProperty as $sPropertyCode => $arPropertyParams) { $properties = array( "IBLOCK_ID" => $this->IBLOCK_ID, "ACTIVE" => "Y", "CODE" => $sPropertyCode, "MULTIPLE" => "N", "PROPERTY_TYPE" => $arPropertyParams["type"], "NAME" => $arPropertyParams["name"]); if (isset($arPropertyParams["properties"])) $properties+=$arPropertyParams["properties"]; $res = $prp->Add($properties); } if (($this->FORUM_ID !== null) && empty($this->arRootSection) && CModule::IncludeModule('forum')) { $arForum = CForumNew::GetByID($this->FORUM_ID); if ($arForum['ACTIVE'] == 'Y') { $arSites = CForumNew::GetSites($this->FORUM_ID); foreach ($arSites as $siteID => $forumUrl) { if (strpos($forumUrl, '/community/forum/') === 0) { $arSites[$siteID] = str_replace(array('///', '//'), '/', $this->base_url . "/element/comment/#TOPIC_ID#/#MESSAGE_ID#/"); } } $arUpForum = array(); $arUpForum["SITES"] = $arSites; CForumNew::Update($this->FORUM_ID, $arUpForum); } } $this->_dataCache($dataType, true); } } function IsDir($options = array(), $replace_symbols = false) { $this->arParams = $this->GetObject($options, $replace_symbols); return $this->arParams["is_dir"]; } function _get_element_cacheID($path, $replace_symbols = false) { return md5(intval($this->IBLOCK_ID).'|'.intval($this->arRootSection['ID']).'|'.$path.($replace_symbols ? "Y" : "N")); } function GetObject($options = array(), $replace_symbols = false, $force = false) { $options = (is_array($options) ? $options : array()); if (!isset($options['check_permissions'])) $options['check_permissions'] = true; if(array_key_exists("path", $options)) { $path = $this->_udecode($options["path"]); } else { if(array_key_exists('section_id', $options)) { $path = 'section' . $options['section_id']; } elseif(array_key_exists('element_id', $options)) { $path = 'element' . $options['element_id']; } else { $path = $this->_path; } } $arSelectFields = array("ID", "NAME", "IBLOCK_ID", "IBLOCK_SECTION_ID", "PREVIEW_TEXT", "CREATED_BY", 'MODIFIED_BY', 'DATE_CREATE', "TIMESTAMP_X", "PROPERTY_" . static::PROPERTY_VERSION, "PROPERTY_".$this->file_prop, "PROPERTY_WEBDAV_INFO", "WF_NEW", "WF_PARENT_ELEMENT_ID", "WF_STATUS_ID", "IBLOCK_CODE", "BP_PUBLISHED"); $contextCache = ''; if(!empty($this->attributes['user_id'])) { $contextCache = $this->attributes['user_id'] . (empty($options['section_id'])? '' : 'section' . $options['section_id']); } elseif(!empty($this->attributes['group_id'])) { $contextCache = $this->attributes['group_id'] . (empty($options['section_id'])? '' : 'section' . $options['section_id']); } $id = $this->_get_element_cacheID($path, $replace_symbols).($options['check_permissions']?'Y':'N').'_'.$contextCache; //todo!!!!! if (!$force && isset($this->CACHE[__METHOD__][$id])) { $arParams = array_merge($this->arParams, $this->CACHE[__METHOD__][$id]); return $arParams; } /** * Analize path part "folder#section_id#/#element_id#" */ $arKeys = array(); if (!empty($this->short_path_template) && preg_match_all("/(?<=\#)([a-z_]+)(?=\#)/is", strToLower($this->short_path_template), $arKeys)) { $arKeys = (is_array($arKeys) ? $arKeys[0] : false); if (!empty($arKeys) && is_array($arKeys)) { $pageTemplateReg = "'^".preg_replace("'#[^#]+?#'", "([^/]*)", $this->short_path_template)."'"; $arValues = array(); if (preg_match($pageTemplateReg, $path, $arValues)) { array_shift($arValues); $arValues = @array_combine($arKeys, $arValues); if (is_array($arValues)) { if (!empty($arValues["element_id"]) && intval($arValues["element_id"]) > 0) $options["element_id"] = (int)$arValues["element_id"]; elseif (!empty($arValues["section_id"]) && intval($arValues["section_id"]) > 0) $options["section_id"] = (int)$arValues["section_id"]; } } } } $params = array( "item_id" => (is_array($this->arRootSection) ? $this->arRootSection["ID"] : 0), "not_found" => false, "is_dir" => false, "is_file" => false, "parent_id" => false, "basename" => ""); $arFilter = array("IBLOCK_ID" => $this->IBLOCK_ID); if($this->arRootSection && is_array($this->arRootSection)) { $arFilter["RIGHT_MARGIN"] = intVal($this->arRootSection["RIGHT_MARGIN"]) - 1; $arFilter["LEFT_MARGIN"] = intVal($this->arRootSection["LEFT_MARGIN"]) + 1; } if ($options["show_history"] == "Y") $arFilter["SHOW_HISTORY"] = "Y"; $arFilter['CHECK_PERMISSIONS'] = ($options['check_permissions'] ? 'Y' : 'N'); $arPath = explode("/", trim($path, "/")); $arNewPath = array(); foreach ($arPath as $p) { if (strlen(trim($p)) > 0) $arNewPath[] = $p; } $arPath = $arNewPath; $arElement = array(); foreach ($arPath as $pathID => $pathName) { foreach($this->meta_names as $metaName => $metaArr) { if ($pathName == $metaArr["alias"]) $arPath[$pathID] = $metaArr["name"]; } } if (is_set($options, "section_id")) { if (empty($options["section_id"]) || ($this->arRootSection && $options["section_id"] == $this->arRootSection["ID"])) { $params["is_dir"] = true; $params["dir_array"] = array("ID" => 0, "DEPTH_LEVEL" => 0, "LEFT_MARGIN" => 0, "RIGHT_MARGIN" => $this->INT_MAX); } else { $arFilter["ID"] = $options["section_id"]; //todo check if section_id in symlink section if(1) { if($this->arParams['is_dir'] && !empty($this->arParams['dir_array']['IBLOCK_ID'])) { $arFilter['IBLOCK_ID'] = $this->arParams['dir_array']['IBLOCK_ID']; } $iblockId = CWebDavSymlinkHelper::getIblockIdForSectionId($options["section_id"]); if($iblockId) { $arFilter['IBLOCK_ID'] = $iblockId; } unset($arFilter["RIGHT_MARGIN"], $arFilter["LEFT_MARGIN"]); } $rs = CIBlockSection::GetList(array(), $arFilter, false, self::getUFNamesForSectionLink()); if ($arr = $rs->Fetch()) { $params["item_id"] = intval($arr["ID"]); $params["parent_id"] = intval($arr["IBLOCK_SECTION_ID"]); $params["is_dir"] = true; $params["dir_array"] = $arr; $params["basename"] = $arr['NAME']; } else { $params["not_found"] = true; } } } elseif (is_set($options, "element_id")) { $arFilter = array( "SHOW_NEW" => "Y", "SHOW_HISTORY" => "Y", "ID" => $options["element_id"], "IBLOCK_ID" => $this->IBLOCK_ID, "CHECK_PERMISSIONS" => ($options['check_permissions'] ? 'Y' : 'N') ); list($contextType, $contextEntityId) = $this->getContextData(); if(CWebDavSymlinkHelper::isLinkElement($contextType, $contextEntityId, $options["element_id"])) { $parentSectionData = CWebDavSymlinkHelper::getLinkDataOfElement($contextType, $contextEntityId, $options["element_id"]); if(!empty($parentSectionData[self::UF_LINK_IBLOCK_ID])) { $arFilter['IBLOCK_ID'] = $parentSectionData[self::UF_LINK_IBLOCK_ID]; } } $db_res = CIBlockElement::GetList( null, $arFilter, false, false, $arSelectFields ); if (!($db_res && $arElement = $db_res->Fetch())) { $params["not_found"] = true; } else { $params["is_file"] = true; $params["parent_id"] = intval($arElement["IBLOCK_SECTION_ID"]); $params["item_id"] = $options["element_id"]; $params["basename"] = $arElement['NAME']; if ($this->e_rights) { $arElement['E_RIGHTS'] = $this->GetPermission('ELEMENT', $arElement['ID']); } if ($this->arRootSection && $this->arRootSection["ID"] != $arElement["IBLOCK_SECTION_ID"]) { $arFilter["ID"] = $arElement["IBLOCK_SECTION_ID"]; $rs = CIBlockSection::GetList(array(), $arFilter, false, array('ID')); if ($arr = $rs->Fetch()) { $params["item_id"] = intval($arr["ID"]); } else { $params["not_found"] = true; } } } } elseif (count($arPath) > 0) { $basename = array_pop($arPath); $params['basename'] = ($replace_symbols == true ? $this->CorrectName($basename) : $basename); foreach ($arPath as $dir) { $arFilter["SECTION_ID"] = $params["item_id"]; $arFilter["=NAME"] = $dir; $rs = CIBlockSection::GetList(array(), $arFilter, false, array_merge(array('ID'), self::getUFNamesForSectionLink())); if ($rs && $arr = $rs->Fetch()) { $params["item_id"] = intval($arr["ID"]); if(!empty($arr[self::UF_LINK_SECTION_ID])) { $params["item_id"] = intval($arr[self::UF_LINK_SECTION_ID]); $arFilter['IBLOCK_ID'] = $arr[self::UF_LINK_IBLOCK_ID]; unset($arFilter["RIGHT_MARGIN"], $arFilter["LEFT_MARGIN"]); } } else { $params["not_found"] = true; break; } } if ($params["not_found"] == false) { $params["parent_id"] = intVal($params["item_id"]); $arFilter["SECTION_ID"] = $params["item_id"]; $arFilter["=NAME"] = $params["basename"]; $rs = CIBlockSection::GetList(array(), $arFilter, false, self::getUFNamesForSectionLink()); if ($arr = $rs->Fetch()) { $params["item_id"] = intval($arr["ID"]); $params["is_dir"] = true; $params["dir_array"] = $arr; } else { $arOrder = array("ID" => "ASC"); $arFilter = array( "IBLOCK_ID" => empty($arFilter['IBLOCK_ID'])? $this->IBLOCK_ID : $arFilter['IBLOCK_ID'], //set iblockId to iblockId in prev.lookup (symlink logic) "SECTION_ID" => $params["item_id"], "CHECK_PERMISSIONS" => ($options['check_permissions'] ? 'Y' : 'N'), "=NAME" => $params["basename"], "SHOW_HISTORY" => "N", "SHOW_NEW" => "Y"); if ($this->workflow == 'workflow') { $arOrderWF = array("ID" => "DESC"); $arFilterWF = $arFilter; $arFilterWF["SHOW_HISTORY"] = "Y"; $arFilterWF[">WF_PARENT_ELEMENT_ID"] = 0; $db_res = CIBlockElement::GetList($arOrderWF, $arFilterWF, false, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()) { $arBuff = array(); do { $res["LAST_ID"] = CIBlockElement::WF_GetLast($res["ID"]); if (!in_array($res["LAST_ID"], $arBuff)) { $db_res = CIBlockElement::GetList($arOrderWF, array("ID" => $res["LAST_ID"], "SHOW_HISTORY" => "Y"), false, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()): if ($res["NAME"] == $params["basename"] && (intval($res["IBLOCK_SECTION_ID"]) == intval($params["item_id"]))): $original = $arElement = $res; if ($res["WF_PARENT_ELEMENT_ID"] > 0) { $arFilterWF = array("ID" => $arElement["WF_PARENT_ELEMENT_ID"], "SHOW_HISTORY" => "Y"); $db_res = CIBlockElement::GetList($arOrderWF, $arFilterWF, false, false, $arSelectFields); if ($db_res) $original = $db_res->Fetch(); } $arElement["REAL_ELEMENT_ID"] = $arElement["ID"]; $arElement["ID"] = $original["ID"]; $arElement["PROPERTY_WEBDAV_INFO_VALUE"] = $original["PROPERTY_WEBDAV_INFO_VALUE"]; $arElement["PROPERTY_WEBDAV_INFO_VALUE_ID"] = $original["PROPERTY_WEBDAV_INFO_VALUE_ID"]; $arElement["original"] = $original; break; endif; endif; $arBuff[] = $res["LAST_ID"]; } } while ($res = $db_res->Fetch()); } } if (empty($arElement)) { $db_res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()): $arElement = $res; endif; } if (!empty($arElement)) { $params["is_file"] = true; } else { $params["not_found"] = true; } } } } else { $params["is_dir"] = true; } if (!$params["not_found"] && !empty($arElement) && $params["is_file"]) { $params["element_id"] = $params["item_id"] = $arElement["ID"]; $params["original"] = $arElement["original"]; unset($arElement["original"]); $params["element_array"] = $arElement; $params["element_name"] = $arElement["NAME"]; $params["file_name"] = $arElement["NAME"]; $params["file_extention"] = strtolower(strrchr($arElement["NAME"] , '.')); $arFile = CFile::GetFileArray($arElement["PROPERTY_".$this->file_prop."_VALUE"]); $params["file_id"] = $arFile["ID"]; $params["file_mimetype"] = $arFile["CONTENT_TYPE"]; $params["file_size"] = $arFile["FILE_SIZE"]; $params["fullpath"] = $arFile["SRC"]; $params["file_array"] = $arFile; } elseif ($params["not_found"]) { $params["item_id"] = false; } $this->CACHE[__METHOD__][$id] = $params; return $params; } function GetObjectPath($arObject, $convert = false) { $result = null; if ($arObject['is_dir']) { $result = $this->_get_path($arObject['item_id'], $convert); } elseif ($arObject['is_file']) { $result = str_replace(array("///","//"), "/", $this->_get_path($arObject['parent_id'], false) . "/" . $arObject['element_name']); if ($convert) $result = $this->_uencode($result, array("utf8" => "Y", "convert" => "full")); } return $result; } function IsLocked($ID, $IBLOCK_ID, &$params) // not used { $params = array("locked_by" => 0, "date_lock" => ""); $bLocked = true; if ($ID <= 0 || $IBLOCK_ID <= 0): $bLocked = false; elseif (!CIBlockElement::WF_IsLocked($ID, $locked_by, $date_lock)): $bLocked = false; elseif (intVal($locked_by) == $GLOBALS["USER"]->GetID()): $bLocked = false; elseif (IsModuleInstalled("workflow")): if (CModule::IncludeModule("workflow") && CIBlock::GetArrayByID($IBLOCK_ID, "WORKFLOW") != "N"): $bLocked = (CWorkflow::IsAdmin() ? false : true); endif; endif; $db_res = CUser::GetByID($locked_by); if ($db_res && $arUser = $db_res->GetNext()) { $locked_by = '['.$arUser["ID"].'] '.trim($arUser["LAST_NAME"]." ".$arUser["NAME"]); } $params = array("locked_by" => $locked_by, "date_lock" => $date_lock); return $bLocked; } function IsTrashEmpty() { static $dataType = 'TrashEmpty'; $trashEmpty = $this->_dataCache($dataType); if ($trashEmpty === false) { $trashEmpty = 'Y'; $trashSectionID = $this->GetMetaID('TRASH'); $cnt = CIBlockElement::GetList( Array("ID"=>"DESC"), $arFilter=Array("SHOW_HISTORY"=>"Y", "IBLOCK_ID"=>$this->IBLOCK_ID, "SECTION_ID"=>$trashSectionID), array(), false, array('ID') ); if ($cnt > 0) { $trashEmpty = 'N'; } else { $dbTrash = CIBlockSection::GetList(Array("ID"=>"DESC"), $arFilter=Array("SHOW_HISTORY"=>"Y", "IBLOCK_ID"=>$this->IBLOCK_ID, "SECTION_ID"=>$trashSectionID), false, array("ID")); if ($dbTrash && $arTrashItem = $dbTrash->Fetch()) { $trashEmpty = 'N'; } } $this->_dataCache($dataType, $trashEmpty); } return ($trashEmpty==='Y'); } /** * This method send file to client by CFile::ViewByUser() * And it is used for send documents to the client Bitrix24.Disk * All doc's is published * @param $id * @param array $misc * @return bool */ function fileViewByUser($id, array $misc = array()) { $id = (int)$id; $iblockId = $this->IBLOCK_ID; if(!empty($misc['IBLOCK_ID'])) { $iblockId = $misc['IBLOCK_ID']; } $filter = array('IBLOCK_ID' => $iblockId, 'ID' => $id, 'CHECK_PERMISSIONS' => 'Y', 'SHOW_NEW' => 'Y'); if ($this->permission < 'U') { $filter['SHOW_HISTORY'] = 'N'; } $object = $this->GetObject(array('element_id' => $id, 'check_permissions' => false), false); if(!$this->CheckWebRights('', array('action' => 'read', 'arElement' => $object), false)) { return false; } $dbRows = CIBlockElement::GetList(array(), $filter, false, array('nTopCount' => 1), array('ID', 'NAME', 'TIMESTAMP_X', 'IBLOCK_ID', 'PROPERTY_' . $this->file_prop)); if ($dbRows && $row = $dbRows->Fetch()) { return CFile::ViewByUser($row['PROPERTY_FILE_VALUE'], array('content_type' => 'application/octet-stream', 'force_download' => true)); } return false; } function countHistoryDocumentByFileId($elementId) { $elementId = (int)$elementId; if($elementId <= 0) { return 0; } if(($this->workflow != 'bizproc' && $this->workflow != 'bizproc_limited')) { return 0; } $filter = array( "DOCUMENT_ID" => array( $this->wfParams['DOCUMENT_TYPE'][0], $this->wfParams['DOCUMENT_TYPE'][1], $elementId ), ); $history = new CBPHistoryService(); return $history->GetHistoryList(array(), $filter, array()); } function findHistoryDocumentByFileId($elementId, $fileId, $documentId) { $elementId = (int)$elementId; $fileId = (int)$fileId; if($fileId <= 0 || $elementId <= 0 || empty($documentId)) { return array(); } if(($this->workflow != 'bizproc' && $this->workflow != 'bizproc_limited')) { return array(); } $by = "modified"; $order = "desc"; $history = new CBPHistoryService(); $dbDocumentHistory = $history->GetHistoryList( array(strtoupper($by) => strtoupper($order)), array( "DOCUMENT_ID" => $documentId, ), false, array('nTopCount' => 20), //todo we search by OLD_FILE_ID this is not true. 20 - magic. And we trust in him array( "ID", "DOCUMENT_ID", "NAME", "MODIFIED", "USER_ID", "USER_NAME", "USER_LAST_NAME", "USER_LOGIN", "DOCUMENT", "USER_SECOND_NAME" ) ); while($document = $dbDocumentHistory->fetch()) { if(!empty($document['DOCUMENT']['OLD_FILE_ID']) && $document['DOCUMENT']['OLD_FILE_ID'] == $fileId) { return $document; } } return $document; } /** * @param $ID * @param int $WF_ID * @param bool $NotCheckWebRights * @param array $params */ function SendHistoryFile($ID, $WF_ID = 0, $NotCheckWebRights = false, $params = array()) // wrong { $ID = intval($ID); $WF_ID = intval($WF_ID); if($ID <=0) { return; } list($contextType, $contextEntityId) = $this->getContextData(); if(CWebDavSymlinkHelper::isLinkElement($contextType, $contextEntityId, $ID)) { $parentSectionData = CWebDavSymlinkHelper::getLinkDataOfElement($contextType, $contextEntityId, $ID); if($parentSectionData) { $linkWebdav = new self($parentSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array( 'ROOT_SECTION_ID' => $parentSectionData[self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $parentSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, )); if($this->withoutAuthorization) { $linkWebdav->withoutAuthorization = true; } return $linkWebdav->SendHistoryFile($ID, $WF_ID, $NotCheckWebRights, $params); } } $io = self::GetIo(); list($arFile, $options, $fullpath, $filename) = $this->getHistoryFileData($ID, $WF_ID, $params); if (empty($arFile)) { return; } $options["logica_full_path"] = $fullpath; if (!file_exists($fullpath) && file_exists($io->GetPhysicalName($fullpath))) $fullpath = $io->GetPhysicalName($fullpath); $options["path"] = $this->_path; $options["mimetype"] = ( (!empty($arFile["CONTENT_TYPE"]) && $arFile["CONTENT_TYPE"] != "unknown" && $arFile["CONTENT_TYPE"] != "application/octet-stream") ? $arFile["CONTENT_TYPE"] : $this->get_mime_type($filename)); $options["size"] = !empty($arFile["FILE_SIZE"]) ? $arFile["FILE_SIZE"] : 0; $options["name"] = $filename; if(!$NotCheckWebRights) { $arElementData = $this->GetObject(array("element_id" => $ID, "check_permissions" => false), false); if(!$this->CheckWebRights("", array("action" => "read", "arElement" => $arElementData), false)) { return; } } if ($options["resized"] == "Y" || $params["cache_image"] == "Y") { CFile::ViewByUser($arFile, array("content_type" => $options["mimetype"], "cache_time" => $options["cache_time"])); } if (file_exists($fullpath)) { if(empty($options['size'])) { $options['size'] = filesize($fullpath); } $options["mtime"] = filemtime($fullpath); $options["stream"] = fopen($fullpath, "r"); } $x = $this->SendFile($options); //, true } /** * @param $id * @param $wfId * @param $params * @return array */ public function getHistoryFileData($id, $wfId, &$params) { $fullpath = ''; $options = $arFile = $arr = array(); $io = self::GetIo(); $arFilter = array( "IBLOCK_ID" => (isset($this->arParams['element_array']['ID']) && $this->arParams['element_array']['ID'] == $id)? $this->arParams['element_array']['IBLOCK_ID'] : $this->IBLOCK_ID, "ID" => $id, "SHOW_HISTORY" => "Y", "CHECK_PERMISSIONS" => "Y" ); if ($this->permission < "U") { $arFilter["SHOW_HISTORY"] = "N"; } if (($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited') && $wfId > 0) { $history = new CBPHistoryService(); $db_res = $history->GetHistoryList(array("ID" => "DESC"), array( "DOCUMENT_ID" => array( $this->wfParams['DOCUMENT_TYPE'][0], $this->wfParams['DOCUMENT_TYPE'][1], $id ), "ID" => $wfId ), false, false, array("ID", "DOCUMENT", "NAME")); if ($db_res && $arr = $db_res->Fetch()) { $arFile = array( "SRC" => $arr["DOCUMENT"]["PROPERTIES"][$this->file_prop]["VALUE"], "NAME" => $arr["DOCUMENT"]["NAME"] ); $arr["NAME"] = $arr["DOCUMENT"]["NAME"]; $fullpath = urldecode($arFile["SRC"]); if (substr($fullpath, 0, 4) != "http") { $fullpath = $io->GetPhysicalName($_SERVER['DOCUMENT_ROOT'] . $arFile["SRC"]); } else { $fullpath = CWebDavTools::urlEncode($fullpath); } $arTmpFile = CFile::MakeFileArray($fullpath); $fullpath = $arTmpFile['tmp_name']; $arFile["FILE_SIZE"] = $arTmpFile["size"]; } } else { $arFilter['CHECK_PERMISSIONS'] = 'N'; //check permissions manual! While infoblock perm's check by every section's (in dropped - we have error). $rs = CIBlockElement::GetList(array(), $arFilter, false, array("nTopCount" => 1), array( "ID", "NAME", "TIMESTAMP_X", "IBLOCK_ID", "PROPERTY_" . $this->file_prop )); if ($rs && $arr = $rs->Fetch()) { if (empty($this->arParams["element_array"])) $this->arParams["element_array"] = $arr; $arFile = CFile::GetFileArray($arr["PROPERTY_FILE_VALUE"]); $options["from_cloud"] = (intval($arFile['HANDLER_ID']) > 0 ? "Y" : "N"); $arTmpFile = array(); if (CFile::IsImage($arFile["FILE_NAME"], $arFile["CONTENT_TYPE"])) { if ($params["width"] > 0 || $params["height"] > 0) { $arTmpFile = CFile::ResizeImageGet($arFile, array( "width" => $params["width"], "height" => $params["height"] ), ($params["exact"] == "Y" ? BX_RESIZE_IMAGE_EXACT : BX_RESIZE_IMAGE_PROPORTIONAL), true, false, true); $arTmpFile['tmp_name'] = ($options["from_cloud"] == "Y" ? "" : $_SERVER["DOCUMENT_ROOT"]) . $arTmpFile["src"]; $options["resized"] = "Y"; $arFile["FILE_SIZE"] = $arTmpFile["size"]; $arFile["SRC"] = $arTmpFile["src"]; } if ($params["cache_image"] == "Y") { $options["cache_time"] = 86400; } } else { $params["cache_image"] = "N"; } if (empty($arTmpFile)) { $arTmpFile = CFile::MakeFileArray($arr["PROPERTY_FILE_VALUE"]); } $fullpath = $arTmpFile['tmp_name']; } } $elementName = $arr['NAME']; return array($arFile, $options, $fullpath, $elementName); } function GetHistoryFileID($elementID) { $elementID = intval($elementID); if($elementID <= 0) { return 0; } $arFilter = array("IBLOCK_ID" => $this->IBLOCK_ID, "ID" => $elementID, "SHOW_HISTORY"=>"Y", "CHECK_PERMISSIONS" => "Y"); if ($this->permission < "U") { $arFilter["SHOW_HISTORY"] = "N"; } $dbElement = CIBlockElement::GetList(array(), $arFilter, false, array("nTopCount" => 1), array("ID", "NAME", "IBLOCK_ID", "PROPERTY_" . $this->file_prop)); $arElement = $dbElement->Fetch(); return $arElement ? intval($arElement["PROPERTY_FILE_VALUE"]) : 0; } function UpdateRootSection() { if ($this->arRootSection !== false) $this->SetRootSection($this->arRootSection['ID'], true); // MARGINs changed if (isset($this->CACHE['CWebDavIblock::GetObject'])) $this->CACHE['CWebDavIblock::GetObject'] = array(); } static function GetReaders($ID, $iblockID = null) { static $arValidTasks = null; static $readersCache = array(); $arReaders = array(); $ID = (int) $ID; if ($ID <= 0) return $arReaders; if (isset($readersCache[$ID])) return $readersCache[$ID]; if ($arValidTasks == null) { $arTasks = CWebDavIblock::GetTasks(); $arValidTasks = array(); foreach ($arTasks as $taskLetter => $taskID) { $arOperations = CTask::GetOperations($taskID, true); if (array_search('element_read', $arOperations) !== false) $arValidTasks[$taskID] = true; } } if ($iblockID === null) { $rElement = CIBlockElement::GetList( array(), array( 'ID' => $ID, 'SHOW_NEW' => 'Y', ), false, false, array( 'ID', 'IBLOCK_ID', ) ); if ($rElement && $arElement = $rElement->Fetch()) { $iblockID = $arElement['IBLOCK_ID']; } } $iblockID = (int) $iblockID; if ($iblockID <= 0) return $arReaders; $bSocNet = (CModule::IncludeModule('socialnetwork')); if (CIBlock::GetArrayByID($iblockID, "RIGHTS_MODE") === "E") { $ibRights = new CIBlockElementRights($iblockID, $ID); $arRights = $ibRights->GetRights(); foreach($arRights as $rightID => $arRight) { if (isset($arValidTasks[$arRight['TASK_ID']])) { $arReaders[] = $arRight['GROUP_CODE']; if ( $bSocNet && preg_match( '/^SG(\d+)_['.SONET_ROLES_OWNER.SONET_ROLES_MODERATOR.SONET_ROLES_USER.']$/', $arRight['GROUP_CODE'], $matches ) ) $arReaders[] = "SG".$matches[1]; } } } else { $gr_res = CIBlock::GetGroupPermissions($iblockID); foreach($gr_res as $group_id => $perm) { if ($perm >= 'R') $arReaders[] = 'G'.$group_id; } } $readersCache[$ID] = array_unique($arReaders); return $readersCache[$ID]; } static function UpdateSearchRights($ID, $iblockID = null) { if (!CModule::IncludeModule('search')) return true; $ID = (int) $ID; if ($ID <= 0) return false; if ($iblockID === null) { $rElement = CIBlockElement::GetList( array(), array( 'ID' => $ID, 'SHOW_NEW' => 'Y', ), false, false, array( 'ID', 'IBLOCK_ID', ) ); if ($rElement && $arElement = $rElement->Fetch()) { $iblockID = $arElement['IBLOCK_ID']; } } $iblockID = (int) $iblockID; if ($iblockID <= 0) return false; $code = CIBlock::GetArrayByID($iblockID, "CODE"); $bSocNet = ( (strpos($code, "user_files") === 0) || (strpos($code, "group_files") === 0) ); if ( ! $bSocNet && CIBlock::GetArrayByID($iblockID, "INDEX_ELEMENT") === "N") { return false; } $arReaders = self::GetReaders($ID, $iblockID); CSearch::ChangePermission( ($bSocNet ? 'socialnetwork' : 'iblock'), $arReaders, $ID ); return true; } public static function sCheckUniqueName($iblockId, $sectionId, $workflow, $basename, &$res) { $iblockId = intVal($iblockId); $sectionId = intVal($sectionId); $basename = trim($basename); if (empty($basename)) return false; $arObject = array(); $arSelectFields = array("ID", "NAME", "IBLOCK_ID", "IBLOCK_SECTION_ID", "WF_PARENT_ELEMENT_ID", "WF_STATUS_ID", "CREATED_BY"); $arFilter = array( "IBLOCK_ID" => $iblockId, "SECTION_ID" => $sectionId, "=NAME" => $basename, 'CHECK_PERMISSIONS' => 'N', "SHOW_NEW" => ($workflow == 'workflow' || $workflow == 'bizproc' ? "Y" : "N") ); $arOrder = array("ID" => "ASC"); $db_res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()) { $arObject = array( "object" => "element", "id" => $res["ID"], "data" => $res); } else { $db_res = CIBlockSection::GetList($arOrder, $arFilter, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()) { $arObject = array( "object" => "section", "id" => $res["ID"], "data" => $res); } } if (!empty($arObject)) {} elseif ($workflow == 'workflow' || $workflow == 'bizproc') { $arFilter["SHOW_HISTORY"] = "Y"; $db_res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelectFields); if ($db_res && $res = $db_res->Fetch()) { $arBuff = array(); do { $res["LAST_ID"] = CIBlockElement::WF_GetLast($res["WF_PARENT_ELEMENT_ID"]); if (empty($arBuff[$res["LAST_ID"]])) { $db_res = CIBlockElement::GetList($arOrder, array("ID" => $res["LAST_ID"], "SHOW_HISTORY" => "Y"), false, false, $arSelectFields); if (!($db_res && $res = $db_res->Fetch())): $arObject = array( "object" => "element", "id" => $res["LAST_ID"], "data" => "element_is_not_found"); break; elseif ($arBuff[$res["LAST_ID"]]["NAME"] == $basename && $arBuff[$res["LAST_ID"]]["IBLOCK_SECTION_ID"] == $sectionId): $arObject = array( "object" => "element", "id" => $res["ID"], "data" => $res); break; else: $arBuff[$res["LAST_ID"]] = $res; endif; } } while ($res = $db_res->Fetch()); } } if (empty($arObject)) { return true; } $res = $arObject; return false; } function CheckUniqueName($basename, $sectionId, &$res) { $iblockId = $this->IBLOCK_ID; list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($sectionId); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $parentSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($parentSectionData) { $iblockId = $parentSectionData[self::UF_LINK_IBLOCK_ID]; if($parentSectionData['ID'] == $sectionId) { $sectionId = $parentSectionData[self::UF_LINK_SECTION_ID]; } } } return self::sCheckUniqueName($iblockId, $sectionId, $this->workflow, $basename, $res); } function _get_mixed_list($section_id, $arParams = array(), $element_id = 0) { list($contextType, $contextEntityId) = $this->getContextData(); if($section_id) { $sectionData = $this->getSectionDataForLinkAnalyze($section_id); if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $parentSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if($parentSectionData) { $linkWebdav = new self($parentSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array( 'ROOT_SECTION_ID' => $parentSectionData[self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $parentSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, )); return $linkWebdav->_get_mixed_list($section_id, $arParams, $element_id); } } } else { if(CWebDavSymlinkHelper::isLinkElement($contextType, $contextEntityId, $element_id)) { $parentSectionData = CWebDavSymlinkHelper::getLinkDataOfElement($contextType, $contextEntityId, $element_id); if($parentSectionData) { $linkWebdav = new self($parentSectionData[self::UF_LINK_IBLOCK_ID], $this->base_url . $this->_path, array( 'ROOT_SECTION_ID' => $parentSectionData[self::UF_LINK_SECTION_ID], 'symlinkMode' => true, 'symlinkSectionData' => $parentSectionData, 'symlinkRealRootSectionData' => $this->arRootSection, )); return $linkWebdav->_get_mixed_list($section_id, $arParams, $element_id); } } } global $by, $order; InitSorting(); if (empty($by)) { $by = "NAME"; $order = "ASC"; } $by = strtoupper($by); $order = strtoupper($order); $section_id = ($section_id === null ? null : intVal($section_id)); $element_id = intVal($element_id); $arParams = (is_array($arParams) ? $arParams : array()); $arParams["COLUMNS"] = (is_array($arParams["COLUMNS"]) ? $arParams["COLUMNS"] : array()); $arFilter = array( "IBLOCK_ID" => $this->IBLOCK_ID, "IBLOCK_ACTIVE" => "Y", "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R", "SHOW_NEW" => "Y"); if ($section_id !== null) $arFilter["SECTION_ID"] = $section_id; $perms = $this->permission; if ( $this->e_rights && !$GLOBALS['USER']->CanDoOperation('webdav_change_settings') ) { if ($element_id > 0) { $arParentPerms = $this->GetPermissions('ELEMENT', (int) $element_id); } else { $arParentPerms = $this->GetPermissions( 'SECTION', ( ($section_id !== null) ? $section_id : ( ($this->arRootSection) ? $this->arRootSection : 0 ) ) ); } if (is_array($arParentPerms)) { if (isset($arParentPerms['element_rights_edit'])) $perms = 'X'; elseif (isset($arParentPerms['element_edit_any_wf_status'])) $perms = 'W'; elseif (isset($arParentPerms['element_edit'])) $perms = 'U'; elseif (isset($arParentPerms['element_read'])) $perms = 'R'; else $perms = 'A'; } } if ($perms < "U") { $arFilter["ACTIVE"] = "Y"; $arFilter["GLOBAL_ACTIVE"] = "Y"; $arFilter["SHOW_HISTORY"] = "N"; $arFilter["SHOW_NEW"] = "N"; $arParams["COLUMNS"] = array_diff($arParams["COLUMNS"], array("ACTIVE", "GLOBAL_ACTIVE", "SORT", "CODE", "EXTERNAL_ID", "DATE_ACTIVE_FROM", "DATE_ACTIVE_TO")); } if ($perms < "W" && $this->workflow == "bizproc") { $arFilter["SHOW_BP_NEW"] = array( "GROUPS" => $this->USER["GROUPS"], "MODULE_ID" => $this->wfParams["DOCUMENT_TYPE"][0], "ENTITY" => $this->wfParams["DOCUMENT_TYPE"][1], "PERMISSION" => "read", "USER_ID" => $GLOBALS["USER"]->GetID()); } if ($element_id > 0 && $arParams["SHOW_VERSIONS"] == "Y") { $arFilter["SHOW_HISTORY"] = "Y"; $arFilter["WF_PARENT_ELEMENT_ID"] = $element_id; if ($perms >= "U" && $perms < "W") $arFilter["CHECK_BP_PERMISSIONS"] = $arFilter["SHOW_BP_NEW"]; } elseif ($element_id > 0) { $arFilter["ID"] = $element_id; } if ($this->arRootSection && ($element_id <= 0)) { if ($arFilter["SECTION_ID"] === null) $arFilter["SECTION_ID"] = $this->arRootSection["ID"]; if (sizeof($arParams['FILTER'])>0) $arFilter["INCLUDE_SUBSECTIONS"] = "Y"; $arFilter["RIGHT_MARGIN"] = $this->arRootSection["RIGHT_MARGIN"]; $arFilter["LEFT_MARGIN"] = $this->arRootSection["LEFT_MARGIN"]; } if ($arFilter["SECTION_ID"] === null) unset($arFilter["SECTION_ID"]); if (isset($arParams["FILTER"]) && sizeof($arParams["FILTER"])>0) { if (isset($arParams["FILTER"]["timestamp_2"]) && strlen($arParams["FILTER"]["timestamp_2"]) > 0 && $arParams["FILTER"]["timestamp_datesel"]!="before") $arParams["FILTER"]["timestamp_2"] .= " 23:59:59"; $arFilter = array_merge($arFilter, $arParams["FILTER"]); } if (isset($arFilter["NAME"]) && isset($arFilter["DESCRIPTION"])) { $arFilter[] = array("LOGIC" => "OR", "NAME"=>$arFilter["NAME"], "DESCRIPTION"=>$arFilter["DESCRIPTION"]); unset($arFilter["NAME"]); unset($arFilter["DESCRIPTION"]); } $arSelectedFields = $arParams["COLUMNS"]; if(in_array("LOCKED_USER_NAME", $arSelectedFields)) $arSelectedFields[] = "WF_LOCKED_BY"; if(in_array("USER_NAME", $arSelectedFields)) $arSelectedFields[] = "MODIFIED_BY"; if(in_array("CREATED_USER_NAME", $arSelectedFields)) $arSelectedFields[] = "CREATED_BY"; if(in_array("DETAIL_TEXT", $arSelectedFields)) $arSelectedFields[] = "DETAIL_TEXT_TYPE"; $arSelectedFields = array_merge($arSelectedFields, array( "ACTIVE", "CODE", "CREATED_BY", "DATE_CREATE", "DATE_CREATE_UNIX", "DESCRIPTION", "DETAIL_PAGE_URL", "EXTERNAL_ID", "IBLOCK_ID", "IBLOCK_CODE", "IBLOCK_SECTION_ID", "ID", "LANG_DIR", "XML_ID", "LID", "LOCKED_USER_NAME", "LOCK_STATUS", "MODIFIED_BY", "NAME", "PREVIEW_TEXT", "PREVIEW_TEXT_TYPE", //"PROPERTY_FORUM_MESSAGE_CNT", "PROPERTY_FORUM_TOPIC_ID", "PROPERTY_".$this->file_prop, "PROPERTY_WEBDAV_INFO", "PROPERTY_WEBDAV_SIZE", "SITE_ID", "TAGS", "TIMESTAMP_X", "TIMESTAMP_X_UNIX", "WF_DATE_LOCK", "WF_NEW", "WF_PARENT_ELEMENT_ID", "WF_STATUS_ID", "WF_LOCKED_BY" )); if ($this->workflow == "bizproc") { $arSelectedFields[] = "BP_PUBLISHED"; $arSelectedFields[] = "BIZPROC"; } elseif ($this->workflow == 'workflow') { $arSelectedFields[] = "WF_COMMENTS"; } $arSelectedFields = array_unique($arSelectedFields); $arSelectedFields = array_filter($arSelectedFields); $this->wfParams["selected_fields"] = $arSelectedFields; if ($element_id > 0) { $arElementResult = array(); $arFilter["SHOW_HISTORY"] = "Y"; $db_res = CIBlockElement::GetList(array(), $arFilter, false, false, $arSelectedFields); if ($db_res) { while ($arElement = $db_res->Fetch()) { $arElement["TYPE"] = "E"; $arElement["FILE"] = CFile::GetFileArray($arElement["PROPERTY_" . $this->file_prop . "_VALUE"]); $arElement["FILE"] = (is_array($arElement["FILE"]) ? $arElement["FILE"] : array("FILE_SIZE" => 0, "CONTENT_TYPE" => "text/plain", "MTIME" => 0)); if ($this->e_rights) { $arElement['E_RIGHTS'] = $this->GetPermission('ELEMENT', $arElement['ID']); } $arElementResult[] = $arElement; } } $db_res = new CDBResult; $db_res->InitFromArray($arElementResult); } else { $arOrder = array($by => $order); $arResult = array(); if (!isset($arFilter["ID"])) { $arSectionFilter = array ( "IBLOCK_ID" => $arFilter["IBLOCK_ID"], "?NAME" => $arFilter["NAME"], "SECTION_ID" => $arFilter["SECTION_ID"], ">=ID" => $arFilter["ID_1"], "<=ID" => $arFilter["ID_2"], ">=TIMESTAMP_X" => $arFilter["TIMESTAMP_X_1"], "<=TIMESTAMP_X" => $arFilter["TIMESTAMP_X_2"], "MODIFIED_BY" => $arFilter["MODIFIED_USER_ID"]? $arFilter["MODIFIED_USER_ID"]: $arFilter["MODIFIED_BY"], ">=DATE_CREATE" => $arFilter["DATE_CREATE_1"], "<=DATE_CREATE" => $arFilter["DATE_CREATE_2"], "CREATED_BY" => $arFilter["CREATED_USER_ID"]? $arFilter["CREATED_USER_ID"]: $arFilter["CREATED_BY"], "ACTIVE" => $arFilter["ACTIVE"], "CHECK_PERMISSIONS" => "Y", ); if (isset($arFilter["content"])) $arSectionFilter["?NAME"] = $arFilter["content"]; $arSectionIDs = array(); $excludeDropped = $excludeOldDropped = $excludeTrash = $excludeSectionMargin = array(); if(!empty($arParams['NON_OLD_DROPPED_SECTION'])) { if($excludeId = $this->GetMetaID(self::OLD_DROPPED)) { $excludeOldDropped = self::$_metaSectionData[$excludeId]; $excludeSectionMargin[] = array( $excludeOldDropped['LEFT_MARGIN'], $excludeOldDropped['RIGHT_MARGIN'], ); } } if(!empty($arParams['NON_DROPPED_SECTION'])) { if($excludeId = $this->GetMetaID(self::DROPPED, false)) { $excludeDropped = self::$_metaSectionData[$excludeId]; $excludeSectionMargin[] = array( $excludeDropped['LEFT_MARGIN'], $excludeDropped['RIGHT_MARGIN'], ); } } if(!empty($arParams['NON_TRASH_SECTION'])) { if($excludeId = $this->GetMetaID(self::TRASH)) { $excludeTrash = self::$_metaSectionData[$excludeId]; $excludeSectionMargin[] = array( $excludeTrash['LEFT_MARGIN'], $excludeTrash['RIGHT_MARGIN'], ); } } $obSection = new CIBlockSection; $rsSection = $obSection->GetList($arOrder, $arSectionFilter, false, array_merge($arSelectedFields, self::getUFNamesForSectionLink(), array('LEFT_MARGIN', 'RIGHT_MARGIN'))); while($arSection = $rsSection->Fetch()) { if($excludeOldDropped && $arSection['LEFT_MARGIN'] >= $excludeOldDropped['LEFT_MARGIN'] && $arSection['RIGHT_MARGIN'] <= $excludeOldDropped['RIGHT_MARGIN']) { continue; } if($excludeTrash && $arSection['LEFT_MARGIN'] >= $excludeTrash['LEFT_MARGIN'] && $arSection['RIGHT_MARGIN'] <= $excludeTrash['RIGHT_MARGIN']) { continue; } if($excludeDropped && $arSection['LEFT_MARGIN'] >= $excludeDropped['LEFT_MARGIN'] && $arSection['RIGHT_MARGIN'] <= $excludeDropped['RIGHT_MARGIN']) { continue; } $arSection["TYPE"] = "S"; $arResult[] = $arSection; if ($this->e_rights) { $arSectionIDs[] = $arSection['ID']; } } if ($this->e_rights) { $arSectionRights = $this->GetPermissions('SECTION', $arSectionIDs); $arSectionRules = $this->GetPermissionRules('SECTION', $arSectionIDs); foreach($arResult as $id => &$arSection) { if ( // if "shared folder" access is restricted ($arSection['XML_ID'] == 'SHARED_FOLDER') && (! isset($arSectionRights[$arSection['ID']]['element_read'])) ) { unset($arResult[$id]); continue; } if (isset($arSectionRights[$arSection['ID']])) $arSection['E_RIGHTS'] = $arSectionRights[$arSection['ID']]; if (isset($arSectionRules[$arSection['ID']]) && $this->IsShared($arSectionRules[$arSection['ID']])) { $arSection['SHARED'] = true; } } unset($arSection); } } $arElementFilter = array ( "IBLOCK_ID" => $arFilter["IBLOCK_ID"], "?NAME" => $arFilter["NAME"], "SECTION_ID" => $arFilter["SECTION_ID"], "ID" => $arFilter["ID"], ">=ID" => $arFilter["ID_1"], "<=ID" => $arFilter["ID_2"], ">=TIMESTAMP_X" => $arFilter["TIMESTAMP_X_1"], "<=TIMESTAMP_X" => $arFilter["TIMESTAMP_X_2"], "EXTERNAL_ID" => $arFilter["EXTERNAL_ID"], "MODIFIED_USER_ID" => $arFilter["MODIFIED_USER_ID"], "MODIFIED_BY" => $arFilter["MODIFIED_BY"], ">=DATE_CREATE" => $arFilter["DATE_CREATE_1"], "<=DATE_CREATE" => $arFilter["DATE_CREATE_2"], "CREATED_BY" => $arFilter["CREATED_BY"], "CREATED_USER_ID" => $arFilter["CREATED_USER_ID"], ">=DATE_ACTIVE_FROM"=> $arFilter["DATE_ACTIVE_FROM_1"], "<=DATE_ACTIVE_FROM"=> $arFilter["DATE_ACTIVE_FROM_2"], ">=DATE_ACTIVE_TO" => $arFilter["DATE_ACTIVE_TO_1"], "<=DATE_ACTIVE_TO" => $arFilter["DATE_ACTIVE_TO_2"], "ACTIVE" => $arFilter["ACTIVE"], "?SEARCHABLE_CONTENT"=> $arFilter["DESCRIPTION"], "?TAGS" => $arFilter["?TAGS"], "WF_STATUS" => $arFilter["WF_STATUS"], "WF_LOCK_STATUS" => $arFilter["WF_LOCK_STATUS"], "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R", "SHOW_NEW" => ($arFilter["SHOW_NEW"] !== "N"? "Y": "N"), "SHOW_HISTORY" => ($arFilter["SHOW_HISTORY"] !== "Y"? "N": "Y"), "SHOW_BP_NEW" => $arFilter["SHOW_BP_NEW"] ); if ($arElementFilter["SHOW_HISTORY"] == "Y") $arElementFilter["SHOW_NEW"] = "N"; $fltSizeFrom = isset($arParams["FILTER"]["FILE_SIZE_1"]) ? $arParams["FILTER"]["FILE_SIZE_1"] : null; $fltSizeTo = isset($arParams["FILTER"]["FILE_SIZE_2"]) ? $arParams["FILTER"]["FILE_SIZE_2"] : null; if (($fltSizeFrom !== null || $fltSizeTo !== null) && isset($arParams["FILTER"]["FILE_SIZE_multiply"]) && in_array($arParams["FILTER"]["FILE_SIZE_multiply"], array("b","kb","mb","gb"))) { $multiply = 1; if ($arParams["FILTER"]["FILE_SIZE_multiply"] === "kb") $multiply = 1024; elseif ($arParams["FILTER"]["FILE_SIZE_multiply"] === "mb") $multiply = 1024*1024; elseif ($arParams["FILTER"]["FILE_SIZE_multiply"] === "gb") $multiply = 1024*1024*1024; if ($fltSizeFrom !== null) { $fltSizeFrom = $fltSizeFrom * $multiply; $arElementFilter[">=PROPERTY_WEBDAV_SIZE"] = $fltSizeFrom; } if ($fltSizeTo !== null) { $fltSizeTo = $fltSizeTo * $multiply; $arElementFilter["<=PROPERTY_WEBDAV_SIZE"] = $fltSizeTo; } } if (isset($arFilter["timestamp_1"]) && isset($arFilter["timestamp_2"])) { $arElementFilter[] = array("LOGIC" => "OR", array("LOGIC" => "AND", ">=DATE_CREATE"=>$arFilter["timestamp_1"], "<=DATE_CREATE"=>$arFilter["timestamp_2"]), array("LOGIC" => "AND", ">=TIMESTAMP_X"=>$arFilter["timestamp_1"], "<=TIMESTAMP_X"=>$arFilter["timestamp_2"]), ); unset($arFilter["timestamp_1"]); unset($arFilter["timestamp_2"]); } elseif (isset($arFilter["timestamp_1"])) { $arElementFilter[] = array("LOGIC" => "OR", ">=DATE_CREATE"=>$arFilter["timestamp_1"], ">=TIMESTAMP_X"=>$arFilter["timestamp_1"]); unset($arFilter["timestamp_2"]); } elseif (isset($arFilter["timestamp_2"])) { $arElementFilter[] = array("LOGIC" => "OR", "<=DATE_CREATE"=>$arFilter["timestamp_2"], "<=TIMESTAMP_X"=>$arFilter["timestamp_2"]); unset($arFilter["timestamp_2"]); } if (isset($arFilter["user"])) { $arElementFilter[] = array("LOGIC" => "OR", "MODIFIED_BY"=>$arFilter["user"], "CREATED_BY"=>$arFilter["user"]); unset($arFilter["user"]); } if(strlen($arFilter["SECTION_ID"])<= 0) unset($arElementFilter["SECTION_ID"]); if(!is_array($arSelectedFields)) { $arSelectedFields = Array("*"); } elseif(!in_array("PROPERTY_WEBDAV_SIZE", $arSelectedFields)) { $arSelectedFields[] = "PROPERTY_WEBDAV_SIZE"; } if(isset($arFilter["INCLUDE_SUBSECTIONS"])) $arElementFilter["INCLUDE_SUBSECTIONS"] = $arFilter["INCLUDE_SUBSECTIONS"]; if(isset($arFilter["CHECK_BP_PERMISSIONS"])) $arElementFilter["CHECK_BP_PERMISSIONS"] = $arFilter["CHECK_BP_PERMISSIONS"]; if(!empty($excludeSectionMargin)) { $arElementFilter['!SUBSECTION'] = $excludeSectionMargin; } $arNavParams = isset($arParams["NAV_PARAMS"]) ? $arParams["NAV_PARAMS"] : false; $arElementIDs = array(); $arElementResult = array(); $obElement = new CIBlockElement; $rsElement = $obElement->GetList($arOrder, $arElementFilter, false, $arNavParams, $arSelectedFields); while($arElement = $rsElement->Fetch()) { $arElement["TYPE"] = "E"; $arElement["FILE"]["FILE_SIZE"] = $this->GetFileSize($arElement); //$arElement['ID'] $arElementResult[] = $arElement; if ($this->e_rights) { $arElementIDs[] = $arElement['ID']; } } if ($this->e_rights) { $arElementRights = $this->GetPermissions('ELEMENT', $arElementIDs); $arElementRules = $this->GetPermissionRules('ELEMENT', $arElementIDs); foreach($arElementResult as $id=>&$arElement) { if (isset($arElementRights[$arElement['ID']])) $arElement['E_RIGHTS'] = $arElementRights[$arElement['ID']]; if (isset($arElementRules[$arElement['ID']]) && $this->IsShared($arElementRules[$arElement['ID']])) $arElement['SHARED'] = true; } unset($arElement); } $arResult = array_merge($arResult, $arElementResult); $db_res = new CDBResult; $db_res->InitFromArray($arResult); } return $db_res; } public function setThroughVersion($version) { if($this->arParams['element_array']['ID']) { CIBlockElement::SetPropertyValuesEx($this->arParams['element_array']['ID'], $this->IBLOCK_ID, (int)$version, static::PROPERTY_VERSION); } } public function GetFileSize($element) { static $PROP_SIZE = "PROPERTY_WEBDAV_SIZE"; $elementID = 0; $arElement = array(); if (is_array($element) && isset($element['ID'])) { $arElement =& $element; $elementID = $arElement['ID']; } elseif( ($elementID = intval($element)) > 0) { } else { return 0; } $result = 0; if ((!is_array($arElement) || empty($arElement)) && $elementID > 0) { $arSelectedFields = array( "ID", "NAME", "PROPERTY_".$this->file_prop, $PROP_SIZE ); $arElementFilter = array( 'ID' => $elementID, 'IBLOCK_ID' => $this->IBLOCK_ID, 'SHOW_HISTORY' => 'Y' ); $rsElement = CIBlockElement::GetList(array(), $arElementFilter, false, false, $arSelectedFields); $arElement = $rsElement->Fetch(); } if (is_array($arElement)) { $result = $arElement[$PROP_SIZE.'_VALUE']; if ( empty($result) && isset($arElement['PROPERTY_'.$this->file_prop.'_VALUE']) && intval($arElement['PROPERTY_'.$this->file_prop.'_VALUE'])>0 ) { $arFile = CFile::GetFileArray(intval($arElement['PROPERTY_'.$this->file_prop.'_VALUE'])); $result = $arFile['FILE_SIZE']; CIBlockElement::SetPropertyValues($elementID, $this->IBLOCK_ID, $result, 'WEBDAV_SIZE'); } } return $result; } function _get_path($section_id, $convert = true) { $res = $this->GetNavChain(array("section_id" => $section_id), $convert); return "/".implode("/", $res); } function _get_section_info_arr(&$arr) { $arr["SHOW"] = array( "EDIT" => ($this->permission > "U" && !$this->check_creator ? "Y" : "N"), "DELETE" => ($this->permission > "U" && !$this->check_creator ? "Y" : "N"), "PERMISSIONS" => ($this->permission > "W"), "UNDELETE" => "N", "RIGHTS" => ($this->e_rights ? "Y" : "N") ); $info = array(); if (!isset($arr["~NAME"])) $arr["~NAME"] = $arr["NAME"]; $arr["PATH"] = str_replace("//", "/", CWebDavIblock::_get_path($arr["IBLOCK_SECTION_ID"], false)."/".$arr["NAME"]); if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { $info["path"] = $arr["PATH"]; if (SITE_CHARSET != "UTF-8") $info["path"] = $GLOBALS["APPLICATION"]->ConvertCharset($info["path"], SITE_CHARSET, "UTF-8"); $info["props"] = array(); $info["props"][] = array('ns'=>'DAV:', 'name'=>"resourcetype", 'val'=>"collection"); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getcontenttype", 'val'=>"httpd/unix-directory"); $info["props"][] = array('ns'=>'DAV:', 'name'=>"creationdate", 'val'=> (isset($arr["DATE_CREATE_UNIX"]) ? $arr["DATE_CREATE_UNIX"] : MakeTimeStamp($arr["DATE_CREATE"]))); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getlastmodified", 'val'=> (isset($arr["TIMESTAMP_X_UNIX"]) ? $arr["TIMESTAMP_X_UNIX"] : MakeTimeStamp($arr["TIMESTAMP_X"]))); $info["props"][] = array('ns'=>'DAV:', 'name'=>"iscollection", 1); $info["props"][] = $this->_get_lock_prop(); } if ($this->_parse_webdav_info($arr) && is_array($arr["PROPS"])) { foreach ($arr["PROPS"] as $ns_name => $ns_props) { foreach ($ns_props as $prop_name => $prop_val) { if(is_scalar($prop_val)) { if ($ns_name == "BX:" && $prop_name == "UNDELETE") { $arr["SHOW"]["EDIT"] = "N"; if ($this->permission > "W") { $arr["SHOW"]["DELETE"] = "Y"; $arr["SHOW"]["UNDELETE"] = "Y"; } else { $arr["SHOW"]["DELETE"] = "N"; } $arr["UNDELETE"] = $prop_val; } $info["props"][] = CWebDavBase::_mkprop($ns_name, $prop_name, $prop_val); } } } } if ($this->e_rights) { $bSuperUser = $GLOBALS['USER']->CanDoOperation('webdav_change_settings'); $arShow = array( 'PERMISSIONS' => 'section_edit', 'EDIT' => 'section_edit', 'DELETE' => 'section_edit', 'UNDELETE' => 'section_delete', "RIGHTS" => "element_rights_edit" ); foreach($arShow as $action => $right) { if (!isset($arr['E_RIGHTS'][$right]) && !$bSuperUser) $arr['SHOW'][$action] = 'N'; } $arr['SHOW']['SHARED'] = $arr['SHARED']; } return $info; } function IsShared($arRights) { //static $arTasks = array(); //static $arPublicGroups = array(); if (!$this->e_rights) return false; //if (empty($arTasks)) //$arTasks = $this->GetTasks(); //if (empty($arPublicGroups)) //{ //$arPublicGroups = array('AU', 'G2'); //if (($dbEmployees = CGroup::GetList($by, $order, array("STRING_ID" => "EMPLOYEES%"))) && ($arEmployees = $dbEmployees->Fetch())) //$arPublicGroups[] = 'G'.$arEmployees['ID']; //} //$arRights = $this->GetERights(($arr['TYPE'] === 'S' ? 'SECTION' : 'ELEMENT'), $arr["ID"]); global $USER; $self = !empty($this->attributes['user_id']) && $this->attributes['user_id'] == $USER->getId(); $selfGroupCode = 'U' . $USER->getId(); foreach ($arRights as $rID => $right) { if ( //in_array($right['GROUP_CODE'], $arPublicGroups) && //(in_array($right['TASK_ID'], array($arTasks['R'], $arTasks['W'], $arTasks['U'], $arTasks['X']))) && $right['IS_INHERITED'] == 'N' && (!$self || $self && $selfGroupCode != $right['GROUP_CODE'])) { return true; } } return false; } function BPParameterRequired() // for doc { if ($this->workflow != 'bizproc') return false; $arDocumentStates = CBPDocument::GetDocumentStates($this->wfParams["DOCUMENT_TYPE"], null); $result = false; foreach ($arDocumentStates as $key => $arDocumentState) { if (is_array($arDocumentState["TEMPLATE_PARAMETERS"])) { foreach ($arDocumentState["TEMPLATE_PARAMETERS"] as $tplID => $tplParam) { if (($tplParam['Required'] == true) && (empty($tplParam['Default']))) { $result = true; break; } } if ($result) break; } } return $result; } function GetMetaID($sMetaName, $createIfNotExist = true) { static $DataType = 'MetaIDS'; $arMetaIDs = $this->_dataCache($DataType); if (!$arMetaIDs || empty($arMetaIDs[$sMetaName])) { if (!isset($this->meta_names[$sMetaName])) { return null; } $rootSectionId = empty($this->arRootSection['ID'])? 0 : $this->arRootSection['ID']; //non create meta folder in depth! hack if($rootSectionId && !empty($this->arRootSection['DEPTH_LEVEL']) && $this->arRootSection['DEPTH_LEVEL'] > 1) { return null; } $rootIblockId = $this->IBLOCK_ID; $sectionId = $this->findMetaSection( $this->meta_names[$sMetaName]['name'], $rootIblockId, $rootSectionId ); if(!$sectionId && $createIfNotExist && !empty($this->meta_names[$sMetaName]['auto_create'])) { $sectionId = $this->createMetaSection( $this->meta_names[$sMetaName]['name'], $rootIblockId, $rootSectionId ); if (intval($sectionId) > 0) { $sectionId = intval($sectionId); } else { return null; } } if (!is_array($arMetaIDs)) { $arMetaIDs = array(); } $arMetaIDs[$sMetaName] = $sectionId; $this->_dataCache($DataType, $arMetaIDs); } return $arMetaIDs[$sMetaName]; } final public static function findMetaSection($metaName, $iblockId, $parentSectionId = 0) { $filter = array( "IBLOCK_ID" => $iblockId, "SECTION_ID" => $parentSectionId, "NAME" => $metaName, "CHECK_PERMISSIONS" => "N" ); $query = CIBlockSection::GetList(array(), $filter, false, array("ID", "LEFT_MARGIN", "RIGHT_MARGIN")); if ($query && $metaSection = $query->GetNext()) { self::$_metaSectionData[$metaSection['ID']] = $metaSection; return $metaSection['ID']; } return false; } final public static function createMetaSection($metaName, $iblockId, $parentSectionId = 0, array $additionalData = array()) { $section = new CIBlockSection(); return $section->Add(array_merge(array( "NAME" => $metaName, "IBLOCK_ID" => $iblockId, "IBLOCK_SECTION_ID" => $parentSectionId, "ACTIVE" => "Y", ), $additionalData)); } function get_file(&$res) { $res["FILE"] = CFile::GetFileArray($res["PROPERTY_" . $this->file_prop . "_VALUE"]); $res["FILE"] = (is_array($res["FILE"]) ? $res["FILE"] : array("FILE_SIZE" => 0, "CONTENT_TYPE" => "text/plain", "MTIME" => 0)); if (isset($res["FILE"]["CONTENT_TYPE"]) && ($res["FILE"]["CONTENT_TYPE"] == "application/zip")) { $ext = GetFileExtension($res["FILE"]["FILE_NAME"]); switch ($ext) // http://en.wikipedia.org/wiki/Microsoft_Office_2007_filename_extensions { case "docx": case "docm": case "dotx": case "dotm": $res["FILE"]["CONTENT_TYPE"] = "application/msword"; break; case "xlsx": case "xlsm": case "xltx": case "xltm": case "xlsb": case "xlam": case "xll": $res["FILE"]["CONTENT_TYPE"] = "application/vnd.ms-excel"; break; case "pptx": case "pptm": case "potx": case "potm": case "ppam": case "ppsx": case "ppsm": $res["FILE"]["CONTENT_TYPE"] = "application/vnd.ms-powerpoint"; break; } } } static function GetTasks() { static $arTasks = null; if ($arTasks == null) { $rs = CTask::GetList( array("LETTER"=>"asc"), array( "MODULE_ID" => "iblock", "BINDING" => "iblock", "SYS" => "Y", ) ); $arTasks = array(); while($ar = $rs->Fetch()) $arTasks[$ar["LETTER"]] = $ar["ID"]; } return $arTasks; } function MetaSectionHide(&$sectionData, $excludeByDiskCondition = false) { static $cacheIdMetaSection = array(); if(empty($this->arRootSection)) { //common lib $userLibNeedCreateDropped = false; } elseif(!empty($this->arRootSection['SOCNET_GROUP_ID'])) { //group lib $userLibNeedCreateDropped = false; } else { //user lib $userLibNeedCreateDropped = true; } $rootId = isset($this->arRootSection['ID'])? $this->arRootSection['ID'] : 0; $key = $this->IBLOCK_ID . '_' . $rootId; if (!isset($cacheIdMetaSection[$key])) { $cacheIdMetaSection[$key] = array(); foreach ($this->meta_names as $metaID => $arMeta) { if ($arMeta['show_in_list'] === false || $excludeByDiskCondition && $arMeta['show_in_list_disk'] === false) { // GetMetaID is already cached //We don't auto create DROPPED folder in common (=shared), group storages. $sectionId = intval($this->GetMetaID($metaID, !($userLibNeedCreateDropped && $metaID == self::DROPPED))); if($sectionId) { $cacheIdMetaSection[$key][$sectionId] = true; } } } } return isset($cacheIdMetaSection[$key][intval($sectionData['ID'])]); } function OnBizprocPublishDocument($ID) { $ID = (int) $ID; if ($ID > 0) { $this->_onEvent('Update', $ID, 'FILE', array('UPDATE_TYPE' => array('PUBLISH'))); } } function _get_file_info_arr(&$res, $arParams = array()) { global $USER; static $arFiles = array(); static $arBPTemplateStates = array(); static $arBPParamRequired = array(); $trashID = $this->GetMetaID('TRASH'); if ($this->workflow == 'bizproc') { if (!isset($arBPParamRequired[$this->IBLOCK_ID])) { $arBPParamRequired[$this->IBLOCK_ID] = $this->IsBpParamRequired(); } } $info = array(); if (!in_array($res["ID"], $arFiles)) { $res["SHOW"] = array(); $res["PERMISSION"] = $this->permission; $res['SHOW']['SHARED'] = $res['SHARED']; $res["~NAME"] = $res["NAME"]; $res['USER_FIELDS'] = $this->GetUfFields($res['ID']); if ($this->permission >= "U") // 'X' if e_rights { $res["SHOW"]["RIGHTS"] = (($this->e_rights && (isset($res['E_RIGHTS']['element_rights_edit']) || $GLOBALS['USER']->CanDoOperation('webdav_change_settings'))) ? "Y" : "N"); if ($this->workflow == 'workflow') { $original = $res; $LAST_ID = CIBlockElement::WF_GetLast($res['ID']); if($LAST_ID != $res['ID']) { $db_res = CIBlockElement::GetList( array(), array("ID" => $LAST_ID, "SHOW_HISTORY" => "Y"), false, array("nTopCount" => 1), $this->wfParams["selected_fields"]); $res = $db_res->GetNext(); $res["FILE"]["FILE_SIZE"] = $this->GetFileSize($res); if ($this->e_rights) { $res['E_RIGHTS'] = $this->GetPermission('ELEMENT', $res['ID']); } } $res["ORIGINAL"] = $original; $res["PERMISSION"] = $original["PERMISSION"]; $res["REAL_ID"] = $res["ID"]; $res["ID"] = $original["ID"]; $res["PROPERTY_WEBDAV_INFO_VALUE"] = $original["PROPERTY_WEBDAV_INFO_VALUE"]; $res["PROPERTY_WEBDAV_INFO_VALUE_ID"] = $original["PROPERTY_WEBDAV_INFO_VALUE_ID"]; $res["TAGS"] = $original["TAGS"]; $res["~TAGS"] = $original["~TAGS"]; $res["PREVIEW_TEXT"] = $original["PREVIEW_TEXT"]; $res["~PREVIEW_TEXT"] = $original["~PREVIEW_TEXT"]; $res["NAME"] = $original["NAME"]; $res["~NAME"] = $original["~NAME"]; $res["LOCK_STATUS"] = $original["LOCK_STATUS"]; $res["LOCKED_USER_NAME"] = $original["LOCKED_USER_NAME"]; $res["WF_LOCKED_BY"] = $original["WF_LOCKED_BY"]; $res["WF_DATE_LOCK"] = $original["WF_DATE_LOCK"]; $res["LAST_ID"] = $LAST_ID; $res["TYPE"] = "E"; $res["SHOW"]["COPY"] = "Y"; $res["STATUS_ID"] = CIBlockElement::WF_GetCurrentStatus($LAST_ID, $res["STATUS_TITLE"]); $res["STATUS_PERMISSION"] = CIBlockElement::WF_GetStatusPermission($res["STATUS_ID"]); if ($res["STATUS_PERMISSION"] >= 2 || ($this->e_rights ? isset($res['E_RIGHTS']['element_edit_any_wf_status']) : ($this->permission >= "W"))) // permissions enouph to edit, draft is shown if any { $res["SHOW"]["UNLOCK"] = ($res['LOCK_STATUS'] == "yellow" || ($res['LOCK_STATUS'] == "red" && CWorkflow::IsAdmin()) ? "Y" : "N"); $res["SHOW"]["LOCK"] = (($res['LOCK_STATUS'] == "green") ? "Y" : "N"); $res["PERMISSION"] = ($res['LOCK_STATUS'] == "red" && !CWorkflow::IsAdmin() ? "R" : $res["PERMISSION"]); // Edit History Delete if ($res['ORIGINAL']['WF_NEW'] == "Y" || $res["WF_STATUS_ID"] <= 1) // Unpublished || Published and has no changes { $res["SHOW"]["HISTORY"] = $res["SHOW"]["DELETE"] = $res["SHOW"]["EDIT"] = ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId() ? "N" : "Y"); } elseif ($res["WF_STATUS_ID"] > 1) // Published element has unpublished changes { $res["SHOW"]["HISTORY"] = $res["SHOW"]["EDIT"] = ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId() ? "N" : "Y"); $res["SHOW"]["DELETE"] = ($res["SHOW"]["EDIT"] == "Y" && $res["PERMISSION"] > "U" ? "Y" : "N"); } if ($res["LOCK_STATUS"] == "red") { $res["SHOW"]["UNLOCK"] = (CWorkflow::IsAdmin() ? "Y" : "N"); $res["SHOW"]["EDIT"] = "N"; $res["SHOW"]["DELETE"] = "N"; } elseif ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId()) { $res["SHOW"]["UNLOCK"] = "N"; $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["DELETE"] = "N"; $res["SHOW"]["EDIT"] = "N"; } } if ($res["STATUS_PERMISSION"] >= 2 || ($this->e_rights ? isset($res['E_RIGHTS']['element_delete']) : ($this->permission >= "W"))) { $res["PERMISSION"] = ($res['LOCK_STATUS'] == "red" && !CWorkflow::IsAdmin() ? "R" : $res["PERMISSION"]); if ($res['ORIGINAL']['WF_NEW'] == "Y" || $res["WF_STATUS_ID"] <= 1) // Unpublished || Published and has no changes { $res["SHOW"]["DELETE"] = ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId() ? "N" : "Y"); } elseif ($res["WF_STATUS_ID"] > 1) // Published element has unpublished changes { $res["SHOW"]["DELETE"] = ($this->check_creator && ($res["CREATED_BY"] != $GLOBALS["USER"]->GetId()) && ($res["PERMISSION"] > "U") ? "N" : "Y"); } } } // $this->workflow == "workflow" elseif($this->workflow == "bizproc") { if ($this->e_rights) $res["PERMISSION"] = $res["E_RIGHTS"]; if($res['LOCK_STATUS'] != "red"): $res['LOCK_STATUS_BP'] = (call_user_func(array( $this->wfParams["DOCUMENT_TYPE"][1], "IsDocumentLocked" ), $res["ID"] | $res["item_id"], "") ? "red" : "green"); $res['LOCK_STATUS'] = ($res['LOCK_STATUS_BP'] == "red" ? "red" : $res['LOCK_STATUS']); endif; $res["PERMISSION"] = ($res['LOCK_STATUS'] == "red" ? "R" : $res["PERMISSION"]); $res["USER_GROUPS"] = $this->USER["GROUPS"]; if ($res["CREATED_BY"] == $GLOBALS["USER"]->GetID()) $res["USER_GROUPS"][] = "Author"; $res["DOCUMENT_ID"] = $this->wfParams["DOCUMENT_TYPE"]; $res["DOCUMENT_ID"][2] = $res["ID"] | $res["item_id"]; $res["~arDocumentStates"] = CBPDocument::GetDocumentStates( $this->wfParams["DOCUMENT_TYPE"], $res["DOCUMENT_ID"]); $res["arDocumentStates"] = array(); foreach ($res["~arDocumentStates"] as $key => $arDocumentState) { $res["~arDocumentStates"][$key]["ViewWorkflow"] = CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::ViewWorkflow, $GLOBALS["USER"]->GetID(), $res["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "AllUserGroups" => $res["USER_GROUPS"], "DocumentStates" => $res["~arDocumentStates"], "WorkflowId" => $key)); if (strlen($arDocumentState["ID"]) > 0 && $res["~arDocumentStates"][$key]["ViewWorkflow"]) { $res["arDocumentStates"][$key] = $arDocumentState; $res["PERMISSION"] = "U"; } } if ($res['LOCK_STATUS'] != "red") { if (CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $res["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $res["USER_GROUPS"], "DocumentStates" => $res["~arDocumentStates"]))) { $res["PERMISSION"] = "W"; } elseif (!CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::ReadDocument, $GLOBALS["USER"]->GetID(), $res["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $res["USER_GROUPS"], "DocumentStates" => $res["~arDocumentStates"]))) { $res["PERMISSION"] = "D"; } } if ($this->CheckRight($res["PERMISSION"], 'element_read') > "D") { if ($arParams["get_clones"] == "Y" && intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0) { $arFilter = array( "WF_PARENT_ELEMENT_ID" => $res["ID"], "SHOW_HISTORY" => "Y", ); $db_rs = CIBlockElement::GetList( array("ID" => "ASC"), $arFilter); if ($db_rs && $rs = $db_rs->Fetch()) { $res["CHILDREN"] = array(); do { if ($rs["IBLOCK_SECTION_ID"] == $trashID) continue; $rs["SHOW"] = array(); $rs["PERMISSION"] = "R"; $rs["DOCUMENT_ID"] = $res["DOCUMENT_ID"]; $rs["DOCUMENT_ID"][2] = $rs["ID"]; $rs["~arDocumentStates"] = CBPDocument::GetDocumentStates( $this->wfParams["DOCUMENT_TYPE"], $rs["DOCUMENT_ID"]); $USER_GROUPS = $this->USER["GROUPS"]; if ($rs["CREATED_BY"] == $GLOBALS["USER"]->GetID()) $USER_GROUPS[] = "Author"; if (!CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::ReadDocument, $GLOBALS["USER"]->GetID(), $rs["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $USER_GROUPS, "DocumentStates" => $rs["~arDocumentStates"] ) ) ) continue; if (CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $rs["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $USER_GROUPS, "DocumentStates" => $rs["~arDocumentStates"]))) { $rs["PERMISSION"] = "W"; } $rs["arDocumentStates"] = array(); foreach ($rs["~arDocumentStates"] as $key => $arDocumentState) { if (CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::ViewWorkflow, $GLOBALS["USER"]->GetID(), $rs["DOCUMENT_ID"], array( "DocumentType" => $this->wfParams["DOCUMENT_TYPE"], "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $USER_GROUPS, "DocumentStates" => $rs["~arDocumentStates"], "WorkflowId" => $key))) { $rs["arDocumentStates"][$key] = $arDocumentState; $rs["PERMISSION"] = (empty($rs["PERMISSION"]) ? "U" : $rs["PERMISSION"]); } } if ($rs["PERMISSION"] >= "U") { if (CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::StartWorkflow, $USER->GetID(), $rs["DOCUMENT_ID"], array( "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $USER_GROUPS, "DocumentStates" => $rs["~arDocumentStates"]))) { $rs["SHOW"]["BP_START"] = "Y"; } $rs["SHOW"]["BP_VIEW"] = (!empty($rs["arDocumentStates"]) ? "Y" : "N"); $rs["SHOW"]["EDIT"] = ($rs["PERMISSION"] >= "W" ? "Y" : "N"); $rs["SHOW"]["BP"] = ($rs["SHOW"]["BP_VIEW"] == "Y" || $rs["SHOW"]["BP_START"] == "Y" ? "Y" : "N"); $rs["SHOW"]["EDIT"] = (($rs["PERMISSION"] >= "W" && intVal($rs["WF_PARENT_ELEMENT_ID"]) > 0) || $this->permission >= "W" ? "Y" : "N"); if ($rs["BP_LOCK_STATUS"] == "red") { $rs["SHOW"]["UNLOCK"] = (CBPDocument::IsAdmin() ? "Y" : "N"); $rs["SHOW"]["EDIT"] = "N"; } elseif ($rs["LOCK_STATUS"] == "red" && $this->permission > "U") // TODO! { $rs["SHOW"]["UNLOCK"] = "Y"; $rs["SHOW"]["EDIT"] = "N"; } elseif ($this->check_creator && $rs["CREATED_BY"] != $GLOBALS["USER"]->GetId()) { $rs["SHOW"]["UNLOCK"] = "N"; $rs["SHOW"]["LOCK"] = "N"; $rs["SHOW"]["DELETE"] = "N"; $rs["SHOW"]["EDIT"] = "N"; } else { $rs["SHOW"]["UNLOCK"] = ($rs['LOCK_STATUS'] == "yellow" ? "Y" : "N"); $rs["SHOW"]["LOCK"] = ($rs['LOCK_STATUS'] == "green" ? "Y" : "N"); $rs["SHOW"]["DELETE"] = $rs["SHOW"]["HISTORY"] = ($rs["PERMISSION"] > "U" ? "Y" : "N"); } } $res["CHILDREN"][$rs["ID"]] = $rs; } while ($rs = $db_rs->Fetch()); } } if (CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::StartWorkflow, $USER->GetID(), $res["DOCUMENT_ID"], array( "IBlockId" => $this->IBLOCK_ID, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $res["USER_GROUPS"], "DocumentStates" => $res["~arDocumentStates"]))) { $res["SHOW"]["BP_START"] = "Y"; } $res["SHOW"]["BP_VIEW"] = (!empty($res["arDocumentStates"]) ? "Y" : "N"); if($this->workflow == 'bizproc') { $res["SHOW"]["BP_VERSIONS"] = (intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0 ? "Y" : "N"); $res["SHOW"]["BP_CLONE"] = (intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0 ? "Y" : "N"); $res["SHOW"]["COPY"] = (intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0 ? "Y" : "N"); } else { $res["SHOW"]["BP_VERSIONS"] = $res["SHOW"]["BP_CLONE"] = $res["SHOW"]["COPY"] = 'N'; } if ($this->CheckRight($res['PERMISSION'], 'element_edit_any_wf_status') < "W" && (intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0) || $res["WF_PARENT_ELEMENT_ID"] == $res["ID"]) { $arDocumentStates = CBPDocument::GetDocumentStates( $this->wfParams["DOCUMENT_TYPE"], null); if (!empty($arDocumentStates)) { CBPDocument::CanUserOperateDocumentType( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $this->wfParams["DOCUMENT_TYPE"], array( "IBlockId" => $this->IBLOCK_ID, "IBlockPermission" => $this->permission, "UserGroups" => $this->USER["GROUPS"], "AllUserGroups" => $res["USER_GROUPS"], "DocumentStates" => $arDocumentStates)); } else { $res["SHOW"]["BP_CLONE"] = "N"; } } $res["SHOW"]["BP"] = ($res["SHOW"]["BP_VIEW"] == "Y" || $res["SHOW"]["BP_START"] == "Y" ? "Y" : "N"); $res["SHOW"]["EDIT"] = ($this->CheckRight($res["PERMISSION"], "element_edit_any_wf_status") >= "W" ? "Y" : "N"); if ($res["LOCK_STATUS"] == "red") { $res["SHOW"]["UNLOCK"] = ((CBPDocument::IsAdmin() || $this->CheckRight($res['PERMISSION'], "element_edit") > "W") ? "Y" : "N"); $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["HISTORY"] = ($this->CheckRight($res['PERMISSION'], 'element_edit') > "U" ? "Y" : "N"); $res["SHOW"]["DELETE"] = "N"; $res["SHOW"]["EDIT"] = "N"; } elseif ($this->InTrash($res)) { $bRightsEdit_gt_W = ($this->CheckRight($res['PERMISSION'], 'element_rights_edit') > "W"); $res["SHOW"]["EDIT"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["HISTORY"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["DELETE"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["UNLOCK"] = "N"; $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["BP_START"] = "N"; $res["SHOW"]["BP_VIEW"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["BP_VERSIONS"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["BP_CLONE"] = ($bRightsEdit_gt_W ? "Y" : "N"); $res["SHOW"]["COPY"] = (intVal($res["WF_PARENT_ELEMENT_ID"]) <= 0 ? "Y" : "N"); } elseif ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId()) { $res["SHOW"]["UNLOCK"] = "N"; $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["DELETE"] = "N"; $res["SHOW"]["EDIT"] = "N"; } else { $bElementEdit_gt_U = ($this->CheckRight($res['PERMISSION'], 'element_rights_edit') > 'U'); $res["SHOW"]["HISTORY"] = ($bElementEdit_gt_U ? "Y" : "N"); $res["SHOW"]["DELETE"] = ($bElementEdit_gt_U ? "Y" : "N"); $res["SHOW"]["UNLOCK"] = (($bElementEdit_gt_U && ($res["LOCK_STATUS"] == "yellow")) ? "Y" : "N"); $res["SHOW"]["LOCK"] = (($bElementEdit_gt_U && ($res["LOCK_STATUS"] == "green")) ? "Y" : "N"); } if ($arBPParamRequired[$this->IBLOCK_ID]) $res["SHOW"]["COPY"] = "N"; } } // $this->workflow == "bizproc" else { $res["SHOW"]["UNLOCK"] = (($res['LOCK_STATUS'] == "yellow" || (($res['LOCK_STATUS'] == "red" ) && ($res["PERMISSION"] > 'W'))) ? "Y" : "N"); $res["SHOW"]["LOCK"] = ($res['LOCK_STATUS'] == "green" ? "Y" : "N"); $res["SHOW"]["COPY"] = "Y"; $res["SHOW"]["HISTORY"] = $res["SHOW"]["DELETE"] = $res["SHOW"]["EDIT"] = ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId() ? "N" : "Y"); $res["SHOW"]["HISTORY"] = (($res["SHOW"]["HISTORY"] == "Y" && $this->workflow == "bizproc_limited") ? "Y" : "N"); if ($this->check_creator && $res["CREATED_BY"] != $GLOBALS["USER"]->GetId()) { $res["SHOW"]["UNLOCK"] = "N"; $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["DELETE"] = "N"; $res["SHOW"]["EDIT"] = "N"; } elseif ($res["LOCK_STATUS"] == "red" && $res["PERMISSION"] < 'X') { $res["SHOW"]["DELETE"] = "N"; $res["SHOW"]["EDIT"] = "N"; } if ($this->e_rights) { $arShow = array( "COPY" => "element_edit", "DELETE" => "element_delete", "UNDELETE" => "element_no_prems", "EDIT" => "element_edit", "HISTORY" => "element_edit", "LOCK" => "element_edit", "UNLOCK" => "element_edit", "RIGHTS" => "element_rights_edit" ); $bInTrash = ($this->InTrash($res)); foreach($arShow as $action => $right) { if ( ($res['LOCK_STATUS'] == 'red') || $bInTrash ) $right = "element_rights_edit"; if (!isset($res['E_RIGHTS'][$right])) $res['SHOW'][$action] = 'N'; } } } } else { $res["PERMISSION"] = ($res["WF_NEW"] == "Y" || (intVal($res["WF_PARENT_ELEMENT_ID"]) > 0 && ($res["WF_PARENT_ELEMENT_ID"] != $res['ID'])) ? "D" : $this->permission); if ($res["PERMISSION"] > "D" && $this->workflow == "bizproc") { $res["PERMISSION"] = ($res["BP_PUBLISHED"] == "Y" ? $this->permission : "D"); } } $res["SHOW"]["UNDELETE"] = "N"; $secPath = "/".implode("/", $this->GetNavChain(array("section_id" => $res["IBLOCK_SECTION_ID"]), false)); $res["SECTION_PATH"] = str_replace("//", "/", $secPath); $res["PATH"] = str_replace("//", "/", $secPath . "/" . $res["~NAME"]); $arFiles[$res["ID"]] = $res; } else { $res = array_merge($res, $arFiles[$res["ID"]]); } if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { $info["path"] = $res['PATH']; $info["path"] = (SITE_CHARSET != "UTF-8" ? $GLOBALS["APPLICATION"]->ConvertCharset($info["path"], SITE_CHARSET, "UTF-8") : $info["path"]); $info["props"] = array(); $info["props"][] = array('ns'=>'DAV:', 'name'=>"creationdate", 'val'=> (isset($res["DATE_CREATE_UNIX"]) ? $res["DATE_CREATE_UNIX"] : MakeTimeStamp($res["DATE_CREATE"]))); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getlastmodified", 'val'=> (isset($res["TIMESTAMP_X_UNIX"]) ? $res["TIMESTAMP_X_UNIX"] : MakeTimeStamp($res["TIMESTAMP_X"]))); $info["props"][] = array('ns'=>'DAV:', 'name'=>"creationdate", 'val'=>MakeTimeStamp($res["DATE_CREATE"])); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getlastmodified", 'val'=>MakeTimeStamp($res["TIMESTAMP_X"])); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getcontenttype", 'val'=>$res["FILE"]["CONTENT_TYPE"]); $info["props"][] = array('ns'=>'DAV:', 'name'=>"getcontentlength", 'val'=>$res["FILE"]["FILE_SIZE"]); $info["props"][] = array('ns'=>'DAV:', 'name'=>"isreadonly", 'val'=>($res["PERMISSION"] >= "W" ? "false" : "true")); $info["props"][] = array('ns'=>'DAV:', 'name'=>"ishidden", 'val'=>($res["ACTIVE"] == "Y" ? "false" : "true")); $info["props"][] = array('ns'=>'DAV:', 'name'=>"iscollection", 'val'=>0); $info["props"][] = array('ns'=>'DAV:', 'name'=>"resourcetype", 'val'=>''); // required by RFC && LibreOffice $info["props"][] = $this->_get_lock_prop(); } if ($this->InTrash($res)) { if ($this->workflow != "bizproc") { $res["SHOW"]["EDIT"] = "N"; $res["SHOW"]["LOCK"] = "N"; $res["SHOW"]["UNLOCK"] = "N"; $bAdmin = false; if ($GLOBALS['USER']->CanDoOperation('webdav_change_settings')) $bAdmin = true; elseif ($this->e_rights && isset($res['E_RIGHTS']['element_rights_edit'])) $bAdmin = true; elseif (!$this->e_rights && $this->permission > "W") $bAdmin = true; $res["SHOW"]["DELETE"] = $bAdmin ? "Y" : "N"; $res["SHOW"]["UNDELETE"] = $bAdmin ? "Y" : "N"; } } if ($this->_parse_webdav_info($res)) { if (is_array($res["PROPS"])) { foreach ($res["PROPS"] as $ns_name => $ns_props) { foreach ($ns_props as $prop_name => $prop_val) { if(is_scalar($prop_val)) { if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') $info["props"][] = CWebDavBase::_mkprop($ns_name, $prop_name, $prop_val); } } } } } return $info; } function _parse_webdav_info(&$res) { if (isset($res["PROPERTY_WEBDAV_INFO_VALUE"]) && strlen($res["PROPERTY_WEBDAV_INFO_VALUE"]) > 0) { $arProps = @unserialize((strlen($res["~PROPERTY_WEBDAV_INFO_VALUE"]) > 0 ? $res["~PROPERTY_WEBDAV_INFO_VALUE"] : $res["PROPERTY_WEBDAV_INFO_VALUE"])); if (is_array($arProps["PROPS"])) $res["PROPS"] = $arProps["PROPS"]; return true; } elseif (isset($res["DESCRIPTION"]) && strlen($res["DESCRIPTION"]) > 0) { $arProps = @unserialize((strlen($res["~DESCRIPTION"]) > 0 ? $res["~DESCRIPTION"] : $res["DESCRIPTION"])); if (is_array($arProps["PROPS"])) $res["PROPS"] = $arProps["PROPS"]; return true; } return false; } function GetNavChain($options = array(), $for_url = false) { static $nav_chain = array(); $bReturn = (strtoupper($for_url) === "ARRAY" ? "ARRAY" : ($for_url === true ? "URL" : "SITE")); if (empty($options) && isset($this->arParams["dir_array"])) // === to deal with 0 at the root of IB $options["section_id"] = intval($this->arParams["dir_array"]["ID"]); elseif (isset($options['section_id'])) $options['section_id'] = intval($options['section_id']); //mixin iblock id for symlinksection $dataCache = $options; $dataCache['IBLOCK_ID'] = $this->IBLOCK_ID; $dataCache['ROOT_SECTION_ID'] = empty($this->arRootSection['ID'])? 0 : $this->arRootSection['ID']; $id = md5(serialize($dataCache)); if (!array_key_exists($id, $nav_chain)) { if ($this->CACHE_OBJ && $this->CACHE_OBJ->InitCache($this->CACHE_TIME, $id, $this->CACHE_PATH."nav_chain")) { $nav_chain[$id] = $this->CACHE_OBJ->GetVars(); } else { $options['check_permissions'] = false; $arObject = $this->GetObject($options); $nav_chain[$id] = array("URL" => array(), "SITE" => array(), "ARRAY" => array()); if ($arObject["not_found"] == false && intVal($arObject["item_id"]) > 0) { $arFile = array(); $section_id = $arObject["item_id"]; if ($arObject["is_file"]) { $arFile = $arObject["element_array"]; $section_id = $arFile["IBLOCK_SECTION_ID"]; $sectionData = $this->getSectionDataForLinkAnalyze($arFile['IBLOCK_SECTION_ID'], array( 'ID' => $arFile['IBLOCK_SECTION_ID'], 'IBLOCK_ID' => $arObject['element_array']['IBLOCK_ID'], )); } else { $sectionData = $this->getSectionDataForLinkAnalyze($arObject["item_id"], array( 'ID' => $arObject["item_id"], 'IBLOCK_ID' => empty($arObject['dir_array']['IBLOCK_ID'])? $this->IBLOCK_ID : $arObject['dir_array']['IBLOCK_ID'], )); } //simple detect link list($contextType, $contextEntityId) = $this->getContextData(); $isSymlink = !$this->_symlinkMode && CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData); if($isSymlink) { $symlinkSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); } if($this->_symlinkMode) { $bRootFounded = (empty($this->_symlinkRealRootSectionData) ? true : false); foreach (CWebDavSymlinkHelper::getNavChain($this->_symlinkSectionData['IBLOCK_ID'], $this->_symlinkSectionData['ID']) as $res) { $this->MetaNames($res); if (!$bRootFounded && $res["ID"] == $this->_symlinkRealRootSectionData["ID"]) { $bRootFounded = true; continue; } if (!$bRootFounded) continue; $url = $this->_uencode($res["NAME"], array("utf8" => "Y", "convert" => "full")); $nav_chain[$id]["URL"][] = $url; $nav_chain[$id]["SITE"][] = $res["NAME"]; $nav_chain[$id]["ARRAY"][] = ($res + array("URL" => $url)); } } $iblockId = $this->IBLOCK_ID; $sectionId = $section_id; if($isSymlink) { $iblockId = $symlinkSectionData['IBLOCK_ID']; $sectionId = $symlinkSectionData['ID']; } $bRootFounded = (empty($this->arRootSection) ? true : false); foreach (CWebDavSymlinkHelper::getNavChain($iblockId, $sectionId) as $res) { $this->MetaNames($res); if (!$bRootFounded && $res["ID"] == $this->arRootSection["ID"]) { $bRootFounded = true; continue; } if (!$bRootFounded) continue; $url = $this->_uencode($res["NAME"], array("utf8" => "Y", "convert" => "full")); $nav_chain[$id]["URL"][] = $url; $nav_chain[$id]["SITE"][] = $res["NAME"]; $nav_chain[$id]["ARRAY"][] = ($res + array("URL" => $url)); } if($isSymlink) { $bRootFounded = (empty($symlinkSectionData[self::UF_LINK_SECTION_ID]) ? true : false); foreach (CWebDavSymlinkHelper::getNavChain($symlinkSectionData[self::UF_LINK_IBLOCK_ID], $section_id) as $res) { $this->MetaNames($res); if (!$bRootFounded && $res["ID"] == $symlinkSectionData[self::UF_LINK_SECTION_ID]) { $bRootFounded = true; continue; } if (!$bRootFounded) continue; $url = $this->_uencode($res["NAME"], array("utf8" => "Y", "convert" => "full")); $nav_chain[$id]["URL"][] = $url; $nav_chain[$id]["SITE"][] = $res["NAME"]; $nav_chain[$id]["ARRAY"][] = ($res + array("URL" => $url)); } } if (!empty($arFile)) { $url = $this->_uencode($res["NAME"], array("utf8" => "Y", "convert" => "full")); $nav_chain[$id]["URL"][] = $url; $nav_chain[$id]["SITE"][] = $arFile["NAME"]; $nav_chain[$id]["ARRAY"][] = ($arFile + array("URL" => $url)); } } if ($this->CACHE_OBJ) { $this->CACHE_OBJ->StartDataCache($this->CACHE_TIME, $id, $this->CACHE_PATH."_nav_chain"); $this->CACHE_OBJ->EndDataCache($nav_chain[$id]); } } } $res = $nav_chain[$id][$bReturn]; return (is_array($res) ? $res : array()); } function GetPath($options = array()) { $result = ''; $elm = $this->GetObject($options); if (!$elm['not_found']) { $result = $this->base_url_full; $result .= "/".implode("/", $this->GetNavChain($options, true)); } if ($elm['is_file']) { $result .= $elm['element_name']; } return $result; } function GetSectionsTree($options = array()) { static $dataType = 'SectionsTree'; if(empty($options['prependPath'])) { $options['prependPath'] = ''; } $dataCache = $options; $dataCache['IBLOCK_ID'] = $this->IBLOCK_ID; $dataCache['ROOT_SECTION_ID'] = empty($this->arRootSection['ID'])? 0 : $this->arRootSection['ID']; $id = md5(serialize($dataCache)); $sections = $this->_dataCache($dataType . $id); if ($sections === false) { $arElement = $this->GetObject($options, false, true); if ($arElement["not_found"]) { $sections = array(); } else { $arFilter = array("IBLOCK_ID" => $this->IBLOCK_ID); if (isset($options['not_check_permissions'])) $arFilter['CHECK_PERMISSIONS'] = 'N'; $bRootFounded = (empty($this->arRootSection) ? true : false); if ($arElement["item_id"] > 0 && !empty($arElement["dir_array"])) { $arFilter["LEFT_MARGIN"] = intVal($arElement["dir_array"]["LEFT_MARGIN"]) + 1; $arFilter["RIGHT_MARGIN"] = intVal($arElement["dir_array"]["RIGHT_MARGIN"]) - 1; } elseif (!empty($this->arRootSection)) { $arFilter["LEFT_MARGIN"] = intVal($this->arRootSection["LEFT_MARGIN"]) + 1; $arFilter["RIGHT_MARGIN"] = intVal($this->arRootSection["RIGHT_MARGIN"]) - 1; } if(!empty($arElement["is_dir"]) && $arElement["item_id"]) { list($contextType, $contextEntityId) = $this->getContextData(); $sectionData = $this->getSectionDataForLinkAnalyze($arElement["item_id"], $arElement); $iblockId = $sectionData['IBLOCK_ID']; if(CWebDavSymlinkHelper::isLink($contextType, $contextEntityId, $sectionData)) { $arFilter['IBLOCK_ID'] = $iblockId; $symlinkSectionData = CWebDavSymlinkHelper::getLinkData($contextType, $contextEntityId, $sectionData); if(!empty($symlinkSectionData[self::UF_LINK_SECTION_ID]) && $symlinkSectionData['ID'] == $arElement["item_id"]) { $margins = CIBlockSection::GetList(array(), array( 'ID' => $symlinkSectionData[self::UF_LINK_SECTION_ID], 'IBLOCK_ID' => $symlinkSectionData[self::UF_LINK_IBLOCK_ID], 'CHECK_PERMISSIONS' => 'N', ), false, array('LEFT_MARGIN', 'RIGHT_MARGIN', 'IBLOCK_ID'))->fetch(); if($margins) { $arFilter["LEFT_MARGIN"] = intVal($margins["LEFT_MARGIN"]) + 1; $arFilter["RIGHT_MARGIN"] = intVal($margins["RIGHT_MARGIN"]) - 1; } } } } $arResult = array(); $db_res = CIBlockSection::GetTreeList($arFilter, array( 'ID', 'CREATED_BY', 'MODIFIED_BY', 'IBLOCK_ID', 'IBLOCK_SECTION_ID', 'NAME', 'LEFT_MARGIN', 'RIGHT_MARGIN', 'DEPTH_LEVEL', 'SOCNET_GROUP_ID', 'IBLOCK_CODE', 'TIMESTAMP_X', )); // TODO: add e_rights check $trashID = $this->GetMetaID('TRASH'); if ($db_res && $res = $db_res->Fetch()) { $deep = -1; $arPath = array(); $arExclude = array(); do { if ($this->MetaNames($res)) { $res["DEPTH_LEVEL"] = intVal($res["DEPTH_LEVEL"]); if(isset($arExclude[(int) $res["IBLOCK_SECTION_ID"]]) || $this->MetaSectionHide($res, !empty($options['NON_DROPPED_SECTION']))) { $arExclude[(int)$res["ID"]] = true; } else { if ($res["DEPTH_LEVEL"] > $deep) { $deep = $res["DEPTH_LEVEL"]; array_push($arPath, strtolower(htmlspecialcharsbx($res["NAME"]))); } elseif ($res["DEPTH_LEVEL"] == $deep) { array_pop($arPath); array_push($arPath, strtolower(htmlspecialcharsbx($res["NAME"]))); } else { while ($res["DEPTH_LEVEL"] < $deep) { array_pop($arPath); $deep--; } array_pop($arPath); array_push($arPath, strtolower(htmlspecialcharsbx($res["NAME"]))); } $res["PATH"] = $options['prependPath'] . implode("/", $arPath); $arResult[$res["ID"]] = $res; } } else { $arExclude[(int)$res["ID"]] = true; } } while ($res = $db_res->Fetch()); } $sections = $arResult; } $this->_dataCache($dataType . $id, $sections); } if(!empty($options['setERights'])) { $sectionIds = array(); foreach ($sections as $section) { $sectionIds[] = $section['ID']; } unset($section); $sectionRights = $this->GetPermissions('SECTION', $sectionIds); foreach ($sections as &$section) { if (isset($sectionRights[$section['ID']])) { $section['E_RIGHTS'] = $sectionRights[$section['ID']]; } } unset($section); } global $USER; if(!empty($options['SET_IS_SHARED']) && $USER->getId()) { $querySelfSharedSections = \Bitrix\Webdav\FolderInviteTable::getList(array( 'filter' => array( 'USER_ID' => $USER->getId(), '!=INVITE_USER_ID' => $USER->getId(), ), 'select' => array('SECTION_ID', 'IBLOCK_ID'), )); while($folderInvite = $querySelfSharedSections->fetch()) { $selfSharedSections[$folderInvite['SECTION_ID']] = $folderInvite; } unset($folderInvite); foreach ($sections as &$section) { if(isset($selfSharedSections[$section['ID']])) { $section['IS_SHARED'] = true; } } unset($section); } return $sections; } function ClearCache($path, $mode=false) { if ($mode == false) { if ($path == "section") { BXClearCache(true, $this->CACHE_PATH."root_section"); BXClearCache(true, $this->CACHE_PATH."section"); BXClearCache(true, $this->CACHE_PATH."sections_tree"); BXClearCache(true, $this->CACHE_PATH."nav_chain"); } } elseif ($mode == 'local') { foreach ($this->CACHE as $method=>$arCache) { if (!is_array($path)) $path = array($path); foreach ($path as $v) { $cache_id = $this->_get_element_cacheID($v, true); if (isset($this->CACHE[$method][$cache_id])) unset($this->CACHE[$method][$cache_id]); $cache_id = $this->_get_element_cacheID($v, false); if (isset($this->CACHE[$method][$cache_id])) unset($this->CACHE[$method][$cache_id]); } } } } function _clear_cache_for_object(&$options) { $options = (is_array($options) ? $options : array()); $arClear = array(); if (array_key_exists("path", $options)) $arClear[] = $options['path']; if (array_key_exists('section_id', $options)) $arClear[] = 'section'.$options['section_id']; if (array_key_exists('element_id', $options)) $arClear[] = 'element'.$options['element_id']; $this->ClearCache($arClear, 'local'); } function CheckRights($method = "", $strong = false, $path = "") { $result = true; if (!parent::CheckRights($method, $strong)) { $result = false; $errorCode = (parent::CheckRights($method, $strong, true)); $GLOBALS["APPLICATION"]->ThrowException(GetMessage('WD_ACCESS_DENIED'), (!!$errorCode ? $errorCode : 'ACCESS_DENIED'), __LINE__); } elseif (!empty($path)) { $path = $this->_udecode($path); $strFileName = basename($path); $extention = strtolower(strrchr($strFileName, '.')); if (in_array($method, array("COPY", "MOVE", "PUT"))) { if (IsFileUnsafe($strFileName) || $strFileName == "index.php") { $result = false; $GLOBALS['APPLICATION']->ThrowException(GetMessage("WD_FILE_ERROR14"), "FORBIDDEN_NAME", __LINE__); } } } return $result; } function CheckWebRights($method = "", $arParams = array(), $simple = true) { if($this->withoutAuthorization) { return true; } $strong = ($method !== ""); $path = ''; if (is_array($arParams['arElement'])) $path = (isset($arParams['arElement']['item_id']) ? $arParams['arElement']['item_id'] : ''); elseif (is_string($arParams['arElement'])) $path = $arParams['arElement']; $result = $this->CheckRights($method, $strong, $path); if ((! $result) || $simple) return $result; $arError = array(); $action = strtolower(is_set($arParams, "action") ? $arParams["action"] : $arParams["ACTION"]); $arElement = (is_set($arParams, "arElement") ? $arParams["arElement"] : array()); static $arErrors = array(); $static_id = md5(serialize(array($action, $arElement["ID"], $GLOBALS["USER"]->GetID()))); if (array_key_exists($static_id, $arErrors)) { $arError = $arErrors[$static_id]; } else { if ( $this->e_rights ) { foreach(array('arElement', 'from', 'to') as $elm) { if (is_set($arParams, $elm)) { if ((!isset($arParams[$elm]['not_found']) || ($arParams[$elm]['not_found']===true)) && !in_array($action, array('create', 'copy', 'move', 'mkcol'))) $arError[] = array("id" => "bad_element", "text" => GetMessage("WD_FILE_ERROR105")); } } if (empty($arError)) { if ($action == 'copy') { //from[] //to[] $arTo = (isset($arParams['to']) ? $arParams['to'] : array()); $arFrom = (isset($arParams['from']) ? $arParams['from'] : array()); $nCount = min(sizeof($arTo), sizeof($arFrom)); for ($i=0;$i<$nCount;$i++) { $To = $arTo[$i]; $From = $arFrom[$i]; $type = (($To['is_file']) ? 'ELEMENT' : 'SECTION'); $id = ($To['not_found'] ? $To['parent_id'] : $To['item_id']); $op = ($From['is_file'] ? 'section_element_bind' : 'section_section_bind'); if (!$this->GetPermission($type, $id, $op)) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } } elseif (($action == 'create') || ($action == 'mkcol')) { //arElement //null if (empty($arElement)) { $arParent = $this->GetObject(); $bAllowEdit = false; if ($arParent['not_found'] === false) { $bAllowEdit = $this->GetPermission(($arParent['is_file'] ? 'ELEMENT' : 'SECTION'), $arParent['item_id'], 'element_edit'); } return $bAllowEdit; } else { $type = 'SECTION'; if (isset($arElement['parent_id']) && $arElement['parent_id']>0) { $id = $arElement['parent_id']; } else { $id = $this->IBLOCK_ID; $type = 'IBLOCK'; } if ($action == 'mkcol') return $this->GetPermission($type, $id, 'section_section_bind'); if ($arElement['is_dir']) { if(!$this->GetPermission($type, $id, 'section_section_bind')) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } else { if (!empty($arParams['create_element_in_section']) || ($this->workflow != "workflow" && $this->workflow != "bizproc")) { if (! ( $this->GetPermission($type, $id, 'section_element_bind') )) $arError[] = array("id" => "cannot_create", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($this->workflow == "workflow") { $db_res = CWorkflowStatus::GetDropDownList("N", "desc"); if (!($db_res && $res = $db_res->Fetch())) $arError[] = array("id" => "bad_wf_statuses", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($this->workflow == 'bizproc') { $arDocumentStates = CBPDocument::GetDocumentStates($this->wfParams['DOCUMENT_TYPE'], null); $arUserGroups = $this->USER["GROUPS"]; $arUserGroups[] = "Author"; $canWrite = false; if (!CBPDocument::CanUserOperateDocumentType( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $this->wfParams['DOCUMENT_TYPE'], array( "IBlockPermission" => $this->permission, "AllUserGroups" => $arUserGroups, "DocumentStates" => $arDocumentStates) )) $arError[] = array("id" => "bad_bizproc_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } } } elseif ($action == 'delete' || $action == 'undelete') // aka move to trash, move op will be checked later { //arElement $type = (($arElement['is_dir']) ? 'SECTION' : 'ELEMENT'); if ($type == 'ELEMENT') { $res = $this->GetPermission($type, $arElement['item_id'], 'element_delete'); if (!$res) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } else { $res = $this->GetPermission($type, $arElement['item_id'], 'section_delete', false); if (!$res) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } } elseif ($action == 'destroy') { //arElement $id = $arElement['item_id']; $type = (($arElement['is_dir']) ? 'SECTION' : 'ELEMENT'); $op = (($arElement['is_dir']) ? 'section_delete' : 'element_delete'); if (!$this->GetPermission($type, $id, $op, false)) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($action == 'edit' || $action == 'lock' || $action == 'proppatch' || $action == 'delete_dropped') { //arElement $id = $arElement['item_id']; $type = $arElement['is_dir'] ? 'SECTION' : 'ELEMENT'; if ($arElement['is_dir']) { if (!$this->GetPermission($type, $id, 'section_edit')) $arError[] = array("id" => "", "text" => GetMessage("WD_ACCESS_DENIED")); } else { if ($arElement["LOCK_STATUS_BP"] == "red") $arError[] = array("id" => "locked", "text" => GetMessage("WD_FILE_ERROR107")); elseif ($this->check_creator && $arElement["CREATED_BY"] != $GLOBALS["USER"]->GetID()) { $arError[] = array("id" => "bad_author", "text" => GetMessage("WD_FILE_ERROR108")); } elseif ($this->GetPermission($type, $id, 'element_edit_any_wf_status')) { true; } elseif ($this->workflow == "workflow" && $this->GetPermission($type, $id, 'element_edit')) { $arWorkFlow = array("LAST_ID" => CIBlockElement::WF_GetLast($arElement["item_id"])); $arWorkFlow["STATUS_ID"] = CIBlockElement::WF_GetCurrentStatus($arWorkFlow["LAST_ID"], $arWorkFlow["STATUS_TITLE"]); $arWorkFlow["STATUS_PERMISSION"] = CIBlockElement::WF_GetStatusPermission($arWorkFlow["STATUS_ID"]); if ($arWorkFlow["STATUS_ID"] > 1 && $arWorkFlow["STATUS_PERMISSION"] < 2) { $arError[] = array("id" => "bad_wf_status_permission", "text" => GetMessage("WD_FILE_ERROR109")); } } elseif ($this->workflow == 'bizproc' && $this->GetPermission($type, $id, 'element_edit')) { $documentId = $this->wfParams['DOCUMENT_TYPE']; $documentId[2] = $arElement["item_id"]; $arDocumentStates = CBPDocument::GetDocumentStates( $this->wfParams['DOCUMENT_TYPE'], $documentId ); $arUserGroups = $this->USER["GROUPS"]; if ($arElement["CREATED_BY"] == $GLOBALS["USER"]->GetID()) $arUserGroups[] = "Author"; if (!CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $documentId, array( "IBlockPermission" => $this->permission, "AllUserGroups" => $arUserGroups, "DocumentStates" => $arDocumentStates) )) { $arError[] = array("id" => "bad_bizproc_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } else { $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } } elseif ($action == 'read' || $action == 'propfind') { //arElement, null if ($arElement) { $id = $arElement['item_id']; $type = (($arElement['is_dir']) ? 'SECTION' : 'ELEMENT'); $op = (($arElement['is_dir']) ? 'section_read' : 'element_read'); if (!$this->GetPermission($type, $id, $op)) $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); if ($type == 'SECTION' && $id == $this->GetMetaID('TRASH')) { if (!$this->GetPermission($type, $id, 'section_delete')) { $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } } else { if (!$this->GetPermission('IBLOCK', $this->IBLOCK_ID, 'section_read')) $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } elseif ($action == 'move') { //from // auto recusive //to // auto recusive $arTo = (isset($arParams['to']) ? $arParams['to'] : array()); $arFrom = (isset($arParams['from']) ? $arParams['from'] : array()); $nCount = min(sizeof($arTo), sizeof($arFrom)); for ($i=0;$i<$nCount;$i++) { $To = $arTo[$i]; $From = $arFrom[$i]; $type = (($From['is_dir']) ? 'SECTION' : 'ELEMENT'); $id = $From['item_id']; $op = ($From['is_dir'] ? 'section_edit' : 'element_edit'); if (!$this->GetPermission($type, $id, $op)) $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); if ($To['not_found']) { $type = 'SECTION'; $id = $To['parent_id']; $op = ($arFrom['is_dir'] ? 'section_section_bind' : 'section_element_bind'); // TODO: bizproc ? if (!$this->GetPermission($type, $id, $op)) { $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } else { $type = (($To['is_dir']) ? 'SECTION' : 'ELEMENT'); $id = $To['item_id']; $op = ($To['is_dir'] ? ($arFrom['is_dir'] ? 'section_section_bind' : 'section_element_bind') : 'element_edit'); // TODO: bizproc ? if (!$this->GetPermission($type, $id, $op)) { $arError[] = array("id" => "bad_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } } } } } else // not e_rights { // check iblock rights if ($this->permission < "R") { $arError[] = array("id" => "cannot_read", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($this->permission > "U") { true; } elseif ($action == "read" || $action == "propfind") { true; } elseif ($this->permission < "U") { $arError[] = array("id" => "cannot_workflow", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($action == "create") { if ($this->workflow != "workflow" && $this->workflow != "bizproc") { $arError[] = array("id" => "cannot_write", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($this->workflow == "workflow") { $db_res = CWorkflowStatus::GetDropDownList("N", "desc"); if (!($db_res && $res = $db_res->Fetch())) $arError[] = array("id" => "bad_wf_statuses", "text" => GetMessage("WD_ACCESS_DENIED")); } elseif ($this->workflow == 'bizproc') { $arDocumentStates = CBPDocument::GetDocumentStates($this->wfParams['DOCUMENT_TYPE'], null); $arUserGroups = $this->USER["GROUPS"]; $arUserGroups[] = "Author"; $canWrite = false; if (!CBPDocument::CanUserOperateDocumentType( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $this->wfParams['DOCUMENT_TYPE'], array( "IBlockPermission" => $this->permission, "AllUserGroups" => $arUserGroups, "DocumentStates" => $arDocumentStates) )) $arError[] = array("id" => "bad_bizproc_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } elseif (!is_array($arElement) || empty($arElement)) { $arError[] = array("id" => "bad_element", "text" => GetMessage("WD_FILE_ERROR105")); } elseif ($action == "clone") { if ($this->workflow != "bizproc") { $arError[] = array("id" => "bad_workflow", "text" => GetMessage("WD_FILE_ERROR106")); } else { // User has to have permissions to read parent document && to create new document $arDocumentStates = CBPDocument::GetDocumentStates($this->wfParams['DOCUMENT_TYPE'], null); if (!($arElement["PERMISSION"] >= "R" && CBPDocument::CanUserOperateDocumentType( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $this->wfParams['DOCUMENT_TYPE'], array( "IBlockPermission" => $this->permission, "AllUserGroups" => array_merge($this->USER["GROUPS"], array("author")), "DocumentStates" => $arDocumentStates)))): $arError[] = array("id" => "bad_permission", "text" => GetMessage("WD_ACCESS_DENIED")); endif; } } elseif (!in_array($action, array("delete", "move", "edit", "unlock", "lock"))) { $arError[] = array("id" => "bad_action", "text" => GetMessage("WD_ERROR_BAD_ACTION")); } else { if ($arElement["LOCK_STATUS_BP"] == "red") $arError[] = array("id" => "locked", "text" => GetMessage("WD_FILE_ERROR107")); elseif ($arElement["LOCK_STATUS"] == "red" && ($action != "unlock" || $arElement["SHOW"]["UNLOCK"] != "Y")) { $arError[] = array("id" => "locked", "text" => str_replace( array("#ID#", "#DATE#"), array($arElement["locked_by"], $arElement["date_lock"]), GetMessage("WD_ERROR_ELEMENT_LOCKED"))); } elseif ($this->check_creator && $arElement["CREATED_BY"] != $GLOBALS["USER"]->GetID()) { $arError[] = array("id" => "bad_author", "text" => GetMessage("WD_FILE_ERROR108")); } elseif ($this->workflow == "workflow") { $arWorkFlow = array("LAST_ID" => CIBlockElement::WF_GetLast($arElement["item_id"])); $arWorkFlow["STATUS_ID"] = CIBlockElement::WF_GetCurrentStatus($arWorkFlow["LAST_ID"], $arWorkFlow["STATUS_TITLE"]); $arWorkFlow["STATUS_PERMISSION"] = CIBlockElement::WF_GetStatusPermission($arWorkFlow["STATUS_ID"]); if ($arWorkFlow["STATUS_ID"] > 1 && $arWorkFlow["STATUS_PERMISSION"] < 2) { $arError[] = array("id" => "bad_wf_status_permission", "text" => GetMessage("WD_FILE_ERROR109")); } } elseif ($this->workflow == 'bizproc') { $documentId = $this->wfParams['DOCUMENT_TYPE']; $documentId[2] = $arElement["item_id"]; $arDocumentStates = CBPDocument::GetDocumentStates( $this->wfParams['DOCUMENT_TYPE'], $documentId ); $arUserGroups = $this->USER["GROUPS"]; if ($arElement["CREATED_BY"] == $GLOBALS["USER"]->GetID()) $arUserGroups[] = "Author"; if (!CBPDocument::CanUserOperateDocument( CBPCanUserOperateOperation::WriteDocument, $GLOBALS["USER"]->GetID(), $documentId, array( "IBlockPermission" => $this->permission, "AllUserGroups" => $arUserGroups, "DocumentStates" => $arDocumentStates) )) { $arError[] = array("id" => "bad_bizproc_permision", "text" => GetMessage("WD_ACCESS_DENIED")); } } } } $arErrors[$static_id] = $arError; } if (empty($arError)) { $e = new CAdminException($arError); $this->LAST_ERROR = $e->GetString(); if ($this->LAST_ERROR == '<br>') $this->LAST_ERROR = ''; return true; } else { $e = new CAdminException($arError); $this->LAST_ERROR = $e->GetString(); if ($this->LAST_ERROR == '<br>') $this->LAST_ERROR = ''; return false; } } function GetUfEntity() { if (empty($this->UF_ENTITY)) { $id = $this->IBLOCK_ID; if (isset($this->arRootSection['ID'])) { $id .= '_'.$this->arRootSection['ID']; } $this->UF_ENTITY = "WEBDAV_".$id."_FILE"; } return $this->UF_ENTITY; } function GetUfFields($id = 0) { global $USER_FIELD_MANAGER; $id = intval($id); if ($id <= 0) { if ($this->UF_FIELDS === null) $this->UF_FIELDS = $USER_FIELD_MANAGER->GetUserFields($this->GetUfEntity(), 0, LANGUAGE_ID); return $this->UF_FIELDS; } else { $result = $USER_FIELD_MANAGER->GetUserFields($this->GetUfEntity(), $id, LANGUAGE_ID); return $result; } } function GetUfFieldsSimpleArray($id = 0) { $arQ = $this->GetUfFields($id); $arRes = array(); foreach($arQ as $k => $v) { $vS = $v['VALUE'] != null ? $v['VALUE'] : ""; $arRes[$k] = $vS; } return $arRes; } function IndexUfValues($arFields) { global $USER_FIELD_MANAGER; if (! ($arFields['MODULE_ID'] == 'iblock') && $arFields['PARAM2'] == $this->IBLOCK_ID) return false; $ufContent = ""; $ufContent .= $USER_FIELD_MANAGER->OnSearchIndex($this->GetUfEntity(), $arFields['ITEM_ID']); $arFields['BODY'] .= "\n" . $ufContent; return $arFields; } function _ib_elm_add($arFields, $bWorkFlow=false, $bUpdateSearch=true, $bResizePictures=false) { global $USER_FIELD_MANAGER; global $APPLICATION; $bUF = (isset($arFields['USER_FIELDS'])); if ($bUF) { $UF_ENTITY = $this->GetUfEntity(); if ( ! $USER_FIELD_MANAGER->CheckFields($UF_ENTITY, 0, $arFields['USER_FIELDS'])) { if(is_object($APPLICATION) && $APPLICATION->GetException()) { $e = $APPLICATION->GetException(); $this->LAST_ERROR .= $e->GetString(); return false; } } $handlerID = AddEventHandler('search', 'BeforeIndex', array($this, 'IndexUfValues')); } if ($bUpdateSearch && $bUF) $bUpdateSearch = false; $el = new CIBlockElement(); $result = $el->Add($arFields, $bWorkFlow, $bUpdateSearch, $bResizePictures); $ID = intval($result); if ($ID <= 0) { $this->LAST_ERROR = $el->LAST_ERROR; return false; } else { if ( isset($arFields['PROPERTY_VALUES']) && ! $this->ValidatePropertyValues($ID, $arFields['PROPERTY_VALUES'], $arFields['IBLOCK_ID']) // as SetPropertyValues doesn't handle SaveFile errors ) { $this->LAST_ERROR = GetMessage("WD_FILE_ERROR111"); $el->Delete($ID); return false; } if ($bUF) { $USER_FIELD_MANAGER->Update($UF_ENTITY, $ID, $arFields['USER_FIELDS']); $el->UpdateSearch($ID, true); } $this->_onEvent('Add', $ID); } if ($bUF) RemoveEventHandler('search', 'BeforeIndex', $handlerID); CWebDavDiskDispatcher::sendEventToOwners(null, array( 'IBLOCK_ID' => (int)$arFields['IBLOCK_ID'], 'ID' => (int)$arFields['IBLOCK_SECTION_ID'], ), 'add'); return (int) $result; } function ValidatePropertyValues($ID, $arProperties, $iblockId = null) { if($iblockId === null) { $iblockId = $this->IBLOCK_ID; } $result = true; $arPropNames = array_keys($arProperties); if (empty($arPropNames)) return $result; foreach ($arProperties as $code => $value) { $dbProps = CIBlockElement::GetProperty($iblockId, $ID, array(), array('CODE' => $code, 'ACTIVE' => 'Y')); if ( $dbProps && ($arProp = $dbProps->Fetch()) ) { if ($arProp['PROPERTY_TYPE'] == 'F') { if (((int) $arProp['VALUE']) > 0) { $arFile = CFile::GetFileArray($arProp['VALUE']); if ( is_array($arFile) && isset($arFile['FILE_SIZE']) && (empty($arProperties[$code]['size']) && !empty($arFile['FILE_SIZE']) || $arFile['FILE_SIZE'] == $arProperties[$code]['size']) ) { unset($arProperties[$code]); } } } else { if ($arProp['VALUE'] == $arProperties[$code]) { unset($arProperties[$code]); } } } } $result = (sizeof($arProperties) <= 0); return $result; } function _ib_elm_delete($ID) { global $USER_FIELD_MANAGER; static $ibe = null; if ($ibe === null) $ibe = new CIBlockElement(); $result = $ibe->Delete($ID); if ($result) { $USER_FIELD_MANAGER->Delete($this->GetUfEntity(), $ID); } else { $this->LAST_ERROR = $ibe->LAST_ERROR; } return $result; } function IsBpParamRequired() // for template { static $dataType = 'IsBpParamRequired'; $result = 'N'; if ($this->workflow == 'bizproc') { $result = $this->_dataCache($dataType); if ($result === false) { $arTemplateStates = CBPWorkflowTemplateLoader::GetDocumentTypeStates( $this->wfParams["DOCUMENT_TYPE"], CBPDocumentEventType::Create ) + CBPWorkflowTemplateLoader::GetDocumentTypeStates( $this->wfParams["DOCUMENT_TYPE"], CBPDocumentEventType::Edit ); foreach ($arTemplateStates as $arTemplateState) { if (is_array($arTemplateState["TEMPLATE_PARAMETERS"])) { foreach ($arTemplateState["TEMPLATE_PARAMETERS"] as $res) { if ( $res["Required"] == 1 && empty($res["Default"]) ) { $result = "Y"; break; } } if ($result === 'Y') break; } } $this->_dataCache($dataType, $result); } } return ($result === 'Y'); } public static function getRootSectionDataForGroup($groupId) { $groupLib = CWebDavIblock::LibOptions('group_files', false, SITE_ID); if ($groupLib && isset($groupLib['id']) && ($iblockId = intval($groupLib['id']))) { $groupSectionId = CIBlockWebdavSocnet::getSectionId($iblockId, 'group', $groupId); if ($groupSectionId) { return array( 'IBLOCK_ID' => $iblockId, 'SECTION_ID' => $groupSectionId, ); } } return array(); } public static function getRootSectionDataForUser($userId) { $userLib = CWebDavIblock::LibOptions('user_files', false, SITE_ID); if ($userLib && isset($userLib['id']) && ($iblockId = intval($userLib['id']))) { $userSectionId = CWebDavIblock::getRootSectionIdForUser($iblockId, $userId); if ($userSectionId) { return array( 'IBLOCK_ID' => $iblockId, 'SECTION_ID' => $userSectionId, ); } } return array(); } public static function getRootSectionIdForUser($iblockId, $userId) { global $USER_FIELD_MANAGER; global $UF_USE_BP; $result = CIBlockWebdavSocnet::getSectionId($iblockId, 'user', $userId); if (($result = intval($result)) > 0) { return $result; } $fields = Array( 'IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y', 'SOCNET_GROUP_ID' => false, 'IBLOCK_SECTION_ID' => 0, 'UF_USE_BP' => 'N', 'UF_USE_EXT_SERVICES' => CWebDavIblock::resolveDefaultUseExtServices(), ); $user = CUser::getById($userId)->fetch(); if(empty($user)) { return false; } $fields['NAME'] = trim($user['LAST_NAME'] . ' ' . $user['FIRST_NAME']); $fields['NAME'] = trim(!empty($fields["NAME"]) ? $fields['NAME'] : $user['LOGIN']); $fields['CREATED_BY'] = $user['ID']; $fields['MODIFIED_BY'] = $user['ID']; if (CIBlock::GetArrayByID($iblockId, "RIGHTS_MODE") === "E") { $tasks = CWebDavIblock::GetTasks(); $fields['RIGHTS'] = array( 'n0' => array('GROUP_CODE' => 'U' . $userId, 'TASK_ID' => $tasks['X']) ); } $UF_USE_BP = $fields['UF_USE_BP']; $USER_FIELD_MANAGER->editFormAddFields('IBLOCK_' . $iblockId . '_SECTION', $fields); $section = new CIBlockSection; $sectionId = $section->add($fields); if (!$sectionId) { return false; } WDClearComponentCache(array( 'webdav.element.edit', 'webdav.element.hist', 'webdav.element.upload', 'webdav.element.view', 'webdav.menu', 'webdav.section.edit', 'webdav.section.list' )); return $sectionId; } /********** new code **********/ function _dataCache($type, $value = null) { if ($type == 'all') { $type = self::GET_ALL_CACHED_SETTINGS; } if ($value === null) // GET { return $this->GetCachedSettings($type); } else { $this->SetCachedSettings($type, $value); } } public function getRootSection() { return $this->arRootSection; } public function getRootSectionDataByKey($key, $default = null) { if(empty($this->arRootSection)) { return $default; } return isset($this->arRootSection[$key])? $this->arRootSection[$key] : $default; } function SetRootSection($id, $force=false, $enableRedirect = true) { $id = intVal($id); $this->CACHE_PATH = $this->cachePathBase; $this->arRootSection = false; if ($id <= 0) { return true; } if($force && isset(self::$arSectionCache[$id])) { unset(self::$arSectionCache[$id]); } if(isset(self::$arSectionCache[$id])) { $this->arRootSection = self::$arSectionCache[$id]; } elseif(!$force) { $res = $this->GetCache($id, "root_section", true); if($res["result"]) { $this->arRootSection = $res["data"]; } } if($this->arRootSection === false) { $arFilter = array( "IBLOCK_ID" => $this->IBLOCK_ID, "ID" => $id, "CHECK_PERMISSIONS" => "N" ); $db_res = CIBlockSection::GetList(array(), $arFilter, false, array_merge(array('UF_USE_EXT_SERVICES'), self::getUFNamesForSectionLink())); if ($db_res && $res = $db_res->Fetch()) { //fixes if (CModule::IncludeModule('socialnetwork')) { // fix an old bug, folder don't contain group name if ($res['NAME'] == GetMessage("SONET_GROUP_PREFIX")) { $arGroup = CSocNetGroup::GetByID(intval($res['SOCNET_GROUP_ID'])); if($arGroup !== false) { $res['NAME'] = GetMessage("SONET_GROUP_PREFIX").$arGroup['NAME']; $ibs = new CIBlockSection(); $ibs->Update($res['ID'], array('NAME' => $res['NAME'])); } } } // fix incorrect iblock settings for socnet if (!$this->_symlinkMode && IsModuleInstalled("bizproc") && (CIBlock::GetArrayByID($this->IBLOCK_ID, "BIZPROC") == "N") ) { $ib = new CIBlock; $res = $ib->Update($this->IBLOCK_ID, array( 'BIZPROC' => 'Y', 'WORKFLOW' => 'N' )); if($enableRedirect) { LocalRedirect($GLOBALS['APPLICATION']->GetCurPageParam()); } } //fixes end $this->arRootSection = $res; self::$arSectionCache[$id] = $res; $arTags = array("iblock_id_" . $this->IBLOCK_ID); $this->SetCache($id, "root_section", self::$arSectionCache[$id], $arTags, true); } else { return false; } } $this->CACHE_PATH = $this->cachePathBase . intval($id).'/'; return true; } /********** Cache **********/ function GetCache($id, $dirName, $useRootSection = true) { $res = array( "result" => false, "data" => null ); if(defined("BX_COMP_MANAGED_CACHE") && $this->CACHE_OBJ) { $cachePath = ($useRootSection ? $this->CACHE_PATH : $this->cachePathBase) . $dirName; if($this->CACHE_OBJ->InitCache($this->CACHE_TIME, $id, $cachePath)) { $res["result"] = true; $res["data"] = $this->CACHE_OBJ->GetVars(); } } return $res; } function SetCache($id, $dirName, $value, $arTags = array(), $useRootSection = true) { global $CACHE_MANAGER; if(defined("BX_COMP_MANAGED_CACHE") && $this->CACHE_OBJ) { $cachePath = ($useRootSection ? $this->CACHE_PATH : $this->cachePathBase) . $dirName; $this->CACHE_OBJ->StartDataCache($this->CACHE_TIME, $id, $cachePath); $CACHE_MANAGER->StartTagCache($cachePath); foreach($arTags as $cTagName) { $CACHE_MANAGER->RegisterTag($cTagName); } $CACHE_MANAGER->EndTagCache(); $this->CACHE_OBJ->EndDataCache($value); } } function CleanCache($id, $dirName, $arTags = array(), $useRootSection = true) { global $CACHE_MANAGER; if(defined("BX_COMP_MANAGED_CACHE") && $this->CACHE_OBJ) { if(count($arTags) > 0) { foreach($arTags as $cTagName) { $CACHE_MANAGER->ClearByTag($cTagName); } } else { $cachePath = ($useRootSection ? $this->CACHE_PATH : $this->cachePathBase) . $dirName; $this->CACHE_OBJ->Clean($id, $cachePath); } } } function GetCachedSettings($type) { $key = $this->IBLOCK_ID . "_" . intval($this->arRootSection["ID"]); if(!array_key_exists($key, self::$arSettingsCache)) { $cacheID = "wd_ib_params_" . $key; $res = $this->GetCache($cacheID, "settings", true); if($res["result"]) { self::$arSettingsCache[$key] = $res["data"]; } } if($type === self::GET_ALL_CACHED_SETTINGS) { return self::$arSettingsCache[$key]; } elseif(isset(self::$arSettingsCache[$key][$type])) { return self::$arSettingsCache[$key][$type]; } return false; } function SetCachedSettings($type, $value) { $key = $this->IBLOCK_ID . "_" . intval($this->arRootSection["ID"]); $cacheID = 'wd_ib_params_' . $key; if(!array_key_exists($key, self::$arSettingsCache)) { self::$arSettingsCache[$key] = $this->GetCachedSettings(self::GET_ALL_CACHED_SETTINGS); } self::$arSettingsCache[$key][$type] = $value; $this->CleanCache($cacheID, "settings", array(), true); $arTags = array("iblock_id_" . $this->IBLOCK_ID); $this->SetCache($cacheID, "settings", self::$arSettingsCache[$key], $arTags, true); } /********** Cache End **********/ /********** IBlock Rights **********/ /* $this->workflow != "workflow" && $this->workflow != "bizproc" */ static protected function GetIBlockRightsObject($type, $iBlockID, $id = null) { if ($type !== self::OBJ_TYPE_IBLOCK && $type !== self::OBJ_TYPE_SECTION && $type !== self::OBJ_TYPE_ELEMENT) { throw new Exception("_get_ib_rights_object invalid type \"".htmlspecialcharsbx($type)."\""); } $ibRights = null; if ($iBlockID === null) { throw new Exception("_get_ib_rights_object called, but no iBlockID is set"); } if ($type !== self::OBJ_TYPE_IBLOCK && $id === null) { throw new Exception("_get_ib_rights_object called, but no ID is set"); } if ($type == self::OBJ_TYPE_SECTION) { $ibRights = new CIBlockSectionRights($iBlockID, $id); } elseif ($type == self::OBJ_TYPE_ELEMENT) { $ibRights = new CIBlockElementRights($iBlockID, $id); } else { $ibRights = new CIBlockRights($iBlockID); } return $ibRights; } static function CheckUserIBlockPermission($permission, $type, $iBlockID, $id = null) { $obj = self::GetIBlockRightsObject($type, $iBlockID, $id); if(!is_object($obj)) { return false; } return $obj::UserHasRightTo($iBlockID, $id, $permission); } /********** IBlock Rights End **********/ public static function checkUfUseExtServices($iblockId) { $iblockId = intval($iblockId); $query = CUserTypeEntity::GetList(array(), array('ENTITY_ID' => 'IBLOCK_'.$iblockId.'_SECTION', 'FIELD_NAME' => 'UF_USE_EXT_SERVICES')); if (!$query || !($row = $query->GetNext())) { $fields = array( 'ENTITY_ID' => 'IBLOCK_'.$iblockId.'_SECTION', 'FIELD_NAME' => 'UF_USE_EXT_SERVICES', 'USER_TYPE_ID' => 'string', 'MULTIPLE' => 'N', 'MANDATORY' => 'N', 'SETTINGS' => array('DEFAULT_VALUE' => self::resolveDefaultUseExtServices()) ); $fields['EDIT_FORM_LABEL'][LANGUAGE_ID] = GetMessage('WD_OPTIONS_ALLOW_EXT_SERVICES'); $userField = new CUserTypeEntity; $userField->Add($fields); $GLOBALS['USER_FIELD_MANAGER']->arFieldsCache = array(); } } /** * Get default value to UF_USE_EXT_SERVICES. This is not DEFAULT_VALUE from DB & USER_FIELD_MANAGER */ public static function resolveDefaultUseExtServices($value = null) { return $value == "N" ? "N" : "Y"; } public static function appendRightsOnElements(array $files, array $rights) { $tasks = CWebDavIblock::GetTasks(); $reformatRights = array(); $i = 0; foreach ($rights as $letter => $groupCodes) { if(!is_array($groupCodes)) { $groupCodes = array($groupCodes); } foreach ($groupCodes as $groupCode) { $reformatRights['n' . $i] = array( 'GROUP_CODE' => $groupCode, 'TASK_ID' => $tasks[$letter],//todo check isset! ); $i++; } unset($groupCode); } unset($right); foreach ($files as $file) { if(!is_array($file)) { continue; } if (CIBlock::GetArrayByID($file['IBLOCK_ID'], "RIGHTS_MODE") === "E") { $rightObject = CWebDavIblock::_get_ib_rights_object('ELEMENT', $file['ID'], $file['IBLOCK_ID']); $rightObject->SetRights(CWebDavTools::appendRights($rightObject, $reformatRights, $tasks)); } } unset($file); } final public static function appendRightsOnSections(array $sections, array $rights) { $tasks = CWebDavIblock::GetTasks(); $reformatRights = array(); $i = 0; foreach ($rights as $letter => $groupCodes) { if(!is_array($groupCodes)) { $groupCodes = array($groupCodes); } foreach ($groupCodes as $groupCode) { $reformatRights['n' . $i] = array( 'GROUP_CODE' => $groupCode, 'TASK_ID' => $tasks[$letter],//todo check isset! ); $i++; } unset($groupCode); } unset($right); foreach ($sections as $section) { $sectionId = (int)$section['ID']; if($sectionId <= 0) { continue; } if (CIBlock::GetArrayByID($section['IBLOCK_ID'], "RIGHTS_MODE") === "E") { $rightObject = CWebDavIblock::_get_ib_rights_object('SECTION', $sectionId, $section['IBLOCK_ID']); $rightObject->SetRights(CWebDavTools::appendRights($rightObject, $reformatRights, $tasks)); } } unset($section); } final public static function removeRightsOnSections(array $sections, array $rights) { $tasks = CWebDavIblock::GetTasks(); $reformatRights = array(); $i = 0; foreach ($rights as $letter => $groupCodes) { if(!is_array($groupCodes)) { $groupCodes = array($groupCodes); } foreach ($groupCodes as $groupCode) { $reformatRights['n' . $i] = array( 'GROUP_CODE' => $groupCode, 'TASK_ID' => $tasks[$letter],//todo check isset! ); $i++; } unset($groupCode); } unset($right); foreach ($sections as $section) { $sectionId = (int)$section['ID']; if($sectionId <= 0) { continue; } if (CIBlock::GetArrayByID($section['IBLOCK_ID'], "RIGHTS_MODE") === "E") { $rightObject = CWebDavIblock::_get_ib_rights_object('SECTION', $sectionId, $section['IBLOCK_ID']); $rightObject->SetRights(CWebDavTools::removeRights($rightObject, $reformatRights, $tasks)); } } unset($section); } /** * @return array */ private function getContextData() { if (!empty($this->attributes['user_id'])) { $contextType = CWebDavSymlinkHelper::ENTITY_TYPE_USER; $contextEntityId = $this->attributes['user_id']; return array($contextType, $contextEntityId); } elseif (!empty($this->attributes['group_id'])) { $contextType = CWebDavSymlinkHelper::ENTITY_TYPE_GROUP; $contextEntityId = $this->attributes['group_id']; return array($contextType, $contextEntityId); } elseif(isset($this->arRootSection['ID'])) { $contextType = CWebDavSymlinkHelper::ENTITY_TYPE_SECTION; $contextEntityId = $this->arRootSection['ID']; return array($contextType, $contextEntityId); } else { $contextType = CWebDavSymlinkHelper::ENTITY_TYPE_SHARED; //todo $contextEntityId !!! $contextEntityId = $this->IBLOCK_ID; return array($contextType, $contextEntityId); } } private function getSectionDataForLinkAnalyze($sectionId, array $miscData = array(), $forwardFromSymlinkSectionToReal = true) { if(!empty($miscData['IBLOCK_ID'])) { $iblockId = $miscData['IBLOCK_ID']; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } else { $iblockId = CWebDavSymlinkHelper::getIblockIdForSectionId($sectionId); } if($forwardFromSymlinkSectionToReal) { if(!empty($this->arParams['dir_array']['ID']) && $this->arParams['dir_array']['ID'] == $sectionId) { //this sectionId is symlink. Forward data to symlink data if(!empty($this->arParams['dir_array'][self::UF_LINK_IBLOCK_ID])) { $sectionId = $this->arParams['dir_array'][self::UF_LINK_SECTION_ID]; $iblockId = $this->arParams['dir_array'][self::UF_LINK_IBLOCK_ID]; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } else { $iblockId = $this->arParams['dir_array']['IBLOCK_ID']; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } } elseif(!empty($miscData['dir_array']['ID']) && $miscData['dir_array']['ID'] == $sectionId) { //this sectionId is symlink. Forward data to symlink data if(!empty($miscData['dir_array'][self::UF_LINK_IBLOCK_ID])) { $sectionId = $miscData['dir_array'][self::UF_LINK_SECTION_ID]; $iblockId = $miscData['dir_array'][self::UF_LINK_IBLOCK_ID]; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } else { $iblockId = $miscData['dir_array']['IBLOCK_ID']; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } } elseif(!empty($miscData['ID']) && $miscData['ID'] == $sectionId) { //this sectionId is symlink. Forward data to symlink data if(!empty($miscData[self::UF_LINK_IBLOCK_ID])) { $sectionId = $miscData[self::UF_LINK_SECTION_ID]; $iblockId = $miscData[self::UF_LINK_IBLOCK_ID]; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } else { $iblockId = $miscData['IBLOCK_ID']; CWebDavSymlinkHelper::setIblockIdForSectionId($sectionId, $iblockId); } } } return array( 'ID' => $sectionId, 'IBLOCK_ID' => $iblockId, ); } final public static function getUFNamesForSectionLink() { if(!self::isEnabledUFSymlinkMode()) { return array(); } return array( self::UF_LINK_IBLOCK_ID, self::UF_LINK_SECTION_ID, self::UF_LINK_CAN_FORWARD, self::UF_LINK_ROOT_SECTION_ID, ); } final public static function isEnabledUFSymlinkMode() { return (bool)self::$_fetchUFSymlinkMode; } final public static function enableUFSymlinkMode() { self::$_fetchUFSymlinkMode = true; } final public static function disableUFSymlinkMode() { self::$_fetchUFSymlinkMode = false; } final public static function needBlockByDisk() { return ( Option::get('disk', 'process_converted', false) === 'Y' || Option::get('webdav', 'process_converted', false) === 'Y' ) || ( isModuleInstalled('webdav') && ( Option::get('disk', 'successfully_converted', false) === 'Y' || Option::get('webdav', 'successfully_converted', false) === 'Y' ) ) ; } final public static function OnBeforeIBlockElementAdd($fields) { if(!static::needBlockByDisk()) { return true; } if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } final public static function OnBeforeIBlockElementUpdate($fields) { if(!static::needBlockByDisk()) { return true; } if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } final public static function OnBeforeIBlockElementDelete($id) { if(!static::needBlockByDisk()) { return true; } $fields = CIBlockElement::GetList(array(), array('ID' => $id), false, false, array('IBLOCK_ID'))->fetch(); if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } final public static function OnBeforeIBlockSectionAdd($fields) { if(!static::needBlockByDisk()) { return true; } if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } final public static function OnBeforeIBlockSectionUpdate($fields) { if(!static::needBlockByDisk()) { return true; } if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } final public static function OnBeforeIBlockSectionDelete($id) { if(!static::needBlockByDisk()) { return true; } $fields = CIBlockSection::GetList(array(), array('ID' => $id), false, array('IBLOCK_ID'))->fetch(); if(empty($fields['IBLOCK_ID'])) { return true; } if(CIBlock::GetArrayByID($fields['IBLOCK_ID'], 'IBLOCK_TYPE_ID') === 'library') { global $APPLICATION; $APPLICATION->throwException(GetMessage('WD_BLOCKED_BY_DISK')); return false; } } }
/var/www/axolotl/data/www/yar.axolotls.ru/bitrix/modules/webdav/classes/iblock.php