diff --git a/application/bootstrap.php b/application/bootstrap.php index 12383e5..f607299 100644 --- a/application/bootstrap.php +++ b/application/bootstrap.php @@ -40,7 +40,7 @@ ini_set('unserialize_callback_func', 'spl_autoload_call'); /** * Set the production status based on domain */ -define('IN_PRODUCTION', $_SERVER['HTTP_HOST'] != 'dev.zurl.ws:82'); +define('IN_PRODUCTION', !in_array($_SERVER['HTTP_HOST'], array('dev.zurl.ws:82', 'customzurltest.local', 'customzurltest2.local'))); //-- Configuration and initialization ----------------------------------------- diff --git a/application/classes/controller/url.php b/application/classes/controller/url.php index e315003..37f14c9 100644 --- a/application/classes/controller/url.php +++ b/application/classes/controller/url.php @@ -63,9 +63,15 @@ class Controller_Url extends Controller_Template { $post ->rule('domain_custom', 'Controller_Url::validate_domain') + ->rule('domain_alias', 'not_empty') ->filter('domain_alias', 'strtolower') ->rule('domain_alias', 'regex', array('~^[a-z0-9\-_]+$~')); } + elseif (Arr::get($_POST, 'type') == 'domain') + { + $post + ->rule('domain', 'Controller_Url::validate_domain'); + } } else { @@ -106,6 +112,11 @@ class Controller_Url extends Controller_Template { $url->and_where('user_id', '=', $this->user); $url->and_where('type', '=', $post['type']); + // For domain URLs, need to check the domain too + if ($post['type'] == 'domain') + $url->and_where('domain_id', '=', $post['domain']); + elseif ($post['type'] == 'domain_custom') + $url->and_where('domain_id', '=', $post['domain_custom']); } $url->find(); @@ -124,11 +135,20 @@ class Controller_Url extends Controller_Template $url->type = $post['type']; if (in_array($url->type, array('custom', 'user'))) $url->custom_alias = $post['alias']; + // Custom domain, custom alias elseif ($url->type == 'domain_custom') { $url->custom_alias = empty($post['domain_alias']) ? null : $post['domain_alias']; $url->domain_id = $post['domain_custom']; } + // Custom domain, "normal" alias + elseif ($url->type == 'domain') + { + $domain = ORM::factory('domain', $post['domain']); + $url->domain_id = $domain->id; + // Domain_url_id is a unique ID for this domain on this URL. + $url->domain_url_id = $domain->next_url_id(); + } } $url->save(); @@ -235,7 +255,15 @@ class Controller_Url extends Controller_Template // Try to find the URL they're talking about $url_pieces = parse_url($post['url']); - $url = Shortener::get_url(substr($url_pieces['path'], 1), $url_pieces['host']); + try + { + $url = Shortener::get_url(substr($url_pieces['path'], 1), $url_pieces['host']); + } + catch (Exception $ex) + { + // Use a dummy URL + $url = Model::factory('url'); + } // Is it a valid URL? if ($url != false && $url->loaded()) @@ -264,8 +292,12 @@ Email: ' . $post['email']; URL ID: ' . $url . ' Number of complaints: ' . $url->complaints; } + + $headers = array('From: "zURL Abuse" '); + if (!empty($post['email'])) + $headers[] = 'Reply-To: ' . $post['email']; - mail('zurl@d15.biz', '[URL ' . $url->id . '] ' . $post['url'], $email, 'From: "zURL Abuse" '); + mail('zurl@dan.cx', '[URL ' . $url->id . '] ' . $post['url'], $email, implode("\r\n", $headers), '-fabuse@zurl.ws'); $page = $this->template->body = new View('url/complaint_received'); } diff --git a/application/classes/model/url.php b/application/classes/model/url.php index 709333e..af88b91 100644 --- a/application/classes/model/url.php +++ b/application/classes/model/url.php @@ -23,11 +23,11 @@ class Model_Url extends ORM } elseif ($name == 'short_url') { - return self::get_short_url($this->id, $this->type, $this->custom_alias, $this->user_id, $this->domain_id); + return self::get_short_url($this->id, $this->type, $this->custom_alias, $this->user_id, $this->domain_id, $this->domain_url_id); } elseif ($name == 'preview_url') { - return self::get_preview_url($this->id, $this->type, $this->custom_alias, $this->user_id, $this->domain_id); + return self::get_preview_url($this->id, $this->type, $this->custom_alias, $this->user_id, $this->domain_id, $this->domain_url_id); } return parent::__get($name); @@ -71,12 +71,27 @@ class Model_Url extends ORM ->find(); } - public static function find_by_domain_custom($alias, $domain) + /** + * Find a URL on a custom domain, either by custom alias, or "normal" alias. + * @param string Alias in the URL + * @param int Domain ID + * @returns The URL, or null if not found + */ + public static function find_by_domain($alias, $domain) { return ORM::factory('url') - ->where('type', '=', 'domain_custom') ->where('domain_id', '=', $domain) - ->where('custom_alias', '=', $alias) + ->and_where_open() + ->or_where_open() + ->where('type', '=', 'domain_custom') + ->where('custom_alias', '=', $alias) + ->or_where_close() + ->or_where_open() + ->where('type', '=', 'domain') + ->where('domain_url_id', '=', Shortener::alias_to_id($alias)) + ->or_where_close() + ->and_where_close() + ->order_by('id') ->find(); } @@ -86,7 +101,7 @@ class Model_Url extends ORM //public static function get_short_url($id) // TODO: This is UUUUGLY! ///public static function get_short_url($row) - public static function get_short_url($id, $type, $custom_alias, $user_id, $domain_id = null) + public static function get_short_url($id, $type, $custom_alias, $user_id, $domain_id = null, $domain_url_id = null) { if (strstr($_SERVER['HTTP_HOST'], 'dev.zurl')) $base = 'dev.zurl.ws:82'; @@ -113,6 +128,11 @@ class Model_Url extends ORM return 'http://' . $domain->domain . '/' . $custom_alias; break; + case 'domain': + $domain = ORM::factory('domain', $domain_id); + return 'http://' . $domain->domain . '/' . Shortener::id_to_alias($domain_url_id); + break; + default: return 'http://' . $base . '/' . Shortener::id_to_alias($id); break; @@ -123,7 +143,7 @@ class Model_Url extends ORM * Get the preview URL for a URL * TODO: Remove duplication with get_short_url above */ - public static function get_preview_url($id, $type, $custom_alias, $user_id, $domain_id) + public static function get_preview_url($id, $type, $custom_alias, $user_id, $domain_id, $domain_url_id = null) { switch ($type) { @@ -139,6 +159,12 @@ class Model_Url extends ORM case 'domain_custom': $domain = ORM::factory('domain', $domain_id); return 'http://' . $domain->domain . '/p/' . $custom_alias; + break; + + case 'domain': + $domain = ORM::factory('domain', $domain_id); + return 'http://' . $domain->domain . '/p/' . Shortener::id_to_alias($domain_url_id); + break; default: return 'http://' . $_SERVER['HTTP_HOST'] . '/p/' . Shortener::id_to_alias($id); diff --git a/application/classes/shortener.php b/application/classes/shortener.php index 9a08cdb..2eefd1c 100644 --- a/application/classes/shortener.php +++ b/application/classes/shortener.php @@ -79,7 +79,9 @@ class Shortener if (!$domain->loaded()) throw new Exception('Domain ' . htmlspecialchars($hostname) . ' not found!'); - return Model_Url::find_by_domain_custom($alias, $domain); + // URL model handles differences between custom and standard aliases, so just pass the + // alias to it. + return Model_Url::find_by_domain($alias, $domain); } } } diff --git a/application/views/account/urls.php b/application/views/account/urls.php index 4599440..99e886b 100644 --- a/application/views/account/urls.php +++ b/application/views/account/urls.php @@ -61,7 +61,7 @@ foreach ($urls as $url) foreach ($visits as $visit) { $wrapped_url = chunk_split($visit->url, 15, '​'); - $short_url = Model_Url::get_short_url($visit->id, $visit->type, $visit->custom_alias, $visit->user_id, $visit->domain_id); + $short_url = Model_Url::get_short_url($visit->id, $visit->type, $visit->custom_alias, $visit->user_id, $visit->domain_id, $visit->domain_url_id); echo ' diff --git a/application/views/includes/url/shorten.php b/application/views/includes/url/shorten.php index aef5b2d..e4cf2b6 100644 --- a/application/views/includes/url/shorten.php +++ b/application/views/includes/url/shorten.php @@ -25,6 +25,14 @@ Due to spam, users are now required to create an account to use zURL. Sorry for

