/** * Resolve a source path to it's folder ID by the source path and the matched source beginning. * * @param int $sourceId * @param string $subpath * * @throws Exception * @return mixed */ private function _resolveSourcePathToFolderId($sourceId, $subpath) { // Are we looking for a subfolder? $subpath = is_string($subpath) ? trim($subpath, '/') : ''; if (strlen($subpath) === 0) { // Get the root folder in the source $folder = craft()->assets->getRootFolderBySourceId($sourceId); // Make sure the root folder actually exists if (!$folder) { throw new Exception('Cannot find the target folder.'); } } else { // Prepare the path by parsing tokens and normalizing slashes. try { $renderedSubpath = craft()->templates->renderObjectTemplate($subpath, $this->element); } catch (\Exception $e) { throw new InvalidSubpathException($subpath); } // Did any of the tokens return null? if (strlen($renderedSubpath) === 0 || trim($renderedSubpath, '/') != $renderedSubpath || strpos($renderedSubpath, '//') !== false) { throw new InvalidSubpathException($subpath); } $subpath = IOHelper::cleanPath($renderedSubpath, craft()->config->get('convertFilenamesToAscii')); $folder = craft()->assets->findFolder(array('sourceId' => $sourceId, 'path' => $subpath . '/')); // Ensure that the folder exists if (!$folder) { // Start at the root, and, go over each folder in the path and create it if it's missing. $parentFolder = craft()->assets->getRootFolderBySourceId($sourceId); // Make sure the root folder actually exists if (!$parentFolder) { throw new Exception('Cannot find the target folder.'); } $segments = explode('/', $subpath); foreach ($segments as $segment) { $folder = craft()->assets->findFolder(array('parentId' => $parentFolder->id, 'name' => $segment)); // Create it if it doesn't exist if (!$folder) { $folderId = $this->_createSubFolder($parentFolder, $segment); $folder = craft()->assets->getFolderById($folderId); } // In case there's another segment after this... $parentFolder = $folder; } } } return $folder->id; }