Posts Tagged ‘PHP’

July 18th, 2010A simple PHP class to access the Google AJAX Language API for text translation

I recently wrote a quick PHP class to do some content translation via the Google AJAX Language API, and thought it may be useful for others.

It is by no means a complete class for the API, and in fact only uses one of its methods (language.translate).

The ‘AJAX’ part of the API name is also mis-leading in this case, as we will not be sending an AJAX request or even using and Client Side code – but rather using CURL on the server side to access the API and then dedode the JSON objects using PHP.

I would recommend extending it to include some kind of file or database driven caching system if you will be using it on a high traffic site or translating entire web pages rather than just snippets. Also be sure to abide by Google’s Terms of Use

Here it is:

<?php

/**
* Translate text via the google translate API
*
* @version 1.0
* @author Chris Wheeler <chris@haydendigital.com>
* @copyright Chris Wheeler
* @date: 2010-07-15
*
* Usage:
*
* $translator = new googletranslate();
* $translator->translate('en', 'fr', 'Hello World!');
*
* Full list of supported languages is at http://code.google.com/apis/ajaxlanguage/documentation/reference.html#LangNameArray
* GOOGLE_SEARCH_API key should be defined with a valid Google Search API key for the domain
*
*/
class googletranslate {

  /**
  * POSTs the text to be translated to the API
  *
  * @return String
  */
  private function postmessage($url, $text){
    set_time_limit(30);
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, "q=" . urlencode($text));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
    $response = preg_split('/' . chr(10) . '/', curl_exec($curl));
    if ($error = curl_error($curl)){
      throw new Exception('CURL Error: ' . $error);
    }
    curl_close ($curl);
    return implode($response);
  }

  /**
  * Translte
  *
  * @return String
  */
  public function translate($from, $to, $text) {
    try {
      if (strlen($text) == 0) {
        throw new Exception('Empty string.');
      }
      if (strlen($text) > 5000) {
        throw new Exception('Text to be translated is too long.');
      }
      $url = 'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&langpair=' . $from . '%7C' . $to . '&key=' . GOOGLE_SEARCH_APIKEY . '&userip=' . $_SERVER['REMOTE_ADDR'];
      $jsonresponse = $this->postmessage($url, $text);
      $response = json_decode($jsonresponse, true);
      if ($response['responseStatus'] == 200) {
        $responsedata = $response['responseData'];
        return $responsedata['translatedText'];
      }
    } catch (Exception $e) {
      // Handle errors if required
    }
    return false;
  }

}

?>

November 6th, 2009Relative dates in PHP/Smarty

Our content management system uses ‘facebook style’ relative dates (e.g ’2 hours ago’) throughout to display information such as page edit history, or order times for our e-commerce customers. This is acheived by a custom modifier I wrote some time ago for smarty.

Here is the code – simply save it as modifier.relative_date.php and place it in the smarty ‘plugins’ directory.


<?php

/*
* Smarty plugin
* -------------------------------------------------------------
* Type:     modifier
* Name:     relative_date
* Version:  1.1
* Date:     November 28, 2008
* Author:   Chris Wheeler <chris@haydendigital.com>
* Purpose:  Output dates relative to the current time
* Input:    timestamp = UNIX timestamp or a date which can be converted by strtotime()
*           days = use date only and ignore the time
*           format = (optional) a php date format (for dates over 1 year)
* -------------------------------------------------------------
*/

