PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Tue Dec 10, 2019 2:49 pm

All times are UTC - 5 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Sat Oct 07, 2006 9:17 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana

_________________
- A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 12:26 am 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana

_________________
- A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Fri Oct 03, 2008 5:26 am 
Offline
Admin
User avatar

Joined: Wed Aug 13, 2003 7:02 am
Posts: 4522
Location: York, UK
"Design/Project Engineer" still comes out as "designproject-engineer" for me 8O


Top
 Profile  
 
PostPosted: Mon Oct 27, 2008 1:33 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana

_________________
- A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Thu Oct 30, 2008 6:18 am 
Offline
Admin
User avatar

Joined: Wed Aug 13, 2003 7:02 am
Posts: 4522
Location: York, UK


Top
 Profile  
 
PostPosted: Thu Dec 04, 2008 5:46 am 
Offline
Forum Newbie
User avatar

Joined: Wed Dec 03, 2008 9:00 am
Posts: 15


Top
 Profile  
 
PostPosted: Tue Apr 20, 2010 2:40 pm 
Offline
Forum Newbie

Joined: Sat Apr 17, 2010 11:21 am
Posts: 2
Hi there, using this code in one of my projects. Thank you for sharing! Here are the updates that I have made. I converted it to my local coding standard, sorry that I made diffing a hassle.

Added Features:
* Added a translation table for non-ascii characters.
* Fixed a bug where low values for maxlength obliterated the string.
* $this->seperator (defaults to hyphen) is used to separate words. I need to have underscores in one project I'm on and hyphens in another.

Syntax: [ Download ] [ Hide ]
<?php

/**
 * This short class will turn user entered titles into URLs
 * that are keyword rich and human readable.  For use with
 * Apache's mod rewrite.
 *
 * @author scottayy@gmail.com
 * @author $Author: $
 *
 */

class SafeUrl {
    /**
     * decode html entities in string?
     * @var boolean
     */

    var $decode = true;
    /**
     * charset to use if $decode is set to true
     * @var string
     */

    var $decode_charset = 'UTF-8';
    /**
     * turns string into all lowercase letters
     * @var boolean
     */

    var $lowercase = true;
    /**
     * strip out html tags from string?
     * @var boolean
     */

    var $strip = true;
    /**
     * maximum length of resulting title
     * @var int
     */

    var $maxlength = 50;
    /**
     * if maxlength is reached, chop at nearest whole word? or hard chop?
     * @var boolean
     */

    var $whole_word = true;
    /**
     * what title to use if no alphanumeric characters can be found
     * @var string
     */

    var $blank = 'no-title';
    /**
     * Allow a differnt character to be used as the separator.
     * @var string
     */

    var $separator = '-';
    /**
     * A table of UTF-8 characters and what to make them.
     * @link http://www.php.net/manual/en/function.strtr.php#90925
     * @var array
     */

    var $translation_table = array(
        'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj','Ð'=>'Dj','đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
        'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
        'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
        'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
        'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
        'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r',
        /**
         * Special characters:
         */

        "'"    => '',       // Single quote
        '&'    => ' and ',  // Amperstand
        "\r\n" => ' ',      // Newline
        "\n"   => ' '       // Newline

    );

    /**
     * Class constructor
     *
     * @param array $options
     */

    function SafeUrl( $options='' ) {
        if (is_array($options)) {
            foreach($options as $property => $value) {
                $this->$property = $value;
            }
        }
    }

    /**
     * the worker function
     *
     * @param string $text
     * @return string
     */

    function makeUrl($text) {
        //Shortcut
        $s = $this->separator;
        //prepare the string according to our options
        if ($this->decode) {
            $text = html_entity_decode($text, ENT_QUOTES, $this->decode_charset);
            $text = strtr($text, $this->translation_table);
        }

        if ($this->lowercase) {
            $text = strtolower($text);
        }
        if ($this->strip) {
            $text = strip_tags($text);
        }

        //filter
        $text = preg_replace("/[^&a-z0-9_-\s']/i", '', $text);
        $text = str_replace(' ', $s, $text);
        $text = trim(preg_replace("/{$s}{2,}/", $s, $text), $s);

        //chop?
        if (strlen($text) > $this->maxlength) {
            $text = substr($text, 0, $this->maxlength);

            if ($this->whole_word) {
                /**
                 * If maxlength is small and leaves us with only part of one
                 * word ignore the "whole_word" filtering.
                 */

                $words = explode($s, $text);
                $temp  = implode($s, array_diff($words, array(array_pop($words))));
                if ($temp != '') {
                    $text = $temp;
                }
            }
        }
        //return =]
        if ($text == '') {
            return null;
        }

        return $text;
    }
}
 


Test File

This is a PHPUnit Unit Test.

Syntax: [ Download ] [ Hide ]
<?php
require_once 'PHPUnit/Framework.php';

require_once dirname(__FILE__) . '/../../lib/SafeUrl.class.php';

/**
 * Test class for SafeUrl.
 * Generated by PHPUnit on 2010-04-20 at 12:57:43.
 */

class SafeUrlTest extends PHPUnit_Framework_TestCase {

    /**
     * @var SafeUrl
     */

    protected $object;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */

