Automated website deployment with PowerShell and SmartFTP

by Shannon Deminick 2. September 2010 07:56

SmartFTP is a fantastic FTP application which handles syncing files very effectively. This means that when you upload your entire website, SmartFTP will automatically detect changes and only upload what is required (instead of overwriting all of the files like some FTP applications do). For each project at TheFARM we have build scripts which run and create a time stamped ZIP package for each deployment environment with all of the necessary files formatted appropriately for each. Our deployment process then involves unzipping the contents of this file, opening up SmartFTP, connecting to the deployment destination and transfering all of the deployment files up (which SmartFTP synchronizes for us).

I thought it would be much more efficient if we automated this process. So we did some investigation and it turns out the SmartFTP conveniently has an API! So we decided to see if we could write a PowerShell script to use the SmartFTP api to automagically transfer/sync all of our deployment files in our Zip package to the necessary FTP site and with a bit of trial and error we managed to do it! Now, I’m not PowerShell expert or anything, and in fact this was my very first PowerShell script ever written so I’m sure this could all be done a bit better, but it works! I’m not going to go into detail about the SmartFTP api or how to write PowerShell stuff because this script will work with some basic requirements:

  • You need both PowerShell and SmartFTP installed
  • Currently this only supports the standard FTP protocol, but if you need SFTP, etc… you can just change the $fav variable’s ‘Protocol’ property
  • The parameters, in this order are:
    • destination
      • the IP address, or host of your FTP server
    • user
      • the username used to login to the FTP server
    • password
      • the password used to login to the FTP server
    • path
      • The FTP path of where you want your files to go on your FTP server
    • port
      • The FTP port to use, default is 21
    • source
      • The source folder to copy to the FTP site, if not specified, uses the current directory that the PowerShell script is run from

Example usage:

FTPSync.ps1 123.123.123.123 MyUserName MyPassword 21 “C:\MyWebsiteFolder” “/websites/MyWebsite”

or you can just double click on the ps1 file and it will prompt you for these details.

So without further adieu, here’s the script!

