Archive

Author Archive

ExpressionEngine: display a navigation menu if an entry is assigned a specific category.

June 29th, 2011

As an avid ExpressionEngine user, I like to dynamically generate as much as I can. This also includes the dynamic generation of navigation menus, naturally. However, there are times when I will use an entry as a static navigation menu by assigned it a specific URL TITLE (for example: whats_new or righthand_menu). Now, in the case of categories, how does one display this right-hand menu ONLY on entries of a weblog that are assigned a specific category? Here is how:

{!--Display right-hand menu ONLY if the entry has been assigned to the AUTOMOBILES category--}
{exp:query sql="select count(w.url_title) AS post_count from exp_weblog_titles w, exp_category_posts cp, exp_categories c where w.entry_id = cp.entry_id and cp.cat_id = c.cat_id and c.cat_url_title='automobiles_category' and w.url_title = '{segment_3}' limit 1"}

{/exp:query}

{!-- Display AUTOMOBILES right-hand menu --}

{exp:query sql="SELECT e1.title, e1.entry_date, e1.edit_date, e2.field_id_2 FROM exp_weblog_titles e1, exp_weblog_data e2 WHERE e1.entry_id = e2.entry_id and e2.weblog_id = 51 and e1.url_title = 'righthand_menu' LIMIT 1"}
{field_id_2}
{/exp:query}

So, what exactly does this do?
The first query retrieves the post count of any entries (in this case, the URL TITLE of the entry is in the third segment of the URL) that are assigned to a specific category (we are looking for 1 here; in fact, the LIMIT 1 line keeps the query from searching for anything greater, as our relevant choices are either 1 or 0). The count is then applied to a PHP variable called assignedCatVar.

If the assignedCatVar is = 1, then the next query grabs the contents of the right-hand menu entry and displays it appropriately on the page.

Simple and effective.

Thantos ExpressionEngine

ExpressionEngine search results: custom template paths for section URLs with categories

February 10th, 2011

We use ExpressionEngine on a number of supported sites, and I tend to use ExpressionEngine’s (EE) internal search mechanism whenever feasible. The search results are generated from path setting specified at Admin › Weblog Administration › Weblog Management › Edit Weblog Preferences› Path Settings › Search Results URL .

For example, setting the Search Results URL value to
{homepage}staff-members will create a SEARCH RESULT of http://mysite.com/staff-members/.

Easy enough, right?

Now, what do you do when you have a Weblog that contains category-based information. The specified Search Results URL does not take this information into account. So, if you have a weblog with a hard-coded path of http://mysite.com/staff-members/category1/johndoe , how do you get the category to show up in the search results?

I have a workaround on the RESULTS template in my SEARCH template group:

{exp:search:search_results}

<?php $autoPath = ‘{auto_path}’;

$lastSegment = basename($autoPath);

//Staff-member URL update, based on the category assigned to the entry

if(strpos($autoPath, ‘staff-members’)){

//variable to assign the category to the appropriate URL segment for the Rule

$catVar = 1;

$basename = ‘catPath’;

?>

{categories}

<?php

$tempname = $basename.$catVar;

$$tempname = “{category_url_title}”;

$catVar++;

?>

{/categories}

<?php $autoPath = “{homepage}”.”staff-members/$catPath1/$lastSegment”;

} ?>

<br /><span><?php echo $autoPath; ?></span>

</div>

{/exp:search:search_results}

So, if the staff-members URL segment exists in the specified URL’s path, the Category/Categories assigned to the Entry are obtained and then added to the URL, defined by the $autoPath variable.

It might not be the most elegant solution, but it works great for us.

Thantos ExpressionEngine

Library Not Registered Javascript error with SharePoint and Internet Explorer 8

January 10th, 2011

We use SharePoint 3.0 for quite a bit of document collaboration. Unfortunately, when using Internet Explorer 8, an error is thrown when we attempted to upload multiple documents within SharePoint. The error details mention Library Not Registered.

