mirror of
https://github.com/xodivorce/xeorl.git
synced 2025-12-19 00:02:57 +05:30
v4.2.6
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
### Xeorl - The All-In-One, Fully Free to Use Advanced Link Shortener and Management Tool - Powered by [@xodivorce](https://instagram.com/xodivorce) ✨
|
||||
[](https://github.com/xeorl/xeorl-portfolio/)
|
||||
[](https://github.com/xeorl/xeorl-portfolio/)
|
||||
[](https://github.com/xeorl/xeorl-portfolio/)
|
||||
[](https://github.com/xeorl/xeorl-portfolio/)
|
||||
<br></br>
|
||||
|
||||
|
||||
BIN
htdocs/.DS_Store
vendored
BIN
htdocs/.DS_Store
vendored
Binary file not shown.
@@ -25,7 +25,9 @@ if (!isset($_SESSION['user_id'])) {
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/_monetization.css">
|
||||
<link rel="stylesheet" href="assets/css/_account.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<?php include "assets/_header.php"; ?>
|
||||
|
||||
BIN
htdocs/assets/.DS_Store
vendored
BIN
htdocs/assets/.DS_Store
vendored
Binary file not shown.
@@ -15,9 +15,9 @@
|
||||
</script>
|
||||
</p>
|
||||
<div class="footer-links">
|
||||
<a href="#">Privacy</a>
|
||||
<a href="#">Terms</a>
|
||||
<a href="#">Contact</a>
|
||||
<a href="https://docs.google.com/document/d/1sZ2TwjST8nKaRl-rSteAd2XHlVZdDhgS6jHRKwjDedc/edit?usp=sharing">Privacy</a>
|
||||
<a href="https://docs.google.com/document/d/1QcUohit6U3ZmWyOZbggbpUr2KrQ6pwy3X-R4zUGfZBo/edit?usp=sharing">Terms</a>
|
||||
<a href="home.php">Contact</a>
|
||||
<a href="https://github.com/xodivorce/xeorl" target="_blank" >Github</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ if (session_status() === PHP_SESSION_NONE) {
|
||||
<div class="logo">
|
||||
<img src="assets/images/url.png" alt="Xeorl Logo" class="logo-img">
|
||||
<span>Xeorl</span>
|
||||
<span class="version-number">4.2.5</span>
|
||||
<span class="version-number">4.2.6</span>
|
||||
</div>
|
||||
|
||||
<label class="burger">
|
||||
|
||||
@@ -1,120 +1,12 @@
|
||||
/* General Styles */
|
||||
body {
|
||||
font-family: "Montserrat", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
color: #111313;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* User Image */
|
||||
.user-image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: -5px;
|
||||
border-radius: 50%;
|
||||
margin-left: 25px;
|
||||
border: 1px solid #ffffff;
|
||||
}
|
||||
|
||||
/* Sidebar Styles */
|
||||
.sidebar {
|
||||
width: 20%;
|
||||
background-color: #ffffff;
|
||||
color: #98E5DD;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: solid 1px rgb(58, 66, 65);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Sidebar Header (Flexbox) */
|
||||
.sidebar .sidebar-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* Allows wrapping when screen is small */
|
||||
align-items: center; /* Ensures vertical alignment */
|
||||
margin-left: -25px;
|
||||
margin-right: -20px;
|
||||
|
||||
margin-top: 45px;
|
||||
}
|
||||
|
||||
/* Image & Text Flexbox */
|
||||
.sidebar .sidebar-header .user-image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.4;
|
||||
color: #171c24;
|
||||
|
||||
}
|
||||
|
||||
.user-email {
|
||||
color: #677583;
|
||||
}
|
||||
|
||||
/* Sidebar Links */
|
||||
.sidebar a {
|
||||
text-decoration: none;
|
||||
color: #171c24;
|
||||
padding: 15px;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
transition: background-color 0.3s ease; /* Keep only background-color for transition */
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.content {
|
||||
width: 80%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.content h2, .content h3 {
|
||||
color: #EEB58F;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media screen and (max-width: 768px) {
|
||||
body {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.sidebar .sidebar-header {
|
||||
justify-content: flex-start;
|
||||
text-align: center;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.sidebar .sidebar-header .user-image {
|
||||
margin-left: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
main {
|
||||
padding: 60px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
BIN
htdocs/core/.DS_Store
vendored
BIN
htdocs/core/.DS_Store
vendored
Binary file not shown.
@@ -1,22 +0,0 @@
|
||||
Copyright (c) 2009 Abraham Williams - http://abrah.am - abraham@abrah.am
|
||||
|
||||
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,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Use to autoload needed classes without Composer.
|
||||
*
|
||||
* @param string $class The fully-qualified class name.
|
||||
* @return void
|
||||
*/
|
||||
spl_autoload_register(function ($class) {
|
||||
// project-specific namespace prefix
|
||||
$prefix = 'Abraham\\TwitterOAuth\\';
|
||||
|
||||
// base directory for the namespace prefix
|
||||
$base_dir = __DIR__ . '/src/';
|
||||
|
||||
// does the class use the namespace prefix?
|
||||
$len = strlen($prefix);
|
||||
if (strncmp($prefix, $class, $len) !== 0) {
|
||||
// no, move to the next registered autoloader
|
||||
return;
|
||||
}
|
||||
|
||||
// get the relative class name
|
||||
$relative_class = substr($class, $len);
|
||||
|
||||
// replace the namespace prefix with the base directory, replace namespace
|
||||
// separators with directory separators in the relative class name, append
|
||||
// with .php
|
||||
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
|
||||
|
||||
// if the file exists, require it
|
||||
if (file_exists($file)) {
|
||||
require $file;
|
||||
}
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"name": "abraham/twitteroauth",
|
||||
"type": "library",
|
||||
"description": "The most popular PHP library for use with the Twitter OAuth REST API.",
|
||||
"keywords": [
|
||||
"twitter",
|
||||
"api",
|
||||
"oauth",
|
||||
"rest",
|
||||
"social",
|
||||
"twitter api",
|
||||
"twitter oauth"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "https://twitteroauth.com",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Abraham Williams",
|
||||
"email": "abraham@abrah.am",
|
||||
"homepage": "https://abrah.am",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/abraham/twitteroauth",
|
||||
"issues": "https://github.com/abraham/twitteroauth/issues"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/abraham/phpunit-testlistener-vcr"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "8.*",
|
||||
"ext-curl": "*",
|
||||
"composer/ca-bundle": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
"squizlabs/php_codesniffer": "^3",
|
||||
"phpmd/phpmd": "^2",
|
||||
"php-vcr/php-vcr": "^1",
|
||||
"php-vcr/phpunit-testlistener-vcr": "dev-php8",
|
||||
"rector/rector": "^0.15.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Abraham\\TwitterOAuth\\": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
3470
htdocs/core/vendor/abraham/twitteroauth/composer.lock
generated
vendored
3470
htdocs/core/vendor/abraham/twitteroauth/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
* Handle setting and storing config for TwitterOAuth.
|
||||
*
|
||||
* @author Abraham Williams <abraham@abrah.am>
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
// Update extension function when updating this list.
|
||||
private const SUPPORTED_VERSIONS = ['1.1', '2'];
|
||||
|
||||
/** @var int How long to wait for a response from the API */
|
||||
protected $timeout = 5;
|
||||
/** @var int how long to wait while connecting to the API */
|
||||
protected $connectionTimeout = 5;
|
||||
/** @var int How many times we retry request when API is down */
|
||||
protected $maxRetries = 0;
|
||||
/** @var int Delay in seconds before we retry the request */
|
||||
protected $retriesDelay = 1;
|
||||
/** @var string Version of the Twitter API requests should target */
|
||||
protected $apiVersion = '2';
|
||||
|
||||
/**
|
||||
* Decode JSON Response as associative Array
|
||||
*
|
||||
* @see http://php.net/manual/en/function.json-decode.php
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $decodeJsonAsArray = false;
|
||||
/** @var string User-Agent header */
|
||||
protected $userAgent = 'TwitterOAuth (+https://twitteroauth.com)';
|
||||
/** @var array Store proxy connection details */
|
||||
protected $proxy = [];
|
||||
|
||||
/** @var bool Whether to encode the curl requests with gzip or not */
|
||||
protected $gzipEncoding = true;
|
||||
|
||||
/** @var integer Size for Chunked Uploads */
|
||||
protected $chunkSize = 250000; // 0.25 MegaByte
|
||||
|
||||
/**
|
||||
* Set the the Twitter API version.
|
||||
*
|
||||
* @param string $apiVersion
|
||||
*/
|
||||
public function setApiVersion(string $apiVersion): void
|
||||
{
|
||||
if (in_array($apiVersion, self::SUPPORTED_VERSIONS, true)) {
|
||||
$this->apiVersion = $apiVersion;
|
||||
} else {
|
||||
throw new TwitterOAuthException('Unsupported API version');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection and response timeouts.
|
||||
*
|
||||
* @param int $connectionTimeout
|
||||
* @param int $timeout
|
||||
*/
|
||||
public function setTimeouts(int $connectionTimeout, int $timeout): void
|
||||
{
|
||||
$this->connectionTimeout = $connectionTimeout;
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of times to retry on error and how long between each.
|
||||
*
|
||||
* @param int $maxRetries
|
||||
* @param int $retriesDelay
|
||||
*/
|
||||
public function setRetries(int $maxRetries, int $retriesDelay): void
|
||||
{
|
||||
$this->maxRetries = $maxRetries;
|
||||
$this->retriesDelay = $retriesDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setDecodeJsonAsArray(bool $value): void
|
||||
{
|
||||
$this->decodeJsonAsArray = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userAgent
|
||||
*/
|
||||
public function setUserAgent(string $userAgent): void
|
||||
{
|
||||
$this->userAgent = $userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $proxy
|
||||
*/
|
||||
public function setProxy(array $proxy): void
|
||||
{
|
||||
$this->proxy = $proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to encode the curl requests with gzip or not.
|
||||
*
|
||||
* @param boolean $gzipEncoding
|
||||
*/
|
||||
public function setGzipEncoding(bool $gzipEncoding): void
|
||||
{
|
||||
$this->gzipEncoding = $gzipEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of each part of file for chunked media upload.
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setChunkSize(int $value): void
|
||||
{
|
||||
$this->chunkSize = $value;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Consumer
|
||||
{
|
||||
/** @var string */
|
||||
public $key;
|
||||
/** @var string */
|
||||
public $secret;
|
||||
/** @var string|null */
|
||||
public $callbackUrl;
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @param string|null $secret
|
||||
* @param null $callbackUrl
|
||||
*/
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $secret,
|
||||
?string $callbackUrl = null,
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callbackUrl = $callbackUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return "Consumer[key=$this->key,secret=$this->secret]";
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
||||
* where the Signature Base String is the text and the key is the concatenated values (each first
|
||||
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
||||
* character (ASCII code 38) even if empty.
|
||||
* - Chapter 9.2 ("HMAC-SHA1")
|
||||
*/
|
||||
class HmacSha1 extends SignatureMethod
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'HMAC-SHA1';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function buildSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
): string {
|
||||
$signatureBase = $request->getSignatureBaseString();
|
||||
|
||||
$parts = [$consumer->secret, null !== $token ? $token->secret : ''];
|
||||
|
||||
$parts = Util::urlencodeRfc3986($parts);
|
||||
$key = implode('&', $parts);
|
||||
|
||||
return base64_encode(hash_hmac('sha1', $signatureBase, $key, true));
|
||||
}
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Request
|
||||
{
|
||||
protected $parameters;
|
||||
protected $httpMethod;
|
||||
protected $httpUrl;
|
||||
public static $version = '1.0';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $httpMethod
|
||||
* @param string $httpUrl
|
||||
* @param ?array $parameters
|
||||
*/
|
||||
public function __construct(
|
||||
string $httpMethod,
|
||||
string $httpUrl,
|
||||
?array $parameters = [],
|
||||
) {
|
||||
$parameters = array_merge(
|
||||
Util::parseParameters(parse_url($httpUrl, PHP_URL_QUERY)),
|
||||
$parameters,
|
||||
);
|
||||
$this->parameters = $parameters;
|
||||
$this->httpMethod = $httpMethod;
|
||||
$this->httpUrl = $httpUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* pretty much a helper function to set up the request
|
||||
*
|
||||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
* @param string $httpMethod
|
||||
* @param string $httpUrl
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public static function fromConsumerAndToken(
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
string $httpMethod,
|
||||
string $httpUrl,
|
||||
array $parameters = [],
|
||||
array $options = [],
|
||||
) {
|
||||
$defaults = [
|
||||
'oauth_version' => Request::$version,
|
||||
'oauth_nonce' => Request::generateNonce(),
|
||||
'oauth_timestamp' => time(),
|
||||
'oauth_consumer_key' => $consumer->key,
|
||||
];
|
||||
if (null !== $token) {
|
||||
$defaults['oauth_token'] = $token->key;
|
||||
}
|
||||
|
||||
// The json payload is not included in the signature on json requests,
|
||||
// therefore it shouldn't be included in the parameters array.
|
||||
if ($options['jsonPayload'] ?? false) {
|
||||
$parameters = $defaults;
|
||||
} else {
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
}
|
||||
|
||||
return new Request($httpMethod, $httpUrl, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function setParameter(string $name, string $value)
|
||||
{
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getParameter(string $name): ?string
|
||||
{
|
||||
return $this->parameters[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function removeParameter(string $name): void
|
||||
{
|
||||
unset($this->parameters[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The request parameters, sorted and concatenated into a normalized string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignableParameters(): string
|
||||
{
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
||||
// Remove oauth_signature if present
|
||||
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
||||
if (isset($params['oauth_signature'])) {
|
||||
unset($params['oauth_signature']);
|
||||
}
|
||||
|
||||
return Util::buildHttpQuery($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base string of this request
|
||||
*
|
||||
* The base string defined as the method, the url
|
||||
* and the parameters (normalized), each urlencoded
|
||||
* and the concated with &.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignatureBaseString(): string
|
||||
{
|
||||
$parts = [
|
||||
$this->getNormalizedHttpMethod(),
|
||||
$this->getNormalizedHttpUrl(),
|
||||
$this->getSignableParameters(),
|
||||
];
|
||||
|
||||
$parts = Util::urlencodeRfc3986($parts);
|
||||
|
||||
return implode('&', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP Method in uppercase
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedHttpMethod(): string
|
||||
{
|
||||
return strtoupper($this->httpMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the url and rebuilds it to be
|
||||
* scheme://host/path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedHttpUrl(): string
|
||||
{
|
||||
$parts = parse_url($this->httpUrl);
|
||||
|
||||
$scheme = $parts['scheme'];
|
||||
$host = strtolower($parts['host']);
|
||||
$path = $parts['path'];
|
||||
|
||||
return "$scheme://$host$path";
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a url usable for a GET request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toUrl(): string
|
||||
{
|
||||
$postData = $this->toPostdata();
|
||||
$out = $this->getNormalizedHttpUrl();
|
||||
if ($postData) {
|
||||
$out .= '?' . $postData;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the data one would send in a POST request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toPostdata(): string
|
||||
{
|
||||
return Util::buildHttpQuery($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Authorization: header
|
||||
*
|
||||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
public function toHeader(): string
|
||||
{
|
||||
$first = true;
|
||||
$out = 'Authorization: OAuth';
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != 'oauth') {
|
||||
continue;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
throw new TwitterOAuthException(
|
||||
'Arrays not supported in headers',
|
||||
);
|
||||
}
|
||||
$out .= $first ? ' ' : ', ';
|
||||
$out .=
|
||||
Util::urlencodeRfc3986($k) .
|
||||
'="' .
|
||||
Util::urlencodeRfc3986($v) .
|
||||
'"';
|
||||
$first = false;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureMethod $signatureMethod
|
||||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
*/
|
||||
public function signRequest(
|
||||
SignatureMethod $signatureMethod,
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
) {
|
||||
$this->setParameter(
|
||||
'oauth_signature_method',
|
||||
$signatureMethod->getName(),
|
||||
);
|
||||
$signature = $this->buildSignature($signatureMethod, $consumer, $token);
|
||||
$this->setParameter('oauth_signature', $signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureMethod $signatureMethod
|
||||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildSignature(
|
||||
SignatureMethod $signatureMethod,
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
): string {
|
||||
return $signatureMethod->buildSignature($this, $consumer, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function generateNonce(): string
|
||||
{
|
||||
return md5(microtime() . random_int(PHP_INT_MIN, PHP_INT_MAX));
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
* The result of the most recent API request.
|
||||
*
|
||||
* @author Abraham Williams <abraham@abrah.am>
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/** @var string|null API path from the most recent request */
|
||||
private ?string $apiPath = null;
|
||||
/** @var int HTTP status code from the most recent request */
|
||||
private int $httpCode = 0;
|
||||
/** @var array HTTP headers from the most recent request */
|
||||
private array $headers = [];
|
||||
/** @var array|object|null Response body from the most recent request */
|
||||
private array|object|null $body = [];
|
||||
/** @var array HTTP headers from the most recent request that start with X */
|
||||
private array $xHeaders = [];
|
||||
|
||||
/**
|
||||
* @param string $apiPath
|
||||
*/
|
||||
public function setApiPath(string $apiPath): void
|
||||
{
|
||||
$this->apiPath = $apiPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApiPath(): ?string
|
||||
{
|
||||
return $this->apiPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|object $body
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|object|string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $httpCode
|
||||
*/
|
||||
public function setHttpCode(int $httpCode): void
|
||||
{
|
||||
$this->httpCode = $httpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHttpCode(): int
|
||||
{
|
||||
return $this->httpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
*/
|
||||
public function setHeaders(array $headers): void
|
||||
{
|
||||
foreach ($headers as $key => $value) {
|
||||
if (substr($key, 0, 1) == 'x') {
|
||||
$this->xHeaders[$key] = $value;
|
||||
}
|
||||
}
|
||||
$this->headers = $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getsHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $xHeaders
|
||||
*/
|
||||
public function setXHeaders(array $xHeaders = []): void
|
||||
{
|
||||
$this->xHeaders = $xHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getXHeaders(): array
|
||||
{
|
||||
return $this->xHeaders;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
* A class for implementing a Signature Method
|
||||
* See section 9 ("Signing Requests") in the spec
|
||||
*/
|
||||
abstract class SignatureMethod
|
||||
{
|
||||
/**
|
||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* Build up the signature
|
||||
* NOTE: The output of this function MUST NOT be urlencoded.
|
||||
* the encoding is handled in OAuthRequest when the final
|
||||
* request is serialized
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function buildSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token = null,
|
||||
);
|
||||
|
||||
/**
|
||||
* Verifies that a given signature is correct
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Consumer $consumer
|
||||
* @param Token $token
|
||||
* @param string $signature
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkSignature(
|
||||
Request $request,
|
||||
Consumer $consumer,
|
||||
Token $token,
|
||||
string $signature,
|
||||
): bool {
|
||||
$built = $this->buildSignature($request, $consumer, $token);
|
||||
|
||||
// Check for zero length, although unlikely here
|
||||
if (strlen($built) == 0 || strlen($signature) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($built) != strlen($signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid a timing leak with a (hopefully) time insensitive compare
|
||||
$result = 0;
|
||||
for ($i = 0; $i < strlen($signature); $i++) {
|
||||
$result |= ord($built[$i]) ^ ord($signature[$i]);
|
||||
}
|
||||
|
||||
return $result == 0;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Token
|
||||
{
|
||||
/** @var string */
|
||||
public $key;
|
||||
/** @var string */
|
||||
public $secret;
|
||||
|
||||
/**
|
||||
* @param string $key The OAuth Token
|
||||
* @param string $secret The OAuth Token Secret
|
||||
*/
|
||||
public function __construct(?string $key, ?string $secret)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the basic string serialization of a token that a server
|
||||
* would respond to request_token and access_token calls with
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'oauth_token=%s&oauth_token_secret=%s',
|
||||
Util::urlencodeRfc3986($this->key),
|
||||
Util::urlencodeRfc3986($this->secret),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,837 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The most popular PHP library for use with the Twitter OAuth REST API.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
use Abraham\TwitterOAuth\{
|
||||
Consumer,
|
||||
HmacSha1,
|
||||
Response,
|
||||
Token,
|
||||
Util\JsonDecoder,
|
||||
};
|
||||
use Composer\CaBundle\CaBundle;
|
||||
|
||||
/**
|
||||
* TwitterOAuth class for interacting with the Twitter API.
|
||||
*
|
||||
* @author Abraham Williams <abraham@abrah.am>
|
||||
*/
|
||||
class TwitterOAuth extends Config
|
||||
{
|
||||
private const API_HOST = 'https://api.twitter.com';
|
||||
private const UPLOAD_HOST = 'https://upload.twitter.com';
|
||||
|
||||
/** @var Response details about the result of the last request */
|
||||
private ?Response $response = null;
|
||||
/** @var string|null Application bearer token */
|
||||
private ?string $bearer = null;
|
||||
/** @var Consumer Twitter application details */
|
||||
private Consumer $consumer;
|
||||
/** @var Token|null User access token details */
|
||||
private ?Token $token = null;
|
||||
/** @var HmacSha1 OAuth 1 signature type used by Twitter */
|
||||
private HmacSha1 $signatureMethod;
|
||||
/** @var int Number of attempts we made for the request */
|
||||
private int $attempts = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $consumerKey The Application Consumer Key
|
||||
* @param string $consumerSecret The Application Consumer Secret
|
||||
* @param ?string $oauthToken The Client Token (optional)
|
||||
* @param ?string $oauthTokenSecret The Client Token Secret (optional)
|
||||
*/
|
||||
public function __construct(
|
||||
string $consumerKey,
|
||||
string $consumerSecret,
|
||||
?string $oauthToken = null,
|
||||
?string $oauthTokenSecret = null,
|
||||
) {
|
||||
$this->resetLastResponse();
|
||||
$this->signatureMethod = new HmacSha1();
|
||||
$this->consumer = new Consumer($consumerKey, $consumerSecret);
|
||||
if (!empty($oauthToken) && !empty($oauthTokenSecret)) {
|
||||
$this->setOauthToken($oauthToken, $oauthTokenSecret);
|
||||
}
|
||||
if (empty($oauthToken) && !empty($oauthTokenSecret)) {
|
||||
$this->setBearer($oauthTokenSecret);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oauthToken
|
||||
* @param string $oauthTokenSecret
|
||||
*/
|
||||
public function setOauthToken(
|
||||
string $oauthToken,
|
||||
string $oauthTokenSecret,
|
||||
): void {
|
||||
$this->token = new Token($oauthToken, $oauthTokenSecret);
|
||||
$this->bearer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oauthTokenSecret
|
||||
*/
|
||||
public function setBearer(string $oauthTokenSecret): void
|
||||
{
|
||||
$this->bearer = $oauthTokenSecret;
|
||||
$this->token = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLastApiPath(): ?string
|
||||
{
|
||||
return $this->response->getApiPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLastHttpCode(): int
|
||||
{
|
||||
return $this->response->getHttpCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLastXHeaders(): array
|
||||
{
|
||||
return $this->response->getXHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|object|null
|
||||
*/
|
||||
public function getLastBody()
|
||||
{
|
||||
return $this->response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the last response cache.
|
||||
*/
|
||||
public function resetLastResponse(): void
|
||||
{
|
||||
$this->response = new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the attempts number.
|
||||
*/
|
||||
private function resetAttemptsNumber(): void
|
||||
{
|
||||
$this->attempts = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays the retries when they're activated.
|
||||
*/
|
||||
private function sleepIfNeeded(): void
|
||||
{
|
||||
if ($this->maxRetries && $this->attempts) {
|
||||
sleep($this->retriesDelay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make URLs for user browser navigation.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url(string $path, array $parameters): string
|
||||
{
|
||||
$this->resetLastResponse();
|
||||
$this->response->setApiPath($path);
|
||||
$query = http_build_query($parameters);
|
||||
return sprintf('%s/%s?%s', self::API_HOST, $path, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make /oauth/* requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
public function oauth(string $path, array $parameters = []): array
|
||||
{
|
||||
$response = [];
|
||||
$this->resetLastResponse();
|
||||
$this->response->setApiPath($path);
|
||||
$url = sprintf('%s/%s', self::API_HOST, $path);
|
||||
$result = $this->oAuthRequest($url, 'POST', $parameters);
|
||||
|
||||
if ($this->getLastHttpCode() != 200) {
|
||||
throw new TwitterOAuthException($result);
|
||||
}
|
||||
|
||||
parse_str($result, $response);
|
||||
$this->response->setBody($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make /oauth2/* requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function oauth2(string $path, array $parameters = [])
|
||||
{
|
||||
$method = 'POST';
|
||||
$this->resetLastResponse();
|
||||
$this->response->setApiPath($path);
|
||||
$url = sprintf('%s/%s', self::API_HOST, $path);
|
||||
$request = Request::fromConsumerAndToken(
|
||||
$this->consumer,
|
||||
$this->token,
|
||||
$method,
|
||||
$url,
|
||||
$parameters,
|
||||
);
|
||||
$authorization =
|
||||
'Authorization: Basic ' .
|
||||
$this->encodeAppAuthorization($this->consumer);
|
||||
$result = $this->request(
|
||||
$request->getNormalizedHttpUrl(),
|
||||
$method,
|
||||
$authorization,
|
||||
$parameters,
|
||||
);
|
||||
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
|
||||
$this->response->setBody($response);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make GET requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function get(string $path, array $parameters = [])
|
||||
{
|
||||
return $this->http('GET', self::API_HOST, $path, $parameters, [
|
||||
'jsonPayload' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make POST requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function post(
|
||||
string $path,
|
||||
array $parameters = [],
|
||||
array $options = [],
|
||||
) {
|
||||
if (!isset($options['jsonPayload'])) {
|
||||
$options['jsonPayload'] = $this->useJsonBody();
|
||||
}
|
||||
|
||||
return $this->http(
|
||||
'POST',
|
||||
self::API_HOST,
|
||||
$path,
|
||||
$parameters,
|
||||
$options,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make DELETE requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function delete(string $path, array $parameters = [])
|
||||
{
|
||||
return $this->http('DELETE', self::API_HOST, $path, $parameters, [
|
||||
'jsonPayload' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make PUT requests to the API.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function put(
|
||||
string $path,
|
||||
array $parameters = [],
|
||||
array $options = [],
|
||||
) {
|
||||
if (!isset($options['jsonPayload'])) {
|
||||
$options['jsonPayload'] = $this->useJsonBody();
|
||||
}
|
||||
|
||||
return $this->http('PUT', self::API_HOST, $path, $parameters, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload media to upload.twitter.com.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function upload(
|
||||
string $path,
|
||||
array $parameters = [],
|
||||
array $options = [],
|
||||
) {
|
||||
if ($options['chunkedUpload'] ?? false) {
|
||||
return $this->uploadMediaChunked($path, $parameters);
|
||||
} else {
|
||||
return $this->uploadMediaNotChunked($path, $parameters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Progression of media upload
|
||||
*
|
||||
* @param string $media_id
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function mediaStatus(string $media_id)
|
||||
{
|
||||
return $this->http(
|
||||
'GET',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'STATUS',
|
||||
'media_id' => $media_id,
|
||||
],
|
||||
['jsonPayload' => false],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to upload media (not chunked) to upload.twitter.com.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function uploadMediaNotChunked(string $path, array $parameters)
|
||||
{
|
||||
if (
|
||||
!is_readable($parameters['media']) ||
|
||||
($file = file_get_contents($parameters['media'])) === false
|
||||
) {
|
||||
throw new \InvalidArgumentException(
|
||||
'You must supply a readable file',
|
||||
);
|
||||
}
|
||||
$parameters['media'] = base64_encode($file);
|
||||
return $this->http('POST', self::UPLOAD_HOST, $path, $parameters, [
|
||||
'jsonPayload' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to upload media (chunked) to upload.twitter.com.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function uploadMediaChunked(string $path, array $parameters)
|
||||
{
|
||||
/** @var object $init */
|
||||
$init = $this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
$path,
|
||||
$this->mediaInitParameters($parameters),
|
||||
['jsonPayload' => false],
|
||||
);
|
||||
if (!property_exists($init, 'media_id_string')) {
|
||||
throw new TwitterOAuthException('Missing "media_id_string"');
|
||||
}
|
||||
// Append
|
||||
$segmentIndex = 0;
|
||||
$media = fopen($parameters['media'], 'rb');
|
||||
while (!feof($media)) {
|
||||
$this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'APPEND',
|
||||
'media_id' => $init->media_id_string,
|
||||
'segment_index' => $segmentIndex++,
|
||||
'media_data' => base64_encode(
|
||||
fread($media, $this->chunkSize),
|
||||
),
|
||||
],
|
||||
['jsonPayload' => false],
|
||||
);
|
||||
}
|
||||
fclose($media);
|
||||
// Finalize
|
||||
$finalize = $this->http(
|
||||
'POST',
|
||||
self::UPLOAD_HOST,
|
||||
'media/upload',
|
||||
[
|
||||
'command' => 'FINALIZE',
|
||||
'media_id' => $init->media_id_string,
|
||||
],
|
||||
['jsonPayload' => false],
|
||||
);
|
||||
return $finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to get params for upload media chunked init.
|
||||
* Twitter docs: https://dev.twitter.com/rest/reference/post/media/upload-init.html
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function mediaInitParameters(array $parameters): array
|
||||
{
|
||||
$allowed_keys = [
|
||||
'media_type',
|
||||
'additional_owners',
|
||||
'media_category',
|
||||
'shared',
|
||||
];
|
||||
$base = [
|
||||
'command' => 'INIT',
|
||||
'total_bytes' => filesize($parameters['media']),
|
||||
];
|
||||
$allowed_parameters = array_intersect_key(
|
||||
$parameters,
|
||||
array_flip($allowed_keys),
|
||||
);
|
||||
return array_merge($base, $allowed_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup any parameters that are known not to work.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function cleanUpParameters(array $parameters)
|
||||
{
|
||||
foreach ($parameters as $key => $value) {
|
||||
// PHP coerces `true` to `"1"` which some Twitter APIs don't like.
|
||||
if (is_bool($value)) {
|
||||
$parameters[$key] = var_export($value, true);
|
||||
}
|
||||
}
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL extension for current API Version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function extension()
|
||||
{
|
||||
return [
|
||||
'1.1' => '.json',
|
||||
'2' => '',
|
||||
][$this->apiVersion];
|
||||
}
|
||||
|
||||
/**
|
||||
* Default content type for sending data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function useJsonBody()
|
||||
{
|
||||
return [
|
||||
'1.1' => false,
|
||||
'2' => true,
|
||||
][$this->apiVersion];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $host
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function http(
|
||||
string $method,
|
||||
string $host,
|
||||
string $path,
|
||||
array $parameters,
|
||||
array $options,
|
||||
) {
|
||||
$this->resetLastResponse();
|
||||
$this->resetAttemptsNumber();
|
||||
$this->response->setApiPath($path);
|
||||
if (!$options['jsonPayload']) {
|
||||
$parameters = $this->cleanUpParameters($parameters);
|
||||
}
|
||||
return $this->makeRequests(
|
||||
$this->apiUrl($host, $path),
|
||||
$method,
|
||||
$parameters,
|
||||
$options,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate API URL.
|
||||
*
|
||||
* Overriding this function is not supported and may cause unintended issues.
|
||||
*
|
||||
* @param string $host
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function apiUrl(string $host, string $path)
|
||||
{
|
||||
return sprintf(
|
||||
'%s/%s/%s%s',
|
||||
$host,
|
||||
$this->apiVersion,
|
||||
$path,
|
||||
$this->extension(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Make requests and retry them (if enabled) in case of Twitter's problems.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
private function makeRequests(
|
||||
string $url,
|
||||
string $method,
|
||||
array $parameters,
|
||||
array $options,
|
||||
) {
|
||||
do {
|
||||
$this->sleepIfNeeded();
|
||||
$result = $this->oAuthRequest($url, $method, $parameters, $options);
|
||||
$response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
|
||||
$this->response->setBody($response);
|
||||
$this->attempts++;
|
||||
// Retry up to our $maxRetries number if we get errors greater than 500 (over capacity etc)
|
||||
} while ($this->requestsAvailable());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we have to retry request if API is down.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function requestsAvailable(): bool
|
||||
{
|
||||
return $this->maxRetries &&
|
||||
$this->attempts <= $this->maxRetries &&
|
||||
$this->getLastHttpCode() >= 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an OAuth / API request
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
private function oAuthRequest(
|
||||
string $url,
|
||||
string $method,
|
||||
array $parameters,
|
||||
array $options = [],
|
||||
) {
|
||||
$request = Request::fromConsumerAndToken(
|
||||
$this->consumer,
|
||||
$this->token,
|
||||
$method,
|
||||
$url,
|
||||
$parameters,
|
||||
$options,
|
||||
);
|
||||
if (array_key_exists('oauth_callback', $parameters)) {
|
||||
// Twitter doesn't like oauth_callback as a parameter.
|
||||
unset($parameters['oauth_callback']);
|
||||
}
|
||||
if ($this->bearer === null) {
|
||||
$request->signRequest(
|
||||
$this->signatureMethod,
|
||||
$this->consumer,
|
||||
$this->token,
|
||||
);
|
||||
$authorization = $request->toHeader();
|
||||
if (array_key_exists('oauth_verifier', $parameters)) {
|
||||
// Twitter doesn't always work with oauth in the body and in the header
|
||||
// and it's already included in the $authorization header
|
||||
unset($parameters['oauth_verifier']);
|
||||
}
|
||||
} else {
|
||||
$authorization = 'Authorization: Bearer ' . $this->bearer;
|
||||
}
|
||||
return $this->request(
|
||||
$request->getNormalizedHttpUrl(),
|
||||
$method,
|
||||
$authorization,
|
||||
$parameters,
|
||||
$options,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Curl options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function curlOptions(): array
|
||||
{
|
||||
$bundlePath = CaBundle::getSystemCaRootBundlePath();
|
||||
$options = [
|
||||
// CURLOPT_VERBOSE => true,
|
||||
CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_TIMEOUT => $this->timeout,
|
||||
CURLOPT_USERAGENT => $this->userAgent,
|
||||
$this->curlCaOpt($bundlePath) => $bundlePath,
|
||||
];
|
||||
|
||||
if ($this->gzipEncoding) {
|
||||
$options[CURLOPT_ENCODING] = 'gzip';
|
||||
}
|
||||
|
||||
if (!empty($this->proxy)) {
|
||||
$options[CURLOPT_PROXY] = $this->proxy['CURLOPT_PROXY'];
|
||||
$options[CURLOPT_PROXYUSERPWD] =
|
||||
$this->proxy['CURLOPT_PROXYUSERPWD'];
|
||||
$options[CURLOPT_PROXYPORT] = $this->proxy['CURLOPT_PROXYPORT'];
|
||||
$options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
|
||||
$options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an HTTP request
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param string $authorization
|
||||
* @param array $postfields
|
||||
* @param ?array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws TwitterOAuthException
|
||||
*/
|
||||
private function request(
|
||||
string $url,
|
||||
string $method,
|
||||
string $authorization,
|
||||
array $postfields,
|
||||
?array $options = [],
|
||||
): string {
|
||||
$curlOptions = $this->curlOptions();
|
||||
$curlOptions[CURLOPT_URL] = $url;
|
||||
$curlOptions[CURLOPT_HTTPHEADER] = [
|
||||
'Accept: application/json',
|
||||
$authorization,
|
||||
'Expect:',
|
||||
];
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
break;
|
||||
case 'POST':
|
||||
$curlOptions[CURLOPT_POST] = true;
|
||||
$curlOptions = $this->setPostfieldsOptions(
|
||||
$curlOptions,
|
||||
$postfields,
|
||||
$options,
|
||||
);
|
||||
break;
|
||||
case 'DELETE':
|
||||
$curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
|
||||
break;
|
||||
case 'PUT':
|
||||
$curlOptions[CURLOPT_CUSTOMREQUEST] = 'PUT';
|
||||
$curlOptions = $this->setPostfieldsOptions(
|
||||
$curlOptions,
|
||||
$postfields,
|
||||
$options,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
in_array($method, ['GET', 'PUT', 'DELETE']) &&
|
||||
!empty($postfields)
|
||||
) {
|
||||
$curlOptions[CURLOPT_URL] .=
|
||||
'?' . Util::buildHttpQuery($postfields);
|
||||
}
|
||||
|
||||
$curlHandle = curl_init();
|
||||
curl_setopt_array($curlHandle, $curlOptions);
|
||||
$response = curl_exec($curlHandle);
|
||||
|
||||
// Throw exceptions on cURL errors.
|
||||
if (curl_errno($curlHandle) > 0) {
|
||||
$error = curl_error($curlHandle);
|
||||
$errorNo = curl_errno($curlHandle);
|
||||
curl_close($curlHandle);
|
||||
throw new TwitterOAuthException($error, $errorNo);
|
||||
}
|
||||
|
||||
$this->response->setHttpCode(
|
||||
curl_getinfo($curlHandle, CURLINFO_HTTP_CODE),
|
||||
);
|
||||
$parts = explode("\r\n\r\n", $response);
|
||||
$responseBody = array_pop($parts);
|
||||
$responseHeader = array_pop($parts);
|
||||
$this->response->setHeaders($this->parseHeaders($responseHeader));
|
||||
|
||||
curl_close($curlHandle);
|
||||
|
||||
return $responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the header info to store.
|
||||
*
|
||||
* @param string $header
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseHeaders(string $header): array
|
||||
{
|
||||
$headers = [];
|
||||
foreach (explode("\r\n", $header) as $line) {
|
||||
if (strpos($line, ':') !== false) {
|
||||
[$key, $value] = explode(': ', $line);
|
||||
$key = str_replace('-', '_', strtolower($key));
|
||||
$headers[$key] = trim($value);
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode application authorization header with base64.
|
||||
*
|
||||
* @param Consumer $consumer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encodeAppAuthorization(Consumer $consumer): string
|
||||
{
|
||||
$key = rawurlencode($consumer->key);
|
||||
$secret = rawurlencode($consumer->secret);
|
||||
return base64_encode($key . ':' . $secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Curl CA option based on whether the given path is a directory or file.
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
private function curlCaOpt(string $path): int
|
||||
{
|
||||
return is_dir($path) ? CURLOPT_CAPATH : CURLOPT_CAINFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set options for JSON Requests
|
||||
*
|
||||
* @param array $options
|
||||
* @param array $postfields
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function setPostfieldsOptions(
|
||||
array $curlOptions,
|
||||
array $postfields,
|
||||
array $options,
|
||||
): array {
|
||||
if ($options['jsonPayload'] ?? false) {
|
||||
$curlOptions[CURLOPT_HTTPHEADER][] =
|
||||
'Content-type: application/json';
|
||||
$curlOptions[CURLOPT_POSTFIELDS] = json_encode(
|
||||
$postfields,
|
||||
JSON_THROW_ON_ERROR,
|
||||
);
|
||||
} else {
|
||||
$curlOptions[CURLOPT_POSTFIELDS] = Util::buildHttpQuery(
|
||||
$postfields,
|
||||
);
|
||||
}
|
||||
|
||||
return $curlOptions;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
/**
|
||||
* @author Abraham Williams <abraham@abrah.am>
|
||||
*/
|
||||
class TwitterOAuthException extends \Exception
|
||||
{
|
||||
}
|
||||
122
htdocs/core/vendor/abraham/twitteroauth/src/Util.php
vendored
122
htdocs/core/vendor/abraham/twitteroauth/src/Util.php
vendored
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The MIT License
|
||||
* Copyright (c) 2007 Andy Smith
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Abraham\TwitterOAuth;
|
||||
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* @param mixed $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function urlencodeRfc3986($input)
|
||||
{
|
||||
$output = '';
|
||||
if (is_array($input)) {
|
||||
$output = array_map(
|
||||
[__NAMESPACE__ . '\Util', 'urlencodeRfc3986'],
|
||||
$input,
|
||||
);
|
||||
} elseif (is_scalar($input)) {
|
||||
$output = rawurlencode((string) $input);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function urldecodeRfc3986($string): string
|
||||
{
|
||||
return urldecode($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a input like a=b&a=c&d=e and returns the parsed
|
||||
* parameters like this
|
||||
* array('a' => array('b','c'), 'd' => 'e')
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parseParameters($input): array
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$pairs = explode('&', $input);
|
||||
|
||||
$parameters = [];
|
||||
foreach ($pairs as $pair) {
|
||||
$split = explode('=', $pair, 2);
|
||||
$parameter = Util::urldecodeRfc3986($split[0]);
|
||||
$value = isset($split[1]) ? Util::urldecodeRfc3986($split[1]) : '';
|
||||
|
||||
if (isset($parameters[$parameter])) {
|
||||
// We have already recieved parameter(s) with this name, so add to the list
|
||||
// of parameters with this name
|
||||
|
||||
if (is_scalar($parameters[$parameter])) {
|
||||
// This is the first duplicate, so transform scalar (string) into an array
|
||||
// so we can add the duplicates
|
||||
$parameters[$parameter] = [$parameters[$parameter]];
|
||||
}
|
||||
|
||||
$parameters[$parameter][] = $value;
|
||||
} else {
|
||||
$parameters[$parameter] = $value;
|
||||
}
|
||||
}
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildHttpQuery(array $params): string
|
||||
{
|
||||
if (empty($params)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Urlencode both keys and values
|
||||
$keys = Util::urlencodeRfc3986(array_keys($params));
|
||||
$values = Util::urlencodeRfc3986(array_values($params));
|
||||
$params = array_combine($keys, $values);
|
||||
|
||||
// Parameters are sorted by name, using lexicographical byte value ordering.
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
uksort($params, 'strcmp');
|
||||
|
||||
$pairs = [];
|
||||
foreach ($params as $parameter => $value) {
|
||||
if (is_array($value)) {
|
||||
// If two or more parameters share the same name, they are sorted by their value
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka
|
||||
sort($value, SORT_STRING);
|
||||
foreach ($value as $duplicateValue) {
|
||||
$pairs[] = $parameter . '=' . $duplicateValue;
|
||||
}
|
||||
} else {
|
||||
$pairs[] = $parameter . '=' . $value;
|
||||
}
|
||||
}
|
||||
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
|
||||
// Each name-value pair is separated by an '&' character (ASCII code 38)
|
||||
return implode('&', $pairs);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Abraham\TwitterOAuth\Util;
|
||||
|
||||
/**
|
||||
* @author louis <louis@systemli.org>
|
||||
*/
|
||||
class JsonDecoder
|
||||
{
|
||||
/**
|
||||
* Decodes a JSON string to stdObject or associative array
|
||||
*
|
||||
* @param string $string
|
||||
* @param bool $asArray
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public static function decode(string $string, bool $asArray)
|
||||
{
|
||||
if (
|
||||
version_compare(PHP_VERSION, '5.4.0', '>=') &&
|
||||
!(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)
|
||||
) {
|
||||
return json_decode($string, $asArray, 512, JSON_BIGINT_AS_STRING);
|
||||
}
|
||||
|
||||
return json_decode($string, $asArray, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Reset Password</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
|
||||
@@ -12,8 +13,9 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<title>Reset Password</title>
|
||||
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
@@ -11,6 +11,7 @@ $success_message = $_SESSION['success_message'] ?? '';
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Reset Password</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
|
||||
@@ -20,9 +21,11 @@ $success_message = $_SESSION['success_message'] ?? '';
|
||||
<link rel="manifest" href="./assets/images/site.webmanifest">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
|
||||
<title>Reset Password</title>
|
||||
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
@@ -10,6 +10,7 @@ $email = isset($_SESSION['email']) ? $_SESSION['email'] : '';
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Enter Confirmation Code</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg" />
|
||||
@@ -20,8 +21,9 @@ $email = isset($_SESSION['email']) ? $_SESSION['email'] : '';
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<title>Enter Confirmation Code</title>
|
||||
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
require 'core/process.php';
|
||||
require 'core/get_statistics.php';
|
||||
require 'core/get_statistics.php';
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
@@ -13,6 +13,7 @@ ini_set('display_errors', 1);
|
||||
<title>Xeorl - Link Shortener and Management Tool</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Xeorl - The All-In-One, Fully Free to Use Advanced Link Shortener and Management Tool - Equipped with Multi-layered URL encryption, URL metadata remover, Mass shrinker, Quick link and Many more! - Powered by @xodivorce...">
|
||||
<meta name="google-adsense-account" content="ca-pub-5747712812070455">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg" />
|
||||
<link rel="shortcut icon" href="./assets/images/favicon.ico" />
|
||||
@@ -23,12 +24,12 @@ ini_set('display_errors', 1);
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/_home.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<?php include "assets/_header.php"; ?>
|
||||
|
||||
<main>
|
||||
<!-- Shorten Section -->
|
||||
<section class="shorten-section" style="user-select: none;">
|
||||
<h1>Open source inits.</h1>
|
||||
<h2>Lovingly hand-crafted.</h2>
|
||||
@@ -42,8 +43,6 @@ ini_set('display_errors', 1);
|
||||
<ul id="links-list"></ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Dashboard Statistics Section -->
|
||||
<section class="dashboard-stats-section" style="user-select: none;">
|
||||
<h1 class="section-heading">Numbers Speak For Themselves.</h1>
|
||||
<h2 class="section-subheading">Challenged By URLs, Defeated By None.</h2>
|
||||
@@ -53,7 +52,6 @@ ini_set('display_errors', 1);
|
||||
to support and resolve any issues you have because your satisfaction
|
||||
means everything to us. For any issues, email us at <a href="mailto:hey@xodivorce.in" class="contact-link">hey@xodivorce.in</a>.
|
||||
</p>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<div class="stat-item">
|
||||
<img src="assets/images/total.png" alt="Total Clicks" class="stat-icon total-icon">
|
||||
@@ -72,8 +70,6 @@ ini_set('display_errors', 1);
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- How to Start Section -->
|
||||
<section class="how-to-start-section" style="user-select: none;">
|
||||
<h1 class="section-heading">Just Three Simple Steps</h1>
|
||||
<h2 class="section-subheading">How to Get Started?</h2>
|
||||
@@ -88,10 +84,9 @@ ini_set('display_errors', 1);
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<?php include 'assets/_cookies.php'; ?>
|
||||
<?php include 'assets/_footer.php'; ?>
|
||||
<script src="assets/js/_home.js"></script>
|
||||
<script src="assets/js/_developer_tools.js"></script>
|
||||
<script src="assets/js/developer_tools.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,6 +8,7 @@ ini_set('display_errors', 1);
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Login</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
|
||||
@@ -18,8 +19,9 @@ ini_set('display_errors', 1);
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Work+Sans:wght@100..900&display=swap" rel="stylesheet">
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="assets/css/_login.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" style="user-select: none;">
|
||||
|
||||
@@ -26,6 +26,8 @@ if (!isset($_SESSION['user_id'])) {
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/_monetization.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<?php include "assets/_header.php"; ?>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Password Reset Success</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
|
||||
@@ -12,8 +13,9 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<title>Password Reset Success</title>
|
||||
<link rel="stylesheet" href="assets/css/_forgot_pass.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
@@ -8,6 +8,7 @@ ini_set('display_errors', 1);
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Register</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="./assets/images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/images/favicon.svg">
|
||||
@@ -18,8 +19,9 @@ ini_set('display_errors', 1);
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<title>Register</title>
|
||||
<link rel="stylesheet" href="assets/css/_register.css">
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" style="user-select: none;">
|
||||
|
||||
@@ -27,8 +27,8 @@ $redirect_url = $_SESSION['redirect_url'];
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/_unzipper.css">
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455"
|
||||
crossorigin="anonymous"></script>
|
||||
<!-- Google Adsense -->
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5747712812070455" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<?php include "assets/_header.php"; ?>
|
||||
|
||||
Reference in New Issue
Block a user