    protected function setUp() {
        $this->object = new SafeUrl;
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */

    protected function tearDown() {

    }

    public function testMakeUrl() {
       
            $this->assertEquals( $this->object->makeUrl(
                'i\'m a test string!! do u like me. or not......., billy bob!!@#'),
                'im-a-test-string-do-u-like-me-or-not-billy-bob');

            $this->assertEquals( $this->object->makeUrl(
                '<b>some HTML</b> in <i>here</i>!!~'),
                'some-html-in-here');

            $this->assertEquals( $this->object->makeUrl(
                'i!@#*#@ l#*(*(#**$*o**(*^v^*(e d//////e\\\\\\\\v,,,,,,,,,,n%$#@!~e*(+=t'),
                'i-love-devnet');

            $this->assertEquals( $this->object->makeUrl(
                'A lOng String wiTh a buNchess of words thats! should be -chopped- at the last whole word'),
                'a-long-string-with-a-bunchess-of-words-thats');

            $this->object->lowercase = false;
            $this->assertEquals( $this->object->makeUrl(
                'Eyjafjallajökull Glacier'),
                'Eyjafjallajokull-Glacier');

            $this->object->maxlength = 100;
            $this->assertEquals( $this->object->makeUrl(
                'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ'),
                'AAAAAAACEEEEIIIIDjNOOOOOOUUUUYBSsaaaaaaaceeeeiiiionoooooouuuyybyRr');

            $this->object->maxlength = 20;
            $this->assertEquals( $this->object->makeUrl(
                    $this->big_mess),
                    'safeurl-new-safeurl');

            /**
             * Regresstion test:
             *
             * If max length was so small that we where left with only one
             * word, then whole_word would leave us with an empty string.
             */

            $this->object->maxlength = 5;
            $this->object->whole_word = true;
            $this->assertEquals( $this->object->makeUrl(
                'supercalafragalisticexpialadoshus'),
                'super');
           

            /**
             * Acceptable Bug:
             *
             * It would be nice if we put a space between block level elements,
             * but it is kind of too much to ask for.
             */

            $this->object->maxlength = 200;
            $html = <<<HTML
                <div>
                    <h1>Title</h1>
                    <h2>Subtitle!</h2>Read the <a href="ReleaseNotes.html">Release Notes</a> for this Revision.<br/>
                </div>
HTML
;
            $this->assertEquals( $this->object->makeUrl(
                    $html),
                    'Title-SubtitleRead-the-Release-Notes-for-this-Revision');
            /**                    ^
             * Look: --------------|
             *
             * Should be:
             *     'Title-Subtitle-Read-the-Release-Notes-for-this-Revision'
             */

    }
   
    var $big_mess = '
            </span></li><li style=\"\" class=\"li2\"><span style=\"color:
            #ff0000;\">\$safeurl = new safeurl(); </span></li><li style=\"\"
            class=\"li1\"><span style=\"color: #ff0000;\">\$safeurl->lowercase
            = false;</span></li><li style=\"\" class=\"li2\"><span
            style=\"color: #ff0000;\">\$safeurl->whole_word = false;</span></li>
            <li style=\"\" class=\"li1\">&nbsp;</li><li style=\"\"
            class=\"li2\"><span style=\"color: #ff0000;\">\$tests = array(
            </span></li><li style=\"\" class=\"li1\"><span style=\"color:
            #ff0000;\"> &nbsp; &nbsp; &nbsp; &nbsp;\'</span>i\span
            style=\"color: #ff0000;\">\'m a test string!! do u like me. or
            not......., billy bob!!@#\'</span>, </li><li style=\"\"
            class=\"li2\">&nbsp; &nbsp; &nbsp; &nbsp; <span
            style=\"color: #ff0000;\">\'<b>some HTML</b> in <i>here</i>!!~\'
            </span>, </li><li style=\"\" class=\"li1\">&nbsp; &nbsp; &nbsp;
            &nbsp; <span style=\"color: #ff0000;\">\'i!@#*#@ l#*(*(#**$*o**(*^v
            ^*(e d//////e<span style=\"color: #000099; font-weight: bold;\">\\
            </span><span style=\"color: #000099; font-weight: bold;\">\\</span>
            <span style=\"color: #000099; font-weight: bold;\">\\</span><span
            style=\"color: #000099; font-weight: bold;\">\\</span>v,,,,,,,,,,n%
            $#@!~e*(+=t\'</span>,</li>'
;

}

 


Top
 Profile  
 
PostPosted: Fri Feb 18, 2011 3:23 am 
Offline
DevNet Resident
User avatar

Joined: Sun Sep 03, 2006 5:19 am
Posts: 1579
Location: Sofia, Bulgaria
1. The allowed chars should be configurable, and timemachine3030 's idea of using a translation table has merit, especially for non-english texts.
2. The & in the permitted-by-default characters might cause problems. I suggest two helper methods that transform this into an URL (for use in header() for example) using rawurlencode and into a HTML link, using htmlspecialchars


Top
 Profile  
 
PostPosted: Fri Feb 18, 2011 11:00 am 
Offline
Forum Newbie

Joined: Sat Apr 17, 2010 11:21 am
Posts: 2


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group