#requires -version 2.0 # Define inputs param ( [parameter(Mandatory=$true)] [string] $dest, [parameter(Mandatory=$true)] [string] $user, [parameter(Mandatory=$true)] [string] $pass, [parameter(Mandatory=$true)] [ValidatePattern('\d+')] [int] $port = 21, [parameter(Mandatory=$false)] [ValidateScript({ Test-Path -Path $_ -PathType Container })] [string] $source, [parameter(Mandatory=$true)] [ValidatePattern('\/+')] [string] $path ) # get current folder $currFolder = (Get-Location -PSProvider FileSystem).ProviderPath; # set current folder [Environment]::CurrentDirectory=$currFolder; # if the source isn't set, then use the current folder if ($source = "") { $source = $currFolder; } Write-Host "------------------------------------------------------" -foregroundcolor yellow -backgroundcolor black Write-Host("{0, -20}{1,20}" -f "Destination", $dest); Write-Host("{0, -20}{1,20}" -f "User", $user); Write-Host("{0, -20}{1,20}" -f "Pass", "********"); Write-Host("{0, -20}{1,20}" -f "Port", $port); Write-Host ""; Write-Host "Source:"; Write-Host $source; Write-Host ""; Write-Host "Path"; Write-Host $path; Write-Host "------------------------------------------------------" -foregroundcolor yellow -backgroundcolor black # Create application $smartFTP = New-Object -comObject SmartFTP.Application; $smartFTP.Visible = [bool]0; $smartFTP.CloseAll(); # create temp favorite item $fav = $smartFTP.CreateObject("sfFavorites.FavoriteItem"); $fav.Name = $user + " @ " + $dest + " (temp favorite by cmdInterface)"; # 1 = FTP standard protocol $fav.Protocol = 1; $fav.Host = $dest; $fav.Port = $port; $fav.Path = $path; $fav.Username = $user; $fav.Password = $pass; # forces it not to be saved $fav.Virtual = "true"; # Add temporary favorite to SmartFTPs FavoriteManager $favMgr = $smartFTP.FavoritesManager; $rootFolder = $favMgr.RootFolder; $rootFolder.AddItem($fav); # Get the transfer queue $queue = $smartFTP.TransferQueue; # stop the queue if it isn't already if ($queue.State -ne 1) { $queue.Stop(); } # Stopped = 1 # clear the queue foreach($item in $queue.Items) { $queue.RemoveItem($item); } # set the thread count for the queue $queue.MaxWorkers = 20; #enable logging $queue.Log = "true"; $queue.LogFolder = $currFolder + "\\LOG"; # create new transfer item $newItem = $smartFTP.CreateObject("sfTransferQueue.TransferQueueItem"); # set the item as a folder and copy operation, $newItem.type = 2; #FOLDER = 2 $newItem.Operation = 1; #COPY = 1 # Set the source $newItem.Source.type = 1; #LOCAL = 1 $newItem.Source.Path = $source; # Set the destination $newItem.Destination.type = 2; #REMOTE = 2 $newItem.Destination.Path = $path; $newItem.Destination.FavoriteIdAsString = $fav.IdAsString; #links up to our connection favorite # and finally add it $queue.AddItemTail($newItem); Write-Host "STARTING" -foregroundcolor yellow -backgroundcolor black; $queue.Start(); while ($queue.Items.Count -ne 0) { Write-Host "Processing...bytes transfered: " $queue.TransferredBytes; Start-Sleep -s 2; #wait 2 seconds } # store the total bytes $totalBytes = $queue.TransferredBytes; # cleanup smartftp app $queue.Quit(); $smartFTP.Exit(); # parse logs # regex to find "[DATE/TIME] STOR FILENAME # which indicates a file transfer $regex = new-object System.Text.RegularExpressions.Regex("\[[\w\-\:]*?\]\sSTOR\s(.+?)\[",,[System.Text.RegularExpressions.RegexOptions]::SingleLine); $totalFiles = 0; Write-Host "Files Transfered" -foregroundcolor cyan -backgroundcolor black Get-ChildItem $queue.LogFolder -include *.log -Recurse | foreach ($_) { $currFile = Get-Content $_.fullname; $match = $regex.Matches($currFile); if ($match.Count -gt 0) { foreach($m in $match) { Write-Host $m.Groups[1]; } $totalFiles++; } remove-item $_.fullname -Force -Recurse ; } Write-Host "COMPLETED (total bytes: " $totalBytes ", total files: )" $totalFiles -foregroundcolor cyan -backgroundcolor black; "------------------------------------------------------" # cleanup COM Remove-Variable smartFTP

Examine RC3 Released

by Shannon Deminick 18. August 2010 18:30

Hopefully this will be a quick RC! I’m really hoping to release v1.0 RTM by early next week (latest). If you are able to help out with some testing it would be amazing!!

Here's what's new:

  • PDF Indexing
  • Easily implement custom data indexing outside of Umbraco
  • More XSLT Extensions for Umbraco
  • Some framework refactoring so a new DLL: Examine.LuceneEngine.dll which contains all of the Lucene.Net implementation
    • Because of this refactoring, if you've built your own providers, you may need to update our code to work, otherwise it is backwards compatible for most people.
  • More unit tests
  • More documentation

Get it while it’s hot! And don’t forget to read the release notes.

DOWNLOAD FROM CODEPLEX HERE

Categories: Examine | Umbraco

Using Examine to index & search with ANY data source

by Shannon Deminick 10. August 2010 10:38

During CodeGarden 2010 a few people were asking how to use Examine to index and search on data from any data source such as custom database tables, etc… Previously, the only way to do this was to override the Umbraco Examine indexing provider, remove the Umbraco functionality embedded in there, and then do a lot of coding yourself.  …But now there’s some great news! As of now you can use all of the Examine goodness with it’s embedded Lucene.Net with any data source and you can do it VERY easily.

Some things you need to know about the new version:

  1. I haven’t made a release version of this yet as it still needs some more testing, though we are putting this into a production site next week.
  2. If you want to try this, currently you’ll need to get the latest source from Examine @ CodePlex
  3. If you are using a previous version of Examine, there’s a few breaking changes as some of the class structures have been moved, however you config file should still work as is… HOWEVER, you should update your config file to reflect the new one with the new class names
  4. There is now 3 DLLs, not just 2:
    • Examine.DLL
      • Still pretty much the same… contains the abstraction layer
    • Examine.LuceneEngine.DLL
      • The new DLL to use to work with data that is not Umbraco specific
    • UmbracoExamine.DLL
      • The DLL that the Umbraco providers are in

