@@ -5,25 +5,25 @@ |
||
| 5 | 5 | "default" => "local", |
| 6 | 6 | |
| 7 | 7 | "local" => [ |
| 8 | - 'base_url' => env('APP_URL', '127.0.0.1'), |
|
| 8 | + 'base_url' => env('APP_URL', '127.0.0.1'), |
|
| 9 | 9 | 'table_name' => 'links', |
| 10 | - 'charset' => 'latin1', |
|
| 10 | + 'charset' => 'latin1', |
|
| 11 | 11 | |
| 12 | - // utf8_bin gives us case sensitive search to the DB |
|
| 13 | - 'collation' => 'latin1_bin', |
|
| 12 | + // utf8_bin gives us case sensitive search to the DB |
|
| 13 | + 'collation' => 'latin1_bin', |
|
| 14 | 14 | |
| 15 | - /** |
|
| 16 | - * For making the urls unique in the DB, we must create an index or unique_key |
|
| 17 | - * for the column url |
|
| 18 | - * But based on different versions of mysql the size of the index key |
|
| 19 | - * is different as you can see here |
|
| 20 | - * https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html#innodb-maximums-minimums |
|
| 21 | - * |
|
| 22 | - * Possible values in byte could be (767, 3072) and based on the |
|
| 23 | - * charset and collation used for the database or the table, given values may differ |
|
| 24 | - * for example for a ** utf8mb4 ** charset the given values could be (767/4, 3072/4); |
|
| 25 | - * |
|
| 26 | - */ |
|
| 15 | + /** |
|
| 16 | + * For making the urls unique in the DB, we must create an index or unique_key |
|
| 17 | + * for the column url |
|
| 18 | + * But based on different versions of mysql the size of the index key |
|
| 19 | + * is different as you can see here |
|
| 20 | + * https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html#innodb-maximums-minimums |
|
| 21 | + * |
|
| 22 | + * Possible values in byte could be (767, 3072) and based on the |
|
| 23 | + * charset and collation used for the database or the table, given values may differ |
|
| 24 | + * for example for a ** utf8mb4 ** charset the given values could be (767/4, 3072/4); |
|
| 25 | + * |
|
| 26 | + */ |
|
| 27 | 27 | 'index_key_prefix_size' => '767', |
| 28 | 28 | |
| 29 | 29 | /** |
@@ -10,12 +10,12 @@ |
||
| 10 | 10 | * |
| 11 | 11 | * @return mixed |
| 12 | 12 | */ |
| 13 | - function shorten (string $url) :string; |
|
| 13 | + function shorten(string $url) :string; |
|
| 14 | 14 | |
| 15 | 15 | /** |
| 16 | 16 | * @param string $url |
| 17 | 17 | * |
| 18 | 18 | * @return mixed |
| 19 | 19 | */ |
| 20 | - function expand (string $url) :string; |
|
| 20 | + function expand(string $url) :string; |
|
| 21 | 21 | } |
| 22 | 22 | \ No newline at end of file |
@@ -6,26 +6,26 @@ |
||
| 6 | 6 | |
| 7 | 7 | class ShorturlServiceProvider extends ServiceProvider |
| 8 | 8 | {
|
| 9 | - /** |
|
| 10 | - * Register bindings in the container. |
|
| 11 | - * |
|
| 12 | - * @return void |
|
| 13 | - */ |
|
| 14 | - public function register() |
|
| 15 | - {
|
|
| 16 | - $this->app->singleton('shorturl', function ($app) {
|
|
| 17 | - return resolve("Ako\Shorturl\Shorturl");
|
|
| 18 | - }); |
|
| 9 | + /** |
|
| 10 | + * Register bindings in the container. |
|
| 11 | + * |
|
| 12 | + * @return void |
|
| 13 | + */ |
|
| 14 | + public function register() |
|
| 15 | + {
|
|
| 16 | + $this->app->singleton('shorturl', function ($app) {
|
|
| 17 | + return resolve("Ako\Shorturl\Shorturl");
|
|
| 18 | + }); |
|
| 19 | 19 | |
| 20 | - $this->mergeConfigFrom(__DIR__ . '/../config/shorturl.php', 'shorturl'); |
|
| 21 | - } |
|
| 20 | + $this->mergeConfigFrom(__DIR__ . '/../config/shorturl.php', 'shorturl'); |
|
| 21 | + } |
|
| 22 | 22 | |
| 23 | - public function boot() |
|
| 24 | - {
|
|
| 25 | - $this->publishes([ |
|
| 26 | - __DIR__.'/../config/shorturl.php' => config_path('shorturl.php')
|
|
| 27 | - ]); |
|
| 23 | + public function boot() |
|
| 24 | + {
|
|
| 25 | + $this->publishes([ |
|
| 26 | + __DIR__.'/../config/shorturl.php' => config_path('shorturl.php')
|
|
| 27 | + ]); |
|
| 28 | 28 | |
| 29 | - $this->loadMigrationsFrom(__DIR__.'/../migrations'); |
|
| 30 | - } |
|
| 29 | + $this->loadMigrationsFrom(__DIR__.'/../migrations'); |
|
| 30 | + } |
|
| 31 | 31 | } |
| 32 | 32 | \ No newline at end of file |
@@ -13,7 +13,7 @@ discard block |
||
| 13 | 13 | */ |
| 14 | 14 | public function register() |
| 15 | 15 | {
|
| 16 | - $this->app->singleton('shorturl', function ($app) {
|
|
| 16 | + $this->app->singleton('shorturl', function($app) {
|
|
| 17 | 17 | return resolve("Ako\Shorturl\Shorturl");
|
| 18 | 18 | }); |
| 19 | 19 | |
@@ -23,9 +23,9 @@ discard block |
||
| 23 | 23 | public function boot() |
| 24 | 24 | {
|
| 25 | 25 | $this->publishes([ |
| 26 | - __DIR__.'/../config/shorturl.php' => config_path('shorturl.php')
|
|
| 26 | + __DIR__ . '/../config/shorturl.php' => config_path('shorturl.php')
|
|
| 27 | 27 | ]); |
| 28 | 28 | |
| 29 | - $this->loadMigrationsFrom(__DIR__.'/../migrations'); |
|
| 29 | + $this->loadMigrationsFrom(__DIR__ . '/../migrations'); |
|
| 30 | 30 | } |
| 31 | 31 | } |
| 32 | 32 | \ No newline at end of file |
@@ -53,8 +53,9 @@ |
||
| 53 | 53 | |
| 54 | 54 | private function getDriverInstance () |
| 55 | 55 | {
|
| 56 | - if (!$this->driver_instance) |
|
| 57 | - $this->setDriverInstance(); |
|
| 56 | + if (!$this->driver_instance) {
|
|
| 57 | + $this->setDriverInstance(); |
|
| 58 | + } |
|
| 58 | 59 | |
| 59 | 60 | return $this->driver_instance; |
| 60 | 61 | } |
@@ -10,7 +10,7 @@ discard block |
||
| 10 | 10 | protected $driver; |
| 11 | 11 | private $driver_instance; |
| 12 | 12 | |
| 13 | - public function __construct (DriverFactory $factory) |
|
| 13 | + public function __construct(DriverFactory $factory) |
|
| 14 | 14 | {
|
| 15 | 15 | $this->factory = $factory; |
| 16 | 16 | } |
@@ -20,7 +20,7 @@ discard block |
||
| 20 | 20 | * |
| 21 | 21 | * @return Shorturl |
| 22 | 22 | */ |
| 23 | - public function onDriver (string $driver) |
|
| 23 | + public function onDriver(string $driver) |
|
| 24 | 24 | {
|
| 25 | 25 | $this->driver = $driver; |
| 26 | 26 | $this->setDriverInstance(); |
@@ -30,7 +30,7 @@ discard block |
||
| 30 | 30 | /** |
| 31 | 31 | * @return void |
| 32 | 32 | */ |
| 33 | - private function setDriverInstance () |
|
| 33 | + private function setDriverInstance() |
|
| 34 | 34 | {
|
| 35 | 35 | $this->driver_instance = $this->factory->make($this->getDriver()); |
| 36 | 36 | } |
@@ -41,17 +41,17 @@ discard block |
||
| 41 | 41 | * |
| 42 | 42 | * @return string |
| 43 | 43 | */ |
| 44 | - public function getDriver (): string |
|
| 44 | + public function getDriver(): string |
|
| 45 | 45 | {
|
| 46 | 46 | return $this->driver ?: config("shorturl.drivers.default");
|
| 47 | 47 | } |
| 48 | 48 | |
| 49 | - public function __call ($method, $args) |
|
| 49 | + public function __call($method, $args) |
|
| 50 | 50 | {
|
| 51 | - return call_user_func_array(array ($this->getDriverInstance(), $method), $args); |
|
| 51 | + return call_user_func_array(array($this->getDriverInstance(), $method), $args); |
|
| 52 | 52 | } |
| 53 | 53 | |
| 54 | - private function getDriverInstance () |
|
| 54 | + private function getDriverInstance() |
|
| 55 | 55 | {
|
| 56 | 56 | if (!$this->driver_instance) |
| 57 | 57 | $this->setDriverInstance(); |
@@ -6,14 +6,14 @@ |
||
| 6 | 6 | |
| 7 | 7 | class Shorturl extends Facade |
| 8 | 8 | {
|
| 9 | - /** |
|
| 10 | - * Get the registered name of the component. |
|
| 11 | - * |
|
| 12 | - * @return string |
|
| 13 | - */ |
|
| 14 | - protected static function getFacadeAccessor() |
|
| 15 | - {
|
|
| 16 | - return 'shorturl'; |
|
| 17 | - } |
|
| 9 | + /** |
|
| 10 | + * Get the registered name of the component. |
|
| 11 | + * |
|
| 12 | + * @return string |
|
| 13 | + */ |
|
| 14 | + protected static function getFacadeAccessor() |
|
| 15 | + {
|
|
| 16 | + return 'shorturl'; |
|
| 17 | + } |
|
| 18 | 18 | |
| 19 | 19 | } |
@@ -1,9 +1,9 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | namespace Ako\Shorturl; |
| 3 | 3 | |
| 4 | - use Ako\Shorturl\Drivers\LocalDriver; |
|
| 4 | + use Ako\Shorturl\Drivers\LocalDriver; |
|
| 5 | 5 | |
| 6 | - class DriverFactory |
|
| 6 | + class DriverFactory |
|
| 7 | 7 | {
|
| 8 | 8 | /** |
| 9 | 9 | * @param string $driver |
@@ -10,7 +10,7 @@ |
||
| 10 | 10 | * |
| 11 | 11 | * @return LocalDriver |
| 12 | 12 | */ |
| 13 | - public function make (string $driver) |
|
| 13 | + public function make(string $driver) |
|
| 14 | 14 | {
|
| 15 | 15 | switch ($driver) {
|
| 16 | 16 | case "local": |
@@ -19,8 +19,8 @@ |
||
| 19 | 19 | ]; |
| 20 | 20 | |
| 21 | 21 | public function __construct(array $attributes = []) |
| 22 | - { |
|
| 23 | - $this->table = config('shorturl.drivers.local.table_name'); |
|
| 24 | - parent::__construct($attributes); |
|
| 25 | - } |
|
| 26 | - } |
|
| 27 | 22 | \ No newline at end of file |
| 23 | + { |
|
| 24 | + $this->table = config('shorturl.drivers.local.table_name'); |
|
| 25 | + parent::__construct($attributes); |
|
| 26 | + } |
|
| 27 | + } |
|
| 28 | 28 | \ No newline at end of file |
@@ -6,31 +6,31 @@ |
||
| 6 | 6 | |
| 7 | 7 | class CreateLinksTable extends Migration |
| 8 | 8 | { |
| 9 | - /** |
|
| 10 | - * Run the migrations. |
|
| 11 | - */ |
|
| 12 | - public function up() |
|
| 13 | - { |
|
| 14 | - $local_conf = config('shorturl.drivers.local'); |
|
| 15 | - Schema::create($local_conf['table_name'], function (Blueprint $table) use ($local_conf) { |
|
| 16 | - $table->charset = $local_conf['charset'] ?? "utf8"; |
|
| 17 | - $table->collation = $local_conf['collation'] ?? "utf8_bin"; |
|
| 18 | - $table->increments('id'); |
|
| 19 | - $table->string('long_path', $local_conf['index_key_prefix_size'])->unique(); |
|
| 20 | - $table->string('short_path', 10)->unique(); |
|
| 21 | - $table->string('base_url')->nullable(); |
|
| 22 | - $table->bigInteger('clicks')->nullable()->default(0); |
|
| 23 | - $table->text('properties')->nullable(); |
|
| 24 | - $table->timestamps(); |
|
| 25 | - }); |
|
| 26 | - } |
|
| 9 | + /** |
|
| 10 | + * Run the migrations. |
|
| 11 | + */ |
|
| 12 | + public function up() |
|
| 13 | + { |
|
| 14 | + $local_conf = config('shorturl.drivers.local'); |
|
| 15 | + Schema::create($local_conf['table_name'], function (Blueprint $table) use ($local_conf) { |
|
| 16 | + $table->charset = $local_conf['charset'] ?? "utf8"; |
|
| 17 | + $table->collation = $local_conf['collation'] ?? "utf8_bin"; |
|
| 18 | + $table->increments('id'); |
|
| 19 | + $table->string('long_path', $local_conf['index_key_prefix_size'])->unique(); |
|
| 20 | + $table->string('short_path', 10)->unique(); |
|
| 21 | + $table->string('base_url')->nullable(); |
|
| 22 | + $table->bigInteger('clicks')->nullable()->default(0); |
|
| 23 | + $table->text('properties')->nullable(); |
|
| 24 | + $table->timestamps(); |
|
| 25 | + }); |
|
| 26 | + } |
|
| 27 | 27 | |
| 28 | - /** |
|
| 29 | - * Reverse the migrations. |
|
| 30 | - */ |
|
| 31 | - public function down() |
|
| 32 | - { |
|
| 33 | - Schema::dropIfExists(config('shorturl.drivers.local.table_name')); |
|
| 34 | - } |
|
| 28 | + /** |
|
| 29 | + * Reverse the migrations. |
|
| 30 | + */ |
|
| 31 | + public function down() |
|
| 32 | + { |
|
| 33 | + Schema::dropIfExists(config('shorturl.drivers.local.table_name')); |
|
| 34 | + } |
|
| 35 | 35 | } |
| 36 | 36 | |
@@ -12,7 +12,7 @@ |
||
| 12 | 12 | public function up() |
| 13 | 13 | { |
| 14 | 14 | $local_conf = config('shorturl.drivers.local'); |
| 15 | - Schema::create($local_conf['table_name'], function (Blueprint $table) use ($local_conf) { |
|
| 15 | + Schema::create($local_conf['table_name'], function(Blueprint $table) use ($local_conf) { |
|
| 16 | 16 | $table->charset = $local_conf['charset'] ?? "utf8"; |
| 17 | 17 | $table->collation = $local_conf['collation'] ?? "utf8_bin"; |
| 18 | 18 | $table->increments('id'); |
@@ -15,84 +15,84 @@ discard block |
||
| 15 | 15 | $this->main_str = $this->config['str_shuffled']; |
| 16 | 16 | $this->head = $this->main_str[0]; |
| 17 | 17 | $this->tail = $this->main_str[strlen($this->main_str) - 1]; |
| 18 | - $this->checkCaseSensitive (); |
|
| 18 | + $this->checkCaseSensitive (); |
|
| 19 | 19 | } |
| 20 | 20 | |
| 21 | - /** |
|
| 22 | - * @param string $url |
|
| 23 | - * |
|
| 24 | - * @return string |
|
| 25 | - */ |
|
| 21 | + /** |
|
| 22 | + * @param string $url |
|
| 23 | + * |
|
| 24 | + * @return string |
|
| 25 | + */ |
|
| 26 | 26 | public function expand (string $url) :string |
| 27 | 27 | {
|
| 28 | - $this->parseUrl($url); |
|
| 29 | - $link = Link::where("short_path", $this->path)->first();
|
|
| 30 | - if ($link) {
|
|
| 31 | - $link->increment("clicks");
|
|
| 32 | - return $link->base_url . "/" . $link->long_path; |
|
| 33 | - } |
|
| 28 | + $this->parseUrl($url); |
|
| 29 | + $link = Link::where("short_path", $this->path)->first();
|
|
| 30 | + if ($link) {
|
|
| 31 | + $link->increment("clicks");
|
|
| 32 | + return $link->base_url . "/" . $link->long_path; |
|
| 33 | + } |
|
| 34 | 34 | return ""; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | - /** |
|
| 38 | - * @param string $url |
|
| 39 | - * |
|
| 40 | - * @return string |
|
| 41 | - * @throws \Exception |
|
| 42 | - */ |
|
| 37 | + /** |
|
| 38 | + * @param string $url |
|
| 39 | + * |
|
| 40 | + * @return string |
|
| 41 | + * @throws \Exception |
|
| 42 | + */ |
|
| 43 | 43 | public function shorten (string $url) :string |
| 44 | 44 | {
|
| 45 | - $this->parseUrl ($url); |
|
| 46 | - |
|
| 47 | - // Check if given url has been shorten previously |
|
| 48 | - $duplicate = Link::where(['long_path' => $this->path])->first(); |
|
| 49 | - if ($duplicate) |
|
| 50 | - return $duplicate->base_url . "/" . $duplicate->short_path; |
|
| 51 | - |
|
| 52 | - $short_path = $this->getNextShortpath(); |
|
| 53 | - |
|
| 54 | - try {
|
|
| 55 | - Link::create([ |
|
| 56 | - "long_path" => $this->path, |
|
| 57 | - "short_path" => $short_path, |
|
| 58 | - 'base_url' => $this->base_url, |
|
| 59 | - 'properties' => $this->props] |
|
| 60 | - ); |
|
| 61 | - } catch (\Exception $e) {
|
|
| 62 | - // If it is duplicate entry exception |
|
| 63 | - // try to insert a new entry |
|
| 64 | - if ($e instanceof \Illuminate\Database\QueryException && $e->getCode() == "23000") {
|
|
| 65 | - return $this->shorten($url); |
|
| 66 | - } |
|
| 67 | - } |
|
| 68 | - return $this->base_url . "/" . $short_path; |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - /** |
|
| 72 | - * Git the first short url |
|
| 73 | - * |
|
| 74 | - * @return string |
|
| 75 | - */ |
|
| 76 | - private function getFirstUrl () : string |
|
| 77 | - {
|
|
| 78 | - $min_length = $this->config['min_length']; |
|
| 79 | - $short_path = ""; |
|
| 80 | - for ($i = 0; $i < $min_length; $i++) |
|
| 81 | - $short_path .= $this->head; |
|
| 82 | - return $short_path; |
|
| 83 | - } |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * |
|
| 87 | - * Get the next short url based on the given item (it gets permutations one by one) |
|
| 88 | - * |
|
| 89 | - * @param string $current_perm |
|
| 90 | - * @return string |
|
| 91 | - */ |
|
| 92 | - private function findNextPerm (string $current_perm) :string |
|
| 45 | + $this->parseUrl ($url); |
|
| 46 | + |
|
| 47 | + // Check if given url has been shorten previously |
|
| 48 | + $duplicate = Link::where(['long_path' => $this->path])->first(); |
|
| 49 | + if ($duplicate) |
|
| 50 | + return $duplicate->base_url . "/" . $duplicate->short_path; |
|
| 51 | + |
|
| 52 | + $short_path = $this->getNextShortpath(); |
|
| 53 | + |
|
| 54 | + try {
|
|
| 55 | + Link::create([ |
|
| 56 | + "long_path" => $this->path, |
|
| 57 | + "short_path" => $short_path, |
|
| 58 | + 'base_url' => $this->base_url, |
|
| 59 | + 'properties' => $this->props] |
|
| 60 | + ); |
|
| 61 | + } catch (\Exception $e) {
|
|
| 62 | + // If it is duplicate entry exception |
|
| 63 | + // try to insert a new entry |
|
| 64 | + if ($e instanceof \Illuminate\Database\QueryException && $e->getCode() == "23000") {
|
|
| 65 | + return $this->shorten($url); |
|
| 66 | + } |
|
| 67 | + } |
|
| 68 | + return $this->base_url . "/" . $short_path; |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + /** |
|
| 72 | + * Git the first short url |
|
| 73 | + * |
|
| 74 | + * @return string |
|
| 75 | + */ |
|
| 76 | + private function getFirstUrl () : string |
|
| 77 | + {
|
|
| 78 | + $min_length = $this->config['min_length']; |
|
| 79 | + $short_path = ""; |
|
| 80 | + for ($i = 0; $i < $min_length; $i++) |
|
| 81 | + $short_path .= $this->head; |
|
| 82 | + return $short_path; |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * |
|
| 87 | + * Get the next short url based on the given item (it gets permutations one by one) |
|
| 88 | + * |
|
| 89 | + * @param string $current_perm |
|
| 90 | + * @return string |
|
| 91 | + */ |
|
| 92 | + private function findNextPerm (string $current_perm) :string |
|
| 93 | 93 | {
|
| 94 | 94 | if (!strlen($current_perm)) |
| 95 | - return $this->head; |
|
| 95 | + return $this->head; |
|
| 96 | 96 | |
| 97 | 97 | $arr = array_reverse(str_split($current_perm)); |
| 98 | 98 | foreach($arr as $key => $current_char) {
|
@@ -100,7 +100,7 @@ discard block |
||
| 100 | 100 | $current_perm = Str::replaceLast($current_char, "", $current_perm); |
| 101 | 101 | return $this->findNextPerm($current_perm) . $this->head; |
| 102 | 102 | } |
| 103 | - $next_char = str_split(Str::after($this->main_str, $current_char))[0]; |
|
| 103 | + $next_char = str_split(Str::after($this->main_str, $current_char))[0]; |
|
| 104 | 104 | return Str::replaceLast($current_char, $next_char, $current_perm); |
| 105 | 105 | } |
| 106 | 106 | } |
@@ -116,56 +116,56 @@ discard block |
||
| 116 | 116 | return $this; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | - private function parseUrl (string $url) |
|
| 120 | - {
|
|
| 121 | - $parse = parse_url($url); |
|
| 122 | - $path = ""; |
|
| 123 | - if ($parse['path'] ?? null) |
|
| 124 | - $path .= str::replaceFirst("/", "", $parse['path']);
|
|
| 125 | - if ($parse['query'] ?? null) |
|
| 126 | - $path .= "?" . $parse['query']; |
|
| 127 | - if ($parse['fragment'] ?? null) |
|
| 128 | - $path .= "#" . $parse['fragment']; |
|
| 129 | - |
|
| 130 | - $this->base_url = str_replace("/" . $path, "", $url);
|
|
| 131 | - $this->path = $path; |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - private function checkCaseSensitive () |
|
| 135 | - {
|
|
| 136 | - if ((!$this->config['case_sensitive'] ?? null)) {
|
|
| 137 | - // Remove upper cases from main string |
|
| 138 | - $this->main_str = preg_replace("/(.)\\1+/", "$1", strtolower($this->main_str));
|
|
| 139 | - } |
|
| 140 | - } |
|
| 141 | - |
|
| 142 | - /** |
|
| 143 | - * @return string |
|
| 144 | - */ |
|
| 145 | - private function getNextShortpath () : string |
|
| 146 | - {
|
|
| 147 | - $tbl = (new Link)->getTable(); |
|
| 148 | - // Get latest short_path(s) |
|
| 149 | - // As multiple instances could be created at the same timestamp which we get |
|
| 150 | - // the latest one based on that |
|
| 151 | - // so we must find the latest one(short_path) in the permutation of the main_str |
|
| 152 | - $latest = collect(\DB::select("SELECT short_path FROM $tbl WHERE created_at = (SELECT MAX(created_at) FROM $tbl)"));
|
|
| 153 | - |
|
| 154 | - if (!$latest->count()) |
|
| 155 | - return $this->getFirstUrl(); |
|
| 156 | - |
|
| 157 | - if ($latest->count() == 1) {
|
|
| 158 | - return $this->findNextPerm($latest->first()->short_path); |
|
| 159 | - } |
|
| 160 | - else {
|
|
| 161 | - foreach ($latest->reverse() as $key => $item) {
|
|
| 162 | - $next = $this->findNextPerm($item->short_path); |
|
| 163 | - |
|
| 164 | - // If next permutation of current item is in fetched items |
|
| 165 | - // find next permutation of the next fetched one |
|
| 166 | - if (!$latest->contains("short_path", $next))
|
|
| 167 | - return $next; |
|
| 168 | - } |
|
| 169 | - } |
|
| 170 | - } |
|
| 119 | + private function parseUrl (string $url) |
|
| 120 | + {
|
|
| 121 | + $parse = parse_url($url); |
|
| 122 | + $path = ""; |
|
| 123 | + if ($parse['path'] ?? null) |
|
| 124 | + $path .= str::replaceFirst("/", "", $parse['path']);
|
|
| 125 | + if ($parse['query'] ?? null) |
|
| 126 | + $path .= "?" . $parse['query']; |
|
| 127 | + if ($parse['fragment'] ?? null) |
|
| 128 | + $path .= "#" . $parse['fragment']; |
|
| 129 | + |
|
| 130 | + $this->base_url = str_replace("/" . $path, "", $url);
|
|
| 131 | + $this->path = $path; |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + private function checkCaseSensitive () |
|
| 135 | + {
|
|
| 136 | + if ((!$this->config['case_sensitive'] ?? null)) {
|
|
| 137 | + // Remove upper cases from main string |
|
| 138 | + $this->main_str = preg_replace("/(.)\\1+/", "$1", strtolower($this->main_str));
|
|
| 139 | + } |
|
| 140 | + } |
|
| 141 | + |
|
| 142 | + /** |
|
| 143 | + * @return string |
|
| 144 | + */ |
|
| 145 | + private function getNextShortpath () : string |
|
| 146 | + {
|
|
| 147 | + $tbl = (new Link)->getTable(); |
|
| 148 | + // Get latest short_path(s) |
|
| 149 | + // As multiple instances could be created at the same timestamp which we get |
|
| 150 | + // the latest one based on that |
|
| 151 | + // so we must find the latest one(short_path) in the permutation of the main_str |
|
| 152 | + $latest = collect(\DB::select("SELECT short_path FROM $tbl WHERE created_at = (SELECT MAX(created_at) FROM $tbl)"));
|
|
| 153 | + |
|
| 154 | + if (!$latest->count()) |
|
| 155 | + return $this->getFirstUrl(); |
|
| 156 | + |
|
| 157 | + if ($latest->count() == 1) {
|
|
| 158 | + return $this->findNextPerm($latest->first()->short_path); |
|
| 159 | + } |
|
| 160 | + else {
|
|
| 161 | + foreach ($latest->reverse() as $key => $item) {
|
|
| 162 | + $next = $this->findNextPerm($item->short_path); |
|
| 163 | + |
|
| 164 | + // If next permutation of current item is in fetched items |
|
| 165 | + // find next permutation of the next fetched one |
|
| 166 | + if (!$latest->contains("short_path", $next))
|
|
| 167 | + return $next; |
|
| 168 | + } |
|
| 169 | + } |
|
| 170 | + } |
|
| 171 | 171 | } |
| 172 | 172 | \ No newline at end of file |
@@ -9,13 +9,13 @@ discard block |
||
| 9 | 9 | protected $props = []; |
| 10 | 10 | protected $config, $main_str, $head, $tail, $base_url, $path; |
| 11 | 11 | |
| 12 | - public function __construct () |
|
| 12 | + public function __construct() |
|
| 13 | 13 | {
|
| 14 | 14 | $this->config = config('shorturl.drivers.local');
|
| 15 | 15 | $this->main_str = $this->config['str_shuffled']; |
| 16 | 16 | $this->head = $this->main_str[0]; |
| 17 | 17 | $this->tail = $this->main_str[strlen($this->main_str) - 1]; |
| 18 | - $this->checkCaseSensitive (); |
|
| 18 | + $this->checkCaseSensitive(); |
|
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | /** |
@@ -23,7 +23,7 @@ discard block |
||
| 23 | 23 | * |
| 24 | 24 | * @return string |
| 25 | 25 | */ |
| 26 | - public function expand (string $url) :string |
|
| 26 | + public function expand(string $url) :string |
|
| 27 | 27 | {
|
| 28 | 28 | $this->parseUrl($url); |
| 29 | 29 | $link = Link::where("short_path", $this->path)->first();
|
@@ -40,9 +40,9 @@ discard block |
||
| 40 | 40 | * @return string |
| 41 | 41 | * @throws \Exception |
| 42 | 42 | */ |
| 43 | - public function shorten (string $url) :string |
|
| 43 | + public function shorten(string $url) :string |
|
| 44 | 44 | {
|
| 45 | - $this->parseUrl ($url); |
|
| 45 | + $this->parseUrl($url); |
|
| 46 | 46 | |
| 47 | 47 | // Check if given url has been shorten previously |
| 48 | 48 | $duplicate = Link::where(['long_path' => $this->path])->first(); |
@@ -73,7 +73,7 @@ discard block |
||
| 73 | 73 | * |
| 74 | 74 | * @return string |
| 75 | 75 | */ |
| 76 | - private function getFirstUrl () : string |
|
| 76 | + private function getFirstUrl() : string |
|
| 77 | 77 | {
|
| 78 | 78 | $min_length = $this->config['min_length']; |
| 79 | 79 | $short_path = ""; |
@@ -89,13 +89,13 @@ discard block |
||
| 89 | 89 | * @param string $current_perm |
| 90 | 90 | * @return string |
| 91 | 91 | */ |
| 92 | - private function findNextPerm (string $current_perm) :string |
|
| 92 | + private function findNextPerm(string $current_perm) :string |
|
| 93 | 93 | {
|
| 94 | 94 | if (!strlen($current_perm)) |
| 95 | 95 | return $this->head; |
| 96 | 96 | |
| 97 | 97 | $arr = array_reverse(str_split($current_perm)); |
| 98 | - foreach($arr as $key => $current_char) {
|
|
| 98 | + foreach ($arr as $key => $current_char) {
|
|
| 99 | 99 | if ($current_char == $this->tail) {
|
| 100 | 100 | $current_perm = Str::replaceLast($current_char, "", $current_perm); |
| 101 | 101 | return $this->findNextPerm($current_perm) . $this->head; |
@@ -110,13 +110,13 @@ discard block |
||
| 110 | 110 | * |
| 111 | 111 | * @return LocalDriver |
| 112 | 112 | */ |
| 113 | - public function withProperties (array $props = []) :LocalDriver |
|
| 113 | + public function withProperties(array $props = []) :LocalDriver |
|
| 114 | 114 | {
|
| 115 | 115 | $this->props = array_merge($this->props, $props); |
| 116 | 116 | return $this; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | - private function parseUrl (string $url) |
|
| 119 | + private function parseUrl(string $url) |
|
| 120 | 120 | {
|
| 121 | 121 | $parse = parse_url($url); |
| 122 | 122 | $path = ""; |
@@ -131,7 +131,7 @@ discard block |
||
| 131 | 131 | $this->path = $path; |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | - private function checkCaseSensitive () |
|
| 134 | + private function checkCaseSensitive() |
|
| 135 | 135 | {
|
| 136 | 136 | if ((!$this->config['case_sensitive'] ?? null)) {
|
| 137 | 137 | // Remove upper cases from main string |
@@ -142,7 +142,7 @@ discard block |
||
| 142 | 142 | /** |
| 143 | 143 | * @return string |
| 144 | 144 | */ |
| 145 | - private function getNextShortpath () : string |
|
| 145 | + private function getNextShortpath() : string |
|
| 146 | 146 | {
|
| 147 | 147 | $tbl = (new Link)->getTable(); |
| 148 | 148 | // Get latest short_path(s) |
@@ -46,8 +46,9 @@ discard block |
||
| 46 | 46 | |
| 47 | 47 | // Check if given url has been shorten previously |
| 48 | 48 | $duplicate = Link::where(['long_path' => $this->path])->first(); |
| 49 | - if ($duplicate) |
|
| 50 | - return $duplicate->base_url . "/" . $duplicate->short_path; |
|
| 49 | + if ($duplicate) {
|
|
| 50 | + return $duplicate->base_url . "/" . $duplicate->short_path; |
|
| 51 | + } |
|
| 51 | 52 | |
| 52 | 53 | $short_path = $this->getNextShortpath(); |
| 53 | 54 | |
@@ -77,8 +78,9 @@ discard block |
||
| 77 | 78 | {
|
| 78 | 79 | $min_length = $this->config['min_length']; |
| 79 | 80 | $short_path = ""; |
| 80 | - for ($i = 0; $i < $min_length; $i++) |
|
| 81 | - $short_path .= $this->head; |
|
| 81 | + for ($i = 0; $i < $min_length; $i++) {
|
|
| 82 | + $short_path .= $this->head; |
|
| 83 | + } |
|
| 82 | 84 | return $short_path; |
| 83 | 85 | } |
| 84 | 86 | |
@@ -91,8 +93,9 @@ discard block |
||
| 91 | 93 | */ |
| 92 | 94 | private function findNextPerm (string $current_perm) :string |
| 93 | 95 | {
|
| 94 | - if (!strlen($current_perm)) |
|
| 95 | - return $this->head; |
|
| 96 | + if (!strlen($current_perm)) {
|
|
| 97 | + return $this->head; |
|
| 98 | + } |
|
| 96 | 99 | |
| 97 | 100 | $arr = array_reverse(str_split($current_perm)); |
| 98 | 101 | foreach($arr as $key => $current_char) {
|
@@ -120,12 +123,15 @@ discard block |
||
| 120 | 123 | {
|
| 121 | 124 | $parse = parse_url($url); |
| 122 | 125 | $path = ""; |
| 123 | - if ($parse['path'] ?? null) |
|
| 124 | - $path .= str::replaceFirst("/", "", $parse['path']);
|
|
| 125 | - if ($parse['query'] ?? null) |
|
| 126 | - $path .= "?" . $parse['query']; |
|
| 127 | - if ($parse['fragment'] ?? null) |
|
| 128 | - $path .= "#" . $parse['fragment']; |
|
| 126 | + if ($parse['path'] ?? null) {
|
|
| 127 | + $path .= str::replaceFirst("/", "", $parse['path']);
|
|
| 128 | + } |
|
| 129 | + if ($parse['query'] ?? null) {
|
|
| 130 | + $path .= "?" . $parse['query']; |
|
| 131 | + } |
|
| 132 | + if ($parse['fragment'] ?? null) {
|
|
| 133 | + $path .= "#" . $parse['fragment']; |
|
| 134 | + } |
|
| 129 | 135 | |
| 130 | 136 | $this->base_url = str_replace("/" . $path, "", $url);
|
| 131 | 137 | $this->path = $path; |
@@ -151,20 +157,21 @@ discard block |
||
| 151 | 157 | // so we must find the latest one(short_path) in the permutation of the main_str |
| 152 | 158 | $latest = collect(\DB::select("SELECT short_path FROM $tbl WHERE created_at = (SELECT MAX(created_at) FROM $tbl)"));
|
| 153 | 159 | |
| 154 | - if (!$latest->count()) |
|
| 155 | - return $this->getFirstUrl(); |
|
| 160 | + if (!$latest->count()) {
|
|
| 161 | + return $this->getFirstUrl(); |
|
| 162 | + } |
|
| 156 | 163 | |
| 157 | 164 | if ($latest->count() == 1) {
|
| 158 | 165 | return $this->findNextPerm($latest->first()->short_path); |
| 159 | - } |
|
| 160 | - else {
|
|
| 166 | + } else {
|
|
| 161 | 167 | foreach ($latest->reverse() as $key => $item) {
|
| 162 | 168 | $next = $this->findNextPerm($item->short_path); |
| 163 | 169 | |
| 164 | 170 | // If next permutation of current item is in fetched items |
| 165 | 171 | // find next permutation of the next fetched one |
| 166 | - if (!$latest->contains("short_path", $next))
|
|
| 167 | - return $next; |
|
| 172 | + if (!$latest->contains("short_path", $next)) {
|
|
| 173 | + return $next; |
|
| 174 | + } |
|
| 168 | 175 | } |
| 169 | 176 | } |
| 170 | 177 | } |