private bool FeatureIsEnabled(FeatureDescriptor fd) { return((DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType) && (fd.Id == "TheAdmin" || fd.Id == "SafeMode")) || _shellDescriptor.Features.Any(sf => sf.Name == fd.Id)); }
public void CreateController(string moduleName, string controllerName) { Context.Output.WriteLine(T("Creating Controller {0} in Module {1}", controllerName, moduleName)); ExtensionDescriptor extensionDescriptor = _extensionManager.AvailableExtensions().FirstOrDefault(extension => DefaultExtensionTypes.IsModule(extension.ExtensionType) && string.Equals(moduleName, extension.Name, StringComparison.OrdinalIgnoreCase)); if (extensionDescriptor == null) { Context.Output.WriteLine(T("Creating Controller {0} failed: target Module {1} could not be found.", controllerName, moduleName)); return; } string moduleControllersPath = HostingEnvironment.MapPath("~/Modules/" + extensionDescriptor.Id + "/Controllers/"); string controllerPath = moduleControllersPath + controllerName + ".cs"; string moduleCsProjPath = HostingEnvironment.MapPath(string.Format("~/Modules/{0}/{0}.csproj", extensionDescriptor.Id)); string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/"); if (!Directory.Exists(moduleControllersPath)) { Directory.CreateDirectory(moduleControllersPath); } if (File.Exists(controllerPath)) { Context.Output.WriteLine(T("Controller {0} already exists in target Module {1}.", controllerName, moduleName)); return; } string controllerText = File.ReadAllText(templatesPath + "Controller.txt"); controllerText = controllerText.Replace("$$ModuleName$$", moduleName); controllerText = controllerText.Replace("$$ControllerName$$", controllerName); File.WriteAllText(controllerPath, controllerText); string projectFileText = File.ReadAllText(moduleCsProjPath); // The string searches in solution/project files can be made aware of comment lines. if (projectFileText.Contains("<Compile Include")) { string compileReference = string.Format("<Compile Include=\"{0}\" />\r\n ", "Controllers\\" + controllerName + ".cs"); projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("<Compile Include"), compileReference); } else { string itemGroupReference = string.Format("</ItemGroup>\r\n <ItemGroup>\r\n <Compile Include=\"{0}\" />\r\n ", "Controllers\\" + controllerName + ".cs"); projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("</ItemGroup>"), itemGroupReference); } File.WriteAllText(moduleCsProjPath, projectFileText); Context.Output.WriteLine(T("Controller {0} created successfully in Module {1}", controllerName, moduleName)); TouchSolution(Context.Output); }
public void CreateDataMigration(string featureName) { Context.Output.WriteLine(T("Creating Data Migration for {0}", featureName)); ExtensionDescriptor extensionDescriptor = _extensionManager.AvailableExtensions().FirstOrDefault(extension => DefaultExtensionTypes.IsModule(extension.ExtensionType) && extension.Features.Any(feature => String.Equals(feature.Id, featureName, StringComparison.OrdinalIgnoreCase))); if (extensionDescriptor == null) { Context.Output.WriteLine(T("Creating data migration failed: target Feature {0} could not be found.", featureName)); return; } string dataMigrationFolderPath = HostingEnvironment.MapPath("~/Modules/" + extensionDescriptor.Id + "/"); string dataMigrationFilePath = dataMigrationFolderPath + "Migrations.cs"; string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/"); string moduleCsProjPath = HostingEnvironment.MapPath(string.Format("~/Modules/{0}/{0}.csproj", extensionDescriptor.Id)); if (!Directory.Exists(dataMigrationFolderPath)) { Directory.CreateDirectory(dataMigrationFolderPath); } if (File.Exists(dataMigrationFilePath)) { Context.Output.WriteLine(T("Data migration already exists in target Module {0}.", extensionDescriptor.Id)); return; } List <SchemaCommand> commands = _schemaCommandGenerator.GetCreateFeatureCommands(featureName, false).ToList(); string dataMigrationText; using (var stringWriter = new StringWriter()) { var interpreter = new CodeGenerationCommandInterpreter(stringWriter); foreach (var command in commands) { interpreter.Visit(command); stringWriter.WriteLine(); } dataMigrationText = File.ReadAllText(templatesPath + "DataMigration.txt"); dataMigrationText = dataMigrationText.Replace("$$FeatureName$$", featureName); dataMigrationText = dataMigrationText.Replace("$$Commands$$", stringWriter.ToString()); } File.WriteAllText(dataMigrationFilePath, dataMigrationText); string projectFileText = File.ReadAllText(moduleCsProjPath); // The string searches in solution/project files can be made aware of comment lines. if (projectFileText.Contains("<Compile Include")) { string compileReference = string.Format("<Compile Include=\"{0}\" />\r\n ", "Migrations.cs"); projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("<Compile Include"), compileReference); } else { string itemGroupReference = string.Format("</ItemGroup>\r\n <ItemGroup>\r\n <Compile Include=\"{0}\" />\r\n ", "Migrations.cs"); projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("</ItemGroup>"), itemGroupReference); } File.WriteAllText(moduleCsProjPath, projectFileText); TouchSolution(Context.Output); Context.Output.WriteLine(T("Data migration created successfully in Module {0}", extensionDescriptor.Id)); }
public ActionResult Index() { bool installThemes = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "PackagingServices") != null && Services.Authorizer.Authorize(StandardPermissions.SiteOwner) && // only site owners _shellSettings.Name == ShellSettings.DefaultName; // of the default tenant var featuresThatNeedUpdate = _dataMigrationManager.GetFeaturesThatNeedUpdate(); ThemeEntry currentTheme = null; ExtensionDescriptor currentThemeDescriptor = _siteThemeService.GetSiteTheme(); if (currentThemeDescriptor != null) { currentTheme = new ThemeEntry(currentThemeDescriptor); } IEnumerable <ThemeEntry> themes = _extensionManager.AvailableExtensions() .Where(extensionDescriptor => { bool hidden = false; string tags = extensionDescriptor.Tags; if (tags != null) { hidden = tags.Split(',').Any(t => t.Trim().Equals("hidden", StringComparison.OrdinalIgnoreCase)); } // is the theme allowed for this tenant ? bool allowed = _shellSettings.Themes.Length == 0 || _shellSettings.Themes.Contains(extensionDescriptor.Id); return(!hidden && allowed && DefaultExtensionTypes.IsTheme(extensionDescriptor.ExtensionType) && (currentTheme == null || !currentTheme.Descriptor.Id.Equals(extensionDescriptor.Id))); }) .Select(extensionDescriptor => { ThemeEntry themeEntry = new ThemeEntry(extensionDescriptor) { NeedsUpdate = featuresThatNeedUpdate.Contains(extensionDescriptor.Id), IsRecentlyInstalled = _themeService.IsRecentlyInstalled(extensionDescriptor), Enabled = _shellDescriptor.Features.Any(sf => sf.Name == extensionDescriptor.Id), CanUninstall = installThemes }; if (_extensionDisplayEventHandler != null) { foreach (string notification in _extensionDisplayEventHandler.Displaying(themeEntry.Descriptor, ControllerContext.RequestContext)) { themeEntry.Notifications.Add(notification); } } return(themeEntry); }) .ToArray(); return(View(new ThemesIndexViewModel { CurrentTheme = currentTheme, InstallThemes = installThemes, Themes = themes })); }
/// <summary> /// Loads only installed modules /// </summary> public IEnumerable <ExtensionDescriptor> GetInstalledModules() { return(_extensionManager.AvailableExtensions().Where(descriptor => DefaultExtensionTypes.IsModule(descriptor.ExtensionType))); }
private ExtensionLoadingContext CreateLoadingContext() { var availableExtensions = extensionManager .AvailableExtensions() .Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType)) .OrderBy(d => d.Id) .ToList(); // Check there are no duplicates var duplicates = availableExtensions.GroupBy(ed => ed.Id).Where(g => g.Count() >= 2).ToList(); if (duplicates.Any()) { var sb = new StringBuilder(); sb.Append(T("There are multiple extensions with the same name installed in this instance.\r\n")); foreach (var dup in duplicates) { sb.Append(T("Extension '{0}' has been found from the following locations: {1}.\r\n", dup.Key, string.Join(", ", dup.Select(e => e.Location)))); } sb.Append(T("This issue can be usually solved by removing or renaming the conflicting extension.")); Logger.Error(sb.ToString()); throw new CMSException(new LocalizedString(sb.ToString())); } var previousDependencies = dependenciesFolder.LoadDescriptors().ToList(); var virtualPathModficationDates = new ConcurrentDictionary <string, DateTime>(StringComparer.OrdinalIgnoreCase); Logger.Info("Probing extensions"); var availableExtensionsProbes1 = parallelCacheContext .RunInParallel(availableExtensions, extension => loaders.Select(loader => loader.Probe(extension)).Where(entry => entry != null).ToArray()) .SelectMany(entries => entries) .GroupBy(entry => entry.Descriptor.Id); var availableExtensionsProbes = parallelCacheContext .RunInParallel(availableExtensionsProbes1, g => new { Id = g.Key, Entries = SortExtensionProbeEntries(g, virtualPathModficationDates) }) .ToDictionary(g => g.Id, g => g.Entries, StringComparer.OrdinalIgnoreCase); Logger.Info("Done probing extensions"); var deletedDependencies = previousDependencies .Where(e => !availableExtensions.Any(e2 => StringComparer.OrdinalIgnoreCase.Equals(e2.Id, e.Name))) .ToList(); // Collect references for all modules Logger.Info("Probing extension references"); var references = parallelCacheContext .RunInParallel(availableExtensions, extension => loaders.SelectMany(loader => loader.ProbeReferences(extension)).ToList()) .SelectMany(entries => entries) .ToList(); Logger.Info("Done probing extension references"); var referencesByModule = references .GroupBy(entry => entry.Descriptor.Id, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.AsEnumerable(), StringComparer.OrdinalIgnoreCase); var referencesByName = references .GroupBy(reference => reference.Name, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.AsEnumerable(), StringComparer.OrdinalIgnoreCase); var sortedAvailableExtensions = availableExtensions.OrderByDependenciesAndPriorities( (item, dep) => referencesByModule.ContainsKey(item.Id) && referencesByModule[item.Id].Any(r => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, r.Name)), item => 0) .ToList(); return(new ExtensionLoadingContext { AvailableExtensions = sortedAvailableExtensions, PreviousDependencies = previousDependencies, DeletedDependencies = deletedDependencies, AvailableExtensionsProbes = availableExtensionsProbes, ReferencesByName = referencesByName, ReferencesByModule = referencesByModule, VirtualPathModficationDates = virtualPathModficationDates, }); }
public void MonitorExtensionsWork(Action <IVolatileToken> monitor) { var locations = _extensionManager.AvailableExtensions().Select(e => e.Location).Distinct(StringComparer.InvariantCultureIgnoreCase); Logger.Information("Start monitoring extension files..."); // Monitor add/remove of any module/theme foreach (string location in locations) { Logger.Debug("Monitoring virtual path \"{0}\"", location); monitor(_virtualPathMonitor.WhenPathChanges(location)); } // Give loaders a chance to monitor any additional changes var extensions = _extensionManager.AvailableExtensions().Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType)).ToList(); foreach (var extension in extensions) { foreach (var loader in _loaders) { loader.Monitor(extension, monitor); } } Logger.Information("Done monitoring extension files..."); }
public bool HasLoader(string featureId) { var descriptor = _extensionManager .AvailableExtensions() .Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType)) .OrderBy(d => d.Id) .FirstOrDefault(e => e.Id == featureId || e.Features.Select(f => f.Id).Contains(featureId)); foreach (var loader in _loaders) { if (loader.LoaderIsSuitable(descriptor)) { return(true); } } return(false); }
private bool FeatureIsTheme(FeatureDescriptor fd) { return(DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType)); }
public IEnumerable <string> GetThemes() { return(_extensionManager.AvailableExtensions() .Where(d => DefaultExtensionTypes.IsTheme(d.ExtensionType)) .Select(s => s.Id)); }
private ActionResult InstallPackageDetails(ExtensionDescriptor extensionDescriptor, string redirectUrl) { if (DefaultExtensionTypes.IsModule(extensionDescriptor.ExtensionType)) { List <PackagingInstallFeatureViewModel> features = extensionDescriptor.Features .Where(featureDescriptor => !DefaultExtensionTypes.IsTheme(featureDescriptor.Extension.ExtensionType)) .Select(featureDescriptor => new PackagingInstallFeatureViewModel { Enable = true, // by default all features are enabled FeatureDescriptor = featureDescriptor }).ToList(); List <PackagingInstallRecipeViewModel> recipes = null; if (_recipeHarvester != null) { recipes = _recipeHarvester.HarvestRecipes(extensionDescriptor.Id) .Select(recipe => new PackagingInstallRecipeViewModel { Execute = false, // by default no recipes are executed Recipe = recipe }).ToList(); } if (features.Count > 0) { return(View("InstallModuleDetails", new PackagingInstallViewModel { Features = features, Recipes = recipes, ExtensionDescriptor = extensionDescriptor })); } } return(Redirect(redirectUrl)); }
// Merging occurs from multiple locations: // In reverse priority order: // "~/Core/App_Data/Localization/<culture_name>/orchard.core.po"; // "~/Modules/<module_name>/App_Data/Localization/<culture_name>/orchard.module.po"; // "~/Themes/<theme_name>/App_Data/Localization/<culture_name>/orchard.theme.po"; // "~/App_Data/Localization/<culture_name>/orchard.root.po"; // "~/App_Data/Sites/<tenant_name>/Localization/<culture_name>/orchard.po"; // The dictionary entries from po files that live in higher priority locations will // override the ones from lower priority locations during loading of dictionaries. // TODO: Add culture name in the po file name to facilitate usage. private IDictionary <string, string> LoadTranslationsForCulture(string culture, AcquireContext <string> context) { IDictionary <string, string> translations = new Dictionary <string, string>(); string corePath = string.Format(CoreLocalizationFilePathFormat, culture); string text = _webSiteFolder.ReadFile(corePath); if (text != null) { _localizationStreamParser.ParseLocalizationStream(text, translations, false); if (!DisableMonitoring) { Logger.Debug("Monitoring virtual path \"{0}\"", corePath); context.Monitor(_webSiteFolder.WhenPathChanges(corePath)); } } foreach (var module in _extensionManager.AvailableExtensions()) { if (DefaultExtensionTypes.IsModule(module.ExtensionType)) { string modulePath = string.Format(ModulesLocalizationFilePathFormat, module.Id, culture); text = _webSiteFolder.ReadFile(modulePath); if (text != null) { _localizationStreamParser.ParseLocalizationStream(text, translations, true); if (!DisableMonitoring) { Logger.Debug("Monitoring virtual path \"{0}\"", modulePath); context.Monitor(_webSiteFolder.WhenPathChanges(modulePath)); } } } } string rootPath = string.Format(RootLocalizationFilePathFormat, culture); text = _webSiteFolder.ReadFile(rootPath); if (text != null) { _localizationStreamParser.ParseLocalizationStream(text, translations, true); if (!DisableMonitoring) { Logger.Debug("Monitoring virtual path \"{0}\"", rootPath); context.Monitor(_webSiteFolder.WhenPathChanges(rootPath)); } } string tenantPath = string.Format(TenantLocalizationFilePathFormat, _shellSettings.Name, culture); text = _webSiteFolder.ReadFile(tenantPath); if (text != null) { _localizationStreamParser.ParseLocalizationStream(text, translations, true); if (!DisableMonitoring) { Logger.Debug("Monitoring virtual path \"{0}\"", tenantPath); context.Monitor(_webSiteFolder.WhenPathChanges(tenantPath)); } } return(translations); }