Ok, now on to the good stuff. First, I’ve added a demo project to this post which you can download HERE. This project is a simple console app that contains a sample XML data file that has 5 records in it. Here’s what the app does:

  1. This re-indexes all data
  2. Searches the index for node id 1
  3. Ensures one record is found in the index
  4. Updates the dateUpdated time stamp for the data record
  5. Re-indexes the record with node id 1’

So assuming that you have some custom data like a custom database table, xml file, or whatever, there’s really only 3 things that you need to do to get Examine indexing your custom data:

  1. Create your own ISimpleDataService
    • There is only 1 method to implement: IEnumerable<SimpleDataSet> GetAllData(string indexType)
    • This is the method that Examine will call to re-index your data
    • A SimpleDataSet is a simple object containing a Dictionary<string, string> and a IndexedNode object (which consists of a Node Id and a Node Type)
    • For example, if you had a database row, your SimpleDataSet object for the row would be the dictionary of the rows values, it’s node id and type … easy.
  2. Use the ToExamineXml() extension method to re-index individual nodes/records
    • Examine relies on data being in the same XML structure as Umbraco (which we might change in version 2 sometime in the future… like next year) so we need to transform simple data into the XML structure. We’ve made this quite easy for you; all you have to do is get the data from your custom data source into a Dictionary<string, string> object and use this extension method to pass the xml structure in to Examine’s ReIndexNode method.
    • For example: ExamineManager.Instance.ReIndexNode(dataSet.ToExamineXml(dataSet["Id"], "CustomData"), "CustomData");  where dataSet is a Dictionary<string, string> .
  3. Update your Examine config to use the new SimpleDataIndexer index provider and the new LuceneSearcher search provider

If you’re not using Umbraco at all, then you’ll only need to have the 2 Examine DLLs which don’t reference the Umbraco DLLs whatsoever so everything is decoupled.

I’d recommend downloading the demo app and running it as it will show you everything you need to know on how to get Examine running with custom data. However, i know that people just like to see code in blog posts, so here’s the config for the demo app:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="Examine" type="Examine.Config.ExamineSettings, Examine"/> <section name="ExamineLuceneIndexSets" type="Examine.LuceneEngine.Config.IndexSets, Examine.LuceneEngine"/> </configSections> <Examine> <ExamineIndexProviders> <providers> <!-- Define the indexer for our custom data. Since we're only indexing one type of data, there's only 1 indexType specified: 'CustomData', however if you have more than one type of index (i.e. Media, Content) then you just need to list them as a comma seperated list without spaces. The dataService is how Examine queries whatever data source you have, in this case it's a custom data service defined in this project. A custom data service only has to implement one method... very easy. --> <add name="CustomIndexer" type="Examine.LuceneEngine.Providers.SimpleDataIndexer, Examine.LuceneEngine" dataService="ExamineDemo.CustomDataService, ExamineDemo" indexTypes="CustomData" runAsync="false"/> </providers> </ExamineIndexProviders> <ExamineSearchProviders defaultProvider="CustomSearcher"> <providers> <!-- A search provider that can query a lucene index, no other work is required here --> <add name="CustomSearcher" type="Examine.LuceneEngine.Providers.LuceneSearcher, Examine.LuceneEngine" /> </providers> </ExamineSearchProviders> </Examine> <ExamineLuceneIndexSets> <!-- Create an index set to hold the data for our index --> <IndexSet SetName="CustomIndexSet" IndexPath="App_Data\CustomIndexSet"> <IndexUserFields> <add Name="name" /> <add Name="description" /> <add Name="dateUpdated" /> </IndexUserFields> </IndexSet> </ExamineLuceneIndexSets> </configuration>
Categories: .Net | Examine | Umbraco

TheFARM needs senior .Net developer!

by Shannon Deminick 5. August 2010 05:50