function smarty_modifier_relative_date($timestamp, $days = false, $format = "M j, Y") {

  if (!is_numeric($timestamp)) {
    // It's not a time stamp, so try to convert it...
    $timestamp = strtotime($timestamp);
  }

  if (!is_numeric($timestamp)) {
    // If its still not numeric, the format is not valid
    return false;
  }

  // Calculate the difference in seconds
  $difference = time() - $timestamp;

  // Check if we only want to calculate based on the day
  if ($days && $difference < (60*60*24)) {
    return "Today";
  }
  if ($difference < 3) {
    return "Just now";
  }
  if ($difference < 60) {    
    return $difference . " seconds ago";
  }
  if ($difference < (60*2)) {    
    return "1 minute ago";
  }
  if ($difference < (60*60)) {
    return intval($difference / 60) . " minutes ago";
  }
  if ($difference < (60*60*2)) {
    return "1 hour ago";
  }
  if ($difference < (60*60*24)) {    
    return intval($difference / (60*60)) . " hours ago";
  }
  if ($difference < (60*60*24*2)) {
    return "1 day ago";
  }
  if ($difference < (60*60*24*7)) {
    return intval($difference / (60*60*24)) . " days ago";
  }
  if ($difference < (60*60*24*7*2)) {
    return "1 week ago";
  }
  if ($difference < (60*60*24*7*(52/12))) {
    return intval($difference / (60*60*24*7)) . " weeks ago";
  }
  if ($difference < (60*60*24*7*(52/12)*2)) {
    return "1 month ago";
  }
  if ($difference < (60*60*24*364)) {
    return intval($difference / (60*60*24*7*(52/12))) . " months ago";
  }

  // More than a year ago, just return the formatted date
  return @date($format, $timestamp);

}

?>

Invoke the modifier with {$date|relative_date}. All comments and suggestions welcome.

October 18th, 2009Validating UK VAT numbers with PHP

I recently had to write some code to validate UK VAT number for a client – so I thought I’d share it to save a bit of time for anyone else who needed to do the same thing.

<?php

/*
* Class: vatnumbervalidator
* Author: Chris Wheeler
* Version: 1.0
* Date: 2009-10-15
*
* Validates VAT numbers, returns 1 if valid or 0 if invalid
*
* Usage Examples:
*
* vatnumbervalidator::check(922577120);
* vatnumbervalidator::check('922 5771 20');
* vatnumbervalidator::check('VAT Number #922 5771 20  ');
*
*/

class vatnumbervalidator {

  public static function check($vatnumber) {

    // cleanup the vat number to remove spaces or non-numeric characters
    $v = vatnumbervalidator::clean($vatnumber);

    // check length
    if (strlen($v) < 9) {
      return 0;
    }

    // calculate the total of each of the first 7 digits, multiplied by 8 descending to 2
    $c = 0;
    $i = 0;
    for ($m=8; $m>=2; $m--) {
      $c += ($v[$i] * $m);
      $i++;
    }

    // subtrack 97 until the checksum is negative
    while ($c >= 0) {
      $c -= 97;
    }
    // inverse the checksum so it becomes positive
    $c = $c / -1;

    // if the checksum is equal to the last two digits of the number, return true
    return ($c == $v[7] . $v[8]);

  }

  public static function clean($vatnumber) {

    // remove all non numeric values
    $v = preg_replace('/[^0-9]/', '', $vatnumber);

    return $v;

  }

}

?>

All feedback and comments appreciated!

September 5th, 2008Sending automated emails which don’t get blocked by ISPs

I’ve recently come across a problem where automated emails are getting blocked by a number of ISPs. I’ve tracked this down to the sender verification methods some ISPs use – If an email comes from an address which isn’t an active mailbox on the server, it is sometimes dropped without any notice to the sender or recipient.

A fair few web sites send automated emails from addresses such as no-reply@domain.com, do-not-reply@domain.com, forum@domain.com etc – if these accounts are not setup the mails will be discarded by some servers.

You should always use a real email account to send emails – even if it silently discards all incoming mail.

Another problem is that if PHP’s mail() function is being used, and php is running as the user ’nobody’, emails by default will be sent from nobody@hostname.isp.com – which in most cases does not exist.

The way around this is to specify the senders email address through the mail function. e.g.

mail($to, $subject, $body, $headers, '-f sales@domain.com')

Note: Even if you have set the ‘From: ‘ field in the email headers, the email envelope address may still be set to a different account, using the ‘-f email@address’ parameter will fix this, and your emails should reach your customers!

Copyright © 2009 Hayden Digital. Blog powered by WordPress