Luckily, there is an easy fix:

  • Open up any MS Office 2007 product. In my instance, I used Office 2007.
  • Go to Help>Office Diagnostics.
  • Run diagnostics. This took about 5 minutes to complete.
  • Return to your SharePoint site. the multiple document upload tool should now be working. Apparently, this fix re-registered any .DLLs that were causing the error. I love easy fixes!

Thantos Office 2007

LDAP and PHP login script

June 10th, 2009

Authenticating users of your web applications can be tedious, especially when your users are expected to remember multiple passwords (which can become a security vulnerability in it’s own right). That being said, integrating your login scripts with Active Directory/LDAP can be beneficial for a variety reasons: stronger passwords, fewer login credentials for your user to remember, and fewer headaches for you. Here is how we integrated LDAP with our online application authentication.

LDAP (short for Lightweight Directory Access Protocol), a directory service that runs over TCP/IP, stores information. The storage is similar to how a database stores information, but the structure is ideal for attribute-based, hierarchical structured data that does not undergo frequent changes (for example, the employees’s name, Active Directory group membership, address, and so forth). The LDAP directory can be thought of as a tree of nodes, where each node represents an entry in the LDAP database. These entries are comprised of a collection of attribute-value pairs, and they are identified uniquely by a ‘distinguished name’ or DN. The DN is important, because this is what we will be using to determine a user’s group membership.
Our login script will

  1. First bind to our LDAP server with a resource account (we are not using anonymous binding, so we will need to provide a resource account’s credentials)
  2. Check that the user’s ID and password are legit and exist in our Active Directory environment
  3. Check if the user is a member of a particular security group

If all of these conditions are met, the users will have successfully logged on and will be granted access to our application.

We will store our authentication function in a php file entitled resourceBind.php. The entire contents of resourceBind.php:
[php]<?php

function UMldap($Username, $SSO_Password){
//*************************************
///////////////////////////////// Using ldap bind
$ldaprdn = ‘bindaccountname’; // ldap rdn or dn
$ldappass = ‘bindaccountpassword’; // associated password
$ldapserver = ‘ldaps://your.ldap.server:3269′;

//This is the Active Directory group that users MUST be a member of in order to login successfully
$groupPath1 = "CN=YOURSECURITYGROUP-GS,OU=Accounting,OU=Lewis-Building,OU=Headquarters,DC=headquarters,DC=acme,DC=com";

/////////////////////////////Base DN
$ldap_base_dn = "CN=Users,DC=headquarters,DC=acme,DC=com";

$ldapconn = ldap_connect($ldapserver)or die("Could not connect to LDAP server.");

if ($ldapconn) { //connect to ldap server
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
// echo "LDAP bind successful…";
$errorCount = 0;

$ld_filter = "samaccountname=" . $Username;
$ldap_base_dn = "DC=com";
//Recursively search for the account name in the directory tree. Slow, but effective…
$result = ldap_search($ldapconn, $ldap_base_dn, $ld_filter);

//Create result set
$entries = ldap_get_entries($ldapconn, $result);

//If the account exists, attempt a bind with it. This will ensure that the provided password is legit

$bind = @ldap_bind($ldapconn, $entries[0][dn], $SSO_Password);
if( !$bind || !isset($bind))
{
//the bind failed, which means that the user could have typed in the wrong ID or password. We will display another login form
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="login" name="login">
Username: <input type=text size=30 name="ssoname" maxlength=30 /><br />
Password: <input type=password size=30 name="ssopass" maxlength=30 /><br />
<button type="submit" value="submit" name="submit" >Logon</button>
</form>
<?php
//no point in running the rest of the function, so exit out.
exit;

}

$ii=0;
for ($i=0; $ii < $entries[$i]["count"]; $ii++)
{

$data = $entries[$i][$ii];

if ($data == "memberof") {

$total_memberof = count($entries[$i][$data]);

$jj=0;
for ($jj=0; $jj<$total_memberof; $jj++) {

//Check the groups that the user is a member of and see if our specific group is in the list
if ($entries[$i][$data][$jj] == $groupPath1)
{
// The user is a member of the group, so lets create a session and then return true
$_SESSION['USERGROUP'] = $entries[$i][$data][$jj];
return true;
break;

}
}//end for
}//end if
}//end for
} else { //could not bind, so display an error message and the login form
// We could not bind with our default resource account, so let’s exit and not waste any time with the users credentials
$displayForm=true;
}

}///close connect IF
//Unbind from our resource account
ldap_unbind($ldapconn);