TheFARM is currently looking for a talented and passionate senior .Net developer. Someone that has a minimum of 4 years ASP.Net development experience, stays up to date with the latest technologies, and actually loves to program. Skill set should include:

  • Expert knowledge of .Net from v2 up to v4
  • Experience with common patterns and practices including Dependency Injection
  • JavaScript, JQuery, AJAX, and everything else to do with client side web programming… yes, you’ll still have to write some CSS and HTML
  • ASP.Net MVC 2+
  • We are an Umbraco CMS development agency so if you’ve used it before, it would be of huge benefit, otherwise be prepared for extensive training
  • … and lots, lots more ;)

If you think you would be suitable for this role, we would love to hear from you! Please email us your CV/Resume to: Work@thefarmdigital.com.au

Tags: , ,

Adding embedded resource with ClientDependency

by Shannon Deminick 3. August 2010 05:32

The uComponents project for Umbraco is coming along rather nicely! So far there are 13 new data types created and a few extensions, hopefully soon we’ll have a package ready to go. In the meantime, I thought I’d share a nice little code snippet that we’re using this throughout uComponents that allows you to add embedded resources to ClientDependency. It’s pretty easy and works perfectly with Umbraco 4.5 or any other site you have running ClientDependency. This will ensure that embedded resources (JavaScript or CSS) are added to the ClientDependency combined scripts/styles and also compressed and cached.

First, I’ll show you how to register your embedded resources using our extension method class (for a Control object):

this.AddResourceToClientDependency(
    "DataTypesForUmbraco.Controls.Shared.Resources.PrevalueEditor.css", 
    ClientDependency.Core.ClientDependencyType.Css);

The above code assumes:

  • The class that you are consuming the code inherits from System.Web.UI.Control
  • That your embedded resource’s path is: DataTypesForUmbraco.Controls.Shared.Resources.PrevalueEditor.css
  • That your embedded resource is a CSS type

Pretty easy right!! Well, the only thing missing is that you’ll need to add our extension method class to your project which looks like this:

/// 
/// Extension methods for embedded resources
/// 
public static class ResourceExtensions
{

    /// 
    /// Adds an embedded resource to the ClientDependency output by name
    /// 
    /// 
    /// 
    /// 
    public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type)
    {
        //get the urls for the embedded resources           
        var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(ctl.GetType(), resourceName);

        //add the resources to client dependency
        ClientDependencyLoader.Instance.RegisterDependency(resourceUrl, type);
    }

    /// 
    /// Adds an embedded resource to the ClientDependency output by name and priority
    /// 
    /// 
    /// 
    /// 
    public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type, int priority)
    {
        //get the urls for the embedded resources           
        var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(ctl.GetType(), resourceName);

        //add the resources to client dependency
        ClientDependencyLoader.Instance.RegisterDependency(priority, resourceUrl, type);
    }

}

So basically, if you have a Control, you can register your embedded resources in ClientDependency with one line of code… sweeeeet.

Categories: .Net | ClientDependency

Examine demo site source code from CodeGarden 2010

by Shannon Deminick 1. July 2010 17:49

A few people were asking for the source code from my Examine presentation at CodeGarden, so here it is. I’m not going to go in to all of the details of this site or the Examine config as it’s pretty simple. However, i will give you a very quick run down of it and if you attended CodeGarden and my presentation, you’d probably already know this.

The Umbraco config for this demo site is simple: A search form, a couple of search result pages with different templates (results using XSLT extensions, results to query media using the FluentAPI, custom results using the FluentAPI). Then there’s the content: 5 very simple nodes consisting of a text field and a numeric field and a miniature blog with some posts and comments.

I’ve included all of the source files and a backup of the database that it was running on. The source files are left in the same state as we left the demo during the presentation. So to get it up and running, just restore the database to your MS SQL server, update your web.config, and put the project files into IIS (or open the solution in Visual Studio).

Download here

Categories: .Net | Examine | Umbraco

Examine slide deck for CodeGarden 2010

by Shannon Deminick 29. June 2010 16:55

A few people had asked during CodeGarden 2010 if I would post up the slide deck for my Examine presentation, so here it is. There’s not a heap of information in there since i think people would have soaked up most of the info during the examples and coding demos but it’s posted here regardless and hopefully it helps a few people.

