Convert Dell service tags and express service tags with PHP

I was given the task at my real job of creating some code to find the service tag from the express service tag of Dell laptops. We only had recorded the express service tag for the 100+ laptops and needed to have the service tag in a project we were working on. I was given some very basic information about the relationship between the two and came up with the following code. With this code you can convert service tags into express service tags and the other way around. It uses a base 36 style formating.

<?php
function convertExpress($tag) {
  $index = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','e');
  
  for($i=10; $i>=0; $i--) {
    $digits[$i] = '0';
    for($k=1; $k<=36; $k++) {
      $tmp = (pow(36, $i)) * $k;
      $tmp2 = $tag - $tmp;
      if($tmp2 < 0) {
        $tmp = (pow(36, $i)) * ($k-1);
        $digits[$i] = $index[$k-1];
        $tag -= $tmp;
        break;
      }
      
      if($tmp2 == 0) {
        $digits[$i] = $index[$k];
        $tag -= $tmp;
        break;
      }   
    }
  }
  $leading = 1;
  foreach($digits as $digit) {
    /*if($digit != '0') {
      $num .= $digit;
    }*/
    if($leading) {
      if($digit != '0') {
        $leading = 0;
        $num .= $digit;
      }
    } else {
      $num .= $digit;
    }
  }
  return $num;
}
?>

To use this code you could use:

<?php
echo convertExpress('(YOUR EXPRESS SERVICE TAG HERE');
?>

Make sure you only use numbers this field.

To get the express service tag from the service tag use the following function:

<?php
function convertTag($tag) {
  $tag = strtoupper($tag);
  $index = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
  $count = strlen($tag);
  $count2 = $count - 1;
  for($i=0; $i<$count; $i++) {
    $digits[$count2] = substr($tag, $i, 1);
    $count2--;
  }
  $numb = 0;
  for($i=0; $i<count($digits); $i++) {
    if($i==0) {
      $m = 1;
    } else {
      $m = pow(36, $i);
    }
    $key = array_keys($index, $digits[$i]);
    $tmp = ($m * $key[0]);
    $numb += $tmp;
  } 
  return $numb;
}
?>

To use this code you can use:

<?php
echo convertTag('(YOUR SERVICE TAG HERE)');
?>

Sanitize copy/paste text from word

In a recent project I have had to deal with text copied from a Microsoft Word document and pasted into a textarea. Word automatically changes a few certain characters to what it thinks it should be, such as the ellipsis and quotes. When dealing with inserting that text into a database I was getting errors. To solve my problems I created a sanitize function to replace these certain characters with acceptable characters.

<?php
// Used to sanitize Microsoft Word's Special Characters
// Good reference http://www.lookuptables.com

function SanitizeFromWord($Text = '') {

	$chars = array(
		130=>',',     // baseline single quote
		131=>'NLG',   // florin
		132=>'"', 	  // baseline double quote
		133=>'...',   // ellipsis
		134=>'**',	  // dagger (a second footnote)
		135=>'***',	  // double dagger (a third footnote)
		136=>'^', 	  // circumflex accent
		137=>'o/oo',  // permile
		138=>'Sh',	  // S Hacek
		139=>'<',	  // left single guillemet
		140=>'OE',	  // OE ligature
		145=>'\'',	  // left single quote
		146=>'\'',	  // right single quote
		147=>'"',	  // left double quote
		148=>'"',	  // right double quote
		149=>'-',	  // bullet
		150=>'-',	  // endash
		151=>'--',	  // emdash
		152=>'~',	  // tilde accent
		153=>'(TM)',  // trademark ligature
		154=>'sh',	  // s Hacek
		155=>'>',	  // right single guillemet
		156=>'oe',	  // oe ligature
		159=>'Y',	  // Y Dieresis
		169=>'(C)',	  // Copyright
		174=>'(R)'	  // Registered Trademark
	);
	
	foreach ($chars as $chr=>$replace) {
		$Text = str_replace(chr($chr), $replace, $Text);
	}
	return $Text;
}
?>

Enjoy!

Remove whitespace from string

I have been doing a lot of coding using the framework CodeIgniter lately so I have been creating many simple helper functions to perform different tasks. My most recent project involves creating PDF files with text from a database. The problem is that the text from the database is dirty, meaning that in a person’s name there could be multiple spaces between the person’s first and last name or even spaces at the end of their name. In dealing with legacy data that you cannot change but needs to be output correctly without those spaces you get creative. I am sure I could use trim(), ltrim() or rtrim() to remove the spaces but that does not remove the multiple spaces between names. The below function should help solve this issue.

