UrlShortner Plugin

The UrlShortner plugin makes a short URL for a long URL. It redirects a visitor from the short URL to the original URL and counts each visit.

Features

  • getShort() makes one short URL for each pair of URL and owner.
  • A short URL can have a second target for mobile devices.
  • The plugin counts all visits and the visits from mobile devices.

Requirements

  • A system plugin, for example Jimbo. The system plugin routes the short URL and supplies the project setting.
  • A MySQL database. The repository has an install dump only for MySQL.
  • The URL area default in the project.

Installation

Install the plugin with the Festi CLI:

./vendor/bin/festi-plugin --mode install --dump ./dumps/ \
    --plugin UrlShortner --repository [email protected]:FestiPlugins/php_festi_plugin_urlshortner.git

This command was not run for this page.

The command does these steps:

  1. It adds the repository to the plugins directory as a git submodule.
  2. It copies install/install.mysql.sql into the dumps directory as a new migration.
  3. It adds the plugin to festi_plugins in the same migration.
  4. It applies the migration.

Add --path if config.php is not in the current directory.

The install dump removes the table shortner_urls before it creates the table. Do not apply the dump again on a database that has short URLs.

URL rule

The install dump does not add the URL rule of the plugin. The annotation of onDisplayUrl() declares the rule:

Plugin Pattern Method Area
UrlShortner ~^/(s-[0-9a-z]+)$~ onDisplayUrl default

Do not use festi-plugin --mode url for this rule. That mode adds a new method to the plugin class, and onDisplayUrl() is already there.

Add the rule in a migration of the project:

  1. Create the migration file:

    ./vendor/bin/festi-make-migration --dump ./dumps/
  2. Write the rule into the file. Use the pattern from "Inserts into Festi Tables" in the migration rules.

  3. Apply the migration:

    ./vendor/bin/festi-migrate --dump ./dumps/

Configuration

The plugin reads one project setting:

Setting Description
shortner_host The host name of the short URLs, for example go.example.com. Do not add the protocol or a slash.

Add this setting to the Project Settings before you call getShort(). If the setting is missing, Jimbo throws a SystemException.

Usage

Make a short URL

<?php

$plugin = Core::getInstance()->getPluginInstance('UrlShortner');

$shortUrl = $plugin->getShort('https://example.com/catalog/items/?page=2');
// http://go.example.com/s-1a2b3

The signature is getShort($url, $owner = null, $options = array()).

Parameter Description
$url The original URL.
$owner An optional owner identifier, maximum 32 characters. The same URL with a different owner gets a different short URL.
$options['length'] The number of characters after the prefix s-. The default is 5. The maximum is 8, because the column code holds 10 characters.
$options['mobile_url'] An optional target URL for mobile devices.

getShort() works as follows:

  1. It calculates md5($url.$owner).
  2. If a row with this hash is in shortner_urls, it returns the stored short URL.
  3. If not, it makes the code s- plus a part of the hash.
  4. It makes a new code if the code is already in the table. It tries five times and then throws an Exception.
  5. It saves the row and returns http://<shortner_host>/<code>.

Example with an owner and a mobile URL:

<?php

$options = array(
    'length'     => 6,
    'mobile_url' => 'https://m.example.com/catalog/items/'
);

$shortUrl = $plugin->getShort('https://example.com/catalog/items/', 'campaign-1', $options);

The PHP examples were not run for this page.

Open a short URL

A request to /<code> in the area default calls onDisplayUrl(). The method does these steps:

  1. It finds the row by the code. If there is no row, it throws an Exception with the code 404.
  2. It adds 1 to stats_open.
  3. For a mobile request, it also adds 1 to stats_open_mobile.
  4. It redirects a mobile request to mobile_url and each other request to original_url.

Other public methods

Method Description
loadByCode($code) Returns the row of shortner_urls for the code.
updateByCode($code, $values) Changes the row of shortner_urls for the code.

Data

The plugin has one table, shortner_urls:

Column Description
id Primary key.
hash md5 of the original URL and the owner.
code The unique code, for example s-1a2b3.
original_url The original URL.
mobile_url The target URL for mobile devices. It can be NULL.
url The full short URL.
owner The owner identifier. It can be NULL.
stats_open The number of all visits.
stats_open_mobile The number of visits from mobile devices.

Sections, permissions and events

The plugin has no permission sections, no management page and no events. It has no init.php.

Known limitations

  • The short URL always starts with http://.
  • The hash is md5 of the URL and the owner joined with no separator. Thus the URL .../a with the owner b and the URL .../ab with no owner get the same short URL.
  • If mobile_url is empty, a mobile request gets a redirect with an empty URL.
  • The second call for the same URL and owner returns the stored short URL. It does not change mobile_url.
  • onDisplayUrl() reads $this->controller. The current plugin base class has $this->core.