Type (what?): + + 'type_domain')); ?> + + + 'type_domain_custom')); ?> + + + 'type_standard')); ?> @@ -33,15 +41,14 @@ Due to spam, users are now required to create an account to use zURL. Sorry for 'type_user')); ?> - - 'type_domain_custom')); ?> - -

Short URL: http://.zurl.ws/

+

+ Domain: 'domain')); ?> +

Short URL: http:// 'domain_custom')); ?>/ diff --git a/res/script.js b/res/script.js index 8bb2445..3333650 100644 --- a/res/script.js +++ b/res/script.js @@ -72,6 +72,8 @@ var Shorten = { $('alias_p').setStyle('display', ''); $('prefix').set('html', 'c'); + if ($('domain_p')) + $('domain_p').setStyle('display', 'none'); if ($('domain_custom_p')) $('domain_custom_p').setStyle('display', 'none'); } @@ -79,12 +81,21 @@ var Shorten = { $('alias_p').setStyle('display', ''); $('prefix').set('html', $('current_user').get('text')); + if ($('domain_p')) + $('domain_p').setStyle('display', 'none'); if ($('domain_custom_p')) $('domain_custom_p').setStyle('display', 'none'); } + else if ($('type_domain') && $('type_domain').checked) + { + $('alias_p').setStyle('display', 'none'); + $('domain_p').setStyle('display', ''); + $('domain_custom_p').setStyle('display', 'none'); + } else if ($('type_domain_custom') && $('type_domain_custom').checked) { $('alias_p').setStyle('display', 'none'); + $('domain_p').setStyle('display', 'none'); $('domain_custom_p').setStyle('display', ''); } else @@ -92,6 +103,8 @@ var Shorten = $('alias_p').setStyle('display', 'none'); if ($('domain_custom_p')) $('domain_custom_p').setStyle('display', 'none'); + if ($('domain_p')) + $('domain_p').setStyle('display', 'none'); } } } diff --git a/zurl.sql b/zurl.sql index 507f883..37edb59 100644 --- a/zurl.sql +++ b/zurl.sql @@ -120,6 +120,7 @@ CREATE TABLE IF NOT EXISTS `urls` ( `type` enum('standard','custom','user','domain','domain_custom') NOT NULL DEFAULT 'standard', `custom_alias` varchar(255) DEFAULT NULL, `domain_id` int(10) unsigned DEFAULT NULL, + `domain_url_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;