I’ve included a PDF version (link at the bottom) and also the image version below (if you’re too lazy to download it :)

Slide2 Slide3 Slide4 Slide5 Slide6 Slide7 Slide8 Slide9 Slide10 Slide11 Slide12 Slide13 Slide14 Slide15

Download slide deck here

Categories: Examine | .Net | Umbraco

Multi-node tree picker source code from CodeGarden 2010

by Shannon Deminick 29. June 2010 14:54

If you missed out on CodeGarden 2010 this year then you definitely missed one heck of a conference! If you want to read more about what happened you can check out these posts here:

This post is about the data type I presented during the Umbraco package competition (which ended up winning too! :). It’s a multi-node picker with the full tree interface to allow you to select the nodes you want. It’s also sort-able with drag/drop functionality.

image

It’s a very simple control but has the capability to be made into a very awesome data type which is why I’m starting up a new CodePlex project called: Data Types for Umbraco (found here). I’m hoping that people in the Umbraco community will want to become developers on this project so a bunch of us can collaborate to create some seriously amazing data types for Umbraco 4.5. Please let me know if you want to contribute to this project as i think it could have huge potential. Instead of everyone creating their own closed source data types and developing them all in different ways, this would help unify and standardize the way we create data types.

So the first thing I will put up there is the full source for this data type as it was meant to be. However, I’m not going to get around to that today, so in the meantime I’ve put the source for this control right here. Remember, this is not really the best way to make this data type but it will give you a good indication of how to use the new JavaScript tree API and how to build a simple UserControl data type.

Enjoy!

ASCX Code

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TreePicker.ascx.cs"
    Inherits="ExamineDemo1.usercontrols.TreePicker" %>
<%@ Register TagPrefix="umb" TagName="tree" Src="~/umbraco/controls/Tree/TreeControl.ascx" %>
<script type="text/javascript">

//a reference to the hidden field
//storing the selected node data
var hiddenField = jQuery("#<%=PickedNodes.ClientID%>");

//create a sortable, drag/drop list and
//initialize the right panel with previously
//saved data.
jQuery(document).ready(function () {
    jQuery(".right").sortable({
        stop: function (event, ui) { StorePickedNodes(); }
    });
    jQuery(".item a.close").live("click", function () {
        jQuery(this).parent().remove();
    });

    //now rebuild the selected items
    try {
        var json = eval('(' + hiddenField.val() + ')');
        jQuery(".right").html(unescape(json.markup));
        StorePickedNodes();
    }
    catch (err) { };
});

//Add event handler to the tree API.
//Bind to the window load event as the document ready event
//is too early to query for the tree api object
jQuery(window).load(function () {
    //add a handler to the tree's nodeClicked event
    jQuery("#<%=TreePickerControl.ClientID%>")
        .UmbracoTreeAPI()
        .addEventHandler("nodeClicked", function (e, node) {
            AddToRight(node);
    });
});

function AddToRight(node) {
    //get the node id of the node selected
    var nodeId = jQuery(node).attr("id");
    //check if node id already exists in the right panel
    if (jQuery(".right").find("li[rel='" + nodeId + "']").length > 0) {
        return;
    }
    //create a copy of the node clicked on the tree
    var jNode = jQuery(node).clone().find("a:first")
    //remove un-needed attributes
    jNode.removeAttr("href")
        .removeAttr("umb:nodedata")
        .attr("href", "javascript:SyncItems(" + nodeId + ");");
    //build a DOM object to put in the right panel
    jQuery("<div class='item'><ul class='rightNode'>" +
            "<li rel='" + nodeId + "' class='closed'>" +
            "</li></ul><a class='close' href='javascript:void(0);'>[X]</a></div>")
        .appendTo(".right")
        .find(".closed").append(jNode);
    //now update the hidden field with the
    //node selection
    StorePickedNodes();
}

//A method to sync the left tree to the item
//selected in the right panel
function SyncItems(nodeId) {
    jQuery("#<%=TreePickerControl.ClientID%>")
        .UmbracoTreeAPI()
        .syncTree(nodeId.toString());
}

