예제 #1
0
        //
        //====================================================================================================
        /// <summary>
        /// Install a collectionZip from the Collection Library (registry, distribution, etc.)
        /// downloads the collection to a private folder
        /// Calls installCollectionFromCollectionFolder.
        /// </summary>
        /// <param name="core"></param>
        /// <param name="collectionGuid"></param>
        /// <param name="return_ErrorMessage"></param>
        /// <param name="ImportFromCollectionsGuidList"></param>
        /// <param name="IsNewBuild"></param>
        /// <param name="repair"></param>
        /// <param name="nonCriticalErrorList"></param>
        /// <param name="logPrefix"></param>
        /// <param name="collectionsInstalledList"></param>
        /// <returns></returns>
        public static bool installCollectionFromLibrary(CoreController core, bool isDependency, Stack <string> contextLog, string collectionGuid, ref string return_ErrorMessage, bool IsNewBuild, bool repair, ref List <string> nonCriticalErrorList, string logPrefix, ref List <string> collectionsInstalledList)
        {
            bool UpgradeOK = true;

            try {
                //
                contextLog.Push(MethodInfo.GetCurrentMethod().Name + ", [" + collectionGuid + "]");
                //
                collectionGuid = GenericController.normalizeGuid(collectionGuid);
                if (string.IsNullOrWhiteSpace(collectionGuid))
                {
                    LogController.logWarn(core, "installCollectionFromRemoteRepo, collectionGuid is null");
                }
                else if (!collectionsInstalledList.Contains(collectionGuid.ToLower(CultureInfo.InvariantCulture)))
                {
                    //
                    // Download all files for this collection and build the collection folder(s)
                    string tempFilesDownloadPath = AddonController.getPrivateFilesAddonPath() + Contensive.Processor.Controllers.GenericController.getGUIDNaked() + "\\";
                    core.tempFiles.createPath(tempFilesDownloadPath);
                    //
                    // -- download the collection file into the download path from the collectionGuid provided
                    DateTime CollectionLastModifiedDate = default;
                    if (CollectionLibraryController.downloadCollectionFromLibrary(core, tempFilesDownloadPath, collectionGuid, ref CollectionLastModifiedDate, ref return_ErrorMessage))
                    {
                        //
                        // -- build the collection folders for all collection files in the download path and created a list of collection Guids that need to be installed
                        var collectionsDownloaded = new List <string>();
                        CollectionInstallController.installCollectionsFromTempFolder(core, isDependency, contextLog, tempFilesDownloadPath, ref return_ErrorMessage, ref collectionsInstalledList, IsNewBuild, repair, ref nonCriticalErrorList, logPrefix, true, ref collectionsDownloaded);
                    }
                    //
                    // -- delete the temporary install folder
                    core.tempFiles.deleteFolder(tempFilesDownloadPath);
                    //
                    // -- invalidate cache
                    core.cache.invalidateAll();
                }
            } catch (Exception ex) {
                LogController.logError(core, ex);
                throw;
            } finally {
                contextLog.Pop();
            }
            return(UpgradeOK);
        }
 //
 //====================================================================================================
 /// <summary>
 /// when breaking changes are required for data, update them here
 /// </summary>
 /// <param name="core"></param>
 /// <param name="DataBuildVersion"></param>
 public static void migrateData(CoreController core, string DataBuildVersion, string logPrefix)
 {
     try {
         CPClass cp = core.cpParent;
         //
         // -- Roll the style sheet cache if it is setup
         core.siteProperties.setProperty("StylesheetSerialNumber", (-1).ToString());
         //
         // -- verify ID is primary key on all tables with an id
         foreach (TableModel table in DbBaseModel.createList <TableModel>(cp))
         {
             if (!string.IsNullOrWhiteSpace(table.name))
             {
                 bool tableHasId = false;
                 {
                     //
                     // -- verify table as an id field
                     string    sql = "SELECT name FROM sys.columns WHERE Name = N'ID' AND Object_ID = Object_ID(N'ccmembers')";
                     DataTable dt  = cp.Db.ExecuteQuery(sql);
                     if (dt != null)
                     {
                         tableHasId = !dt.Rows.Equals(0);
                     }
                 }
                 if (tableHasId)
                 {
                     //
                     // -- table has id field, make sure it is primary key
                     string sql = ""
                                  + " select Col.Column_Name"
                                  + " from INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col"
                                  + " where (Col.Constraint_Name = Tab.Constraint_Name) AND (Col.Table_Name = Tab.Table_Name) AND (Constraint_Type = 'PRIMARY KEY') AND (Col.Table_Name = '" + table.name + "')";
                     bool idPrimaryKeyFound = false;
                     foreach (DataRow dr in core.db.executeQuery(sql).Rows)
                     {
                         if (GenericController.encodeText(dr["Column_Name"]).ToLower().Equals("id"))
                         {
                             idPrimaryKeyFound = true;
                             break;
                         }
                     }
                     if (!idPrimaryKeyFound)
                     {
                         try {
                             core.db.executeNonQuery("alter table " + table.name + " add primary key (ID)");
                         } catch (Exception ex) {
                             LogController.logError(core, ex, "Content Table [" + table.name + "] does not include column ID. Exception happened while adding column and setting it primarykey.");
                         }
                     }
                 }
             }
         }
         //
         // -- continue only if a previous build exists
         if (!string.IsNullOrEmpty(DataBuildVersion))
         {
             //
             // -- 4.1 to 5 conversions
             if (GenericController.versionIsOlder(DataBuildVersion, "4.1"))
             {
                 //
                 // -- create Data Migration Assets collection
                 var migrationCollection = DbBaseModel.createByUniqueName <AddonCollectionModel>(cp, "Data Migration Assets");
                 if (migrationCollection == null)
                 {
                     migrationCollection      = DbBaseModel.addDefault <AddonCollectionModel>(cp);
                     migrationCollection.name = "Data Migration Assets";
                 }
                 //
                 // -- remove all addon content fieldtype rules
                 Contensive.Models.Db.DbBaseModel.deleteRows <Contensive.Models.Db.AddonContentFieldTypeRulesModel>(cp, "(1=1)");
                 //
                 // -- delete /admin www subfolder
                 core.wwwFiles.deleteFolder("admin");
                 //
                 // -- delete .asp and .php files
                 foreach (BaseClasses.CPFileSystemBaseClass.FileDetail file in core.wwwFiles.getFileList(""))
                 {
                     if (file == null)
                     {
                         continue;
                     }
                     if (string.IsNullOrWhiteSpace(file.Name))
                     {
                         continue;
                     }
                     if (file.Name.Length < 4)
                     {
                         continue;
                     }
                     string extension = System.IO.Path.GetExtension(file.Name).ToLower(CultureInfo.InvariantCulture);
                     if ((extension == ".php") || (extension == ".asp"))
                     {
                         core.wwwFiles.deleteFile(file.Name);
                     }
                 }
                 //
                 // -- create www /cclib folder and copy in legacy resources
                 core.programFiles.copyFile("cclib.zip", "cclib.zip", core.wwwFiles);
                 core.wwwFiles.unzipFile("cclib.zip");
                 //
                 // -- remove all the old menu entries and leave the navigation entries
                 var navContent = DbBaseModel.createByUniqueName <ContentModel>(cp, Contensive.Models.Db.NavigatorEntryModel.tableMetadata.contentName);
                 if (navContent != null)
                 {
                     core.db.executeNonQuery("delete from ccMenuEntries where ((contentcontrolid<>0)and(contentcontrolid<>" + navContent.id + ")and(contentcontrolid is not null))");
                 }
                 //
                 // -- reinstall newest font-awesome collection
                 string returnErrorMessage       = "";
                 var    context                  = new Stack <string>();
                 var    nonCritialErrorList      = new List <string>();
                 var    collectionsInstalledList = new List <string>();
                 CollectionLibraryController.installCollectionFromLibrary(core, false, context, Constants.fontAwesomeCollectionGuid, ref returnErrorMessage, false, true, ref nonCritialErrorList, logPrefix, ref collectionsInstalledList);
                 //
                 // -- reinstall newest redactor collection
                 returnErrorMessage       = "";
                 context                  = new Stack <string>();
                 nonCritialErrorList      = new List <string>();
                 collectionsInstalledList = new List <string>();
                 CollectionLibraryController.installCollectionFromLibrary(core, false, context, Constants.redactorCollectionGuid, ref returnErrorMessage, false, true, ref nonCritialErrorList, logPrefix, ref collectionsInstalledList);
                 //
                 // -- addons with active-x -- remove programid and add script code that logs error
                 string newCode = ""
                                  + "function m"
                                  + " ' + CHAR(13)+CHAR(10) + ' \ncp.Site.ErrorReport(\"deprecated active-X add-on executed [#\" & cp.addon.id & \", \" & cp.addon.name & \"]\")"
                                  + " ' + CHAR(13)+CHAR(10) + ' \nend function"
                                  + "";
                 string sql = "update ccaggregatefunctions set help='Legacy activeX: ' + objectprogramId, objectprogramId=null, ScriptingCode='" + newCode + "' where (ObjectProgramID is not null)";
                 LogController.logInfo(core, "MigrateData, removing activex addons, adding exception logging, sql [" + sql + "]");
                 core.db.executeNonQuery(sql);
                 //
                 // -- create page menus from section menus
                 using (var cs = new CsModel(core)) {
                     sql = "select m.name as menuName, m.id as menuId, p.name as pageName, p.id as pageId, s.name as sectionName, m.*"
                           + " from ccDynamicMenus m"
                           + " left join ccDynamicMenuSectionRules r on r.DynamicMenuId = m.id"
                           + " left join ccSections s on s.id = r.SectionID"
                           + " left join ccPageContent p on p.id = s.RootPageID"
                           + " where (p.id is not null)and(s.active>0)"
                           + " order by m.id, s.sortorder,s.id";
                     if (cs.openSql(sql))
                     {
                         int sortOrder = 0;
                         do
                         {
                             string menuName = cs.getText("menuName");
                             if (!string.IsNullOrWhiteSpace(menuName))
                             {
                                 var menu = DbBaseModel.createByUniqueName <MenuModel>(cp, menuName);
                                 if (menu == null)
                                 {
                                     menu      = DbBaseModel.addEmpty <MenuModel>(cp);
                                     menu.name = menuName;
                                     try {
                                         menu.classItemActive = cs.getText("classItemActive");
                                         menu.classItemFirst  = cs.getText("classItemFirst");
                                         menu.classItemHover  = cs.getText("classItemHover");
                                         menu.classItemLast   = cs.getText("classItemLast");
                                         menu.classTierAnchor = cs.getText("classTierItem");
                                         menu.classTierItem   = cs.getText("classTierItem");
                                         menu.classTierList   = cs.getText("classTierList");
                                         menu.classTopAnchor  = cs.getText("classTopItem");
                                         menu.classTopItem    = cs.getText("classTopItem");
                                         menu.classTopList    = cs.getText("classTopList");
                                         menu.classTopWrapper = cs.getText("classTopWrapper");
                                     } catch (Exception ex) {
                                         LogController.logError(core, ex, "migrateData error populating menu from dynamic menu.");
                                     }
                                     menu.save(cp);
                                 }
                                 //
                                 // -- set the root page's menuHeadline to the section name
                                 var page = DbBaseModel.create <PageContentModel>(cp, cs.getInteger("pageId"));
                                 if (page != null)
                                 {
                                     page.menuHeadline = cs.getText("sectionName");
                                     page.save(cp);
                                     //
                                     // -- create a menu-page rule to attach this page to the menu in the current order
                                     var menuPageRule = DbBaseModel.addEmpty <MenuPageRuleModel>(cp);
                                     if (menuPageRule != null)
                                     {
                                         menuPageRule.name      = "Created from v4.1 menu sections " + core.dateTimeNowMockable.ToString();
                                         menuPageRule.pageId    = page.id;
                                         menuPageRule.menuId    = menu.id;
                                         menuPageRule.active    = true;
                                         menuPageRule.sortOrder = sortOrder.ToString().PadLeft(4, '0');
                                         menuPageRule.save(cp);
                                         sortOrder += 10;
                                     }
                                 }
                             }
                             cs.goNext();
                         } while (cs.ok());
                     }
                 }
                 //
                 // -- create a theme addon for each template for styles and meta content
                 using (var csTemplate = cp.CSNew()) {
                     if (csTemplate.Open("page templates"))
                     {
                         do
                         {
                             int    templateId           = csTemplate.GetInteger("id");
                             string templateStylePrepend = "";
                             string templateStyles       = csTemplate.GetText("StylesFilename");
                             //
                             // -- add shared styles to the template stylesheet
                             using (var csStyleRule = cp.CSNew()) {
                                 if (csStyleRule.Open("shared styles template rules", "(TemplateID=" + templateId + ")"))
                                 {
                                     do
                                     {
                                         int sharedStyleId = csStyleRule.GetInteger("styleid");
                                         using (var csStyle = cp.CSNew()) {
                                             if (csStyleRule.Open("shared styles", "(id=" + sharedStyleId + ")"))
                                             {
                                                 //
                                                 // -- prepend lines beginning with @ t
                                                 string styles = csStyleRule.GetText("StyleFilename");
                                                 if (!string.IsNullOrWhiteSpace(styles))
                                                 {
                                                     //
                                                     // -- trim off leading spaces, newlines, comments
                                                     styles = styles.Trim();
                                                     while (!string.IsNullOrWhiteSpace(styles) && styles.Substring(0, 1).Equals("@"))
                                                     {
                                                         if (styles.IndexOf(Environment.NewLine) >= 0)
                                                         {
                                                             templateStylePrepend += styles.Substring(0, styles.IndexOf(Environment.NewLine));
                                                             styles = styles.Substring(styles.IndexOf(Environment.NewLine) + 1).Trim();
                                                         }
                                                         else
                                                         {
                                                             templateStylePrepend += styles;
                                                             styles = string.Empty;
                                                         }
                                                     }
                                                     ;
                                                     templateStyles += Environment.NewLine + styles;
                                                 }
                                             }
                                         }
                                         csStyleRule.GoNext();
                                     } while (csStyleRule.OK());
                                 }
                             }
                             //
                             // -- create an addon
                             var themeAddon = DbBaseModel.addDefault <AddonModel>(cp);
                             themeAddon.name                   = "Theme assets for template " + csTemplate.GetText("name");
                             themeAddon.otherHeadTags          = csTemplate.GetText("otherheadtags");
                             themeAddon.javaScriptBodyEnd      = csTemplate.GetText("jsendbody");
                             themeAddon.stylesFilename.content = templateStylePrepend + Environment.NewLine + templateStyles;
                             themeAddon.collectionId           = migrationCollection.id;
                             themeAddon.save(cp);
                             //
                             // -- create an addon template rule to set dependency
                             var rule = DbBaseModel.addEmpty <AddonTemplateRuleModel>(cp);
                             rule.addonId    = themeAddon.id;
                             rule.templateId = templateId;
                             rule.save(cp);
                             //
                             csTemplate.GoNext();
                         } while (csTemplate.OK());
                     }
                 }
                 //
                 // -- reset the html minify so it is easier to resolve other issues
                 core.siteProperties.setProperty("ALLOW HTML MINIFY", false);
                 //
                 // -- remove contentcategoryid from all edit page
                 cp.Db.ExecuteNonQuery("update ccfields set Authorable=0 where name='contentcategoryid'");
                 cp.Db.ExecuteNonQuery("update ccfields set Authorable=0 where name='editsourceid'");
                 cp.Db.ExecuteNonQuery("update ccfields set Authorable=0 where name='editarchive'");
                 cp.Db.ExecuteNonQuery("update ccfields set Authorable=0 where name='editblank'");
                 //
                 // -- remove legacy workflow fields
                 UpgradeController.dropLegacyWorkflowField(core, "editsourceid");
                 cp.Db.ExecuteNonQuery("delete from ccfields where name='editsourceid'");
                 //
                 UpgradeController.dropLegacyWorkflowField(core, "editblank");
                 cp.Db.ExecuteNonQuery("delete from ccfields where name='editblank'");
                 //
                 UpgradeController.dropLegacyWorkflowField(core, "editarchive");
                 cp.Db.ExecuteNonQuery("delete from ccfields where name='editarchive'");
                 //
                 UpgradeController.dropLegacyWorkflowField(core, "contentcategoryid");
                 cp.Db.ExecuteNonQuery("delete from ccfields where name='contentcategoryid'");
                 //
                 //
                 // -- end of 4.1 to 5 conversion
             }
             //
             // -- 5.19.1223 conversion -- render AddonList no copyFilename
             if (GenericController.versionIsOlder(DataBuildVersion, "5.19.1223"))
             {
                 //
                 // -- verify design block installation
                 string returnUserError = "";
                 if (!cp.Db.IsTable("dbtext"))
                 {
                     if (!cp.Addon.InstallCollectionFromLibrary(Constants.designBlockCollectionGuid, ref returnUserError))
                     {
                         throw new Exception("Error installing Design Blocks, required for data upgrade. " + returnUserError);
                     }
                 }
                 //
                 // -- add a text block and childPageList to every page without an addonlist
                 foreach (var page in DbBaseModel.createList <PageContentModel>(cp, "(addonList is null)"))
                 {
                     convertPageContentToAddonList(core, page);
                 }
                 core.siteProperties.setProperty("PageController Render Legacy Copy", false);
             }
             //
             // -- 5.2005.9.4 conversion -- collections incorrectly marked not-updateable - mark all except themes (templates)
             if (GenericController.versionIsOlder(DataBuildVersion, "5.2005.9.4"))
             {
                 //
                 // --
                 cp.Db.ExecuteNonQuery("update ccaddoncollections set updatable=1 where name not like '%theme%'");
             }
             //
             // -- 5.2005.19.1 conversion -- rename site property EmailUrlRootRelativePrefix to LocalFileModeProtocolDomain
             if (GenericController.versionIsOlder(DataBuildVersion, "5.2005.19.1"))
             {
                 //
                 // --
                 if (string.IsNullOrWhiteSpace(cp.Site.GetText("webAddressProtocolDomain")))
                 {
                     cp.Site.SetProperty("webAddressProtocolDomain", cp.Site.GetText("EmailUrlRootRelativePrefix"));
                 }
             }
             //
             // -- delete legacy corehelp collection. Created with fields that have only field name, legacy install layed collections over the application collection
             //    new install loads fields directly from collection, which coreHelp then marks all fields inactive.
             core.db.delete("{6e905db1-d3f0-40af-aac4-4bd78e680fae}", "ccaddoncollections");
         }
         // -- Reload
         core.cache.invalidateAll();
         core.clearMetaData();
     } catch (Exception ex) {
         LogController.logError(core, ex);
         throw;
     }
 }
        //
        //====================================================================================================
        /// <summary>
        /// Builds collection folders for a collectionZip file
        /// unzip a folder and if the collection is not in the collections installed or the collectionsToInstall, save the collection to the appropriate collection folder and add it to the collectionsToInstall
        /// </summary>
        /// <param name="core"></param>
        /// <param name="sourceTempFolderPathFilename"></param>
        /// <param name="CollectionLastChangeDate"></param>
        /// <param name="collectionGuid"></param>
        /// <param name="return_ErrorMessage"></param>
        /// <param name="collectionsDownloaded">collection guids that have been saved to the collection folder and need to be saved to the database druing this install.</param>
        /// <param name="collectionsInstalledList">collection guids that have been saved to the database during this install.</param>
        /// <param name="collectionsBuildingFolder">folder building is recursive. These are the collection guids whose folders are currently being built.</param>
        /// <returns></returns>
        public static bool buildCollectionFolderFromCollectionZip(CoreController core, Stack <string> contextLog, string sourceTempFolderPathFilename, DateTime CollectionLastChangeDate, ref string return_ErrorMessage, ref List <string> collectionsDownloaded, ref List <string> collectionsInstalledList, ref List <string> collectionsBuildingFolder)
        {
            try {
                //
                contextLog.Push(MethodInfo.GetCurrentMethod().Name + ", [" + sourceTempFolderPathFilename + "]");
                traceContextLog(core, contextLog);
                //
                string collectionPath     = "";
                string collectionFilename = "";
                core.tempFiles.splitDosPathFilename(sourceTempFolderPathFilename, ref collectionPath, ref collectionFilename);
                string CollectionVersionFolderName = "";
                if (!core.tempFiles.pathExists(collectionPath))
                {
                    //
                    // return false, The working folder is not there
                    return_ErrorMessage = "<p>There was a problem with the installation. The installation folder is not valid.</p>";
                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, CheckFileFolder was false for the temp folder [" + collectionPath + "]");
                    return(false);
                }
                //
                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, processing files in temp folder [" + collectionPath + "]");
                //
                // --move collection file to a temp directory
                // -- use try-finally to delete temp folder
                string tmpInstallPath = "tmpInstallCollection" + GenericController.getGUIDNaked() + "\\";
                try {
                    core.tempFiles.copyFile(sourceTempFolderPathFilename, tmpInstallPath + collectionFilename);
                    if (collectionFilename.ToLowerInvariant().Substring(collectionFilename.Length - 4) == ".zip")
                    {
                        core.tempFiles.unzipFile(tmpInstallPath + collectionFilename);
                        core.tempFiles.deleteFile(tmpInstallPath + collectionFilename);
                    }
                    //
                    // -- find xml file in temp folder and process it
                    bool CollectionXmlFileFound = false;
                    foreach (FileDetail file in core.tempFiles.getFileList(tmpInstallPath))
                    {
                        if (file.Name.Substring(file.Name.Length - 4).ToLower(CultureInfo.InvariantCulture) == ".xml")
                        {
                            //
                            LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", build collection folder for Collection file [" + file.Name + "]");
                            //
                            XmlDocument CollectionFile = new XmlDocument();
                            try {
                                CollectionFile.LoadXml(core.tempFiles.readFileText(tmpInstallPath + file.Name));
                            } catch (Exception ex) {
                                //
                                // -- There was a parse error in this xml file. Set the return message and the flag
                                // -- If another xml files shows up, and process OK it will cover this error
                                return_ErrorMessage = "There was a problem installing the Collection File [" + tmpInstallPath + file.Name + "]. The error reported was [" + ex.Message + "].";
                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, error reading collection [" + sourceTempFolderPathFilename + "]");
                                continue;
                            }
                            string CollectionFileBaseName = GenericController.toLCase(CollectionFile.DocumentElement.Name);
                            if ((CollectionFileBaseName != "contensivecdef") && (CollectionFileBaseName != CollectionFileRootNode) && (CollectionFileBaseName != GenericController.toLCase(CollectionFileRootNodeOld)))
                            {
                                //
                                // -- Not a problem, this is just not a collection file
                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, xml base name wrong [" + CollectionFileBaseName + "]");
                                continue;
                            }
                            bool IsFound = false;
                            //
                            // Collection File
                            //
                            string Collectionname = XmlController.getXMLAttribute(core, ref IsFound, CollectionFile.DocumentElement, "name", "");
                            string collectionGuid = XmlController.getXMLAttribute(core, ref IsFound, CollectionFile.DocumentElement, "guid", Collectionname);
                            if ((!collectionsInstalledList.Contains(collectionGuid.ToLower(CultureInfo.InvariantCulture))) && (!collectionsDownloaded.Contains(collectionGuid.ToLower(CultureInfo.InvariantCulture))))
                            {
                                if (string.IsNullOrEmpty(Collectionname))
                                {
                                    //
                                    // ----- Error condition -- it must have a collection name
                                    //
                                    return_ErrorMessage = "<p>There was a problem with this Collection. The collection file does not have a collection name.</p>";
                                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, collection has no name");
                                    continue;
                                }
                                //
                                //------------------------------------------------------------------
                                // Build Collection folder structure in /Add-ons folder
                                //------------------------------------------------------------------
                                //
                                collectionsDownloaded.Add(collectionGuid.ToLower(CultureInfo.InvariantCulture));
                                CollectionXmlFileFound = true;
                                if (string.IsNullOrEmpty(collectionGuid))
                                {
                                    //
                                    // must have a guid
                                    collectionGuid = Collectionname;
                                }
                                //
                                //
                                CollectionVersionFolderName = verifyCollectionVersionFolderName(core, collectionGuid, Collectionname);
                                string CollectionVersionFolder = AddonController.getPrivateFilesAddonPath() + CollectionVersionFolderName;
                                //
                                core.tempFiles.copyPath(tmpInstallPath, CollectionVersionFolder, core.privateFiles);
                                //
                                // -- iterate through all nodes of this collection xml file and install all dependencies
                                foreach (XmlNode metaDataSection in CollectionFile.DocumentElement.ChildNodes)
                                {
                                    string ChildCollectionGUID = null;
                                    string ChildCollectionName = null;
                                    bool   Found = false;
                                    switch (GenericController.toLCase(metaDataSection.Name))
                                    {
                                    case "resource":
                                        break;

                                    case "getcollection":
                                    case "importcollection":
                                        //
                                        // -- Download Collection file into install folder
                                        ChildCollectionName = XmlController.getXMLAttribute(core, ref Found, metaDataSection, "name", "");
                                        ChildCollectionGUID = XmlController.getXMLAttribute(core, ref Found, metaDataSection, "guid", metaDataSection.InnerText);
                                        if (string.IsNullOrEmpty(ChildCollectionGUID))
                                        {
                                            ChildCollectionGUID = metaDataSection.InnerText;
                                        }
                                        ChildCollectionGUID = GenericController.normalizeGuid(ChildCollectionGUID);
                                        string statusMsg = "Installing collection [" + ChildCollectionName + ", " + ChildCollectionGUID + "] referenced from collection [" + Collectionname + "]";
                                        LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, getCollection or importcollection, childCollectionName [" + ChildCollectionName + "], childCollectionGuid [" + ChildCollectionGUID + "]");
                                        if (GenericController.strInstr(1, CollectionVersionFolder, ChildCollectionGUID, 1) == 0)
                                        {
                                            if (string.IsNullOrEmpty(ChildCollectionGUID))
                                            {
                                                //
                                                // -- Needs a GUID to install
                                                return_ErrorMessage = statusMsg + ". The installation can not continue because an imported collection could not be downloaded because it does not include a valid GUID.";
                                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, return message [" + return_ErrorMessage + "]");
                                            }
                                            else
                                            {
                                                if ((!collectionsBuildingFolder.Contains(ChildCollectionGUID)) && (!collectionsDownloaded.Contains(ChildCollectionGUID)) && (!collectionsInstalledList.Contains(ChildCollectionGUID)))
                                                {
                                                    //
                                                    // -- add to the list of building folders to block recursive loop
                                                    collectionsBuildingFolder.Add(ChildCollectionGUID);
                                                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, [" + ChildCollectionGUID + "], not found so needs to be installed");
                                                    //
                                                    // If it is not already installed, download and install it also
                                                    //
                                                    string   workingTempPath = GenericController.getGUIDNaked() + "\\";
                                                    DateTime libraryCollectionLastModifiedDate = default(DateTime);
                                                    try {
                                                        //
                                                        // try-finally to delete the working folder
                                                        if (!CollectionLibraryController.downloadCollectionFromLibrary(core, workingTempPath, ChildCollectionGUID, ref libraryCollectionLastModifiedDate, ref return_ErrorMessage))
                                                        {
                                                            //
                                                            // -- did not download correctly
                                                            LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, [" + statusMsg + "], downloadCollectionFiles returned error state, message [" + return_ErrorMessage + "]");
                                                            if (string.IsNullOrEmpty(return_ErrorMessage))
                                                            {
                                                                return_ErrorMessage = statusMsg + ". The installation can not continue because there was an unknown error while downloading the necessary collection file, [" + ChildCollectionGUID + "].";
                                                            }
                                                            else
                                                            {
                                                                return_ErrorMessage = statusMsg + ". The installation can not continue because there was an error while downloading the necessary collection file, guid [" + ChildCollectionGUID + "]. The error was [" + return_ErrorMessage + "]";
                                                            }
                                                        }
                                                        else
                                                        {
                                                            LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, libraryCollectionLastChangeDate [" + libraryCollectionLastModifiedDate.ToString() + "].");
                                                            bool installDependentCollection = true;
                                                            var  localCollectionConfig      = CollectionFolderModel.getCollectionFolderConfig(core, ChildCollectionGUID);
                                                            if (localCollectionConfig == null)
                                                            {
                                                                //
                                                                // -- collection not installed, ok to install
                                                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, collection");
                                                            }
                                                            else
                                                            {
                                                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, localCollectionConfig.lastChangeDate [" + localCollectionConfig.lastChangeDate.ToString() + "].");
                                                                if (localCollectionConfig.lastChangeDate < libraryCollectionLastModifiedDate)
                                                                {
                                                                    //
                                                                    // -- downloaded collection is newer than installed collection, reinstall
                                                                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, **** local version is older than library, needs to reinstall.");
                                                                }
                                                                else
                                                                {
                                                                    //
                                                                    // -- download is older than installed, skip the rest of the xml file processing
                                                                    installDependentCollection = false;
                                                                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, **** local version is newer or the same as library, can skip install.");
                                                                    break;
                                                                }
                                                            }
                                                            if (installDependentCollection)
                                                            {
                                                                //
                                                                // -- install the downloaded file
                                                                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, collection missing or needs to be updated.");
                                                                if (!buildCollectionFoldersFromCollectionZips(core, contextLog, workingTempPath, libraryCollectionLastModifiedDate, ref collectionsDownloaded, ref return_ErrorMessage, ref collectionsInstalledList, ref collectionsBuildingFolder))
                                                                {
                                                                    LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, [" + statusMsg + "], BuildLocalCollectionFolder returned error state, message [" + return_ErrorMessage + "]");
                                                                    if (string.IsNullOrEmpty(return_ErrorMessage))
                                                                    {
                                                                        return_ErrorMessage = statusMsg + ". The installation can not continue because there was an unknown error installing the included collection file, guid [" + ChildCollectionGUID + "].";
                                                                    }
                                                                    else
                                                                    {
                                                                        return_ErrorMessage = statusMsg + ". The installation can not continue because there was an unknown error installing the included collection file, guid [" + ChildCollectionGUID + "]. The error was [" + return_ErrorMessage + "]";
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    } catch (Exception) {
                                                        //
                                                        // -- exception in try-finally for folder handling, just rethrow to the catch for hte method
                                                        throw;
                                                    } finally {
                                                        //
                                                        // -- remove child installation working folder
                                                        core.tempFiles.deleteFolder(workingTempPath);
                                                        //
                                                        // -- no longer building this folder
                                                        collectionsBuildingFolder.Remove(ChildCollectionGUID);
                                                    }
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    if (!string.IsNullOrEmpty(return_ErrorMessage))
                                    {
                                        //
                                        // -- if error during xml processing, skip the rest of the xml nodes and go to the next file.
                                        break;
                                    }
                                }
                            }
                            if (!string.IsNullOrEmpty(return_ErrorMessage))
                            {
                                //
                                // -- stop processing xml nodes if error
                                break;
                            }
                            //
                            // If the collection parsed correctly, update the Collections.xml file and exit loop
                            updateCollectionFolderConfig(core, Collectionname, collectionGuid, CollectionLastChangeDate, CollectionVersionFolderName);
                            break;
                        }
                        if (!string.IsNullOrEmpty(return_ErrorMessage))
                        {
                            //
                            // -- stop files if error
                            break;
                        }
                    }
                    //
                    // -- all files finished
                    if (string.IsNullOrEmpty(return_ErrorMessage) && !CollectionXmlFileFound)
                    {
                        //
                        // no errors, but xml file not found. Make an error
                        return_ErrorMessage = "<p>There was a problem with the installation. The collection zip was not downloaded successfully.</p>";
                    }
                } catch (Exception) {
                    throw;
                } finally {
                    //
                    // delete the tmp working folder
                    core.tempFiles.deleteFolder(tmpInstallPath);
                }
                //
                LogController.logInfo(core, MethodInfo.GetCurrentMethod().Name + ", BuildLocalCollectionFolder, Exiting with ErrorMessage [" + return_ErrorMessage + "]");
                //
                return(string.IsNullOrEmpty(return_ErrorMessage));
            } catch (Exception ex) {
                LogController.logError(core, ex);
                throw;
            } finally {
                contextLog.Pop();
            }
        }