Updated to reflect live site
Signed-off-by: Sophia Atkinson <sophialul@protonmail.com>
@ -65,7 +65,7 @@ function ludo_blacklist_ip_form () {
|
||||
<input type="hidden" name="nonce" value="$nonce" />
|
||||
|
||||
<p>Blacklist following IPs (one range or IP per line, no wildcards allowed) :</p>
|
||||
<p><textarea cols="50" rows="10" name="blacklist_form">$liste_ip_display</textarea></p>
|
||||
<p><textarea class="blacklist-ips" cols="50" rows="10" name="blacklist_form">$liste_ip_display</textarea></p>
|
||||
|
||||
<p><input type="submit" value="Save" /></p>
|
||||
<p>I suggest to add here IPs that you saw adding bulk URL. It is your own responsibility to check the use of the IPs you block. WARNING : erroneous entries may create unexpected behaviours, please double-check before validation.</p>
|
||||
|
@ -65,8 +65,12 @@ function apelly_blacklist_domain_root ( $bol, $url ) {
|
||||
|
||||
// stop
|
||||
//yourls_die( 'Blacklisted domain', 'Forbidden', 403 );
|
||||
"<center>Blacklisted domain.</center>";
|
||||
die();
|
||||
return array(
|
||||
'status' => 'fail',
|
||||
'code' => 'error:url',
|
||||
'message' => 'Blacklisted domain',
|
||||
'errorCode' => '403',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,7 +108,7 @@ function apelly_blacklist_domain_form () {
|
||||
<input type="hidden" name="nonce" value="$nonce" />
|
||||
|
||||
<p>Blacklist following domains</p>
|
||||
<p><textarea cols="60" rows="15" name="blacklist_form">$domain_list_display</textarea></p>
|
||||
<p><textarea class="blacklist-domains" cols="60" rows="15" name="blacklist_form">$domain_list_display</textarea></p>
|
||||
|
||||
<p><input type="submit" value="Save" /></p>
|
||||
</form>
|
||||
|
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Anti spam
|
||||
Plugin URI: http://yourls.org/
|
||||
Description: Absolute anti-spam plugin. Checks URL against major black lists and removes all crap. Might OR MIGHT NOT work for you. Read the readme.
|
||||
Version: 1.0.4
|
||||
Author: Ozh
|
||||
Author URI: http://ozh.org/
|
||||
*/
|
||||
|
||||
|
||||
// Check for spam when someone adds a new link
|
||||
yourls_add_filter( 'shunt_add_new_link', 'ozh_yourls_antispam_check_add' );
|
||||
function ozh_yourls_antispam_check_add( $false, $url ) {
|
||||
// Sanitize URL and make sure there's a protocol
|
||||
$url = yourls_sanitize_url( $url );
|
||||
|
||||
// only check for 'http(s)'
|
||||
if( !in_array( yourls_get_protocol( $url ), array( 'http://', 'https://' ) ) )
|
||||
return $false;
|
||||
|
||||
if ( ozh_yourls_antispam_is_blacklisted( $url ) === yourls_apply_filter( 'ozh_yourls_antispam_malformed', 'malformed' ) ) {
|
||||
return array(
|
||||
'status' => 'fail',
|
||||
'code' => 'error:nourl',
|
||||
'message' => yourls__( 'Missing or malformed URL' ),
|
||||
'errorCode' => '400',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ozh_yourls_antispam_is_blacklisted( $url ) != false ) {
|
||||
return array(
|
||||
'status' => 'fail',
|
||||
'code' => 'error:spam',
|
||||
'message' => 'This domain is blacklisted',
|
||||
'errorCode' => '403',
|
||||
);
|
||||
}
|
||||
|
||||
// All clear, not interrupting the normal flow of events
|
||||
return $false;
|
||||
}
|
||||
|
||||
|
||||
// Has the remote link become compromised lately? Check on redirection
|
||||
yourls_add_action( 'redirect_shorturl', 'ozh_yourls_antispam_check_redirect' );
|
||||
function ozh_yourls_antispam_check_redirect( $url, $keyword = false ) {
|
||||
|
||||
if( is_array( $url ) && $keyword == false ) {
|
||||
$keyword = $url[1];
|
||||
$url = $url[0];
|
||||
}
|
||||
|
||||
// Check when the link was added
|
||||
// If shorturl is fresh (ie probably clicked more often?) check once every 15 times, otherwise once every 5 times
|
||||
// Define fresh = 3 days = 259200 secondes
|
||||
// TODO: when there's a shorturl_meta table, store last check date to allow checking every 2 or 3 days
|
||||
$now = date( 'U' );
|
||||
$then = date( 'U', strtotime( yourls_get_keyword_timestamp( $keyword ) ) );
|
||||
$chances = ( ( $now - $then ) > 259200 ? 15 : 5 );
|
||||
|
||||
if( $chances == mt_rand( 1, $chances ) ) {
|
||||
if( ozh_yourls_antispam_is_blacklisted( $url ) != false ) {
|
||||
// Delete link & die
|
||||
yourls_delete_link_by_keyword( $keyword );
|
||||
yourls_die( 'This domain has been blacklisted. This short URL has been deleted from our record.', 'Domain blacklisted', '403' );
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing, move along
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Is the link spam? true for "yes it's shit", false for "nope, safe"
|
||||
function ozh_yourls_antispam_is_blacklisted( $url ) {
|
||||
$parsed = parse_url( $url );
|
||||
|
||||
if( !isset( $parsed['host'] ) )
|
||||
return yourls_apply_filter( 'ozh_yourls_antispam_malformed', 'malformed' );
|
||||
|
||||
// Remove www. from domain (but not from www.com)
|
||||
$parsed['host'] = preg_replace( '/^www\.(.+\.)/i', '$1', $parsed['host'] );
|
||||
|
||||
// Major blacklists. There's a filter if you want to manipulate this.
|
||||
$blacklists = yourls_apply_filter( 'ozh_yourls_antispam_list',
|
||||
array(
|
||||
'dbl.spamhaus.org',
|
||||
'multi.surbl.org',
|
||||
)
|
||||
);
|
||||
|
||||
// Check against each blacklist, exit if blacklisted
|
||||
foreach( $blacklists as $blacklist ) {
|
||||
$domain = $parsed['host'] . '.' . $blacklist . '.';
|
||||
$record = @dns_get_record( $domain );
|
||||
|
||||
if( $record && count( $record ) > 0 )
|
||||
return yourls_apply_filter( 'ozh_yourls_antispam_blacklisted', true );
|
||||
}
|
||||
|
||||
// All clear, probably not spam
|
||||
return yourls_apply_filter( 'ozh_yourls_antispam_clean', false );
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
Plugin for YOURLS 1.5+: Antispam
|
||||
|
||||
# What for
|
||||
|
||||
This is a __merciless__ __antispam__ plugin that uses the three major blacklists (<a href="http://spamhaus.org">Spamhaus</a>, <a href="http://uribl.com/">URIBL</a> and <a href="http://surbl.org/">SURBL</a>).
|
||||
|
||||
URL are checked against the blacklist when short urls are created. They are also randomly checked when someone follows a short
|
||||
URL and if the link has been compromised recently, the short URL is deleted.
|
||||
|
||||
# How to
|
||||
|
||||
* In `/user/plugins`, create a new folder named `antispam`
|
||||
* Drop these files in that directory
|
||||
* Go to the Plugins administration page and activate the plugin
|
||||
* Have fun
|
||||
|
||||
# Disclaimer
|
||||
|
||||
Checking against blacklists may or may not work for you, this may depend on the type of spam you are getting and on other factors such as your server IP, your server ISP, the DNS you are using. It may even result in all domains being blacklisted from your server. Try and see.
|
@ -7,7 +7,7 @@ $theme: "dark";
|
||||
$lightest: #464646;
|
||||
$light: #313131;
|
||||
$default: #232323;
|
||||
$darker: #1d1d1d;
|
||||
$darker: #121212;
|
||||
$darkest: #161616;
|
||||
|
||||
// Accents
|
||||
|
@ -1,10 +1,10 @@
|
||||
<div class="top" id="add">
|
||||
<form id="new_url_form" action="javascript:add_link();" method="get">
|
||||
<label>Link</label>
|
||||
<input type="url" id="add-url" name="url" value="" class="text" placeholder="e.g. sleeky.flynntes.com" required>
|
||||
<input type="url" id="add-url" name="url" value="" class="text" placeholder="e.g. a.domain.com" required autocomplete="off">
|
||||
<label class="short">Short URL</label>
|
||||
<input type="text" id="add-keyword" name="keyword" value="" class="text" placeholder="e.g. theme">
|
||||
<input type="hidden" id="nonce-add" name="nonce-add" value="">
|
||||
<input type="button" id="add-button" name="add-button" value="Shorten" class="button" onclick="add_link();">
|
||||
<input type="text" id="add-keyword" name="keyword" value="" class="text" placeholder="e.g. theme" autocomplete="off">
|
||||
<input type="hidden" id="nonce-add" name="nonce-add" value="" autocomplete="off">
|
||||
<input type="button" id="add-button" name="add-button" value="Shorten" class="button" autocomplete="off" onclick="add_link();">
|
||||
</form>
|
||||
</div>
|
||||
|
BIN
user/plugins/backend/assets/img/favicon-16.webp
Normal file
After Width: | Height: | Size: 252 B |
BIN
user/plugins/backend/assets/img/favicon-32.webp
Normal file
After Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 13 KiB |
10
user/plugins/backend/assets/img/wordmark-black.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg class="iconLeft" data-v-423bf9ae="" viewBox="0 0 416 90" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(4.6332 0 0 4.6332 144.49 -1.8649)" data-v-423bf9ae="">
|
||||
<path d="m4.24 13.92q-0.71 0-1.39-0.35-0.68-0.34-1.16-0.9l0.69-0.6q0.85 0.98 1.95 0.98 0.64 0 1.06-0.27 0.42-0.28 0.42-0.77 0-0.31-0.15-0.55-0.14-0.25-0.46-0.45-0.31-0.2-0.56-0.31-0.24-0.12-0.69-0.28-0.53-0.21-0.86-0.38t-0.68-0.42-0.52-0.6q-0.17-0.34-0.17-0.77 0-0.82 0.67-1.32 0.68-0.5 1.73-0.5 1.47 0 2.4 1.09l-0.64 0.54q-0.8-0.77-1.79-0.77-0.66 0-1.05 0.26-0.39 0.25-0.39 0.68 0 0.21 0.1 0.39 0.11 0.19 0.23 0.31 0.13 0.11 0.41 0.26t0.45 0.21q0.16 0.06 0.53 0.2 0.56 0.21 0.86 0.36t0.71 0.43q0.42 0.28 0.6 0.66 0.19 0.39 0.19 0.91 0 0.89-0.67 1.42-0.67 0.54-1.82 0.54zm11.1-1q-0.91 1-2.4 1-1.5 0-2.4-0.99-0.91-0.99-0.91-2.75 0-1.75 0.91-2.75 0.9-1 2.4-1 1.49 0 2.4 0.98 0.9 0.99 0.9 2.75 0 1.75-0.9 2.76zm-2.4 0.11q1.07 0 1.68-0.76 0.6-0.76 0.6-2.11t-0.59-2.1-1.69-0.75q-1.12 0-1.7 0.73-0.59 0.74-0.59 2.14 0 1.36 0.59 2.11 0.59 0.74 1.7 0.74zm6.83 3.07-0.98 0.49v-10h0.98v0.65q0.42-0.39 0.87-0.6 0.44-0.21 1.13-0.21 1.44 0 2.28 1.01 0.83 1.02 0.83 2.72 0 1.77-0.85 2.76-0.85 1-2.2 1-1.29 0-2.06-0.9v3.08zm1.94-3.07q1.03 0 1.59-0.74t0.56-2.13q0-1.31-0.58-2.08-0.59-0.77-1.62-0.77-1.28 0-1.89 1.1v3.52q0.85 1.1 1.94 1.1zm9.1 0.65q-0.26 0.26-0.63 0.26-0.36 0-0.62-0.26-0.26-0.27-0.26-0.62t0.26-0.61q0.26-0.27 0.62-0.27 0.37 0 0.63 0.27 0.26 0.26 0.26 0.61t-0.26 0.62zm6.79 0.07h-0.92l-1.76-7.16h1l1.17 5.13q0.07 0.39 0.09 0.53 0.02-0.06 0.05-0.26 0.04-0.2 0.07-0.31l1.1-5.09h0.81l1.12 5.1q0.03 0.13 0.13 0.63 0.03-0.25 0.11-0.63l1.12-5.1h1.01l-1.76 7.16h-0.91l-1.11-4.87q-0.06-0.2-0.13-0.63-0.07 0.46-0.11 0.6l-1.08 4.9zm10.48 0.17q-1.7 0-1.7-1.71v-4.73h-1.69v-0.89h1.69v-2.46l0.98-0.49v2.95h2.4v0.89h-2.4v4.31q0 0.6 0.21 0.9 0.2 0.3 0.84 0.3 0.74 0 1.36-0.42l-0.11 1.02q-0.6 0.33-1.58 0.33zm9.1-9.23q-0.37 0-0.58 0.07-0.22 0.07-0.31 0.23t-0.11 0.3q-0.03 0.13-0.03 0.38v0.92h1.91v0.89h-1.91v5.39h1.91v0.88h-4.37v-0.88h1.48v-5.39h-1.48v-0.89h1.48v-1.07q0-0.93 0.53-1.33 0.52-0.41 1.38-0.41 0.74 0 1.5 0.34v0.88q-0.65-0.31-1.4-0.31z"/>
|
||||
</g>
|
||||
<g transform="matrix(1.4702 0 0 1.4702 -6.5121 -28.119)" data-v-423bf9ae="">
|
||||
<path d="M76.31 35.389H47.45c-9.202 0-16.853 6.692-18.39 15.46h10.653c1.267-3.025 4.257-5.156 7.737-5.156h28.86c4.625 0 8.389 3.76 8.389 8.385v7.838c0 4.625-3.764 8.387-8.389 8.387H47.45c-.062 0-.12-.017-.182-.018H30.764c3.077 6.111 9.392 10.322 16.687 10.322h28.86c10.306 0 18.69-8.385 18.69-18.691v-7.838C95 43.774 86.616 35.389 76.31 35.389z"/>
|
||||
<path d="M29.527 64.611l.001.004H40.97l-.004-.004H52.55c9.234 0 16.904-6.739 18.404-15.553H60.315c-1.246 3.072-4.252 5.249-7.766 5.249h-9.538v.004h-19.18v-.004h-.141a8.304 8.304 0 0 1-1.917-.242c-3.7-.872-6.471-4.183-6.471-8.146v-7.838c0-4.625 3.764-8.385 8.389-8.385h28.86c.059 0 .114.016.173.017h16.514c-3.077-6.11-9.392-10.321-16.687-10.321H23.69C13.384 19.394 5 27.779 5 38.082v7.838c0 9.778 7.55 17.812 17.124 18.612.518.043 1.037.079 1.566.079h5.837z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
BIN
user/plugins/backend/assets/img/wordmark-black.webp
Normal file
After Width: | Height: | Size: 3.9 KiB |
10
user/plugins/backend/assets/img/wordmark-white.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg class="iconLeft" data-v-423bf9ae="" viewBox="0 0 416 90" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(4.6332 0 0 4.6332 144.49 -1.8649)" fill="#fff" data-v-423bf9ae="">
|
||||
<path d="m4.24 13.92q-0.71 0-1.39-0.35-0.68-0.34-1.16-0.9l0.69-0.6q0.85 0.98 1.95 0.98 0.64 0 1.06-0.27 0.42-0.28 0.42-0.77 0-0.31-0.15-0.55-0.14-0.25-0.46-0.45-0.31-0.2-0.56-0.31-0.24-0.12-0.69-0.28-0.53-0.21-0.86-0.38t-0.68-0.42-0.52-0.6q-0.17-0.34-0.17-0.77 0-0.82 0.67-1.32 0.68-0.5 1.73-0.5 1.47 0 2.4 1.09l-0.64 0.54q-0.8-0.77-1.79-0.77-0.66 0-1.05 0.26-0.39 0.25-0.39 0.68 0 0.21 0.1 0.39 0.11 0.19 0.23 0.31 0.13 0.11 0.41 0.26t0.45 0.21q0.16 0.06 0.53 0.2 0.56 0.21 0.86 0.36t0.71 0.43q0.42 0.28 0.6 0.66 0.19 0.39 0.19 0.91 0 0.89-0.67 1.42-0.67 0.54-1.82 0.54zm11.1-1q-0.91 1-2.4 1-1.5 0-2.4-0.99-0.91-0.99-0.91-2.75 0-1.75 0.91-2.75 0.9-1 2.4-1 1.49 0 2.4 0.98 0.9 0.99 0.9 2.75 0 1.75-0.9 2.76zm-2.4 0.11q1.07 0 1.68-0.76 0.6-0.76 0.6-2.11t-0.59-2.1-1.69-0.75q-1.12 0-1.7 0.73-0.59 0.74-0.59 2.14 0 1.36 0.59 2.11 0.59 0.74 1.7 0.74zm6.83 3.07-0.98 0.49v-10h0.98v0.65q0.42-0.39 0.87-0.6 0.44-0.21 1.13-0.21 1.44 0 2.28 1.01 0.83 1.02 0.83 2.72 0 1.77-0.85 2.76-0.85 1-2.2 1-1.29 0-2.06-0.9v3.08zm1.94-3.07q1.03 0 1.59-0.74t0.56-2.13q0-1.31-0.58-2.08-0.59-0.77-1.62-0.77-1.28 0-1.89 1.1v3.52q0.85 1.1 1.94 1.1zm9.1 0.65q-0.26 0.26-0.63 0.26-0.36 0-0.62-0.26-0.26-0.27-0.26-0.62t0.26-0.61q0.26-0.27 0.62-0.27 0.37 0 0.63 0.27 0.26 0.26 0.26 0.61t-0.26 0.62zm6.79 0.07h-0.92l-1.76-7.16h1l1.17 5.13q0.07 0.39 0.09 0.53 0.02-0.06 0.05-0.26 0.04-0.2 0.07-0.31l1.1-5.09h0.81l1.12 5.1q0.03 0.13 0.13 0.63 0.03-0.25 0.11-0.63l1.12-5.1h1.01l-1.76 7.16h-0.91l-1.11-4.87q-0.06-0.2-0.13-0.63-0.07 0.46-0.11 0.6l-1.08 4.9zm10.48 0.17q-1.7 0-1.7-1.71v-4.73h-1.69v-0.89h1.69v-2.46l0.98-0.49v2.95h2.4v0.89h-2.4v4.31q0 0.6 0.21 0.9 0.2 0.3 0.84 0.3 0.74 0 1.36-0.42l-0.11 1.02q-0.6 0.33-1.58 0.33zm9.1-9.23q-0.37 0-0.58 0.07-0.22 0.07-0.31 0.23t-0.11 0.3q-0.03 0.13-0.03 0.38v0.92h1.91v0.89h-1.91v5.39h1.91v0.88h-4.37v-0.88h1.48v-5.39h-1.48v-0.89h1.48v-1.07q0-0.93 0.53-1.33 0.52-0.41 1.38-0.41 0.74 0 1.5 0.34v0.88q-0.65-0.31-1.4-0.31z"/>
|
||||
</g>
|
||||
<g transform="matrix(1.4702 0 0 1.4702 -6.5121 -28.119)" fill="#fff" data-v-423bf9ae="">
|
||||
<path d="M76.31 35.389H47.45c-9.202 0-16.853 6.692-18.39 15.46h10.653c1.267-3.025 4.257-5.156 7.737-5.156h28.86c4.625 0 8.389 3.76 8.389 8.385v7.838c0 4.625-3.764 8.387-8.389 8.387H47.45c-.062 0-.12-.017-.182-.018H30.764c3.077 6.111 9.392 10.322 16.687 10.322h28.86c10.306 0 18.69-8.385 18.69-18.691v-7.838C95 43.774 86.616 35.389 76.31 35.389z"/>
|
||||
<path d="M29.527 64.611l.001.004H40.97l-.004-.004H52.55c9.234 0 16.904-6.739 18.404-15.553H60.315c-1.246 3.072-4.252 5.249-7.766 5.249h-9.538v.004h-19.18v-.004h-.141a8.304 8.304 0 0 1-1.917-.242c-3.7-.872-6.471-4.183-6.471-8.146v-7.838c0-4.625 3.764-8.385 8.389-8.385h28.86c.059 0 .114.016.173.017h16.514c-3.077-6.11-9.392-10.321-16.687-10.321H23.69C13.384 19.394 5 27.779 5 38.082v7.838c0 9.778 7.55 17.812 17.124 18.612.518.043 1.037.079 1.566.079h5.837z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
BIN
user/plugins/backend/assets/img/wordmark-white.webp
Normal file
After Width: | Height: | Size: 3.9 KiB |
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Google Safe Browsing Lookup admin page
|
||||
*
|
||||
*/
|
||||
|
||||
// Display admin page
|
||||
function ozh_yourls_gsb_display_page() {
|
||||
|
||||
// Check if a form was submitted
|
||||
if( isset( $_POST['ozh_yourls_gsb'] ) ) {
|
||||
// Check nonce
|
||||
yourls_verify_nonce( 'gsb_page' );
|
||||
|
||||
// Process form
|
||||
ozh_yourls_gsb_update_option();
|
||||
}
|
||||
|
||||
// Get value from database
|
||||
$ozh_yourls_gsb = yourls_get_option( 'ozh_yourls_gsb' );
|
||||
|
||||
// Create nonce
|
||||
$nonce = yourls_create_nonce( 'gsb_page' );
|
||||
|
||||
echo <<<HTML
|
||||
<h2>Google Safe Browsing API Key</h2>
|
||||
|
||||
<p>Google requires you to have a <strong>Google account</strong> and a Safe Browsing <strong>API key</strong>
|
||||
to use their <a href="https://developers.google.com/safe-browsing/lookup_guide">Safe Browsing Lookup Service</a>.</p>
|
||||
<p>Get your API key here: <a href="https://developers.google.com/safe-browsing/key_signup">https://developers.google.com/safe-browsing/key_signup</a></p>
|
||||
|
||||
<h3>Disclaimer from Google</h3>
|
||||
<p>Google works to provide the most accurate and up-to-date phishing and malware information. However, it cannot
|
||||
guarantee that its information is comprehensive and error-free: some risky sites may not be identified, and some safe
|
||||
sites may be identified in error.</p>
|
||||
|
||||
<h3>Configure the plugin</h3>
|
||||
<form method="post">
|
||||
<input type="hidden" name="nonce" value="$nonce" />
|
||||
<p><label for="ozh_yourls_gsb">API Key</label> <input type="text" id="ozh_yourls_gsb" name="ozh_yourls_gsb" value="$ozh_yourls_gsb" size="70" /></p>
|
||||
<p><input type="submit" value="Update value" /></p>
|
||||
</form>
|
||||
HTML;
|
||||
}
|
||||
|
||||
// Update option in database
|
||||
function ozh_yourls_gsb_update_option() {
|
||||
$in = $_POST['ozh_yourls_gsb'];
|
||||
|
||||
if( $in ) {
|
||||
// Validate ozh_yourls_gsb: alpha & digits
|
||||
$in = preg_replace( '/[^a-zA-Z0-9-_]/', '', $in );
|
||||
|
||||
// Update value in database
|
||||
yourls_update_option( 'ozh_yourls_gsb', $in );
|
||||
|
||||
yourls_redirect( yourls_admin_url( 'plugins.php?page=ozh_yourls_gsb' ) );
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Google Safe Browsing Lookup client for YOURLS
|
||||
*
|
||||
*/
|
||||
|
||||
class ozh_yourls_GSB {
|
||||
|
||||
const PROTOCOL_VER = '4.0';
|
||||
const CLIENT = 'yourls-plugin-gsb';
|
||||
const APP_VER = '1.0';
|
||||
|
||||
private $url = '';
|
||||
private $api_key = false;
|
||||
|
||||
/**
|
||||
* Constructor : checks that plugin is properly configured
|
||||
*
|
||||
*/
|
||||
public function __construct( $api_key ) {
|
||||
$this->api_key = $api_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL is blacklisted against GSB Lookup API
|
||||
*
|
||||
* The function returns an array of a boolean and a string.
|
||||
* The boolean indicates whether $this->url is blacklisted (true) or not blacklisted (false)
|
||||
* The string gives diagnosis details: reason of blacklisting, null if clear, or an error message if applicable
|
||||
*
|
||||
* @return array array of boolean ( is blacklisted, description )
|
||||
*/
|
||||
public function is_blacklisted( $url ) {
|
||||
if( !$this->api_key ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->url = urlencode( yourls_sanitize_url( $url ) );
|
||||
if( !$this->url ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$request = $this->request();
|
||||
|
||||
switch( $request->status_code ) {
|
||||
case 200:
|
||||
$response = json_decode($request->body);
|
||||
$blacklisted = true;
|
||||
if (!isset($response->matches))
|
||||
$blacklisted = false;
|
||||
return array($blacklisted, ($blacklisted ? $response->matches[0]->threatType : null));
|
||||
|
||||
case 400:
|
||||
return array( false, 'Could not check Google Safe Browsing: Bad Request' );
|
||||
|
||||
case 403:
|
||||
return array( false, 'Could not check Google Safe Browsing: API key not authorized' );
|
||||
|
||||
case 503:
|
||||
return array( false, 'Could not check Google Safe Browsing: service unavailable' );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request wrapper
|
||||
*
|
||||
* @return Request request object
|
||||
*/
|
||||
private function request() {
|
||||
$api_url = sprintf( 'https://safebrowsing.googleapis.com/v4/threatMatches:find?key=%s',
|
||||
$this->api_key
|
||||
);
|
||||
|
||||
// Request headers
|
||||
$headers = array(
|
||||
'Content-Type' => 'application/json'
|
||||
);
|
||||
|
||||
// Request data
|
||||
$data = array(
|
||||
'client' => array(
|
||||
'clientId' => self::CLIENT,
|
||||
'clientVersion' => self::APP_VER
|
||||
),
|
||||
'threatInfo' => array(
|
||||
'threatTypes' => array('MALWARE', 'SOCIAL_ENGINEERING', 'POTENTIALLY_HARMFUL_APPLICATION', 'UNWANTED_SOFTWARE'),
|
||||
'platformTypes' => array('ANY_PLATFORM'),
|
||||
'threatEntryTypes' => array('URL'),
|
||||
'threatEntries' => array(
|
||||
array(
|
||||
'url' => $this->url
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Request options ?
|
||||
$options = array(
|
||||
);
|
||||
|
||||
return yourls_http_post( $api_url, $headers, json_encode($data), $options );
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Google Safe Browsing
|
||||
Plugin URI: https://github.com/yourls/google-safe-browsing/
|
||||
Description: Check new links against Google's Safe Browsing service
|
||||
Version: 1.1
|
||||
Author: Ozh
|
||||
Author URI: http://ozh.org/
|
||||
*/
|
||||
|
||||
|
||||
// No direct call
|
||||
if( !defined( 'YOURLS_ABSPATH' ) ) die();
|
||||
|
||||
yourls_add_filter( 'shunt_add_new_link', 'ozh_yourls_gsb_check_add' );
|
||||
|
||||
/**
|
||||
* Check for spam when someone adds a new link
|
||||
*
|
||||
* The filter used here is 'shunt_add_new_link', which passes in false as first argument. See
|
||||
* https://github.com/YOURLS/YOURLS/blob/1.7/includes/functions.php#L192-L194
|
||||
*
|
||||
* @param bool $false bool false is passed in by the filter 'shunt_add_new_link'
|
||||
* @param string $url URL to check, as passed in by the filter
|
||||
* @return mixed false if nothing to do, anything else will interrupt the flow of events
|
||||
*/
|
||||
function ozh_yourls_gsb_check_add( $false, $url ) {
|
||||
|
||||
list( $blacklisted, $desc ) = ozh_yourls_gsb_is_blacklisted( $url );
|
||||
|
||||
// If blacklisted, halt here
|
||||
if ( $blacklisted ) {
|
||||
return array(
|
||||
'status' => 'fail',
|
||||
'code' => 'error:' . $desc,
|
||||
'message' => 'This domain is blacklisted by Google Safe Browsing because of ' . $desc . ' suspicion. <a href="http://code.google.com/apis/safebrowsing/safebrowsing_faq.html#whyAdvisory" target="_blank">Read more</a>.',
|
||||
'errorCode' => '403',
|
||||
);
|
||||
}
|
||||
|
||||
// If not blacklisted but still unsure (error message), we should warn the user
|
||||
if( $desc ) {
|
||||
define( 'OZH_YOURLS_GSB_EXTRA_INFO', $desc );
|
||||
yourls_add_filter( 'add_new_link', 'ozh_yourls_gsb_extra_info' );
|
||||
}
|
||||
|
||||
// All clear, don't interrupt the normal flow of events
|
||||
return $false;
|
||||
}
|
||||
|
||||
yourls_add_action( 'plugins_loaded', 'ozh_yourls_gsb_add_page' );
|
||||
|
||||
/**
|
||||
* Register our plugin admin page
|
||||
*/
|
||||
function ozh_yourls_gsb_add_page() {
|
||||
yourls_register_plugin_page( 'ozh_yourls_gsb', 'Google Safe Browsing', 'ozh_yourls_gsb_admin_page' );
|
||||
|
||||
if( ! yourls_get_option( 'ozh_yourls_gsb' ) ) {
|
||||
ozh_yourls_gsb_please_configure();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra information to the notification when a link has been added
|
||||
*
|
||||
* @param array Array passed in by filter 'add_new_link'
|
||||
* @return array
|
||||
*/
|
||||
function ozh_yourls_gsb_extra_info( $return ) {
|
||||
$return['message'] .= '<br/>(' . OZH_YOURLS_GSB_EXTRA_INFO . ')';
|
||||
$return['status'] = 'error';
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL is blacklisted by Google Safe Browsing
|
||||
*
|
||||
* @param string $url URL to check
|
||||
* @return array array( (boolean)is_blacklisted, (string)description )
|
||||
*/
|
||||
function ozh_yourls_gsb_is_blacklisted( $url ) {
|
||||
include_once dirname( __FILE__ ) . '/includes/class-gsb.php';
|
||||
|
||||
$api_key = yourls_get_option( 'ozh_yourls_gsb' );
|
||||
if( !$api_key ) {
|
||||
ozh_yourls_gsb_please_configure();
|
||||
return false;
|
||||
}
|
||||
|
||||
$gsb = new ozh_yourls_GSB( $api_key );
|
||||
|
||||
return $gsb->is_blacklisted( $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the admin page
|
||||
*
|
||||
*/
|
||||
function ozh_yourls_gsb_admin_page() {
|
||||
include_once dirname( __FILE__ ) . '/includes/admin-page.php';
|
||||
ozh_yourls_gsb_display_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nag user about missing configuration
|
||||
*
|
||||
*/
|
||||
function ozh_yourls_gsb_please_configure() {
|
||||
yourls_add_notice( 'Plugin <strong>Google Safe Browsing</strong> is not configured' );
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
Plugin for YOURLS 1.7+: Google Safe Browsing
|
||||
|
||||
# What for
|
||||
|
||||
Check every new URL against Google's Safe Browsing Lookup service, reject those who are identified as malware or phishing
|
||||
|
||||
# How to
|
||||
|
||||
* In `/user/plugins`, create a new folder named `google-safe-browsing`
|
||||
* Drop these files in that directory
|
||||
* Go to the Plugins administration page and activate the plugin
|
||||
* Follow on-screen instructions
|
||||
* Have fun
|
||||
|
||||
# Disclaimer
|
||||
|
||||
Using this plugin requires you to understand Google's Safe Browsing TOS. In short:
|
||||
* you need a Google account
|
||||
* you are limited to a certain amount of queries per day (10,000 as of writing this)
|
||||
* you must understand that the service is not perfect.
|
||||
|
||||
[Read more](https://developers.google.com/safe-browsing/lookup_guide#AcceptableUsage)
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
// Project Honeypot http:BL plugin for Yourls - URL Shortener ~ Block Page Template
|
||||
// Copyright (c) 2016, Josh Panter
|
||||
|
||||
// No direct call
|
||||
if( !defined( 'YOURLS_ABSPATH' ) ) die();
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
?>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>ALERT!</title>
|
||||
<link rel="icon" href="%img%" type="image/png" />
|
||||
|
||||
<!-- Bootstrap core CSS -- USE LOCAL CACHE
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/spacelab/bootstrap.min.css" rel="stylesheet" integrity="sha384-L/tgI3wSsbb3f/nW9V6Yqlaw3Gj7mpE56LWrhew/c8MIhAYWZ/FNirA64AVkB5pI" crossorigin="anonymous"> -->
|
||||
|
||||
<!-- Bootstrap core CSS -- LOCAL CACHE -->
|
||||
<link href="%css%" rel="stylesheet" integrity="sha384-L/tgI3wSsbb3f/nW9V6Yqlaw3Gj7mpE56LWrhew/c8MIhAYWZ/FNirA64AVkB5pI" crossorigin="anonymous">
|
||||
|
||||
<!-- Add extra support of older browsers -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div style="padding:15px 0px 0px 0px;" class="col-md-6 col-md-offset-3">
|
||||
<div style="text-align: center;" class="well well-lg">
|
||||
<div style="display: inline-block; text-align: left">
|
||||
|
||||
<h2 class="text-danger" style="text-align:center;"><img src="%img%" width="30" height="30"/> Forbidden: Access Denied <img src="%img%" width="30" height="30"/></h2>
|
||||
</br>
|
||||
<p>Your IP: <strong>%ip%</strong>, has been flagged by <a href='https://www.projecthoneypot.org' target='_blank'>Project Honey Pot</a> due to the following:
|
||||
<ul>
|
||||
<li>Behavior Type: <strong>%typemeaning%</strong></li>
|
||||
<li>Threat Level: <strong>%threat%</strong></li>
|
||||
</ul>
|
||||
<p>Information regarding threat levels can be found <a href="https://www.projecthoneypot.org/threat_info.php" target="_blank">here</a>.</p>
|
||||
%greyList%
|
||||
<p style="display:none;">Otherwise, please have fun with <a href="http://planetozh.com/smelly.php">this page</a></p>
|
||||
<p>Thank you.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<footer>
|
||||
<script type="text/javascript">
|
||||
function setcookie( name, value, expires, path, domain, secure ) {
|
||||
// set time, it's in milliseconds
|
||||
var today = new Date();
|
||||
today.setTime( today.getTime() );
|
||||
|
||||
if ( expires ) {
|
||||
expires = expires * 1000 * 60 * 60 * 24;
|
||||
}
|
||||
var expires_date = new Date( today.getTime() + (expires) );
|
||||
|
||||
document.cookie = name + "=" +escape( value ) +
|
||||
( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
|
||||
( ( path ) ? ";path=" + path : "" ) +
|
||||
( ( domain ) ? ";domain=" + domain : "" ) +
|
||||
( ( secure ) ? ";secure" : "" );
|
||||
}
|
||||
function letmein() {
|
||||
setcookie('notabot','true',1,'/', '', '');
|
||||
location.reload(true);
|
||||
}
|
||||
</script>
|
||||
</footer>
|
||||
</html>
|
11
user/plugins/httpBL/assets/bootstrap.min.css
vendored
@ -1,18 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS `httpBL_log` (
|
||||
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
|
||||
`action` varchar(9) NOT NULL,
|
||||
`ip` varchar(255) NOT NULL,
|
||||
`type` varchar(50) NOT NULL,
|
||||
`threat` varchar(3) NOT NULL,
|
||||
`activity` varchar(255) NOT NULL,
|
||||
`page` varchar(255) NOT NULL,
|
||||
`ua` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`timestamp`)
|
||||
) ENGINE=INNODB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `httpBL_wl` (
|
||||
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
|
||||
`ip` varchar(255) NOT NULL,
|
||||
`notes` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`timestamp`)
|
||||
) ENGINE=INNODB DEFAULT CHARSET=latin1;
|
Before Width: | Height: | Size: 2.4 KiB |
@ -1,129 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
Please take a moment to review this document in order to make the contribution
|
||||
process easy and effective for everyone involved.
|
||||
|
||||
Submitting an issue that is improperly or incompletely written is a waste of time for everybody.
|
||||
|
||||
Following these guidelines helps to communicate that you respect the time of
|
||||
the developers managing and developing this open source project. In return,
|
||||
they should reciprocate that respect in addressing your issue or assessing
|
||||
patches and features.
|
||||
|
||||
|
||||
## Using the issue tracker
|
||||
|
||||
The issue tracker is the preferred channel for [bug reports](#bug-reports),
|
||||
[feature requests](#feature-requests) and [submitting pull
|
||||
requests](#pull-requests), but please respect the following restrictions:
|
||||
|
||||
* Please **do not** use the issue tracker for personal support requests.
|
||||
Use [discussions](https://github.com/telepathics/yourls-emojis/discussions) instead to ask the community for help.
|
||||
|
||||
* Please **do not** derail or troll issues.
|
||||
Keep the discussion on topic and respect the opinions of others.
|
||||
|
||||
|
||||
## Bug reports
|
||||
|
||||
A bug is a _demonstrable problem_ that is caused by the code in the repository.
|
||||
Good bug reports are extremely helpful - thank you!
|
||||
|
||||
Guidelines for bug reports:
|
||||
|
||||
1. **Use the GitHub issue search**
|
||||
Check if the issue has already been reported. Reporting duplicates is a waste of
|
||||
time for everyone. Search in **all issues**, open and closed.
|
||||
2. **Check if the issue has been fixed**
|
||||
Try to reproduce it using the latest `master` or development branch in the repository.
|
||||
Maybe it has been fixed since the last stable release.
|
||||
3. **Give details**
|
||||
A good bug report shouldn't leave others needing to chase you up for more
|
||||
information. Please try to be as detailed as possible in your report.
|
||||
Give any information that is relevant to the bug:
|
||||
* YOURLS & MySQL & PHP versions
|
||||
* Server Software
|
||||
* Browser name & version
|
||||
|
||||
What is the expected output? What do you see instead? See the report example below.
|
||||
7. **Isolate the problem**
|
||||
Isolate the problem as much as you can, reduce to the bare minimum required to reproduce the issue.
|
||||
Don't describe a general situation that doesn't work as expected and just count on us to pin
|
||||
point the problem.
|
||||
|
||||
|
||||
## Feature requests
|
||||
|
||||
Feature requests are welcome. But take a moment to find out whether your idea
|
||||
fits with the scope and aims of the project. It's up to *you* to make a strong
|
||||
case to convince the YOURLS developers of the merits of this feature. Please
|
||||
provide as much detail and context as possible.
|
||||
|
||||
|
||||
## Pull requests
|
||||
|
||||
Good pull requests - patches, improvements, new features - are a fantastic
|
||||
help. They should remain focused in scope and avoid containing unrelated
|
||||
commits.
|
||||
|
||||
1. **Please ask first**
|
||||
Before embarking on any significant pull request (e.g. implementing features,
|
||||
refactoring code), otherwise you risk spending a lot of time working on
|
||||
something that the developers might not want to merge into the project.
|
||||
2. **Licensing**
|
||||
By submitting a patch, you agree that your code will be licensed under the
|
||||
[MIT License](https://github.com/telepathics/yourls-emojis/blob/master/LICENSE) terms.
|
||||
3. **Coding Standards**
|
||||
Please adhere to the coding conventions used throughout the project (indentation,
|
||||
comments, etc.). Make sure you've tested your patch under
|
||||
different scenarios (various browsers, non default installation path, etc.).
|
||||
|
||||
Adhering to the following this process is the best way to get your work
|
||||
merged:
|
||||
|
||||
1. [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo), clone your fork,
|
||||
and configure the remotes.
|
||||
|
||||
```bash
|
||||
# Clone your fork of the repo into the current directory
|
||||
git clone https://github.com/<your-username>/<repo-name>
|
||||
# Navigate to the newly cloned directory
|
||||
cd <repo-name>
|
||||
# Assign the original repo to a remote called "upstream"
|
||||
git remote add upstream https://github.com/<upsteam-owner>/<repo-name>
|
||||
```
|
||||
|
||||
2. If you cloned a while ago, get the latest changes from upstream.
|
||||
|
||||
```bash
|
||||
git checkout <dev-branch>
|
||||
git pull upstream <dev-branch>
|
||||
```
|
||||
|
||||
3. Create a new topic branch (off the main project development branch) to
|
||||
contain your feature, change, or fix.
|
||||
|
||||
```bash
|
||||
git checkout -b <topic-branch-name>
|
||||
```
|
||||
|
||||
4. Commit your changes in logical chunks. Please adhere to these [git commit
|
||||
message guidelines](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
|
||||
or your code is unlikely be merged into the main project. Use Git's
|
||||
[interactive rebase](https://docs.github.com/en/github/using-git/about-git-rebase)
|
||||
feature to tidy up your commits before making them public.
|
||||
|
||||
5. Locally merge (or rebase) the upstream development branch into your topic branch:
|
||||
|
||||
```bash
|
||||
git pull [--rebase] upstream <dev-branch>
|
||||
```
|
||||
|
||||
6. Push your topic branch up to your fork:
|
||||
|
||||
```bash
|
||||
git push origin <topic-branch-name>
|
||||
```
|
||||
|
||||
10. [Open a Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
|
||||
with a clear title and description.
|
@ -1,3 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: telepathics
|
@ -1,36 +0,0 @@
|
||||
name: PHP Composer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate --strict
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
|
||||
# Docs: https://getcomposer.org/doc/articles/scripts.md
|
||||
|
||||
# - name: Run test suite
|
||||
# run: composer run-script test
|
@ -1,3 +0,0 @@
|
||||
.DS_Store
|
||||
/vendor/
|
||||
/build/
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 telepathics
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,34 +0,0 @@
|
||||
# YOURLS Emojis
|
||||
A YOURLS plugin that allows emojis in the custom short URLs.
|
||||
## Description
|
||||
Emojis in domain names and URLs are becoming increasingly popular, so I thought it would be fun to be able to include them in your YOURLS short codes.
|
||||
|
||||
[](https://github.com/YOURLS/awesome-yourls/)
|
||||
[](https://github.com/sponsors/telepathics)
|
||||
[](https://github.com/telepathics/yourls-emojis/actions/workflows/php.yml)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Unzip the [latest release](https://github.com/telepathics/yourls-emojis/releases) and move it into your YOURLS `/user/plugins` folder
|
||||
2. Visit your plugins page (e.g. https://sho.rt/admin/plugins.php)
|
||||
3. Activate the "Emojis" plugin by telepathics
|
||||
4. Have fun!
|
||||
|
||||
### Upgrading
|
||||
1. Delete (or replace) the old folder
|
||||
2. Follow aforementioned installation instructions
|
||||
|
||||
## Contributing
|
||||
|
||||
Feature suggestion? Bug to report?
|
||||
|
||||
__Before opening any issue, please search for existing [issues](https://github.com/telepathics/yourls-emojis/issues) (open and closed) and read the [Contributing Guidelines](https://github.com/telepathics/yourls-emojis/blob/main/.github/CONTRIBUTING.md).__
|
||||
|
||||
Also visit the living [to do](https://github.com/telepathics/yourls-emojis/projects/1) kanban board and [discussions](https://github.com/telepathics/yourls-emojis/discussions) page.
|
||||
|
||||
## License
|
||||
Released under the [MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
See also:
|
||||
[YOURLS](https://github.com/YOURLS/YOURLS) ♡
|
||||
[SteppingHat/php-emoji-detector](https://github.com/SteppingHat/php-emoji-detector) ♡ [unicode.org](https://unicode.org/Public/emoji/13.1/emoji-test.txt)
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "telepathics/yourls-emojis",
|
||||
"description": "A YOURLS plugin that allows emojis in the custom short URLs",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/telepathics/yourls-emojis",
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"steppinghat/emoji-detector": "^1.1"
|
||||
}
|
||||
}
|
63
user/plugins/telepathics-yourls-emojis/composer.lock
generated
@ -1,63 +0,0 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d8ae5b9fddab58bd68089f83a8564e1e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "steppinghat/emoji-detector",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SteppingHat/php-emoji-detector.git",
|
||||
"reference": "d2301e9553795e1ac2f3f2638438b3808654c57f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SteppingHat/php-emoji-detector/zipball/d2301e9553795e1ac2f3f2638438b3808654c57f",
|
||||
"reference": "d2301e9553795e1ac2f3f2638438b3808654c57f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^5.0@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SteppingHat\\EmojiDetector\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Javan Eskander",
|
||||
"homepage": "https://javaneskander.com"
|
||||
}
|
||||
],
|
||||
"description": "Detect and validate emoji in an input string",
|
||||
"homepage": "https://github.com/steppinghat/emoji-detector",
|
||||
"time": "2021-03-18T06:03:22+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Emojis
|
||||
Description: Create an emoji-only short link, like http://sho.rt/✨ or http://sho.rt/😎🆒🔗
|
||||
Version: 1.0
|
||||
Author: telepathics
|
||||
Author URI: https://telepathics.xyz
|
||||
*/
|
||||
|
||||
if( !defined( 'YOURLS_ABSPATH' ) ) die();
|
||||
require_once(__DIR__ . '/vendor/autoload.php');
|
||||
use SteppingHat\EmojiDetector;
|
||||
|
||||
/*
|
||||
* Accept detected emojis
|
||||
*/
|
||||
yourls_add_filter( 'get_shorturl_charset', 'path_emojis_in_charset');
|
||||
function path_emojis_in_charset($in) {
|
||||
return $in . file_get_contents(__DIR__ . '/util/emojis.txt');
|
||||
}
|
||||
|
||||
/*
|
||||
* Accepts URLs that are ONLY emojis
|
||||
*/
|
||||
yourls_add_filter( 'sanitize_url', 'path_emojis_sanitize_url' );
|
||||
function path_emojis_sanitize_url($unsafe_url) {
|
||||
$clean_url = '';
|
||||
$detector = new SteppingHat\EmojiDetector\EmojiDetector();
|
||||
$detect_emoji = $detector->detect(urldecode($unsafe_url));
|
||||
|
||||
if( sizeof($detect_emoji) > 0 ) {
|
||||
foreach ($detect_emoji as $emoji) {
|
||||
$clean_url .= $emoji->getEmoji();
|
||||
}
|
||||
return $clean_url;
|
||||
}
|
||||
return $unsafe_url;
|
||||
}
|
||||
|
||||
/*
|
||||
* filter wrong spacing whoopsies
|
||||
* see @link https://github.com/YOURLS/YOURLS/issues/1303
|
||||
*/
|
||||
yourls_add_filter( 'sanitize_url', 'fix_long_url' );
|
||||
function fix_long_url( $url, $unsafe_url ) {
|
||||
$search = array ( '%2520', '%2521', '%2522', '%2523', '%2524', '%2525', '%2526', '%2527', '%2528', '%2529', '%252A', '%252B', '%252C', '%252D', '%252E', '%252F', '%253D', '%253F', '%255C', '%255F' );
|
||||
$replace = array ( '%20', '%21', '%22', '%23', '%24', '%25', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%2D', '%2E', '%2F', '%3D', '%3F', '%5C', '%5F' );
|
||||
$url = str_ireplace ( $search, $replace ,$url );
|
||||
return yourls_apply_filter( 'after_fix_long_url', $url, $unsafe_url );
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* you can update the emoji list by changing the unicode link below
|
||||
* then, visit your site's /user/plugins/yourls-emojis/util/get_emojis.php page to run the script
|
||||
*
|
||||
* most recent 13.1 https://www.unicode.org/emoji/charts/full-emoji-list.html
|
||||
*/
|
||||
|
||||
if( !defined( 'YOURLS_ABSPATH' ) ) die();
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
/*
|
||||
* Last retrieved: April 11, 2021
|
||||
*/
|
||||
function get_emojis() {
|
||||
$detect_emoji = Emoji\detect_emoji(file_get_contents('https://unicode.org/Public/emoji/13.1/emoji-test.txt'));
|
||||
$file = fopen(__DIR__ . '/emojis.txt', 'w+');
|
||||
|
||||
if ( sizeof($detect_emoji) > 0 ) {
|
||||
foreach ( $detect_emoji as $emoji ) {
|
||||
fwrite($file, $emoji['emoji']);
|
||||
}
|
||||
}
|
||||
}
|
||||
get_emojis();
|
22
user/plugins/timezones/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Timezones [](https://github.com/YOURLS/awesome-yourls/)
|
||||
|
||||
A plugin to tell YOURLS your time zone and how you'd like times and dates displayed
|
||||
|
||||
Require [YOURLS](https://yourls.org) `1.7.10` and above.
|
||||
|
||||
## Usage
|
||||
|
||||
<kbd>
|
||||
<img src="https://user-images.githubusercontent.com/223647/81840321-1ecb1b80-9549-11ea-9c5f-aae25bc2f944.png" />
|
||||
</kbd>
|
||||
|
||||
## Installation
|
||||
|
||||
1. In `/user/plugins`, create a new folder named `timezones`.
|
||||
2. Drop these files in that directory.
|
||||
3. Go to the Plugins administration page (eg. `http://sho.rt/admin/plugins.php`) and activate the plugin.
|
||||
4. Have fun!
|
||||
|
||||
## License
|
||||
|
||||
Do whatever the hell you want with it
|
273
user/plugins/timezones/admin.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
/**
|
||||
* Time Zone plugin admin page
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display time zone configuration page
|
||||
*/
|
||||
function yourls_tzp_admin_page() {
|
||||
|
||||
// Check if a form was submitted
|
||||
if( isset( $_POST['time_zone'] ) ) {
|
||||
// Check nonce and process form
|
||||
yourls_verify_nonce( 'time_zone_config' );
|
||||
$options = yourls_tzp_config_update_settings();
|
||||
echo yourls_notice_box('Timezone settings updated');
|
||||
} else {
|
||||
$options = (array)yourls_get_option( 'timezone' );
|
||||
}
|
||||
|
||||
$user_time_zone = yourls_tzp_get_value($options, 'time_zone', 'UTC');
|
||||
$user_time_zone_display = $user_time_zone;
|
||||
if (substr($user_time_zone, 0, 1) == '+' or substr($user_time_zone, 0, 1) == '-') {
|
||||
$user_time_zone_display = 'UTC' . $user_time_zone_display;
|
||||
}
|
||||
$user_date_format = yourls_tzp_get_value($options, 'date_format', 'Y/m/d');
|
||||
$user_date_format_custom = yourls_tzp_get_value($options, 'date_format_custom', 'Y/m/d');
|
||||
$user_time_format = yourls_tzp_get_value($options, 'time_format', 'H:i');
|
||||
$user_time_format_custom = yourls_tzp_get_value($options, 'time_format_custom', 'H:i');
|
||||
|
||||
// Draw page
|
||||
yourls_tzp_js_css();
|
||||
print '<h2>Time Zone Configuration</h2>
|
||||
<p>This plugin allows to specify a time zone and to format time/date display</p>';
|
||||
|
||||
if( defined('YOURLS_HOURS_OFFSET') ) {
|
||||
print '<p><strong>Note:</strong> you have <code>YOURLS_HOURS_OFFSET</code> defined in your config.php. This plugin will override this setting.</p>';
|
||||
}
|
||||
|
||||
print '<form method="post">
|
||||
<input type="hidden" name="nonce" value="' . yourls_create_nonce( 'time_zone_config' ) . '" />';
|
||||
|
||||
// Time zones drop down
|
||||
print '<h3>Time zone: </h3>
|
||||
<div class="settings">
|
||||
<p>Choose a city near your location, in the same timezone as you, or a UTC time offset.</p>';
|
||||
yourls_tzp_tz_dropdown( $user_time_zone );
|
||||
print '<p>Universal time (<code>UTC</code>) time is: <tt id="utc_time">' . date( 'Y-m-d H:i:s', yourls_tzp_timezoned_timestamp( time(), 'UTC' ) ). '</tt></p>';
|
||||
if($user_time_zone) {
|
||||
print "<p>Time in <code>$user_time_zone_display</code> is: <tt id='local_time'>" . date( 'Y-m-d H:i:s', yourls_tzp_timezoned_timestamp( time(), $user_time_zone) ) . '</tt></p>';
|
||||
}
|
||||
print '</div>';
|
||||
|
||||
// Display radio button for date format
|
||||
$choices = array(
|
||||
'j F Y', // 13 April 2020
|
||||
'F j, Y', // May 10, 2020
|
||||
'd/m/Y', // 20/10/2020
|
||||
'm/d/Y', // 10/20/2020
|
||||
'Y/m/d', // 2020/10/20
|
||||
);
|
||||
yourls_tzp_format_radio( 'Date Format', 'date_format', $choices, $user_time_zone, $user_date_format, $user_date_format_custom );
|
||||
|
||||
// Display radio button for date format
|
||||
$choices = array(
|
||||
'H:i', // 21:23
|
||||
'g:i a', // 9:23 pm
|
||||
'g:i A', // 9:23 PM
|
||||
);
|
||||
yourls_tzp_format_radio( 'Time Format', 'time_format', $choices, $user_time_zone, $user_time_format, $user_time_format_custom );
|
||||
|
||||
print '<p><input type="submit" class="button primary" value="Update configuration" /></p>
|
||||
</form>
|
||||
<p><strong>Note:</strong> custom formats need a PHP <code><a href="https://php.net/date">date()</a></code> string.';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Output CSS & JS
|
||||
*/
|
||||
function yourls_tzp_js_css() {
|
||||
$plugin_url = yourls_plugin_url( __DIR__ );
|
||||
print <<<JSCSS
|
||||
<link href='$plugin_url/assets/select2.min.css' rel='stylesheet' />
|
||||
<script src='$plugin_url/assets/select2.min.js'></script>
|
||||
<script src='$plugin_url/assets/php-date-formatter.min.js'></script>
|
||||
<script>
|
||||
jQuery( document ).ready(function() {
|
||||
// auto select radio when custom input field is focused
|
||||
$('.custom :input').focusin(function() {
|
||||
$(this).prev().click();
|
||||
});
|
||||
|
||||
// easy selector on timezones
|
||||
$('#time_zone').select2({
|
||||
templateResult: format_region,
|
||||
placeholder:'Choose a time zone'
|
||||
});
|
||||
|
||||
// Real time date format preview
|
||||
$(".custom_format").on("keyup", function() {
|
||||
format_preview($(this).attr('id'), $(this).val());
|
||||
});
|
||||
|
||||
// Click a radio to change custom format accordingly
|
||||
$('.radio_format').change(
|
||||
function(){
|
||||
if (this.checked) {
|
||||
name = $(this).attr('name');
|
||||
value = $(this).attr('value');
|
||||
$('#'+name+'_custom_value').val(value).trigger($.Event("keyup"));
|
||||
}
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
// Real time preview of date/time format
|
||||
function format_preview(id, value) {
|
||||
if($('#local_time')) {
|
||||
time = $('#local_time').text();
|
||||
} else {
|
||||
time = $('#utc_time').text();
|
||||
}
|
||||
id = id.replace('_custom_value', '');
|
||||
fmt = new DateFormatter();
|
||||
parse = fmt.parseDate(time, 'Y-m-d H:i:s');
|
||||
format = fmt.formatDate(parse, value );
|
||||
$('#tz_test_' + id).text(format);
|
||||
}
|
||||
|
||||
// modify dropdown list
|
||||
function format_region(item) {
|
||||
if (!item.id) {
|
||||
return item.text;
|
||||
}
|
||||
var text = item.text.split('/');
|
||||
var region=text[0];
|
||||
var city=text[1];
|
||||
return $('<span class="region">'+region+'</span> '+city+'</span>');
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
text-align:left;
|
||||
}
|
||||
h3 {
|
||||
border-bottom:1px solid #ccc;
|
||||
}
|
||||
div.settings {
|
||||
padding-bottom:1em;
|
||||
}
|
||||
.region{
|
||||
color:#aaa;
|
||||
font-style:italic;
|
||||
}
|
||||
</style>
|
||||
JSCSS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the time zone drop down
|
||||
*
|
||||
* @param string $user_time_zone Timezone to be marked as "selected" in the dropdown
|
||||
*/
|
||||
function yourls_tzp_tz_dropdown( $user_time_zone ) {
|
||||
// Continent list
|
||||
$continent = array(
|
||||
'Africa' => DateTimeZone::AFRICA,
|
||||
'America' => DateTimeZone::AMERICA,
|
||||
'Antarctica' => DateTimeZone::ANTARCTICA,
|
||||
'Asia' => DateTimeZone::ASIA,
|
||||
'Atlantic' => DateTimeZone::ATLANTIC,
|
||||
'Australia' => DateTimeZone::AUSTRALIA,
|
||||
'Europe' => DateTimeZone::EUROPE,
|
||||
'Indian' => DateTimeZone::INDIAN,
|
||||
'Pacific' => DateTimeZone::PACIFIC,
|
||||
);
|
||||
|
||||
// Timezones per continents
|
||||
$timezones = array();
|
||||
foreach ($continent as $name => $mask) {
|
||||
$zones = DateTimeZone::listIdentifiers($mask);
|
||||
foreach($zones as $timezone) {
|
||||
// Remove region name
|
||||
$timezones[$name][$timezone] = substr($timezone, strlen($name) +1);
|
||||
}
|
||||
}
|
||||
|
||||
// Manual UTC offset
|
||||
$offset_range = array(
|
||||
'-12', '-11:30', '-11', '-10:30', '-10', '-9.5', '-9',
|
||||
'-8:30', '-8', '-7:30', '-7', '-6:30', '-6', '-5:30',
|
||||
'-5', '-4:30', '-4', '-3:30', '-3', '-2:30', '-2',
|
||||
'-1:30', '-1', '-0:30', 'UTC', '+0:30', '+1', '+1:30',
|
||||
'+2', '+2:30', '+3', '+3:30', '+4', '+4:30', '+5',
|
||||
'+5:30', '+5:45', '+6', '+6:30', '+7', '+7:30', '+8',
|
||||
'+8:30', '+8:45', '+9', '+9:30', '+10', '+10:30', '+11',
|
||||
'+11:30', '+12', '+12:45', '+13', '+13:45', '+14'
|
||||
);
|
||||
|
||||
foreach( $offset_range as $offset_name ) {
|
||||
$offset_value = $offset_name;
|
||||
$offset_name = str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), $offset_name );
|
||||
if ($offset_name != 'UTC') {
|
||||
$offset_name = 'UTC' . $offset_name;
|
||||
}
|
||||
// $offset_value = 'UTC' . $offset_value;
|
||||
$timezones['UTC'][$offset_value] = $offset_name;
|
||||
}
|
||||
|
||||
print '<select name="time_zone" id="time_zone">';
|
||||
print '<option value="" dzisabled="dzisabled">Choose a time zone</option>';
|
||||
foreach($timezones as $region => $list) {
|
||||
print '<optgroup label="' . $region . '">' . "\n";
|
||||
foreach($list as $timezone => $name) {
|
||||
print '<option value="' . $timezone . '" ' . (($timezone == $user_time_zone) ? "selected='selected'":"") . '>' . "$region/$name" . '</option>' . "\n";
|
||||
}
|
||||
print '<optgroup>' . "\n";
|
||||
}
|
||||
print '</select>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output radio button list
|
||||
*
|
||||
* @param string $title Dropdown title
|
||||
* @param string $input_name Dropdown 'radio' name
|
||||
* @param array $formats List of available choices, to which 'custom' will be appended
|
||||
* @param string $tz Time zone
|
||||
* @param string $selected Checked radio value
|
||||
* @param string $custom Custom format value
|
||||
*/
|
||||
function yourls_tzp_format_radio( $title, $input_name, $formats, $tz, $selected, $custom ) {
|
||||
print "<h3>$title:</h3>
|
||||
<div class='settings'>";
|
||||
|
||||
foreach ($formats as $format) {
|
||||
$checked = ( $format === $selected ) ? 'checked="checked"' : '' ;
|
||||
print "<p><label><input type='radio' class='radio_format radio_$input_name' name='$input_name' value='$format' $checked >";
|
||||
print yourls_date_i18n( $format, yourls_tzp_timezoned_timestamp( time(), $tz ), true );
|
||||
print "</label></p>\n";
|
||||
}
|
||||
|
||||
$checked = ( 'custom' === $selected ) ? 'checked="checked"' : '' ;
|
||||
$preview = date( $custom, yourls_tzp_timezoned_timestamp( time(), $tz ) );
|
||||
print "<label class='custom'><input type='radio' id='${input_name}_custom' name='$input_name' value='custom' $checked >
|
||||
Custom: <input type='text' class='text custom_format' id='${input_name}_custom_value' name='${input_name}_custom_value' value='$custom' />
|
||||
<span class='tz_test' id='tz_test_$input_name'>$preview</span>
|
||||
</label>\n";
|
||||
|
||||
print '</div>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update time zone in database
|
||||
*/
|
||||
function yourls_tzp_config_update_settings() {
|
||||
|
||||
$settings = array(
|
||||
'time_zone' => yourls_tzp_get_value($_POST, 'time_zone', 'UTC'),
|
||||
'date_format' => yourls_tzp_get_value($_POST, 'date_format', 'Y/m/d'),
|
||||
'date_format_custom' => yourls_tzp_get_value($_POST, 'date_format_custom_value', 'Y/m/d'),
|
||||
'time_format' => yourls_tzp_get_value($_POST, 'time_format', 'H:i'),
|
||||
'time_format_custom' => yourls_tzp_get_value($_POST, 'time_format_custom_value', 'H:i'),
|
||||
);
|
||||
|
||||
yourls_update_option( 'timezone', $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
13
user/plugins/timezones/assets/php-date-formatter.min.js
vendored
Normal file
1
user/plugins/timezones/assets/select2.min.css
vendored
Normal file
2
user/plugins/timezones/assets/select2.min.js
vendored
Normal file
124
user/plugins/timezones/plugin.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Time Zones ⏰
|
||||
Plugin URI: https://github.com/YOURLS/timezones
|
||||
Description: Tell YOURLS what timezone you are in
|
||||
Version: 1.3
|
||||
Author: YOURLS contributors
|
||||
Author URI: https://yourls.org/
|
||||
*/
|
||||
|
||||
// No direct call
|
||||
if( !defined( 'YOURLS_ABSPATH' ) ) die();
|
||||
|
||||
/**
|
||||
* Register plugin admin page
|
||||
*/
|
||||
yourls_add_action( 'plugins_loaded', 'yourls_tzp_config' );
|
||||
function yourls_tzp_config() {
|
||||
if( yourls_is_admin() ) {
|
||||
require_once __DIR__ . '/admin.php';
|
||||
}
|
||||
yourls_register_plugin_page( 'time_zone_config', 'Time Zone Configuration', 'yourls_tzp_admin_page' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for time offset
|
||||
*/
|
||||
yourls_add_filter( 'get_time_offset', 'yourls_tzp_get_time_offset' );
|
||||
function yourls_tzp_get_time_offset() {
|
||||
return yourls_tzp_timezoned_offset( yourls_tzp_read_options( 'time_zone', 'UTC' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for timestamps
|
||||
*/
|
||||
yourls_add_filter( 'get_timestamp', 'yourls_tzp_get_timestamp' );
|
||||
function yourls_tzp_get_timestamp($timestamp_offset, $timestamp, $offset) {
|
||||
return yourls_tzp_timezoned_timestamp( $timestamp, yourls_tzp_read_options( 'time_zone', 'UTC' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for date + time format
|
||||
*/
|
||||
yourls_add_filter( 'get_datetime_format', 'yourls_tzp_get_datetime_format' );
|
||||
function yourls_tzp_get_datetime_format() {
|
||||
return yourls_tzp_get_date_format() . ' ' . yourls_tzp_get_time_format();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for date (no time) format
|
||||
*/
|
||||
yourls_add_filter( 'get_date_format', 'yourls_tzp_get_date_format' );
|
||||
function yourls_tzp_get_date_format() {
|
||||
$date_format = yourls_tzp_read_options('date_format', 'Y/m/d');
|
||||
if( $date_format == 'custom' ) {
|
||||
$date_format = yourls_tzp_read_options('date_format_custom', 'Y/m/d');
|
||||
}
|
||||
return $date_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for time (no date) format
|
||||
*/
|
||||
yourls_add_filter( 'get_time_format', 'yourls_tzp_get_time_format' );
|
||||
function yourls_tzp_get_time_format() {
|
||||
$time_format = yourls_tzp_read_options('time_format', 'H:i');
|
||||
if( $time_format == 'custom' ) {
|
||||
$time_format = yourls_tzp_read_options('time_format_custom', 'H:i');
|
||||
}
|
||||
|
||||
return $time_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return time offset of a timezone from UTC
|
||||
*
|
||||
* @param string $timezone Optional timezone (eg "Europe/Paris"). Default is UTC
|
||||
* @return int Timezoned time offset
|
||||
*/
|
||||
function yourls_tzp_timezoned_offset($timezone = 'UTC') {
|
||||
$tz = new DateTime('now', new DateTimeZone($timezone));
|
||||
return $tz->getOffset()/3600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return timezoned and formatted time
|
||||
*
|
||||
* @param int $timestamp Optional timestamp. If omitted, function will use time()
|
||||
* @param string $timezone Optional timezone (eg "Europe/Paris"). Default is UTC
|
||||
* @param string $format Optional format as what PHP's date() needs. Default it 'U' (epoch)
|
||||
* @return string Timezoned and formatted time
|
||||
*/
|
||||
function yourls_tzp_timezoned_timestamp($timestamp = false, $timezone = 'UTC') {
|
||||
$timestamp = $timestamp ? $timestamp : time();
|
||||
$offset = yourls_tzp_timezoned_offset($timezone);
|
||||
return $timestamp + $offset * 3600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (string)key from array, or return false if not defined
|
||||
*
|
||||
* @param array $array Array
|
||||
* @param string $key Key
|
||||
* @return string Value of (string)$array[$key], or false
|
||||
*/
|
||||
function yourls_tzp_get_value( $array, $key, $default ) {
|
||||
return isset ( $array[$key] ) ? (string)($array[$key]) : $default ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read timezone options from the DB, and return all keys or specified key
|
||||
*
|
||||
* @param string $key Key of timezone option array
|
||||
* @return array|mixed Array of options, or value for specified key if exists (false otherwise)
|
||||
*/
|
||||
function yourls_tzp_read_options( $key = false, $default = false ) {
|
||||
$options = (array)yourls_get_option( 'timezone' );
|
||||
|
||||
if( $key !== false ) {
|
||||
$options = array_key_exists($key, $options) ? $options[$key] : $default ;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
@ -42,12 +42,17 @@ function dd_preview_show( $keyword ) {
|
||||
$qrcode = 'https://api.qrserver.com/v1/create-qr-code/?size=256x256&format=svg&bgcolor=1D1D1D&color=fff&charset-source=UTF-8&ecc=H&data='.YOURLS_SITE.'/'.$keyword;
|
||||
|
||||
echo <<<HTML
|
||||
<h2>Link Preview</h2>
|
||||
<style>
|
||||
div.nav-open#navOpen{
|
||||
display: none
|
||||
}
|
||||
</style>
|
||||
<h2 class="linkpre">Link Preview</h2>
|
||||
<p>You requested the short URL <strong><a href="$base/$keyword">$base/$keyword</a></strong></p>
|
||||
<p>This short URL points to:</p>
|
||||
<ul>
|
||||
<li>Long URL: <strong><a href="$base/$keyword">$url</a></strong></li>
|
||||
<li>Page title: <strong>$title</strong></li>
|
||||
<li>Long URL: <strong class="qrurl"><a href="$base/$keyword">$url</a></strong></li>
|
||||
<li>Page title: <strong class="qrurl">$title</strong></li>
|
||||
<li>QR Code: <br><img src="$qrcode"></li>
|
||||
</ul>
|
||||
<p>If you still want to visit this link, please <strong><a href="$base/$keyword">click here</a></strong>.</p>
|
||||
|