Example #1
0
        /// <summary>
        /// Upload single item from the archive into the physical directory
        /// </summary>
        /// <param name="archivePath">Path to the archive</param>
        /// <returns>Uploaded item descriptor</returns>
        protected virtual IDescriptor UploadSingleItem(string archivePath)
        {
            //get path to the plugins directory
            var pluginsDirectory = _fileProvider.MapPath(PluginManager.PluginsPath);

            //get path to the themes directory
            var themesDirectory = string.Empty;

            if (!string.IsNullOrEmpty(_themeProvider.ThemesPath))
            {
                themesDirectory = _fileProvider.MapPath(_themeProvider.ThemesPath);
            }

            IDescriptor descriptor = null;
            var         uploadedItemDirectoryName = string.Empty;

            using (var archive = ZipFile.OpenRead(archivePath))
            {
                //the archive should contain only one root directory (the plugin one or the theme one)
                var rootDirectories = archive.Entries.Where(entry => entry.FullName.Count(ch => ch == '/') == 1 && entry.FullName.EndsWith("/")).ToList();
                if (rootDirectories.Count != 1)
                {
                    throw new Exception($"The archive should contain only one root plugin or theme directory. " +
                                        $"For example, Payments.PayPalDirect or DefaultClean. " +
                                        $"To upload multiple items, the archive should have the '{UploadedItemsFileName}' file in the root");
                }

                //get directory name (remove the ending /)
                uploadedItemDirectoryName = rootDirectories.First().FullName.TrimEnd('/');

                //try to get descriptor of the uploaded item
                foreach (var entry in archive.Entries)
                {
                    //whether it's a plugin descriptor
                    var isPluginDescriptor = entry.FullName
                                             .Equals($"{uploadedItemDirectoryName}/{PluginManager.PluginDescriptionFileName}", StringComparison.InvariantCultureIgnoreCase);

                    //or whether it's a theme descriptor
                    var isThemeDescriptor = entry.FullName
                                            .Equals($"{uploadedItemDirectoryName}/{_themeProvider.ThemeDescriptionFileName}", StringComparison.InvariantCultureIgnoreCase);

                    if (!isPluginDescriptor && !isThemeDescriptor)
                    {
                        continue;
                    }

                    using (var unzippedEntryStream = entry.Open())
                    {
                        using (var reader = new StreamReader(unzippedEntryStream))
                        {
                            //whether a plugin is upload
                            if (isPluginDescriptor)
                            {
                                descriptor = PluginManager.GetPluginDescriptorFromText(reader.ReadToEnd());

                                //ensure that the plugin current version is supported
                                if (!(descriptor as PluginDescriptor).SupportedVersions.Contains(NopVersion.CurrentVersion))
                                {
                                    throw new Exception($"This plugin doesn't support the current version - {NopVersion.CurrentVersion}");
                                }
                            }

                            //or whether a theme is upload
                            if (isThemeDescriptor)
                            {
                                descriptor = _themeProvider.GetThemeDescriptorFromText(reader.ReadToEnd());
                            }

                            break;
                        }
                    }
                }
            }

            if (descriptor == null)
            {
                throw new Exception("No descriptor file is found. It should be in the root of the archive.");
            }

            if (string.IsNullOrEmpty(uploadedItemDirectoryName))
            {
                throw new Exception($"Cannot get the {(descriptor is PluginDescriptor ? "plugin" : "theme")} directory name");
            }

            //get path to upload
            var directoryPath = descriptor is PluginDescriptor ? pluginsDirectory : themesDirectory;
            var pathToUpload  = _fileProvider.Combine(directoryPath, uploadedItemDirectoryName);

            //ensure it's a new directory (e.g. some old files are not required when re-uploading a plugin)
            //furthermore, zip extract functionality cannot override existing files
            //but there could deletion issues (related to file locking, etc). In such cases the directory should be deleted manually
            if (_fileProvider.DirectoryExists(pathToUpload))
            {
                _fileProvider.DeleteDirectory(pathToUpload);
            }

            //unzip archive
            ZipFile.ExtractToDirectory(archivePath, directoryPath);

            return(descriptor);
        }
