Friday 21 December 2012

Workflow email task Link

So you've created a work flow in SharePoint Designer and now you want to let someone know they have a task, but you don't want to just tell them that they have a task and go find it you want to send them a link to the task. Let's face it odds are they're a middle tier manager who's responsibility extends to approving business card request and paid time off; a B.Com degree paying off.

So let's pretend that you have a workflow already set up and all you want to do is create this assignment email: 
In SharePoint Destroyer Designer navigate to your workflows

once you've selected your work flow, edit it.


now that you're ready to edit your work flow, add a step and inside that step create a "start custom task process" action. In the picture below the task is called "Business Card request Task" this is a name I gave it, originally it should start as "Task".


once you've opened the task, under Customization click "Change the behaviour of a single task"


this will load 5 default steps
  1. Before a task is assigned
  2. when a task is pending
  3. when a task expires
  4. when a task is deleted
  5. when a task is completed
You are concerned with the second one "Pending". Add the action email user.


Once you select the user add the appropriate fields


To Create the link address click the link button circled in green above.


Click the fx button to build the URL for your link

Select the current task, and pick the Form_URN, this will give you the task item url

Keep hitting ok followed by a publish and give it a try.

Wednesday 19 December 2012

Find Text on Publishing Page

Sometimes you need to find a specific text string on your site, maybe it's a common typo, or it could be a name change lets say mr Chooch turned into Dr Chooch and you want to know all the pages that Mr Chooch appears on.


param($web_app_url=$(read-host "Please provide web app url of the list to be delete (EG:'http://SSRAP1'):"))

$TextToFind = $(read-host "Please Provide the text to find")
 
if($ListToDelete -eq $null -or $ListToDelete -eq '')
{
    throw "You must specify a text string to search for"
}

function LoadSharePointPowerShellEnviroment
{
write-host "Setting up Powershell enviroment for Sharepoint" -foregroundcolor Blue
Add-PSSnapin "Microsoft.Sharepoint.PowerShell" -ErrorAction SilentlyContinue
Write-host "Sharepoint PowerShell Snapin loaded." -foregroundcolor Green
}

function ScrubPages($nodeWeb2)
{
    $pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($nodeWeb2)
   
    try
    {
        $pubPages = $pubWeb.GetPublishingPages($pubWeb)
        foreach($pp in $pubPages)
        {
            $content = $pp.ListItem["Page Content"]
       
            if($content -ne $null)
            {
                if ($content.Contains($TextToFind))
                {
                    $data = @{"url" = $pubWeb.url.ToString() + "/pages/" + $pp.name.ToString() }
                    New-Object PSObject -Property $data         
                }
            }
        }
    }
    catch [Exception]
    {
         #It wasn't a publishing page
    } 

}

function RecurseNav([Microsoft.SharePoint.SPWeb]$nodeWeb)
{
    $subWebs = $nodeWeb.GetSubwebsForCurrentUser()
    ScrubPages($nodeWeb)

    foreach ($nextweb in $subWebs)
    {
        RecurseNav($nextWeb)
    }
}


try
{
    if($web_app_url -eq $null -or $web_app_url -eq '')
    {
        throw "You must specify your server name. Value provided was null/empty."
    }
  
    $web = Get-SPWeb $web_app_url

    RecurseNav($web) | Out-GridView
}
catch [Exception]
{
    Write-Host -ForegroundColor Red "Error: $_"


Saturday 1 December 2012

Validate & Verify a Date

When I say Verify, I mean make sure that it's in a correct format; this can very easily be accomplished using regex; if you don't know what that is, it's basically an expression to check formatting of a string against. I suggest reading the following site:

Zytrax this is an excellent source for regex knowledge, I use it regularly.

The following JavaScript function takes in a string and checks it against the following pattern ##/##/####. you may notice it doesn't make sure that the month is between 1-12 or the day is less then 31, it just makes sure that you entered 3 numbers and that they're separated by forward-slashes.

function validdateDate(dateString)
{
    var datePattern = /^\d{2}[/]\d{2}[/]\d{4}$/;
    return datePattern.test(dateString);
}

Now Validate, well that's a bit more tricky. First lets talk about what I mean by validate, if you run the date 02/29/2011 against a simple date Regex it will come back as valid, but it's clearly not since that date never occurred.

At first I thought I could just load the individual month day year into a constructor for a JavaScript Date object and just get an invalid date exception, but no such luck, lovely JavaScript  will just bump the date up to 03/01/2011. Good bad it doesn't really matter, what matters is that I still haven't validated my Date. It's high school programming time.

To resolve this issue first we need a function to check if we're dealing with a leap year, simple enough you can grab the algorithm from numerous sites; I got this one from Wikipedia or if your super lazy it's below.

function isLeapYear(year)
{
    if(year%400==0)
        return true;
    else if(year%100==0)
        return false;
    else if(year%4==0)
        return true;
    return false;
}

Now that we can tell if we're dealing with a leap year lets check to make sure that our date is an actual date. that has occurred.

function verifyDate(dateString)
{
    var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];

    if(dateString.length != 10)
        return false;

    var da = dateString.split("/");
  
    if(da[2] <= new Date().getFullYear())
    {
        if(da[0] > 0 && da[0] < 13)
        {
            if(da[0] == 2 && isLeapYear(da[2]))
                return (da[1] > 0 && da[1] < 30);
            else
                return (da[1] > 0 && da[1] < daysInMonth[da[0]-1]);
        }
    }
    return false;
}

Well there you have it, are there other much more robust ways to check date, sure there are, could I have written this function to take in some sort of pattern to check against rather then just month/day/year, absolutely, but i'm not writing an API, I'm just making a one off function to filter out shitty data before it hits my server.