//were going to store both the node ids
//and the html markup to re-render the 
//right hand column as JSON to be put into
//the database.
function StorePickedNodes() {
    var val = "[";
    jQuery(".right .item ul.rightNode li").each(function () {
        val += jQuery(this).attr("rel") + ",";
    });
    if (val != "[") val = val.substr(0, val.length - 1);
    val += "]";
    //append the html markup
    var obj = "{ \"val\": " + val + ", \"markup\": \"" + escape(jQuery(".right").html()) + "\"}";
    hiddenField.val(obj);       
}

</script>

<%--Inline styles are dodgy, but simple for
this demonstration--%>

<style type="text/css">
.multiTreePicker .item ul.rightNode 
{
    float:left;
    margin:0;
    padding:0;    	
}
.multiTreePicker .item ul.rightNode li
{
    margin:0;
    padding: 0;
    list-style:none;
    font:icon;
    font-family:Arial,Lucida Grande;
    font-size:12px;
    min-height:20px;
}
.multiTreePicker .item ul.rightNode li a
{
    background-repeat:no-repeat !important;
    border:0 none;
    color:#2F2F2F;
    height:18px;
    line-height:18px;
    padding:0 0 0 18px;
    text-decoration:none;
}
.multiTreePicker .item a
{
    float:left;
}   
.multiTreePicker .item a.close 
{
    margin-left:5px;
}
.multiTreePicker .item
{
    cursor: pointer;
    width:100%;
    height:20px;
}
.multiTreePicker .left.propertypane
{
    width: 300px;
    float: left;
    clear:none;
    margin-right:10px;
}
.multiTreePicker .right.propertypane
{
    width: 300px;
    float: left;
    clear:right;
    padding:5px;
}
.multiTreePicker .header
{
    width:622px;
}
   
</style>

<div class="multiTreePicker">
    <div class="header propertypane">
        <div>Select items</div>
    </div>
    <div class="left propertypane">        
        <umb:tree runat="server" ID="TreePickerControl" 
            CssClass="myTreePicker" Mode="Standard" 
            DialogMode="id" ShowContextMenu="false" 
            IsDialog="true" TreeType="content" />
    </div>
    <div class="right propertypane">
    </div>
</div>

<asp:HiddenField runat="server" ID="PickedNodes" />

C# Code Behind


public partial class TreePicker : 
    System.Web.UI.UserControl, IUsercontrolDataEditor
{
        


    #region IUsercontrolDataEditor Members

    public object value
    {
        get
        {
            //put the node in umbraco
            return PickedNodes.Value;
        }
        set
        {
            //get from umbraco
            PickedNodes.Value = value.ToString();
        }
    }

    #endregion
}
Categories: .Net | Umbraco

Umbraco 4.1 Database Structure

by Shannon Deminick 15. June 2010 14:38

