/// <summary> /// Returns a list of available content templates for the specified contenttype under a given repository path. /// </summary> /// <typeparam name="T">Type that tells which types will be returned.</typeparam> /// <param name="contentTypeName">ContentTypeName that is searched for.</param> /// <param name="contextPath">A repository where templates are searched.</param> /// <returns>An IEnumerable list with the given types.</returns> public static IEnumerable <T> GetTemplatesForType <T>(string contentTypeName, string contextPath) where T : Node { var path = RepositoryPath.Combine(contextPath, contentTypeName); if (Providers.Instance.SearchManager.ContentQueryIsAllowed) { return (ContentQuery.Query(SafeQueries.InFolder, new QuerySettings { EnableAutofilters = FilterStatus.Disabled, EnableLifespanFilter = FilterStatus.Disabled }, path).Nodes.Where(ct => ct is T).Cast <T>()); } else { return(NodeQuery.QueryChildren(path).Nodes.Where(ct => ct is T).Cast <T>()); } }
protected virtual Content GetContextNode() { Node node = GetBindingRoot(); if (node == null) { throw new InvalidOperationException("BindingRoot cannot be null."); } node = AncestorIndex == 0 ? node : node.GetAncestor(AncestorIndex); if (!string.IsNullOrEmpty(RelativeContentPath)) { node = Node.LoadNode(RepositoryPath.Combine(node.Path, RelativeContentPath)); } return(Content.Create(node)); }
public static int GetCommentCount(int parentId) { var parent = NodeHead.Get(parentId); if (parent == null) { return(-1); } var commentFolderPath = RepositoryPath.Combine(parent.Path, "Comments"); var queryText = string.Format("+InFolder:\"{0}\" +Type:Comment .COUNTONLY", commentFolderPath); var settings = new QuerySettings { EnableAutofilters = false }; var result = ContentQuery.Query(queryText, settings); return(result.Count); }
/// <summary> /// Returns all members from workspace local groups /// </summary> public IEnumerable <IUser> GetWorkspaceMembers() { var members = new List <IUser>(); var groupFolderPath = RepositoryPath.Combine(this.Path, LocalGroupsFolderName); var settings = new SenseNet.Search.QuerySettings { EnableAutofilters = FilterStatus.Disabled }; var workspaceGroups = SenseNet.Search.ContentQuery.Query(SafeQueries.InTreeAndTypeIs, settings, groupFolderPath, typeof(Group).Name).Nodes; foreach (var group in workspaceGroups.OfType <IGroup>()) { members.AddRange(group.Members.OfType <IUser>()); } return(members.Distinct()); }
// ================================================================== Overridable methods public virtual Node GetCurrentSkin() { if (PortalContext.Current != null) { if (PortalContext.Current.ContextWorkspace != null && PortalContext.Current.ContextWorkspace.WorkspaceSkin != null) { return(PortalContext.Current.ContextWorkspace.WorkspaceSkin); } if (PortalContext.Current.Site != null && PortalContext.Current.Site.SiteSkin != null) { return(PortalContext.Current.Site.SiteSkin); } } var path = RepositoryPath.Combine(RepositoryStructure.SkinRootFolderPath, SkinConfig.DefaultSkinName); return(Node.LoadNode(path)); }
public void Invalidate(string appTypeName, string path) { if (locked) { return; } SnTrace.Repository.Write("ApplicationCache is invalidated. AppTypeName:{0}, Path:{1}", appTypeName, path); var cachePath = RepositoryPath.Combine(PersistentAppCacheFolderPath, appTypeName); var cacheFile = Node.Load <ApplicationCacheFile>(cachePath); if (cacheFile != null) { locked = true; cacheFile.ForceDelete(); locked = false; } }
/// <summary> /// Returns a list of available content templates for the specified contenttype under a given repository path. /// </summary> /// <typeparam name="T">Type that tells which types will be returned.</typeparam> /// <param name="contentTypeName">ContentTypeName that is searched for.</param> /// <param name="contextPath">A repository where templates are searched.</param> /// <returns>An IEnumerable list with the given types.</returns> public static IEnumerable <T> GetTemplatesForType <T>(string contentTypeName, string contextPath) where T : Node { var path = RepositoryPath.Combine(contextPath, contentTypeName); if (RepositoryInstance.ContentQueryIsAllowed) { return (ContentQuery.Query(string.Format("InFolder:\"{0}\"", path), new QuerySettings { EnableAutofilters = false, EnableLifespanFilter = false }).Nodes. Where(ct => ct is T).Cast <T>()); } else { return(NodeQuery.QueryChildren(path).Nodes.Where(ct => ct is T).Cast <T>()); } }
// =================================================================================== Events /// <summary> /// Checks whether the Move operation is acceptable by the current <see cref="DirectoryProvider"/>. /// The operation will be cancelled if it is prohibited. /// Do not use this method directly from your code. /// </summary> protected override void OnMoving(object sender, CancellableNodeOperationEventArgs e) { // AD Sync check var ADProvider = DirectoryProvider.Current; if (ADProvider != null) { var targetNodePath = RepositoryPath.Combine(e.TargetNode.Path, this.Name); var allowMove = ADProvider.AllowMoveADObject(this, targetNodePath); if (!allowMove) { e.CancelMessage = "Moving of synced nodes is only allowed within AD server bounds!"; e.Cancel = true; } } base.OnMoving(sender, e); }
public async Task Cors_HttpContext_PolicyFound() { await Test(async() => { // set allowed domains for test var setting = await Node.LoadAsync <Settings>( RepositoryPath.Combine(Repository.SettingsFolderPath, "Portal.settings"), CancellationToken.None); var currentSettingText = RepositoryTools.GetStreamString(setting.Binary.GetStream()); var newSettingText = EditJson(currentSettingText, @" { ""AllowedOriginDomains"": [ ""localhost:*"", ""*.sensenet.com"" ] } "); setting.Binary.SetStream(RepositoryTools.GetStreamFromString(newSettingText)); setting.Save(SavingMode.KeepVersion); // default settings support localhost and sensenet.com var p = await AssertOriginPrivate("localhost", true); Assert.IsTrue(p.SupportsCredentials); p = await AssertOriginPrivate("localhost:123", true); Assert.IsTrue(p.SupportsCredentials); p = await AssertOriginPrivate("example.sensenet.com", true); Assert.IsTrue(p.SupportsCredentials); await AssertOriginPrivate("sensenet.com", false); await AssertOriginPrivate("example.com", false); }); async Task <CorsPolicy> AssertOriginPrivate(string origin, bool expected) { var cpp = new SnCorsPolicyProvider(null); var context = new DefaultHttpContext(); context.Request.Headers["Origin"] = origin; var p = await cpp.GetPolicyAsync(context, SnCorsPolicyProvider.DefaultSenseNetCorsPolicyName); Assert.AreEqual(expected, p.Origins.Contains(origin)); return(p); } }
public async Task Upload_LowLevelApi() { var uploadRootPath = "/Root/UploadTests"; var uploadFolder = await Content.LoadAsync(uploadRootPath).ConfigureAwait(false); if (uploadFolder == null) { uploadFolder = Content.CreateNew("/Root", "SystemFolder", "UploadTests"); await uploadFolder.SaveAsync().ConfigureAwait(false); } //var file = Content.CreateNew(uploadFolder.Path, "File", Guid.NewGuid().ToString()); //await file.SaveAsync().ConfigureAwait(false); var fileName = Guid.NewGuid().ToString() + ".txt"; var uploadStream = Tools.GenerateStreamFromString(_fileContent); UploadData uploadData = new UploadData { FileName = fileName, ContentType = "File" }; // ACTION await RESTCaller.UploadAsync(uploadStream, uploadData, uploadFolder.Path).ConfigureAwait(false); // ASSERT var filePath = RepositoryPath.Combine(uploadRootPath, fileName); var content = await Content.LoadAsync(filePath).ConfigureAwait(false); string downloadedFileContent = null; await RESTCaller.GetStreamResponseAsync(content.Id, async response => { if (response == null) { return; } using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) using (var reader = new StreamReader(stream)) downloadedFileContent = reader.ReadToEnd(); }, CancellationToken.None).ConfigureAwait(false); Assert.AreEqual(_fileContent, downloadedFileContent); }
public void Content_CreateList() { string contentTypeName = "Automobile"; if (ContentTypeManager.Current.GetContentTypeByName(contentTypeName) == null) { ContentTypeInstaller.InstallContentType(AutomobileHandler.ExtendedCTD); } var idList = new List <int>(); for (int i = 1; i <= 5; i++) { string contentName = "AutoListItem" + i; SNC.Content auto = SNC.Content.Load(RepositoryPath.Combine(_testRoot.Path, contentName)); if (auto == null) { auto = SNC.Content.CreateNew(contentTypeName, _testRoot, contentName); } auto["Manufacturer"] = "Manuf" + i; auto.Save(); idList.Add(auto.Id); } //---- NodeQuery query = new NodeQuery(); query.Add(new TypeExpression(ActiveSchema.NodeTypes[contentTypeName])); query.Add(new StringExpression(StringAttribute.Name, StringOperator.StartsWith, "AutoListItem")); IEnumerable <SNC.Content> contentList = SNC.Content.Query(query); var contentListCount = contentList.ToList().Count; //---- foreach (var id in idList) { Node.ForceDelete(id); } //---- Assert.IsTrue(contentListCount == 5); }
// Creating test node private Page CreateTestPage() { string testPagePath = RepositoryPath.Combine(_rootNodePath, _pageName); if (Node.Exists(testPagePath)) { Node.ForceDelete(testPagePath); } //if (Node.Exists("/Root/TestPage")) // Node.DeletePhysical("/Root/TestPage"); Page f = new Page(Node.LoadNode(_rootNodePath)); f.Name = _pageName; f.PageTemplateNode = PageTemplate.LoadNode(_pageTemplatePath) as PageTemplate; f.Save(); return(f); }
// ================================================================================= Static API public static string GetActionLinkTemplate(string templateName) { using (new SystemAccount()) { // As this is an SN7 feature, we use TryResolve instead of Resolve because we // do not want to look for the path in the Global folder, only under skins. string actionTemplatePath; if (SkinManagerBase.TryResolve(RepositoryPath.Combine(ACTIONTEMPLATEFOLDERPATH, templateName), out actionTemplatePath)) { var template = Node.Load <HtmlTemplate>(actionTemplatePath); if (template != null) { return(template.TemplateText); } } } return(string.Empty); }
/// <summary> /// Retrieves likes for a given Content/Post/Comment /// </summary> /// <param name="parentId"></param> /// <returns></returns> public static QueryResult GetLikes(int parentId) { //var queryText = string.Format("+ParentId:{{{{+ParentId:\"{0}\" +Name:Likes}}}} +Type:Like", parentId); //var queryText = string.Format("+ParentId:\"{0}\" +Type:Like", parentId); var parent = NodeHead.Get(parentId); if (parent == null) { return(null); } var likeFolderPath = RepositoryPath.Combine(parent.Path, "Likes"); var queryText = string.Format("+InFolder:\"{0}\" +Type:Like", likeFolderPath); var result = ContentQuery.Query(queryText, new QuerySettings { EnableAutofilters = false }); return(result); }
public void Invalidate(string appTypeName, string path) { if (locked) { return; } Logger.WriteVerbose("ApplicationCache is invalidated.", Logger.EmptyCategoryList, new Dictionary <string, object> { { "AppTypeName", appTypeName }, { "Path", path } }); var cachePath = RepositoryPath.Combine(PersistentAppCacheFolderPath, appTypeName); var cacheFile = Node.Load <ApplicationCacheFile>(cachePath); if (cacheFile != null) { locked = true; cacheFile.ForceDelete(); locked = false; } }
/// <summary> /// Retrieves comments for a given Post/Content /// </summary> /// <param name="postid">Id of Post.</param> /// <returns></returns> public static QueryResult GetComments(int parentId) { var parent = NodeHead.Get(parentId); if (parent == null) { return(null); } var commentFolderPath = RepositoryPath.Combine(parent.Path, "Comments"); var settings = new QuerySettings { EnableAutofilters = FilterStatus.Disabled, Sort = new[] { new SortInfo("CreationDate", true) } }; var result = ContentQuery.Query("+InFolder:@0 +Type:Comment", settings, commentFolderPath); return(result); }
//================================================================================= Settings API (STATIC) /// <summary> /// Loads a settings content with a specified name (or relative path) from the Settings folder. /// </summary> /// <typeparam name="T">The settings type.</typeparam> /// <param name="settingsName">Name or relative path of the settings content.</param> /// <param name="contextPath">The content where the search for the setting will start.</param> /// <returns>Strongly typed settings content or null.</returns> public static T GetSettingsByName <T>(string settingsName, string contextPath) where T : Settings { if (string.IsNullOrEmpty(settingsName)) { throw new ArgumentNullException("settingsName"); } if (!string.IsNullOrEmpty(contextPath) && !contextPath.Equals(Repository.RootPath)) { // Try to load the settings content from the local Settings folder (e.g. '/Root/folder1/folder2/Settings/filename.settings'). // Use the node only if it is really a settings content (cannot use Node.Load<T> here because it throws an exception in case of a type mismatch). var node = Node.LoadNode(RepositoryPath.Combine(contextPath, SETTINGSCONTAINERNAME, settingsName + "." + EXTENSION)) as T; return(node ?? GetSettingsByName <T>(settingsName, RepositoryPath.GetParentPath(contextPath))); } //load settings from the global settings folder return(Node.Load <T>(RepositoryPath.Combine(SETTINGSCONTAINERPATH, settingsName + "." + EXTENSION))); }
private void HandleAuthorCheckoutDocument(HttpContext context) { var workspacePath = context.Request.Form["service_name"]; var documentPath = context.Request.Form["document_name"]; var nodePath = RepositoryPath.Combine(workspacePath, documentPath); // only open it, do not check it out. file is not yet checked in. it will be checked out via lists.asmx var file = Node.LoadNode(nodePath) as File; var metainfo = GetDocMetaInfo(file); var responseStr = GetFormattedString(string.Format(CHECKOUTDOCUMENTSTR, metainfo)); context.Response.Charset = ""; context.Response.ContentType = "application/x-vermeer-rpc"; context.Response.AddHeader("Content-Length", responseStr.Length.ToString()); context.Response.Write(responseStr); context.Response.Flush(); context.Response.End(); }
// ================================================================================= Settings API (STATIC) /// <summary> /// Loads a settings content with a specified name (or relative path) from the Settings folder. /// </summary> /// <typeparam name="T">The settings type.</typeparam> /// <param name="settingsName">Name or relative path of the settings content.</param> /// <param name="contextPath">The content where the search for the setting will start.</param> /// <returns>Strongly typed settings content or null.</returns> public static T GetSettingsByName <T>(string settingsName, string contextPath) where T : Settings { if (string.IsNullOrEmpty(settingsName)) { throw new ArgumentNullException(nameof(settingsName)); } try { return(SettingsCache.GetSettingsByName <T>(settingsName, contextPath) ?? Node.Load <T>(RepositoryPath.Combine(SETTINGSCONTAINERPATH, settingsName + "." + EXTENSION))); } catch (Exception ex) { SnTrace.System.WriteError($"Error loading setting: {settingsName}. {ex.Message}"); } return(null); }
private void WaitForMultipleTasksTest(int taskCount, bool waitForAll, string expectedMessage, params string[] taskResults) { Content content; var paths = new string[taskCount]; var tasks = new Node[taskCount]; for (int i = 0; i < paths.Length; i++) { var name = Guid.NewGuid().ToString(); paths[i] = RepositoryPath.Combine(TestRoot.Path, name); content = Content.CreateNew("ApprovalWorkflowTask", TestRoot, name); content.Save(); tasks[i] = content.ContentHandler; } var wfContent = new WaitForMultipleTasksWorkflow(TestRoot); wfContent.Tasks = tasks; wfContent.WaitForAll = waitForAll; wfContent.Save(); wfContent = Node.Load <WaitForMultipleTasksWorkflow>(wfContent.Id); InstanceManager.Start(wfContent); for (int i = 0; i < taskResults.Length; i++) { if (taskResults[i] != "no" && taskResults[i] != "yes") { continue; } var task = Node.LoadNode(paths[i]); task["Result"] = taskResults[i]; task.Save(); } string msg; if (!WfWatcher.WaitForFinished(out msg)) { Assert.Inconclusive("Workflow message was not received"); } Assert.IsTrue(msg == expectedMessage, String.Concat("Received message: '", msg, "'. Expected: '", expectedMessage, "'")); }
public override object Execute(Content content, params object[] parameters) { if (parameters.Length < 1) { throw new ArgumentException("Target path is missing."); } var nodePath = parameters[0] as string; var back = PortalContext.Current.BackUrl ?? "/"; var targetAppPath = RepositoryPath.Combine(nodePath, "(apps)"); var targetThisPath = RepositoryPath.Combine(targetAppPath, "This"); // we don't use the system account here, the user must have create rights here if (!Node.Exists(targetAppPath)) { var apps = new SystemFolder(Node.LoadNode(nodePath)) { Name = "(apps)" }; apps.Save(); } if (!Node.Exists(targetThisPath)) { var thisFolder = new Folder(Node.LoadNode(targetAppPath)) { Name = "This" }; thisFolder.Save(); } try { Node.Copy(content.Path, targetThisPath); } catch (Exception ex) { SnLog.WriteException(ex); } HttpContext.Current.Response.Redirect(back, true); return(null); }
public void Linq_MultiReference() { var path1 = TestRoot2.Path + "/Neighbor1"; var path2 = TestRoot2.Path + "/Neighbor2"; var names = new[] { "Mother1", "Mother2", "Child1", "Child2", "Child3" }; try { var node1 = Node.Load <RefTestNode>(path1); if (node1 == null) { node1 = new RefTestNode(TestRoot2); node1.Name = "Neighbor1"; node1.Save(); var refNodes = names.Select(n => Node.Load <RefTestNode>(RepositoryPath.Combine(TestRoot2.Path, n))).ToArray(); node1.Neighbors = refNodes; node1.Save(); } var node2 = Node.Load <RefTestNode>(path2); if (node2 == null) { node2 = new RefTestNode(TestRoot2); node2.Name = "Neighbor2"; node2.Save(); var refNodes = (new[] { "Mother1", "Child1" }).Select(n => Node.Load <RefTestNode>(RepositoryPath.Combine(TestRoot2.Path, n))).ToArray(); node2.Neighbors = refNodes; node2.Save(); } //-------- var child2 = Node.LoadNode(TestRoot2.Path + "/Child2"); var result = Content.All.DisableAutofilters().Where(c => ((RefTestNode)c.ContentHandler).Neighbors.Contains(child2)).ToArray(); Assert.IsTrue(result.Length == 1, String.Format("result.Length is {0}, expected: 1.", result.Length)); Assert.IsTrue(result.First().Name == "Neighbor1", String.Format("result.First().Name is {0}, expected: 'Neighbor1'.", result.First().Name)); } finally { Node.ForceDelete(path1); Node.ForceDelete(path2); } }
public static Handlers.ViewBase CopyViewLocal(string listPath, string viewPath, bool setAsDefault) { if (string.IsNullOrEmpty(listPath)) { throw new ArgumentNullException("listPath"); } if (string.IsNullOrEmpty(viewPath)) { throw new ArgumentNullException("viewPath"); } var viewName = RepositoryPath.GetFileNameSafe(viewPath); var viewsFolderPath = RepositoryPath.Combine(listPath, ViewManager.VIEWSFOLDERNAME); var views = Content.Load(viewsFolderPath) ?? Tools.CreateStructure(viewsFolderPath, "SystemFolder"); var viewsGc = views != null ? views.ContentHandler as GenericContent : null; //set at least the ListView type as allowed content type if (viewsGc != null && viewsGc.GetAllowedChildTypes().Count() == 0) { using (new SystemAccount()) { viewsGc.AllowedChildTypes = new[] { ContentType.GetByName("ListView") }; viewsGc.Save(SavingMode.KeepVersion); } } Node.Copy(viewPath, viewsFolderPath); var localView = Node.Load <Handlers.ViewBase>(RepositoryPath.Combine(viewsFolderPath, viewName)); if (setAsDefault) { var cl = Node.Load <ContentList>(listPath); if (cl != null) { cl.DefaultView = viewName; cl.Save(); } } return(localView); }
// Returns the folder (parent) as container of the VotingItems private Node GetFolder(Node contextNode) { var folderName = DateTime.Now.ToString("yyyy_MM_dd"); var folderPath = RepositoryPath.Combine(ContextNode.Path, folderName); using (new SystemAccount()) { // If Folder doesn't exists if (!Node.Exists(folderPath)) { var newFolder = Content.CreateNew("Folder", contextNode, folderName); newFolder.Fields["DisplayName"].SetData(folderName); newFolder.Fields["Name"].SetData(folderName); newFolder.Save(); return(newFolder.ContentHandler); } // Return existing Folder return(Node.LoadNode(folderPath)); } }
public void WF_WaitForMultipleContent_All() { Content content; var paths = new string[3]; var nodes = new Node[3]; for (int i = 0; i < paths.Length; i++) { paths[i] = RepositoryPath.Combine(TestRoot.Path, "Car" + i); if (Node.Exists(paths[i])) { Node.ForceDelete(paths[i]); } content = Content.CreateNew("Car", TestRoot, "Car" + i); content.Save(); nodes[i] = content.ContentHandler; } var wfContent = new WaitForMultipleContentWorkflow(TestRoot); wfContent.Triggers = nodes; wfContent.WaitForAll = true; wfContent.Save(); wfContent = Node.Load <WaitForMultipleContentWorkflow>(wfContent.Id); InstanceManager.Start(wfContent); for (int i = 0; i < paths.Length; i++) { var car = Node.LoadNode(paths[i]); car.Index++; car.Save(); } string msg; if (!WfWatcher.WaitForFinished(out msg)) { Assert.Inconclusive("#2"); } Assert.IsTrue(msg == "Finished", String.Concat("Received message: '", msg, "'. Expected: 'Finished'")); }
public void LockHandler_UnlockAndVersionRaising() { var folderName = "UnlockAndVersionRaising"; var contentName = "Car1"; var testRoot = Node.Load <Folder>(_rootNodePath); var folderPath = RepositoryPath.Combine(_rootNodePath, folderName); var folder = Node.Load <Folder>(folderPath); if (folder != null) { folder.ForceDelete(); } folder = new Folder(testRoot); folder.Name = folderName; folder.InheritableVersioningMode = ContentRepository.Versioning.InheritableVersioningType.MajorAndMinor; folder.Save(); List <VersionNumber> versions; var contentPath = RepositoryPath.Combine(folderPath, contentName); var content = Content.CreateNew("Car", folder, contentName); content.Save(); versions = Node.GetVersionNumbers(content.Id); content = Content.Load(contentPath); content.Publish(); content = Content.Load(contentPath); ((GenericContent)content.ContentHandler).CheckOut(); content = Content.Load(contentPath); content.Publish(); content = Content.Load(contentPath); ((GenericContent)content.ContentHandler).CheckOut(); content = Content.Load(contentPath); content.Publish(); }
// ================================================================== Helper methods private string ResolvePath(string relpath, string skinname, bool fallbackToRoot) { // absolute path is given: no fallback, no check if (IsNotSkinRelativePath(relpath)) { return(relpath); } var skinRelPath = TrimSkinPrefix(relpath); if (!string.IsNullOrEmpty(skinname)) { try { _skinMapLock.TryEnterReadLock(RepositoryEnvironment.DefaultLockTimeout); // look for the file under the current skin or the default skin var resolved = ResolvePathInternal(skinname, skinRelPath); if (!string.IsNullOrEmpty(resolved)) { return(resolved); } } finally { if (_skinMapLock.IsReadLockHeld) { _skinMapLock.ExitReadLock(); } } } // if fallback to root is not requested if (!fallbackToRoot) { return(string.Empty); } // backward compatibility: fallback to the global folder return(RepositoryPath.Combine(RepositoryStructure.SkinGlobalFolderPath, skinRelPath)); }
private static Node GetParent(Node contextNode) { var parent = Node.LoadNode(RepositoryPath.Combine(contextNode.Path, "Workflows/MailProcess")); if (parent == null) { var workflows = Node.LoadNode(RepositoryPath.Combine(contextNode.Path, "Workflows")); if (workflows == null) { using (new SystemAccount()) { workflows = new SystemFolder(contextNode); workflows.Name = "Workflows"; try { workflows.Save(); } catch (Exception ex) { Logger.WriteException(ex, ExchangeHelper.ExchangeLogCategory); return(null); } } } using (new SystemAccount()) { parent = new SenseNet.ContentRepository.Folder(workflows); parent.Name = "MailProcess"; try { parent.Save(); } catch (Exception ex) { Logger.WriteException(ex, ExchangeHelper.ExchangeLogCategory); return(null); } } } return(parent); }
public void Path_Combine_1() { var val = RepositoryPath.Combine("/Root1"); Assert.AreEqual("/Root1", val); val = RepositoryPath.Combine("/Root", "AAA", "BBB"); Assert.AreEqual("/Root/AAA/BBB", val); val = RepositoryPath.Combine("/Root", "/AAA", "BBB/"); Assert.AreEqual("/Root/AAA/BBB/", val); val = RepositoryPath.Combine("/Root/", "AAA/", "/BBB"); Assert.AreEqual("/Root/AAA/BBB", val); val = RepositoryPath.Combine("/Root", "/", "BBB"); Assert.AreEqual("/Root/BBB", val); val = RepositoryPath.Combine("/Root", "", "BBB"); Assert.AreEqual("/Root/BBB", val); }
/// <summary> /// Creates a new Like for the given Post/Content/Comment /// </summary> /// <param name="clientId"></param> /// <param name="contextPath">New posts from journal items will be created under contextPath</param> /// <returns></returns> public static void CreateLike(string clientId, string contextPath, out int postId) { var likedContent = GetPostFromId(clientId, contextPath); var likesFolder = Node.LoadNode(RepositoryPath.Combine(likedContent.Path, "Likes")) as GenericContent; if (likesFolder == null) { likesFolder = new SystemFolder(likedContent) as GenericContent; likesFolder.Name = "Likes"; likesFolder.Hidden = true; likesFolder.Save(); } var likeContent = new GenericContent(likesFolder, "Like"); likeContent.Save(); // return postId, as it will be used for LikeList and LikeMarkup postId = likedContent.Id; }