diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8669f8b --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Ignore everything +/* +/*/ + +# Except Infinity Squared +!public/ +!index.php +!result.php +!header.php +!footer.php +!.gitignore + +# Specifically ignore the config file +public/config.php diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 5c82c9c..94cd850 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Infinity Squared ================ A beautiful theme for YOURLS, carefully crafted by [Tom Slominski](http://tomslominski.net/). -See the project's [Wiki pages](https://github.com/tomslominski/infinity-squared) at GitHub for the latest installation and upgrade instructions. +See the project's [Wiki pages](https://github.com/tomslominski/infinity-squared/wiki) at GitHub for the latest installation and upgrade instructions. qTip 2 is dual licensed under [MIT](http://en.wikipedia.org/wiki/MIT_License) or [GPLv2](http://en.wikipedia.org/wiki/GNU_General_Public_License) licenses. diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..9a5ef87 --- /dev/null +++ b/footer.php @@ -0,0 +1,16 @@ + +
+

+ + +

+

+

+
+ + + + + diff --git a/header.php b/header.php new file mode 100644 index 0000000..6ab0cd6 --- /dev/null +++ b/header.php @@ -0,0 +1,104 @@ + + + + + +<?php echo ISQ::$general['name']; ?> + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

+ +
+ +
diff --git a/index.php b/index.php old mode 100755 new mode 100644 index 1685691..de1f534 --- a/index.php +++ b/index.php @@ -1,196 +1,20 @@ - -' . yourls__( 'An error has occured :(', 'isq_translation') . ''; - -if ( $message = $url. yourls__( 'added to database', 'isq_translation') ) { - $error = '

' . yourls__( 'URL shortened successfully', 'isq_translation') . '

' . yourls__( 'View the details of your short URL below.', 'isq_translation') . '

'; - } elseif ( $message = $url. yourls__( 'already exists in database', 'isq_translation') ) { - $error = $genericerror . '

' . yourls__( 'This URL already exists in this database. This website does not allow a single URL to have multiple short links.', 'isq_translation') . '

'; - } elseif ( $message = yourls__( 'Short URL', 'isq_translation') . $url . yourls__( 'already exists in database or is reserved', 'isq_translation') ) { - $error = $genericerror . '

' . yourls__( 'This short URL already exists in this database or is reserved. This website does not allow a single URL to have multiple short links. It could\'ve also been reserved by the admin.', 'isq_translation') . '

'; - } elseif ( $message = yourls__( 'Missing URL input', 'isq_translation') ) { - $error = $genericerror . '

' . yourls__( 'You did not enter the URL you want to shorten or the server lost it. Please try again.', 'isq_translation') . '

'; - } elseif ( $message = yourls__( 'This URL is a short URL', 'isq_translation') ) { - $error = $genericerror . '

' . yourls__( 'You cannot shorten a short URL!', 'isq_translation') . '

'; - } -?> - - - -<?php echo $ISQtitle; ?> - - - - - - - - - - - - - - - - - -
-
-

- -
-
- Facebook'; } - if (!empty(ISQ::$social['twitter'])) { $ISQtwitter = ''; } - if (!empty(ISQ::$social['plus'])) { $ISQplus = '
'; } - if (!empty(ISQ::$social['linkedin'])) { $ISQlinkedin = ''; } - if (!empty(ISQ::$general['qr'])) { $ISQqr = '

' . yourls__( 'QR code', 'isq-translation' ) . '

' . yourls__( 'Share your code with external devices', 'isq-translation' ) . '

QR'; } - - $output_original = yourls__( 'Original URL:', 'isq_translation'); - $output_short = yourls__( 'Short URL:', 'isq_translation'); - /* translators: This is short for statistics */ - $output_stats = yourls__( 'Stats:', 'isq_translation'); - $output_copy = yourls__( 'Click on a link and press Ctrl+C to quickly copy it', 'isq_translation'); - $output_share_h2 = yourls__( 'Share', 'isq_translation'); - $output_share_p = yourls__( 'Share your short URL', 'isq_translation'); - - echo << -

-

-

-

$output_copy

-
- - $ISQqr - -

$output_share_h2

-

$output_share_p

- $ISQfacebook - $ISQtwitter - $ISQplus - $ISQlinkedin -RESULT; - - // Part to be executed when no form has been submitted - } else { - - $site = YOURLS_SITE; - - $site_enter = yourls__( 'Enter a new URL to shorten', 'isq_translation'); - $site_hover = yourls__( 'Hover over the labels to see more information', 'isq_translation'); - $site_long = yourls__( 'Long URL (required):', 'isq_translation'); - $site_long_hover = yourls__( 'Paste the long URL here', 'isq_translation'); - $site_keyword = yourls__( 'Custom keyword:', 'isq_translation'); - $site_keyword_hover = yourls__( 'A keyword replaces the default short string', 'isq_translation'); - $site_title = yourls__( 'Optional title:', 'isq_translation'); - $site_title_hover = yourls__( 'Optional title used when sharing a link from YOURLS', 'isq_translation'); - $site_submit = yourls__( 'Shorten', 'isq_translation'); - - echo <<$site_enter -