We’re finally shipping Umbraco 4.1 with all of the real database constraints, indexes and keys that it so much deserves! This issue was reported on over 3 years ago (http://umbraco.codeplex.com/workitem/8162) and it’s now a reality! So without further adieu, here’s the complete database diagram. If you stare at it long enough you might notice some constraints missing which may be true, but this is by design (I assure you :). I’ve attempted to compact the diagram to as small as possible but no matter which way you cut it, it’s a bit crazy. Enjoy! (click the image to see the full size)

 

image

Categories: Umbraco | .Net

100 Unit tests in Umbraco 4.1

by Shannon Deminick 14. June 2010 19:14

Well, hopefully there’ll be even more before the final release of 4.1 but as of tonight, there’s an even 100 written and passing! Most of these have to do with the data layer as we’ve implemented all of the proper database constraints, keys and indexes for 4.1! Here’s the full list of tests for those interested:

  • Application_Create_New_User_Assign_Application_And_Delete_User
  • Application_Make_New
  • Application_Make_New_Assign_User_And_Delete
  • ApplicationTree_Make_New_Then_Delete_App
  • DataTypeDefinition_Assign_Data_Type_To_Doc_Type_Then_Create_Doc_And_Set_Value
  • DataTypeDefinition_Assign_Data_Type_With_PreValues
  • DataTypeDefinition_Make_New
  • Dictionary_Attempt_Duplicate_Key
  • Dictionary_Change_Key
  • Dictionary_Contructor_Guid
  • Dictionary_Contructor_Key
  • Dictionary_Create_Add_Text_And_Delete
  • Dictionary_Delete_Parent_With_Children
  • Dictionary_Get_Top_Level_Items
  • Dictionary_IsTopMostItem
  • Dictionary_Parent_Child_Relationship
  • Dictionary_ToXml
  • Document_Assign_Domain
  • Document_Copy
  • Document_Copy_And_Relate
  • Document_Delete_All_Docs_By_Document_Type
  • Document_Delete_Heirarchy_Permanently
  • Document_Empty_Recycle_Bin
  • Document_Make_New
  • Document_Make_New_And_Publish
  • Document_Move
  • Document_Publish_Then_UnPublish
  • Document_Publish_With_Result
  • Document_Publish_With_Subs
  • Document_Regenerate_Previews
  • Document_RePublish_All
  • Document_Save_And_Publish_Then_Roll_Back
  • Document_To_Preview_Xml
  • Document_Undelete
  • DocumentType_Add_Properties_To_Tab_Then_Delete_It
  • DocumentType_Delete_Doc_Type_With_Content
  • DocumentType_Delete_Doc_Type_With_Content_And_Children_Of_Different_Doc_Types
  • DocumentType_Get_All
  • DocumentType_Has_Children
  • DocumentType_Make_New
  • IOHelper_MapPathTestVDirTraversal
  • Language_Delete_Default_Language
  • Language_Delete_With_Assigned_Dictionary_Items
  • Language_Delete_With_Assigned_Domain
  • Language_Get_By_Culture_Code
  • Language_GetAll
  • Language_Make_Duplicate
  • Language_Make_New
  • Language_To_Xml
  • Macro_Make_New
  • Macro_Make_New_Add_Property
  • Macro_Not_Found_Constructor
  • MacroProperty_Not_Found_Constructor
  • Media_Delete_All_Docs_By_Document_Type
  • Media_Delete_Heirarchy_Permanently
  • Media_Empty_Recycle_Bin
  • Media_Make_New
  • Media_Move
  • Media_Undelete
  • Media_Update_Data
  • MediaType_Add_Properties_To_Tab_Then_Delete_It
  • MediaType_Delete_Media_Type_With_Media_And_Children_Of_Diff_Media_Types
  • MediaType_Get_All
  • Member_Add_To_Group
  • Member_Make_New
  • MemberGroup_Add_Member_To_Group_And_Delete_Group
  • MemberGroup_Make_New
  • MembershipProvider_Create_User
  • MembershipProvider_Create_User_Assign_New_Role
  • MemberType_Delete_With_Assigned_Members
  • MemberType_Make_New
  • Notification_Assign_To_New_Node_Then_Delete_Node
  • Notification_Assign_To_New_User_Then_Delete_User
  • Notification_Make_New
  • Permission_Assign_To_New_Node_Then_Delete_Node
  • Permission_Assign_To_New_User_Then_Delete_User
  • Permission_Make_New
  • PropertyType_Make_New
  • Relation_Make_New
  • Relation_Relate_Docs_And_Delete_Parent
  • StyleSheet_Make_New
  • StyleSheet_Make_New_AddProperty
  • Tag_Add_Tags_To_Node
  • Tag_Make_New
  • Tag_Make_New_Assign_Node_Delete_Node
  • Task_Assign_To_New_Node_Delete_Node_And_Ensure_Tasks_Removed
  • Task_Make_New_And_Close
  • Task_Not_Found_Constructor
  • TaskType_Make_Duplicate
  • TaskType_Make_New_Assign_Tasks_And_Remove
  • TaskType_Not_Found_Constructor1
  • TaskType_Not_Found_Constructor2
  • Template_Assign_To_Document_And_Delete
  • Template_Make_New
  • Template_Make_New_With_Master_And_Remove_Heirarchy_And_Delete
  • User_Delete_Admin_Not_Allowed
  • User_Make_New_Duplicate_Login
  • User_Make_New_Override1
  • User_Make_New_Override2
  • User_Not_Found_Constructor
Categories: Umbraco | .Net