2016-01-29 20:58:49 +01:00
|
|
|
<?php
|
|
|
|
namespace App\Factories;
|
|
|
|
|
|
|
|
use App\Models\Link;
|
|
|
|
use App\Helpers\CryptoHelper;
|
|
|
|
use App\Helpers\LinkHelper;
|
|
|
|
|
|
|
|
|
|
|
|
class LinkFactory {
|
2017-02-04 05:12:47 +01:00
|
|
|
const MAXIMUM_LINK_LENGTH = 65535;
|
|
|
|
|
2016-01-29 20:58:49 +01:00
|
|
|
private static function formatLink($link_ending, $secret_ending=false) {
|
|
|
|
/**
|
|
|
|
* Given a link ending and a boolean indicating whether a secret ending is needed,
|
|
|
|
* return a link formatted with app protocol, app address, and link ending.
|
|
|
|
* @param string $link_ending
|
|
|
|
* @param boolean $secret_ending
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
$short_url = env('APP_PROTOCOL') . env('APP_ADDRESS') . '/' . $link_ending;
|
|
|
|
|
|
|
|
if ($secret_ending) {
|
|
|
|
$short_url .= '/' . $secret_ending;
|
|
|
|
}
|
2016-02-20 00:42:21 +01:00
|
|
|
|
2016-01-29 20:58:49 +01:00
|
|
|
return $short_url;
|
|
|
|
}
|
|
|
|
|
2016-04-02 04:45:29 +02:00
|
|
|
public static function createLink($long_url, $is_secret=false, $custom_ending=null, $link_ip='127.0.0.1', $creator=false, $return_object=false, $is_api=false) {
|
2016-01-29 20:58:49 +01:00
|
|
|
/**
|
|
|
|
* Given parameters needed to create a link, generate appropriate ending and
|
|
|
|
* return formatted link.
|
|
|
|
*
|
|
|
|
* @param string $custom_ending
|
|
|
|
* @param boolean (optional) $is_secret
|
|
|
|
* @param string (optional) $custom_ending
|
|
|
|
* @param string $link_ip
|
|
|
|
* @param string $creator
|
2016-04-02 04:45:29 +02:00
|
|
|
* @param bool $return_object
|
|
|
|
* @param bool $is_api
|
2016-01-29 20:58:49 +01:00
|
|
|
* @return string $formatted_link
|
|
|
|
*/
|
|
|
|
|
2017-02-04 05:12:47 +01:00
|
|
|
if (strlen($long_url) > self::MAXIMUM_LINK_LENGTH) {
|
|
|
|
// If $long_url is longer than the maximum length, then
|
|
|
|
// throw an Exception
|
|
|
|
throw new \Exception('Sorry, but your link is longer than the
|
|
|
|
maximum length allowed.');
|
|
|
|
}
|
|
|
|
|
2016-01-29 20:58:49 +01:00
|
|
|
$is_already_short = LinkHelper::checkIfAlreadyShortened($long_url);
|
|
|
|
|
|
|
|
if ($is_already_short) {
|
|
|
|
throw new \Exception('Sorry, but your link already
|
|
|
|
looks like a shortened URL.');
|
|
|
|
}
|
|
|
|
|
2017-04-11 18:51:40 +02:00
|
|
|
if (!$is_secret && (!isset($custom_ending) || $custom_ending === '') && (LinkHelper::longLinkExists($long_url, $creator) !== false)) {
|
2016-01-29 20:58:49 +01:00
|
|
|
// if link is not specified as secret, is non-custom, and
|
|
|
|
// already exists in Polr, lookup the value and return
|
2017-04-11 18:51:40 +02:00
|
|
|
$existing_link = LinkHelper::longLinkExists($long_url, $creator);
|
2016-01-29 20:58:49 +01:00
|
|
|
return self::formatLink($existing_link);
|
|
|
|
}
|
|
|
|
|
2017-03-20 22:19:28 +01:00
|
|
|
if (isset($custom_ending) && $custom_ending !== '') {
|
2016-01-29 20:58:49 +01:00
|
|
|
// has custom ending
|
|
|
|
$ending_conforms = LinkHelper::validateEnding($custom_ending);
|
|
|
|
if (!$ending_conforms) {
|
|
|
|
throw new \Exception('Sorry, but custom endings
|
2016-07-21 03:28:31 +02:00
|
|
|
can only contain alphanumeric characters, hyphens, and underscores.');
|
2016-01-29 20:58:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$ending_in_use = LinkHelper::linkExists($custom_ending);
|
|
|
|
if ($ending_in_use) {
|
|
|
|
throw new \Exception('Sorry, but this URL ending is already in use.');
|
|
|
|
}
|
|
|
|
|
|
|
|
$link_ending = $custom_ending;
|
|
|
|
}
|
|
|
|
else {
|
2016-08-15 05:43:08 +02:00
|
|
|
if (env('SETTING_PSEUDORANDOM_ENDING')) {
|
|
|
|
// generate a pseudorandom ending
|
|
|
|
$link_ending = LinkHelper::findPseudoRandomEnding();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// generate a counter-based ending or use existing ending if possible
|
|
|
|
$link_ending = LinkHelper::findSuitableEnding();
|
|
|
|
}
|
2016-01-29 20:58:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$link = new Link;
|
|
|
|
$link->short_url = $link_ending;
|
|
|
|
$link->long_url = $long_url;
|
|
|
|
$link->ip = $link_ip;
|
|
|
|
$link->is_custom = $custom_ending != null;
|
|
|
|
|
2016-04-02 04:45:29 +02:00
|
|
|
$link->is_api = $is_api;
|
|
|
|
|
2016-01-29 20:58:49 +01:00
|
|
|
if ($creator) {
|
|
|
|
// if user is logged in, save user as creator
|
|
|
|
$link->creator = $creator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($is_secret) {
|
|
|
|
$rand_bytes_num = intval(env('POLR_SECRET_BYTES'));
|
|
|
|
$secret_key = CryptoHelper::generateRandomHex($rand_bytes_num);
|
|
|
|
$link->secret_key = $secret_key;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$secret_key = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$link->save();
|
|
|
|
|
|
|
|
$formatted_link = self::formatLink($link_ending, $secret_key);
|
|
|
|
|
2016-02-14 08:14:25 +01:00
|
|
|
if ($return_object) {
|
|
|
|
return $link;
|
|
|
|
}
|
|
|
|
|
2016-01-29 20:58:49 +01:00
|
|
|
return $formatted_link;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|