$site_hover

-
-

-

-

-

-
-HTML; - - } - ?> -
- -
-

-

- - - - - -
- - -
- - + + +

+

+
+

+

+

+

+ +

+
+ + diff --git a/public/CHANGELOG.md b/public/CHANGELOG.md old mode 100755 new mode 100644 diff --git a/public/config.php b/public/config-sample.php old mode 100755 new mode 100644 similarity index 67% rename from public/config.php rename to public/config-sample.php index 92f39d5..bf64523 --- a/public/config.php +++ b/public/config-sample.php @@ -1,10 +1,13 @@ 'kwl.me', // The name of your URL shortener + 'name' => 'URL shortener', // The name of your URL shortener 'qr' => 1, // Do you want to display a QR code? - 'mobile' => 0 // Do you want to enable the mobile version? + 'clipboard' => 1 // Do you want to enable zeroClipboard? (uses flash) ); // Menu- The width of ∞² menu allows you to have about 10 links @@ -38,6 +41,14 @@ ISQ::$social = array( 'facebook' => 1, 'twitter' => 1, 'plus' => 1, - 'linkedin' => 1 + 'linkedin' => 1, + 'tumblr' => 1 +); + +// reCAPTCHA API keys +// Get yourls from https://www.google.com/recaptcha/admin +ISQ::$recaptcha = array( + 'public' => '', + 'private' => '' ); ?> diff --git a/public/fonts/icons.svg b/public/fonts/icons.svg new file mode 100644 index 0000000..a222691 --- /dev/null +++ b/public/fonts/icons.svg @@ -0,0 +1,11 @@ + + + +Generated by IcoMoon + + + + + + + \ No newline at end of file diff --git a/public/fonts/icons.ttf b/public/fonts/icons.ttf new file mode 100644 index 0000000..09bb899 Binary files /dev/null and b/public/fonts/icons.ttf differ diff --git a/public/fonts/icons.woff b/public/fonts/icons.woff new file mode 100644 index 0000000..0ec1426 Binary files /dev/null and b/public/fonts/icons.woff differ diff --git a/public/formalize.css b/public/formalize.css old mode 100755 new mode 100644 diff --git a/public/img/button.png b/public/img/button.png old mode 100755 new mode 100644 diff --git a/public/img/facebook.png b/public/img/facebook.png old mode 100755 new mode 100644 diff --git a/public/img/noise.png b/public/img/noise.png old mode 100755 new mode 100644 diff --git a/public/img/select_arrow.gif b/public/img/select_arrow.gif old mode 100755 new mode 100644 diff --git a/public/img/tumblr.png b/public/img/tumblr.png new file mode 100644 index 0000000..2468c87 Binary files /dev/null and b/public/img/tumblr.png differ diff --git a/public/js/jquery.formalize.min.js b/public/js/jquery.formalize.min.js old mode 100755 new mode 100644 diff --git a/public/recaptchalib.php b/public/recaptchalib.php new file mode 100644 index 0000000..a08e52c --- /dev/null +++ b/public/recaptchalib.php @@ -0,0 +1,276 @@ + $value ) + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; + + // Cut the last '&' + $req=substr($req,0,strlen($req)-1); + return $req; +} + + + +/** + * Submits an HTTP POST to a reCAPTCHA server + * @param string $host + * @param string $path + * @param array $data + * @param int port + * @return array response + */ +function _recaptcha_http_post($host, $path, $data, $port = 80) { + + $req = _recaptcha_qsencode ($data); + + $http_request = "POST $path HTTP/1.0\r\n"; + $http_request .= "Host: $host\r\n"; + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; + $http_request .= "\r\n"; + $http_request .= $req; + + $response = ''; + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { + die ('Could not open socket'); + } + + fwrite($fs, $http_request); + + while ( !feof($fs) ) + $response .= fgets($fs, 1160); // One TCP-IP packet + fclose($fs); + $response = explode("\r\n\r\n", $response, 2); + + return $response; +} + + + +/** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey A public key for reCAPTCHA + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @return string - The HTML to be embedded in the user's form. + */ +function recaptcha_get_html ($pubkey, $error = null) +{ + if ($pubkey == null || $pubkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' + || $_SERVER['SERVER_PORT'] == 443) { // http://stackoverflow.com/questions/1175096/how-to-find-out-if-you-are-using-https-without-serverhttps + $server = RECAPTCHA_API_SECURE_SERVER; + } else { + $server = RECAPTCHA_API_SERVER; + } + + $errorpart = ""; + if ($error) { + $errorpart = "&error=" . $error; + } + return ' + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @param array $extra_params an array of extra variables to post to the server + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + $extra_params + ); + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://www.google.com/recaptcha/mailhide/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/public/style.css b/public/style.css old mode 100755 new mode 100644 index ab4911c..cd9c4f1 --- a/public/style.css +++ b/public/style.css @@ -3,6 +3,21 @@ Infinity Squared CSS https://github.com/tomslominski/infinity-squared */ +/* Structure */ +body { + background: #F1F1F1; + color: black; + font-family: 'Ubuntu', sans-serif, Helvetica, Arial; + font-size: 62.5%; +} + +#container { + width: 60%; + min-width: 720px; + margin: 0 auto; + background-color: white; +} + /* General */ ::selection { background: rgba(1,63,109,0.7); @@ -29,23 +44,30 @@ a, a:visited, .footer a, .footer a:visited { text-decoration: none; } -p { +p, a { font-size: 1.2em; } -/* Structure */ -body { - background: #F1F1F1; - color: black; - font-family: 'Ubuntu', sans-serif, Helvetica, Arial; - font-size: 62.5%; +@font-face { + font-family: 'icons'; + src:url('fonts/icons.woff') format('woff'), + url('fonts/icons.ttf') format('truetype'), + url('fonts/icons.svg#icons') format('svg'); + font-weight: normal; + font-style: normal; } -#container { - width: 60%; - min-width: 720px; - margin: 0 auto; - background-color: white; +[class^="icon-"], [class*=" icon-"] { + font-family: 'icons'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } /* Header */ @@ -88,7 +110,6 @@ h1 a:hover { color: white; padding: 0 2% 0 2%; margin-bottom: 30px; - font-size: 1.2em; } .menu a { @@ -134,22 +155,18 @@ h2 { float: right; } -a.bookmarklet { - border-radius: 11px; - background: #ddd url(../img/button.png) repeat-x; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #ddd)); - background: -moz-linear-gradient(top center, #fff 0%, #ddd 100%); - border: 1px solid; - border-color: #ddd #bbb #999; - cursor: pointer; - color: #333; - font: bold 12px/1.2 Arial, sans-serif; - outline: 0; - overflow: visible; - padding: 3px 10px 4px; - text-shadow: #fff 0 1px 1px; - text-decoration: none; - margin-right: 2%; +.radio { + margin-right: 10%; +} + +input[type="radio"] { + margin-right: 1%; +} + +.bookmarklet:before { + font-family: 'icons'; + content: "\e600"; + margin: 2px; } /* Tooltips */ @@ -178,6 +195,31 @@ a.bookmarklet { .error { color: red; + padding-bottom: 20px; + font-weight: bold; + text-align: center; + font-size: 1.2rem; +} + +.social-sharer { + display: inline-block; + padding: 0 2px; +} + +.output label { + width: 20%; +} + +.output input { + width: 60% +} + +.output button { + float: right; +} + +.output button.active { + color:#013F6D; } /* Footer */ @@ -193,6 +235,10 @@ a.bookmarklet { font-size: 1.1em; } +.footer a { + font-size: 1.1em; +} + .footer a:hover { text-decoration: none; border-bottom: dashed 1px #013F6D; @@ -221,7 +267,20 @@ header { margin-top:0; } -.desktop-only { +.desktop-only, .zclip { display:none; } } + +/* Error page */ +#wrap > h1 > a { + display: none; +} + +#wrap > h2, +#wrap > p { + color: red; +} + +/* Importing custom user styles */ +@import url("public/user-style.css"); diff --git a/result.php b/result.php new file mode 100644 index 0000000..c1dee16 --- /dev/null +++ b/result.php @@ -0,0 +1,60 @@ +is_valid) { + // What happens when the CAPTCHA was entered incorrectly + die ( '

' . yourls__( 'The reCAPTCHA wasn\'t entered correctly. Go back and try it again.', 'isq_translation' ) . '

' ); +} + +?> + + + + + +

+

+
+

' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . ''; } ?>

+

' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . ''; } ?>

+

' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . ''; } ?>

+

+
+ + +' . yourls__( 'QR code', 'isq-translation' ) . '

' . yourls__( 'Share your link with external devices', 'isq-translation' ) . '

QR'; } ?> + + +

+

+Facebook'; } ?> +Tweet'; } ?> +'; } ?> +'; } ?> +Share on Tumblr'; } ?> +