Example #2
0
        /// <summary>
        /// Upload multiple items from the archive into the physical directory
        /// </summary>
        /// <param name="archivePath">Path to the archive</param>
        /// <param name="uploadedItems">Uploaded items</param>
        /// <returns>List of uploaded items descriptor</returns>
        protected virtual IList <IDescriptor> UploadMultipleItems(string archivePath, IList <UploadedItem> uploadedItems)
        {
            //get path to the plugins directory
            var pluginsDirectory = _fileProvider.MapPath(PluginManager.PluginsPath);

            //get path to the themes directory
            var themesDirectory = string.Empty;

            if (!string.IsNullOrEmpty(_themeProvider.ThemesPath))
            {
                themesDirectory = _fileProvider.MapPath(_themeProvider.ThemesPath);
            }

            //get descriptors of items contained in the archive
            var descriptors = new List <IDescriptor>();

            using (var archive = ZipFile.OpenRead(archivePath))
            {
                foreach (var item in uploadedItems)
                {
                    if (!item.Type.HasValue)
                    {
                        continue;
                    }

                    //ensure that the current version of nopCommerce is supported
                    if (!item.SupportedVersions?.Contains(NopVersion.CurrentVersion) ?? true)
                    {
                        continue;
                    }

                    //the item path should end with a slash
                    var itemPath = $"{item.DirectoryPath?.TrimEnd('/')}/";

                    //get path to the descriptor entry in the archive
                    var descriptorPath = string.Empty;
                    if (item.Type == UploadedItemType.Plugin)
                    {
                        descriptorPath = $"{itemPath}{PluginManager.PluginDescriptionFileName}";
                    }

                    if (item.Type == UploadedItemType.Theme && !string.IsNullOrEmpty(_themeProvider.ThemeDescriptionFileName))
                    {
                        descriptorPath = $"{itemPath}{_themeProvider.ThemeDescriptionFileName}";
                    }

                    //try to get the descriptor entry
                    var descriptorEntry = archive.Entries.FirstOrDefault(entry => entry.FullName.Equals(descriptorPath, StringComparison.InvariantCultureIgnoreCase));
                    if (descriptorEntry == null)
                    {
                        continue;
                    }

                    //try to get descriptor of the uploaded item
                    IDescriptor descriptor = null;
                    using (var unzippedEntryStream = descriptorEntry.Open())
                    {
                        using (var reader = new StreamReader(unzippedEntryStream))
                        {
                            //whether a plugin is upload
                            if (item.Type == UploadedItemType.Plugin)
                            {
                                descriptor = PluginManager.GetPluginDescriptorFromText(reader.ReadToEnd());
                            }

                            //or whether a theme is upload
                            if (item.Type == UploadedItemType.Theme)
                            {
                                descriptor = _themeProvider.GetThemeDescriptorFromText(reader.ReadToEnd());
                            }
                        }
                    }
                    if (descriptor == null)
                    {
                        continue;
                    }

                    //ensure that the plugin current version is supported
                    if (descriptor is PluginDescriptor pluginDescriptor && !pluginDescriptor.SupportedVersions.Contains(NopVersion.CurrentVersion))
                    {
                        continue;
                    }

                    //get path to upload
                    var uploadedItemDirectoryName = _fileProvider.GetFileName(itemPath.TrimEnd('/'));
                    var pathToUpload = _fileProvider.Combine(item.Type == UploadedItemType.Plugin ? pluginsDirectory : themesDirectory, uploadedItemDirectoryName);

                    //ensure it's a new directory (e.g. some old files are not required when re-uploading a plugin or a theme)
                    //furthermore, zip extract functionality cannot override existing files
                    //but there could deletion issues (related to file locking, etc). In such cases the directory should be deleted manually
                    if (_fileProvider.DirectoryExists(pathToUpload))
                    {
                        _fileProvider.DeleteDirectory(pathToUpload);
                    }

                    //unzip entries into files
                    var entries = archive.Entries.Where(entry => entry.FullName.StartsWith(itemPath, StringComparison.InvariantCultureIgnoreCase));
                    foreach (var entry in entries)
                    {
                        //get name of the file
                        var fileName = entry.FullName.Substring(itemPath.Length);
                        if (string.IsNullOrEmpty(fileName))
                        {
                            continue;
                        }

                        var filePath      = _fileProvider.Combine(pathToUpload, fileName.Replace("/", "\\"));
                        var directoryPath = _fileProvider.GetDirectoryName(filePath);

                        //whether the file directory is already exists, otherwise create the new one
                        if (!_fileProvider.DirectoryExists(directoryPath))
                        {
                            _fileProvider.CreateDirectory(directoryPath);
                        }

                        //unzip entry to the file (ignore directory entries)
                        if (!filePath.Equals($"{directoryPath}\\", StringComparison.InvariantCultureIgnoreCase))
                        {
                            entry.ExtractToFile(filePath);
                        }
                    }

                    //item is uploaded
                    descriptors.Add(descriptor);
                }
            }

            return(descriptors);
        }