<?php
function replace_whitespace($Value = '')
{
	// Replace any whitespace with only a single space
	return preg_replace('/\s+/', ' ', trim($Value));
}
?>

Usage:

<?php
echo '<pre>';
$Text = 'Daniel     Kassner';
echo $Text,' - ',strlen($Text),'<br />';
$Text = ReplaceWhitespace($Text);
echo $Text,' - ',strlen($Text);
echo '</pre>';
?>

Output:

Daniel     Kassner - 18
Daniel Kassner - 14

Get date by position (ie. third Wednesday of January)

In a recent project I needed to come up with code to calculate something like the first, second, third day of whatever month. Unfortunately the strtotime() function does not let you enter “third Wednesday of January” to calculate the date. This is where the code below works great for such things.

<?php
function GetDayByPosition($Position, $Weekday, $Month, $Year) {
	// Sanatize some of the inputs
	$Position = strtolower($Position);
	$Weekday = strtolower($Weekday);
	
	// Go to next month so we can then go back 1 week at end of script for calculating last xxx of month
	if ($Position=='last') { $Month += 1; }
        // We cannot have 13 months so set as January of the next year.
	// This was pointed out by Evan who made a comment on the posting of this script
	if ($Month > 12) {
		$Month = 1;
		$Year += 1;
	}
	// Create new date object for the first of the month
	$D = new DateTime($Year.'-'.$Month.'-1');
	$DOW = $D->format('w'); // Get the current day of the week based on the 1st of the month
	$keys = array('sunday'=>0,'monday'=>1,'tuesday'=>2,'wednesday'=>3,
				  'thursday'=>4,'friday'=>5,'saturday'=>6);
	// Calculate what the offset is based on the current day of the week
	// vs the day in the week you want to get
	$offset = $keys[$Weekday] - $DOW;
	if ($offset<0) { $offset += 7; }

	switch ($Position) {
		// Don't need to add anything to first
		case 'second':
			$offset += 7; // Add 1 week
			break;
		case 'third':
			$offset += 14; // Add 2 weeks
			break;
		case 'fourth':
			$offset += 21; // Add 3 weeks
			break;
		case 'last':
			$offset -= 7; // Go back 7 days
			break;
	}
	// Add the current offset of days to the date object
	$D->modify('+'.$offset.' days');
	return $D->format('Y-m-d');
	
}
?>

Usage:

<?php
// This will output 2009-01-05
echo 'First Monday of January 2009: ',GetDayByPosition('first', 'monday', 1, 2009),'<br />';
// This will output 2009-01-13
echo 'Second Tuesday of January 2009: ',GetDayByPosition('second', 'tuesday', 1, 2009),'<br />';
// This will output 2009-01-21
echo 'Third Wednesday of January 2009: ',GetDayByPosition('third', 'wednesday', 1, 2009),'<br />';
// This will output 2009-01-22
echo 'Fourth Thursday of January 2009: ',GetDayByPosition('fourth', 'thursday', 1, 2009),'<br />';
// This will output 2009-01-30
echo 'Last Friday of January 2009: ',GetDayByPosition('last', 'friday', 1, 2009),'<br />';
?>

This can be used in a recurring calendar events page to allow similar event creation like the recurring events in Microsoft Outlook or any other popular calender applications.

Format US phone number using PHP

Have you ever needed to format a phone number in a particular way? The following code will format into the USA standard phone numbers and has the option to convert letters into their number form.