//*************************************

}//end function

?>
[/php]

And, our login page, which we will call login.php, and which will be located in the same directory as resourceBind.php:
[php]<?php
//Disable error messages
error_reporting(0);
?>
<?php require_once(‘resourceBind.php’); ?>
<?php
if ($_POST) {

//Handy function to remove specific special characters from user provided input. ALWAYS validate user input. In this case, we are removing characters that are not allowed in usernames and passwords.
function cleanTxt($text)
{
$code_entities_match =

array(‘–’,'>’,'&quot;’,'!’,'#’,'$’,'%’,'^’,'&’,'*’,'(‘,’)',’{‘,’}',’|',’:',’"’,'<’,’[',']‘,’\\’,';’,"’",’,',’/',’*',’~',’`');
$code_entities_replace = array(‘-’,'-’,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”);
$text = str_replace($code_entities_match, $code_entities_replace, $text);
return $text;
}
//Set form variables
$Username=stripslashes(cleanTxt($_POST['ssoname']));
$SSO_Password=stripslashes($_POST['ssopass']);

//Get Ip Address and User Agent information. This is useful info to store in sessions, or a database table, especially if you need to track timestamps and access
$userIP = $_SERVER['REMOTE_ADDR'];
//Get Timestamp
$myDate = date("Y-m-d H:i:s");//Date in easy-to-read format

$displayForm=false;

if(UMldap($Username,$SSO_Password)){
//set complex string in case there is no ‘whencreated’ field for the username

//User has valid credentials. We are creating a new session variable with the user name. This is also a good place to effectively double up your authentication security by checking to see if the user name exists in another medium, such as a MySQL or Oracle table.
$_SESSION['USERCMS'] = $Username;

//The login is a smashing success, so redirect the user to the protected page.
$MM_redirectWithSuccess = "Successful_login.php";
header("Location: ". $MM_redirectWithSuccess );

} else {
/We can’t log the user in, so display the login form again
$displayForm=true;
}

//unbind
ldap_unbind($ldapconn);

//*************************************
}//end POST check

?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >

<head>
<title>LDAP Login Form</title>
</head>
<body>
<h1>Login</h1>
<?php

//—————————————————————————-
//Form variables to display previously filled out fields
$displayForm=true;
$ssoname=”;
$ssopass=”;
//—————————————————————————-

//Display the login form
if ($displayForm){//Display the request form
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="login" name="login">

UserID:
<input type=text size=30 name="ssoname" maxlength=30 />

Password:
<input type=password size=30 name="ssopass" maxlength=30 />
<br />

<button type="submit" value="submit" name="submit" >Logon</button>

</form>

<?php
}
?>

<!– Javascript to move the cursor to the Username form field. This is a small convenience to the user. –>
<script type="text/javascript" language="JavaScript">
document.forms['login'].elements['ssoname'].focus();
</script>

</body>
</html>
[/php]

To figure out how everything works, please read the comments within the code. If you are interested in learning more, please check out Hugh’s excellent book:

Thantos PHP

Outlook rule to save attachments to a web directory

April 24th, 2009

If you are like me, you get a lot of email messages with attachments in your Outlook email account.  Wouldn’t it be nice to automate the migration of these attachments to a folder of your choosing?  Well, you can, and we will show you how. Read more…

Thantos Office 2007

New look, new feel

April 4th, 2009

Lightyeardesign.com finally has a new look, after 4 years of stagnation (only in appearance, though…).  When one specializes in development for others, it can often be rather easy to neglect one’s own appearance. We finally bucked up to the suds, and the new look is born!

Thantos Miscellany