PHP Classes

File: class.relink.php

Recommend this page to a friend!
  Classes of Benjamin Falk   Relink   class.relink.php   Download  
File: class.relink.php
Role: Class source
Content type: text/plain
Description: Contains the class itself
Class: Relink
Rewrite URLs based on mod_rewrite configuration
Author: By
Last change: Fixed a little bug, that links like ?var1&var2=1 did not work.
Date: 15 years ago
Size: 7,048 bytes
 

Contents

Class file image Download
<?php
   
/**
     * RELINK v.0.2.1
     * Copyright 2008 Benjamin Falk
     * Contact: falk [at] citrosaft [dot] net

     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.

     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details.

     * You should have received a copy of the GNU General Public License
     * along with this program. If not, see <http://www.gnu.org/licenses/>.
     */
   
   
error_reporting(E_ALL);
   
    class
RELINK
   
{
       
/*
            The following variables get
            automatically filled up
        */
       
var $auto = false; //Gets true, when .htaccess contains #set link auto on
       
var $rules = array(); //Contains all link-rules
       
var $replacements = array(); //Contains all replacements
       
var $parts = array(); //Contains all parts of a rule
       
var $linkStart = ''; //Contains the startvalue of every link

        /*
            CONSTRUCTOR
            Reads a given .htaccess-file and adds rules
           
            (string) $file Contains the path of .htaccess
            (boolean) $ignoreFile True, if you want to ignore for example index.php in index.php?foo=bar
        */
       
function __construct($file='./.htaccess', $ignoreFile=true)
        {
           
$htaccess = file($file);
            foreach (
$htaccess as $line)
            {
               
//Check if the auto-detection is turned on
               
if ($this->auto === false)
                {
                    if (
strtolower(trim($line)) == '#set link auto on')
                       
$this->auto = true;
                }
                else
                {
                   
$line = trim($line);
                    if (
strtolower(trim($line)) == '#set link auto off')
                       
$this->auto = false;
                    elseif (
strtolower(substr($line,0,($lslen = strlen('#set link start ')))) == '#set link start ')
                       
$this->linkStart = substr($line,$lslen);
                    elseif (
substr($line,0,strlen('RewriteRule ')) == 'RewriteRule ')
                    {
                       
//Add rule...
                       
$regex = $replacement = '';
                        list(
$null, $regex, $replacement) = preg_split('/[\s]+/', $line);
                       
$this->addRule($regex, $replacement, $ignoreFile);
                    }
                }
            }
           
            if (
$this->linkStart == '')
            {
                if (isset(
$_SERVER['PHP_SELF']))
                   
$this->linkStart .= dirname($_SERVER['PHP_SELF']).'/';
            }
            if (
substr($this->linkStart,-1) != '/') $this->linkStart .= '/';
        }

       
/*
            (boolean) addRule
            Adds a rule for rewriting the links easier
           
            (string) $regex Contains the part in what the link should replaced in
                                        For example (.+?)\.html for main.html
            (string) $replacement Contains the real page, so main.html should get into index.php?page=main
        */
       
function addRule($regex, $replacement, $ignoreFile=true)
        {
            if (
$regex == '' || $replacement == '') return false;
           
           
//Get parts of replacement
           
if ($ignoreFile === true) {
               
$replacement = preg_replace('/^([\w\d\.\/]*)\?/', '', $replacement);
            }
            else
                if (
substr($replacement,0,1) == '?') $replacement = substr($replacement,1);
           
parse_str($replacement, $replacementParts);
           
           
$availParts = array();
            foreach (
$replacementParts as $key => $value)
            {
                if (
substr($value,0,1) == '$')
                {
                   
$availParts[intval(substr($value,1))] = $key;
                }
                elseif (
substr($key,0,1) == '$')
                {
                   
$availParts[intval(substr($key,1))] = $value;
                }
            }
           
            if (
substr($regex,0,1) == '^') $regex = substr($regex,1);
            if (
substr($regex,-1) == '$') $regex = substr($regex,0,-1);
           
           
array_unshift($this->parts, $availParts);
           
array_unshift($this->rules, $regex);
           
array_unshift($this->replacements, $replacement);
           
            return
true;
        }
       
       
/*
            (mixed) replaceLink
            Converts a normal link such as ?foo=bar into the known
            replacement set by an .htaccess-file.
           
            (string) $link Contains the baselink
            (boolean) $ignoreFile If true, the filename of the link gets ignored and only
                                        the variables after the questmark gets parsed.
        */
       
function replaceLink($link, $ignoreFile=true)
        {
            if (
preg_match('/(^http\:\/\/)|(^mailto\:)/i', $link)) return $link; //Ignore absolute links
           
if (substr($link,0,1) == '/') return $link; //Ignore root-links like /index.php
           
           
$_link = $link;
            if (
$ignoreFile === true)
            {
               
$link = preg_replace('/^([\w\d\.\/]*)\?/', '', $link);
            }
            else
                if (
substr($link,0,1) == '?') $link = substr($link,1);
           
parse_str($link, $linkParts);
           
$partsCount = count($linkParts);
           
           
//Get the rule with the exact parts
           
foreach ($this->parts as $index => $part)
            {
               
$continue = false;
                if (
count($part) == $partsCount)
                {
//If the given values have the same count as the current rule...
                   
foreach ($linkParts as $key => $val)
                    {
                        if (
$key !== '' && $val === '') //Ignore if there are different parts like ?var1&var2=1
                           
continue;
                        else
                        {
                           
//Check if the exact parts are avail
                           
if (!in_array($key, $part))
                            {
                               
$continue = true;
                                break;
                            }
                        }
                    }
                   
                    if (
$continue == true)
                    {
//If you want to replace a link such as ?val1&val2: This is the part, which does that
                       
foreach ($linkParts as $key => $val)
                        {
                           
//Check if the exact parts are avail
                           
if (in_array($val, $part))
                               
$continue = false;
                            else
                            {
                               
$continue = true;
                                break;
                            }
                        }
                    }
                   
                    if (
$continue) continue;
                   
                   
//Got ya!
                   
$rule = $this->rules[$index];
                   
$ruleParts = preg_split('/(\(.+?\))|\{.*?\}|\[.*\]/s', $rule, -1, PREG_SPLIT_DELIM_CAPTURE);
                   
                   
$rIndex = 0;
                   
$nLink = '';
                   
$failed = false;
                    foreach (
$ruleParts as $rulePart)
                    {
                        if (
$rulePart == '') continue;
                       
                        if (
substr($rulePart,0,1) == '(' && substr($rulePart,-1) == ')')
                        {
                           
//Current one is a variable
                           
$rIndex++;
                            if (
$this->parts[$index][$rIndex] === null)
                            {
                               
$failed = true;
                                break;
                            }
                           
                            if (
$this->parts[$index][$rIndex] === '')
                            {
//If the given link is like ?foo&bar, this might be the part, which is checking everything
                               
reset($linkParts);
                                if (
$rIndex == 1)
                                   
$nLink.= addslashes(key($linkParts));
                                else
                                {
                                   
$_rIndex = 1;
                                    while ((
current($linkParts)) !== false)
                                    {
                                       
next($linkParts);
                                       
$_rIndex++;
                                        if (
$_rIndex == $rIndex)
                                           
$nLink.= addslashes(key($linkParts));
                                    }
                                }
                            }
                            else
                            {
                               
$rVar = $this->parts[$index][$rIndex];
                               
$nLink.= addslashes($linkParts[$rVar]);
                            }
                        }
                        else
                           
$nLink .= $rulePart;
                    }
                   
                   
$nLink = stripslashes($nLink);
                   
                    if (
$failed == true) return $this->linkStart.$_link;
                    else return
$this->linkStart.$nLink;
                   
                    break;
                }
            }
           
//Nothing found...
           
return $this->linkStart.$_link;
        }
    }
?>