<?php
/*
Written by: Daniel Kassner
Website: http://www.danielkassner.com
Originally posted on: http://www.wlscripting.com
Date: 09-13-2007 and last updated: 05-21-2010
*/
if (!function_exists('format_phone_us')) {
	function format_phone_us($phone = '', $convert = true, $trim = true)
	{
		// If we have not entered a phone number just return empty
		if (empty($phone)) {
			return false;
		}

		// Strip out any extra characters that we do not need only keep letters and numbers
		$phone = preg_replace("/[^0-9A-Za-z]/", "", $phone);
		// Keep original phone in case of problems later on but without special characters
		$OriginalPhone = $phone;

		// If we have a number longer than 11 digits cut the string down to only 11
		// This is also only ran if we want to limit only to 11 characters
		if ($trim == true && strlen($phone)>11) {
			$phone = substr($phone, 0, 11);
		}

		// Do we want to convert phone numbers with letters to their number equivalent?
		// Samples are: 1-800-TERMINIX, 1-800-FLOWERS, 1-800-Petmeds
		if ($convert == true && !is_numeric($phone)) {
			$replace = array('2'=>array('a','b','c'),
							 '3'=>array('d','e','f'),
							 '4'=>array('g','h','i'),
							 '5'=>array('j','k','l'),
							 '6'=>array('m','n','o'),
							 '7'=>array('p','q','r','s'),
							 '8'=>array('t','u','v'),
							 '9'=>array('w','x','y','z'));

			// Replace each letter with a number
			// Notice this is case insensitive with the str_ireplace instead of str_replace 
			foreach($replace as $digit=>$letters) {
				$phone = str_ireplace($letters, $digit, $phone);
			}
		}

		$length = strlen($phone);
		// Perform phone number formatting here
		switch ($length) {
			case 7:
				// Format: xxx-xxxx
				return preg_replace("/([0-9a-zA-Z]{3})([0-9a-zA-Z]{4})/", "$1-$2", $phone);
			case 10:
				// Format: (xxx) xxx-xxxx
				return preg_replace("/([0-9a-zA-Z]{3})([0-9a-zA-Z]{3})([0-9a-zA-Z]{4})/", "($1) $2-$3", $phone);
			case 11:
				// Format: x(xxx) xxx-xxxx
				return preg_replace("/([0-9a-zA-Z]{1})([0-9a-zA-Z]{3})([0-9a-zA-Z]{3})([0-9a-zA-Z]{4})/", "$1($2) $3-$4", $phone);
			default:
				// Return original phone if not 7, 10 or 11 digits long
				return $OriginalPhone;
		}
	}
}
?>

To use the code:

<?php
$phone = '1-800-FLOWERS';
echo format_phone_us($phone); // Returns 1(800) 356-9377

$newPhone = format_phone_us($phone, false);
echo $newPhone; // Returns 1(800) FLO-WERS
?>

PHP code list all Mondays for a year

Ever need some code to list all the Mondays in a specified year? Here is some code to do just that:

<?php
function getMondays($year) {
  $newyear = $year;
  $week = 0;
  $day = 0;
  $mo = 1;
  $mondays = array();
  $i = 1;
  while ($week != 1) {
   $day++;
   $week = date("w", mktime(0, 0, 0, $mo,$day, $year));
  }
  array_push($mondays,date("r", mktime(0, 0, 0, $mo,$day, $year)));
  while ($newyear == $year) {
   $test =  strtotime(date("r", mktime(0, 0, 0, $mo,$day, $year)) . "+" . $i . " week");
   $i++;
   if ($year == date("Y",$test)) {
     array_push($mondays,date("r", $test));
   }
   $newyear = date("Y",$test);
  }
  return $mondays;
}
echo '<pre>';
print_r(getMondays('2010'));
echo '</pre>';
?>

Need to do this more often!

How can you not enjoy this? Sunny, warm, beach, motorcycles and not a care in the world!

Fun ride out at the beach

Interesting thing is that this is the same place I parked my truck and walked out a few years ago to take this shot 50 to 100 yards off shore in February:

Lake Michigan Shelf Ice, Whitehall Michigan

Working with zero filled numbers in PHP

A while ago I had posted some code to zero fill a number on another site I run. At the time it was the only way I knew of to perform that function. The code that I am referring to is listed below.

<?php
function zerofill ($num,$zerofill) {
    // Get the current string length of the original number
    // Loop through that number until it has reached the count in $zerofill
    while (strlen($num)<$zerofill) {
        $num = "0".$num;
    }
    return $num;
}
?>

And would be used such as:

<?php
// Output will be 005
echo zerofill(5, 3);
?>

What this code does is takes 2 inputs, one for the number and the other for the length you want the number to be. As you see above we input the numbers 5 and 3 into the function arguments. The output of the function would return 005 and not 5.

One of the comments left on my older posting suggested to use the built in PHP function sprintf instead of the while loop. At the time that was posted I did not have the time to look into the proper usage of that function and then I lost track of things and never got around to checking it out. This is why I am posting this article now about using sprintf for zero filling a number. Using the same function name and arguments I have re-written the code for zero filling a number with the sprintf function.

<?php
function zerofill ($num, $zerofill = 3) {
	return sprintf("%0".$zerofill."s", $num);
}
?>

I did a very quick non intense test to see which code functioned faster with a loop of about 10,000 numbers recording the microtime before and after the loop then calculating the difference. The sprint function appears to be slightly faster.

Now that we have a function to add the zeros to a number you might want to remove said zero’s from the number for use someplace else. Below is a function that will do just that. Just enter the number you want to remove the zeros from as the only argument and it will return the newly formatted number.

<?php
function zeroremove($value) {
    return preg_replace("/(\.\d+?)0+$/", "$1", $value)*1;
}
?>