mirror of
https://github.com/Neetpone/ponepaste.git
synced 2025-03-11 14:10:06 +01:00
Make pages work again
This commit is contained in:
parent
c7fcd033b0
commit
ee11e95019
32 changed files with 279 additions and 1361 deletions
|
@ -139,7 +139,5 @@ $admin_logs = AdminLog::with('user')
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -297,8 +297,5 @@ function getRecentadmin($count = 5) {
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -284,7 +284,5 @@ if (isset($_GET['delete'])) {
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -222,8 +222,6 @@ require_once('common.php');
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.js"></script>
|
||||
<script type="text/javascript" language="javascript" class="init">
|
||||
$(document).ready(function () {
|
||||
$('#pastesTable').dataTable({
|
||||
|
@ -233,6 +231,5 @@ require_once('common.php');
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -291,8 +291,6 @@ if ($last_ip == $ip) {
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.js"></script>
|
||||
<script type="text/javascript" language="javascript" class="init">
|
||||
$(document).ready(function () {
|
||||
$('#pastesTable').dataTable({
|
||||
|
|
|
@ -240,7 +240,5 @@ while ($row = mysqli_fetch_array($result)) {
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,397 +0,0 @@
|
|||
<?php
|
||||
|
||||
class SSP {
|
||||
/**
|
||||
* Create the data output array for the DataTables rows
|
||||
*
|
||||
* @param array $columns Column information array
|
||||
* @param array $data Data from the SQL get
|
||||
* @return array Formatted data in a row based format
|
||||
*/
|
||||
static function data_output($columns, $data) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $ien = count($data); $i < $ien; $i++) {
|
||||
$row = array();
|
||||
|
||||
for ($j = 0, $jen = count($columns); $j < $jen; $j++) {
|
||||
$column = $columns[$j];
|
||||
|
||||
// Is there a formatter?
|
||||
if (isset($column['formatter'])) {
|
||||
$row[$column['dt']] = $column['formatter']($data[$i][$column['db']], $data[$i]);
|
||||
} else {
|
||||
$row[$column['dt']] = $data[$i][$columns[$j]['db']];
|
||||
}
|
||||
}
|
||||
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paging
|
||||
*
|
||||
* Construct the LIMIT clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL limit clause
|
||||
*/
|
||||
static function limit($request, $columns) {
|
||||
$limit = '';
|
||||
|
||||
if (isset($request['start']) && $request['length'] != -1) {
|
||||
$limit = "LIMIT " . intval($request['start']) . ", " . intval($request['length']);
|
||||
}
|
||||
|
||||
return $limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ordering
|
||||
*
|
||||
* Construct the ORDER BY clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL order by clause
|
||||
*/
|
||||
static function order($request, $columns) {
|
||||
$order = '';
|
||||
|
||||
if (isset($request['order']) && count($request['order'])) {
|
||||
$orderBy = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
for ($i = 0, $ien = count($request['order']); $i < $ien; $i++) {
|
||||
// Convert the column index into the column data property
|
||||
$columnIdx = intval($request['order'][$i]['column']);
|
||||
$requestColumn = $request['columns'][$columnIdx];
|
||||
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['orderable'] == 'true') {
|
||||
$dir = $request['order'][$i]['dir'] === 'DESC' ?
|
||||
'ASC' :
|
||||
'DESC';
|
||||
|
||||
$orderBy[] = '`' . $column['db'] . '` ' . $dir;
|
||||
}
|
||||
}
|
||||
|
||||
$order = 'ORDER BY ' . implode(', ', $orderBy);
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searching / Filtering
|
||||
*
|
||||
* Construct the WHERE clause for server-side processing SQL query.
|
||||
*
|
||||
* NOTE this does not match the built-in DataTables filtering which does it
|
||||
* word by word on any field. It's possible to do here performance on large
|
||||
* databases would be very poor
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @param array $bindings Array of values for PDO bindings, used in the
|
||||
* sql_exec() function
|
||||
* @return string SQL where clause
|
||||
*/
|
||||
static function filter($request, $columns, &$bindings) {
|
||||
$globalSearch = array();
|
||||
$columnSearch = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
if (isset($request['search']) && $request['search']['value'] != '') {
|
||||
$str = $request['search']['value'];
|
||||
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$globalSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Individual column filtering
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
$str = $requestColumn['search']['value'];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true' &&
|
||||
$str != '') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$columnSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the filters into a single string
|
||||
$where = '';
|
||||
|
||||
if (count($globalSearch)) {
|
||||
$where = '(' . implode(' OR ', $globalSearch) . ')';
|
||||
}
|
||||
|
||||
if (count($columnSearch)) {
|
||||
$where = $where === '' ?
|
||||
implode(' AND ', $columnSearch) :
|
||||
$where . ' AND ' . implode(' AND ', $columnSearch);
|
||||
}
|
||||
|
||||
if ($where !== '') {
|
||||
$where = 'WHERE ' . $where;
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the SQL queries needed for an server-side processing requested,
|
||||
* utilising the helper functions of this class, limit(), order() and
|
||||
* filter() among others. The returned array is ready to be encoded as JSON
|
||||
* in response to an SSP request, or can be modified if needed before
|
||||
* sending back to the client.
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $sql_details SQL connection details - see sql_connect()
|
||||
* @param string $table SQL table to query
|
||||
* @param string $primaryKey Primary key of the table
|
||||
* @param array $columns Column information array
|
||||
* @return array Server-side processing response array
|
||||
*/
|
||||
static function simple($request, $sql_details, $table, $primaryKey, $columns, $columns2) {
|
||||
$bindings = array();
|
||||
$db = self::sql_connect($sql_details);
|
||||
|
||||
// Build the SQL query string from the request
|
||||
$limit = self::limit($request, $columns);
|
||||
$order = self::order($request, $columns);
|
||||
$where = self::filter($request, $columns, $bindings);
|
||||
|
||||
// Main query to actually get the data
|
||||
$data = self::Ssql_exec($db, $bindings,
|
||||
"SELECT SQL_CALC_FOUND_ROWS pastes.id AS id, users.name AS member
|
||||
FROM `$table`
|
||||
INNER JOIN users ON users.id = pastes.user_id
|
||||
$where
|
||||
$order
|
||||
$limit"
|
||||
);
|
||||
|
||||
// Data set length after filtering
|
||||
$resFilterLength = self::sql_exec($db,
|
||||
"SELECT FOUND_ROWS()"
|
||||
);
|
||||
$recordsFiltered = $resFilterLength[0][0];
|
||||
// Total data set length
|
||||
$resTotalLength = self::sql_exec($db,
|
||||
"SELECT COUNT(`{$primaryKey}`)
|
||||
FROM `$table`"
|
||||
);
|
||||
$recordsTotal = $resTotalLength[0][0];
|
||||
|
||||
/*
|
||||
* Output
|
||||
*/
|
||||
return array(
|
||||
"draw" => intval($request['draw']),
|
||||
"recordsTotal" => intval($recordsTotal),
|
||||
"recordsFiltered" => intval($recordsFiltered),
|
||||
"data" => self::data_output($columns2, $data)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @param array $sql_details SQL server connection details array, with the
|
||||
* properties:
|
||||
* * host - host name
|
||||
* * db - database name
|
||||
* * user - user name
|
||||
* * pass - user password
|
||||
* @return resource Database connection handle
|
||||
*/
|
||||
static function sql_connect($sql_details) {
|
||||
try {
|
||||
$db = @new PDO(
|
||||
"mysql:host={$sql_details['host']};dbname={$sql_details['db']}",
|
||||
$sql_details['user'],
|
||||
$sql_details['pass'],
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
self::fatal(
|
||||
"An error occurred while connecting to the database. " .
|
||||
"The error reported by the server was: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute an SQL query on the database
|
||||
*
|
||||
* @param resource $db Database handler
|
||||
* @param array $bindings Array of PDO binding values from bind() to be
|
||||
* used for safely escaping strings. Note that this can be given as the
|
||||
* SQL query string if no bindings are required.
|
||||
* @param string $sql SQL query to execute.
|
||||
* @return array Result from the query (all rows)
|
||||
*/
|
||||
static function sql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
//echo $sql;
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$result = $stmt->fetchAll();
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function Ssql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$loop = '0';
|
||||
|
||||
while ($arr = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[$loop]['id'] = $arr['id'];
|
||||
$result[$loop]['member'] = $arr['member'];
|
||||
$result[$loop]['ip'] = $arr['ip'];
|
||||
$vis = Trim($arr['visible']);
|
||||
if ($vis == '0') {
|
||||
$result[$loop]['visible'] = "Public";
|
||||
} elseif ($vis == '1') {
|
||||
$result[$loop]['visible'] = "Unlisted";
|
||||
} elseif ($vis == '2') {
|
||||
$result[$loop]['visible'] = "Private";
|
||||
}
|
||||
$myid = $arr['id'];
|
||||
$result[$loop]['details'] = "<a class='btn btn-default btn-sm' href=pastes.php?details=" . $myid . "> Details </a>";
|
||||
$result[$loop]['view'] = "<a class='btn btn-success btn-sm' href=../paste.php?id=" . $myid . "> View </a>";
|
||||
$result[$loop]['delete'] = "<a class='btn btn-danger btn-sm' href=pastes.php?delete=" . $myid . "> Delete </a> <a class='btn btn-link btn-sm' href=ipbans.php?banip=" . $arr['ip'] . "> Ban IP </a>";
|
||||
$loop = $loop + 1;
|
||||
}
|
||||
// Return all
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throw a fatal error.
|
||||
*
|
||||
* This writes out an error message in a JSON string which DataTables will
|
||||
* see and show to the user in the browser.
|
||||
*
|
||||
* @param string $msg Message to send to the client
|
||||
*/
|
||||
static function fatal($msg) {
|
||||
echo json_encode(array(
|
||||
"error" => $msg
|
||||
));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PDO binding key which can be used for escaping variables safely
|
||||
* when executing a query with sql_exec()
|
||||
*
|
||||
* @param array &$a Array of bindings
|
||||
* @param * $val Value to bind
|
||||
* @param int $type PDO field type
|
||||
* @return string Bound key to be used in the SQL where this parameter
|
||||
* would be used.
|
||||
*/
|
||||
static function bind(&$a, $val, $type) {
|
||||
$key = ':binding_' . count($a);
|
||||
|
||||
$a[] = array(
|
||||
'key' => $key,
|
||||
'val' => $val,
|
||||
'type' => $type
|
||||
);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pull a particular property from each assoc. array in a numeric array,
|
||||
* returning and array of the property values from each item.
|
||||
*
|
||||
* @param array $a Array to get data from
|
||||
* @param string $prop Property to read
|
||||
* @return array Array of property values
|
||||
*/
|
||||
static function pluck($a, $prop) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $len = count($a); $i < $len; $i++) {
|
||||
$out[] = $a[$i][$prop];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,397 +0,0 @@
|
|||
<?php
|
||||
|
||||
class SSP {
|
||||
/**
|
||||
* Create the data output array for the DataTables rows
|
||||
*
|
||||
* @param array $columns Column information array
|
||||
* @param array $data Data from the SQL get
|
||||
* @return array Formatted data in a row based format
|
||||
*/
|
||||
static function data_output($columns, $data) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $ien = count($data); $i < $ien; $i++) {
|
||||
$row = array();
|
||||
|
||||
for ($j = 0, $jen = count($columns); $j < $jen; $j++) {
|
||||
$column = $columns[$j];
|
||||
|
||||
// Is there a formatter?
|
||||
if (isset($column['formatter'])) {
|
||||
$row[$column['dt']] = $column['formatter']($data[$i][$column['db']], $data[$i]);
|
||||
} else {
|
||||
$row[$column['dt']] = $data[$i][$columns[$j]['db']];
|
||||
}
|
||||
}
|
||||
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paging
|
||||
*
|
||||
* Construct the LIMIT clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL limit clause
|
||||
*/
|
||||
static function limit($request, $columns) {
|
||||
$limit = '';
|
||||
|
||||
if (isset($request['start']) && $request['length'] != -1) {
|
||||
$limit = "LIMIT " . intval($request['start']) . ", " . intval($request['length']);
|
||||
}
|
||||
|
||||
return $limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ordering
|
||||
*
|
||||
* Construct the ORDER BY clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL order by clause
|
||||
*/
|
||||
static function order($request, $columns) {
|
||||
$order = '';
|
||||
|
||||
if (isset($request['order']) && count($request['order'])) {
|
||||
$orderBy = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
for ($i = 0, $ien = count($request['order']); $i < $ien; $i++) {
|
||||
// Convert the column index into the column data property
|
||||
$columnIdx = intval($request['order'][$i]['column']);
|
||||
$requestColumn = $request['columns'][$columnIdx];
|
||||
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['orderable'] == 'true') {
|
||||
$dir = $request['order'][$i]['dir'] === 'DESC' ?
|
||||
'ASC' :
|
||||
'DESC';
|
||||
|
||||
$orderBy[] = '`' . $column['db'] . '` ' . $dir;
|
||||
}
|
||||
}
|
||||
|
||||
$order = 'ORDER BY ' . implode(', ', $orderBy);
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searching / Filtering
|
||||
*
|
||||
* Construct the WHERE clause for server-side processing SQL query.
|
||||
*
|
||||
* NOTE this does not match the built-in DataTables filtering which does it
|
||||
* word by word on any field. It's possible to do here performance on large
|
||||
* databases would be very poor
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @param array $bindings Array of values for PDO bindings, used in the
|
||||
* sql_exec() function
|
||||
* @return string SQL where clause
|
||||
*/
|
||||
static function filter($request, $columns, &$bindings) {
|
||||
$globalSearch = array();
|
||||
$columnSearch = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
if (isset($request['search']) && $request['search']['value'] != '') {
|
||||
$str = $request['search']['value'];
|
||||
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$globalSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Individual column filtering
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
$str = $requestColumn['search']['value'];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true' &&
|
||||
$str != '') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$columnSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the filters into a single string
|
||||
$where = '';
|
||||
|
||||
if (count($globalSearch)) {
|
||||
$where = '(' . implode(' OR ', $globalSearch) . ')';
|
||||
}
|
||||
|
||||
if (count($columnSearch)) {
|
||||
$where = $where === '' ?
|
||||
implode(' AND ', $columnSearch) :
|
||||
$where . ' AND ' . implode(' AND ', $columnSearch);
|
||||
}
|
||||
|
||||
if ($where !== '') {
|
||||
$where = 'WHERE ' . $where;
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the SQL queries needed for an server-side processing requested,
|
||||
* utilising the helper functions of this class, limit(), order() and
|
||||
* filter() among others. The returned array is ready to be encoded as JSON
|
||||
* in response to an SSP request, or can be modified if needed before
|
||||
* sending back to the client.
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $sql_details SQL connection details - see sql_connect()
|
||||
* @param string $table SQL table to query
|
||||
* @param string $primaryKey Primary key of the table
|
||||
* @param array $columns Column information array
|
||||
* @return array Server-side processing response array
|
||||
*/
|
||||
static function simple($request, $sql_details, $table, $primaryKey, $columns, $columns2) {
|
||||
$bindings = array();
|
||||
$db = self::sql_connect($sql_details);
|
||||
|
||||
// Build the SQL query string from the request
|
||||
$limit = self::limit($request, $columns);
|
||||
$order = self::order($request, $columns);
|
||||
$where = self::filter($request, $columns, $bindings);
|
||||
|
||||
// Main query to actually get the data
|
||||
$data = self::Ssql_exec($db, $bindings,
|
||||
"SELECT SQL_CALC_FOUND_ROWS `" . implode("`, `", self::pluck($columns, 'db')) . "`
|
||||
FROM `$table`
|
||||
$where
|
||||
$order
|
||||
$limit"
|
||||
);
|
||||
|
||||
// Data set length after filtering
|
||||
$resFilterLength = self::sql_exec($db,
|
||||
"SELECT FOUND_ROWS()"
|
||||
);
|
||||
$recordsFiltered = $resFilterLength[0][0];
|
||||
// Total data set length
|
||||
$resTotalLength = self::sql_exec($db,
|
||||
"SELECT COUNT(`{$primaryKey}`)
|
||||
FROM `$table`"
|
||||
);
|
||||
$recordsTotal = $resTotalLength[0][0];
|
||||
|
||||
/*
|
||||
* Output
|
||||
*/
|
||||
return array(
|
||||
"draw" => intval($request['draw']),
|
||||
"recordsTotal" => intval($recordsTotal),
|
||||
"recordsFiltered" => intval($recordsFiltered),
|
||||
"data" => self::data_output($columns2, $data)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @param array $sql_details SQL server connection details array, with the
|
||||
* properties:
|
||||
* * host - host name
|
||||
* * db - database name
|
||||
* * user - user name
|
||||
* * pass - user password
|
||||
* @return resource Database connection handle
|
||||
*/
|
||||
static function sql_connect($sql_details) {
|
||||
try {
|
||||
$db = @new PDO(
|
||||
"mysql:host={$sql_details['host']};dbname={$sql_details['db']}",
|
||||
$sql_details['user'],
|
||||
$sql_details['pass'],
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
self::fatal(
|
||||
"An error occurred while connecting to the database. " .
|
||||
"The error reported by the server was: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute an SQL query on the database
|
||||
*
|
||||
* @param resource $db Database handler
|
||||
* @param array $bindings Array of PDO binding values from bind() to be
|
||||
* used for safely escaping strings. Note that this can be given as the
|
||||
* SQL query string if no bindings are required.
|
||||
* @param string $sql SQL query to execute.
|
||||
* @return array Result from the query (all rows)
|
||||
*/
|
||||
static function sql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
//echo $sql;
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$result = $stmt->fetchAll();
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function Ssql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$loop = '0';
|
||||
|
||||
while ($arr = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[$loop]['id'] = $arr['id'];
|
||||
$result[$loop]['m_report'] = $arr['m_report'];
|
||||
$result[$loop]['p_report'] = $arr['p_report'];
|
||||
$vis = Trim($arr['rep_reason']);
|
||||
if ($vis == '0') {
|
||||
$result[$loop]['rep_reason'] = "Public";
|
||||
} elseif ($vis == '1') {
|
||||
$result[$loop]['rep_reason'] = "Unlisted";
|
||||
} elseif ($vis == '2') {
|
||||
$result[$loop]['rep_reason'] = "Private";
|
||||
}
|
||||
$rid = $arr['p_report'];
|
||||
$result[$loop]['details'] = "<a class='btn btn-default btn-sm' href=pastes.php?details=" . $rid . "> Details </a>";
|
||||
$result[$loop]['view'] = "<a class='btn btn-success btn-sm' href=../paste.php?id=" . $rid . "> View </a>";
|
||||
$result[$loop]['delete'] = "<a class='btn btn-danger btn-sm' href=pastes.php?delete=" . $rid . "> Remove </a>";
|
||||
$result[$loop]['delete'] = "<a class='btn btn-danger btn-sm' href=pastes.php?delete=" . $rid . "> Delete </a>";
|
||||
$loop = $loop + 1;
|
||||
}
|
||||
// Return all
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throw a fatal error.
|
||||
*
|
||||
* This writes out an error message in a JSON string which DataTables will
|
||||
* see and show to the user in the browser.
|
||||
*
|
||||
* @param string $msg Message to send to the client
|
||||
*/
|
||||
static function fatal($msg) {
|
||||
echo json_encode(array(
|
||||
"error" => $msg
|
||||
));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PDO binding key which can be used for escaping variables safely
|
||||
* when executing a query with sql_exec()
|
||||
*
|
||||
* @param array &$a Array of bindings
|
||||
* @param * $val Value to bind
|
||||
* @param int $type PDO field type
|
||||
* @return string Bound key to be used in the SQL where this parameter
|
||||
* would be used.
|
||||
*/
|
||||
static function bind(&$a, $val, $type) {
|
||||
$key = ':binding_' . count($a);
|
||||
|
||||
$a[] = array(
|
||||
'key' => $key,
|
||||
'val' => $val,
|
||||
'type' => $type
|
||||
);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pull a particular property from each assoc. array in a numeric array,
|
||||
* returning and array of the property values from each item.
|
||||
*
|
||||
* @param array $a Array to get data from
|
||||
* @param string $prop Property to read
|
||||
* @return array Array of property values
|
||||
*/
|
||||
static function pluck($a, $prop) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $len = count($a); $i < $len; $i++) {
|
||||
$out[] = $a[$i][$prop];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,401 +0,0 @@
|
|||
<?php
|
||||
|
||||
class SSP {
|
||||
/**
|
||||
* Create the data output array for the DataTables rows
|
||||
*
|
||||
* @param array $columns Column information array
|
||||
* @param array $data Data from the SQL get
|
||||
* @return array Formatted data in a row based format
|
||||
*/
|
||||
static function data_output($columns, $data) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $ien = count($data); $i < $ien; $i++) {
|
||||
$row = array();
|
||||
|
||||
for ($j = 0, $jen = count($columns); $j < $jen; $j++) {
|
||||
$column = $columns[$j];
|
||||
|
||||
// Is there a formatter?
|
||||
if (isset($column['formatter'])) {
|
||||
$row[$column['dt']] = $column['formatter']($data[$i][$column['db']], $data[$i]);
|
||||
} else {
|
||||
$row[$column['dt']] = $data[$i][$columns[$j]['db']];
|
||||
}
|
||||
}
|
||||
|
||||
$out[] = $row;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paging
|
||||
*
|
||||
* Construct the LIMIT clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL limit clause
|
||||
*/
|
||||
static function limit($request, $columns) {
|
||||
$limit = '';
|
||||
|
||||
if (isset($request['start']) && $request['length'] != -1) {
|
||||
$limit = "LIMIT " . intval($request['start']) . ", " . intval($request['length']);
|
||||
}
|
||||
|
||||
return $limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ordering
|
||||
*
|
||||
* Construct the ORDER BY clause for server-side processing SQL query
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @return string SQL order by clause
|
||||
*/
|
||||
static function order($request, $columns) {
|
||||
$order = '';
|
||||
|
||||
if (isset($request['order']) && count($request['order'])) {
|
||||
$orderBy = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
for ($i = 0, $ien = count($request['order']); $i < $ien; $i++) {
|
||||
// Convert the column index into the column data property
|
||||
$columnIdx = intval($request['order'][$i]['column']);
|
||||
$requestColumn = $request['columns'][$columnIdx];
|
||||
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['orderable'] == 'true') {
|
||||
$dir = $request['order'][$i]['dir'] === 'asc' ?
|
||||
'ASC' :
|
||||
'DESC';
|
||||
|
||||
$orderBy[] = '`' . $column['db'] . '` ' . $dir;
|
||||
}
|
||||
}
|
||||
|
||||
$order = 'ORDER BY ' . implode(', ', $orderBy);
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searching / Filtering
|
||||
*
|
||||
* Construct the WHERE clause for server-side processing SQL query.
|
||||
*
|
||||
* NOTE this does not match the built-in DataTables filtering which does it
|
||||
* word by word on any field. It's possible to do here performance on large
|
||||
* databases would be very poor
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $columns Column information array
|
||||
* @param array $bindings Array of values for PDO bindings, used in the
|
||||
* sql_exec() function
|
||||
* @return string SQL where clause
|
||||
*/
|
||||
static function filter($request, $columns, &$bindings) {
|
||||
$globalSearch = array();
|
||||
$columnSearch = array();
|
||||
$dtColumns = self::pluck($columns, 'dt');
|
||||
|
||||
if (isset($request['search']) && $request['search']['value'] != '') {
|
||||
$str = $request['search']['value'];
|
||||
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$globalSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Individual column filtering
|
||||
for ($i = 0, $ien = count($request['columns']); $i < $ien; $i++) {
|
||||
$requestColumn = $request['columns'][$i];
|
||||
$columnIdx = array_search($requestColumn['data'], $dtColumns);
|
||||
$column = $columns[$columnIdx];
|
||||
|
||||
$str = $requestColumn['search']['value'];
|
||||
|
||||
if ($requestColumn['searchable'] == 'true' &&
|
||||
$str != '') {
|
||||
$binding = self::bind($bindings, '%' . $str . '%', PDO::PARAM_STR);
|
||||
$columnSearch[] = "`" . $column['db'] . "` LIKE " . $binding;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the filters into a single string
|
||||
$where = '';
|
||||
|
||||
if (count($globalSearch)) {
|
||||
$where = '(' . implode(' OR ', $globalSearch) . ')';
|
||||
}
|
||||
|
||||
if (count($columnSearch)) {
|
||||
$where = $where === '' ?
|
||||
implode(' AND ', $columnSearch) :
|
||||
$where . ' AND ' . implode(' AND ', $columnSearch);
|
||||
}
|
||||
|
||||
if ($where !== '') {
|
||||
$where = 'WHERE ' . $where;
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the SQL queries needed for an server-side processing requested,
|
||||
* utilising the helper functions of this class, limit(), order() and
|
||||
* filter() among others. The returned array is ready to be encoded as JSON
|
||||
* in response to an SSP request, or can be modified if needed before
|
||||
* sending back to the client.
|
||||
*
|
||||
* @param array $request Data sent to server by DataTables
|
||||
* @param array $sql_details SQL connection details - see sql_connect()
|
||||
* @param string $table SQL table to query
|
||||
* @param string $primaryKey Primary key of the table
|
||||
* @param array $columns Column information array
|
||||
* @return array Server-side processing response array
|
||||
*/
|
||||
static function simple($request, $sql_details, $table, $primaryKey, $columns, $columns2) {
|
||||
$bindings = array();
|
||||
$db = self::sql_connect($sql_details);
|
||||
|
||||
// Build the SQL query string from the request
|
||||
$limit = self::limit($request, $columns);
|
||||
$order = self::order($request, $columns);
|
||||
$where = self::filter($request, $columns, $bindings);
|
||||
|
||||
// Main query to actually get the data
|
||||
$data = self::Ssql_exec($db, $bindings,
|
||||
"SELECT SQL_CALC_FOUND_ROWS `" . implode("`, `", self::pluck($columns, 'db')) . "`
|
||||
FROM `$table`
|
||||
$where
|
||||
$order
|
||||
$limit"
|
||||
);
|
||||
|
||||
// Data set length after filtering
|
||||
$resFilterLength = self::sql_exec($db,
|
||||
"SELECT FOUND_ROWS()"
|
||||
);
|
||||
$recordsFiltered = $resFilterLength[0][0];
|
||||
// Total data set length
|
||||
$resTotalLength = self::sql_exec($db,
|
||||
"SELECT COUNT(`{$primaryKey}`)
|
||||
FROM `$table`"
|
||||
);
|
||||
$recordsTotal = $resTotalLength[0][0];
|
||||
|
||||
/*
|
||||
* Output
|
||||
*/
|
||||
return array(
|
||||
"draw" => intval($request['draw']),
|
||||
"recordsTotal" => intval($recordsTotal),
|
||||
"recordsFiltered" => intval($recordsFiltered),
|
||||
"data" => self::data_output($columns2, $data)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @param array $sql_details SQL server connection details array, with the
|
||||
* properties:
|
||||
* * host - host name
|
||||
* * db - database name
|
||||
* * user - user name
|
||||
* * pass - user password
|
||||
* @return resource Database connection handle
|
||||
*/
|
||||
static function sql_connect($sql_details) {
|
||||
try {
|
||||
$db = @new PDO(
|
||||
"mysql:host={$sql_details['host']};dbname={$sql_details['db']}",
|
||||
$sql_details['user'],
|
||||
$sql_details['pass'],
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
self::fatal(
|
||||
"An error occurred while connecting to the database. " .
|
||||
"The error reported by the server was: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute an SQL query on the database
|
||||
*
|
||||
* @param resource $db Database handler
|
||||
* @param array $bindings Array of PDO binding values from bind() to be
|
||||
* used for safely escaping strings. Note that this can be given as the
|
||||
* SQL query string if no bindings are required.
|
||||
* @param string $sql SQL query to execute.
|
||||
* @return array Result from the query (all rows)
|
||||
*/
|
||||
static function sql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
//echo $sql;
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$result = $stmt->fetchAll();
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function Ssql_exec($db, $bindings, $sql = null) {
|
||||
// Argument shifting
|
||||
if ($sql === null) {
|
||||
$sql = $bindings;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
if (is_array($bindings)) {
|
||||
for ($i = 0, $ien = count($bindings); $i < $ien; $i++) {
|
||||
$binding = $bindings[$i];
|
||||
$stmt->bindValue($binding['key'], $binding['val'], $binding['type']);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
self::fatal("An SQL error occurred: " . $e->getMessage());
|
||||
}
|
||||
$loop = '0';
|
||||
|
||||
while ($arr = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[$loop]['id'] = $arr['id'];
|
||||
$result[$loop]['username'] = $arr['username'];
|
||||
$result[$loop]['platform'] = $arr['platform'];
|
||||
$result[$loop]['date'] = $arr['date'];
|
||||
$ver = $arr['verified'];
|
||||
|
||||
$myid = $arr['id'];
|
||||
if ($ver == '0') {
|
||||
$result[$loop]['ban'] = "<span class='bg-red'>User unverified</span>";
|
||||
} elseif ($ver == '1') {
|
||||
$result[$loop]['ban'] = "<a class='btn btn-danger btn-sm' href=users.php?ban=" . $myid . "> Ban </a>";
|
||||
} elseif ($ver == '2') {
|
||||
$result[$loop]['ban'] = "<a class='btn btn-success btn-sm' href=users.php?unban=" . $myid . "> Unban </a>";
|
||||
}
|
||||
$result[$loop]['view'] = "<a class='btn btn-default btn-sm' href=users.php?details=" . $myid . "> Details </a>";
|
||||
$result[$loop]['delete'] = "<a class='btn btn-danger btn-sm' href=users.php?delete=" . $myid . "> Delete </a>";
|
||||
$loop = $loop + 1;
|
||||
}
|
||||
// Return all
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throw a fatal error.
|
||||
*
|
||||
* This writes out an error message in a JSON string which DataTables will
|
||||
* see and show to the user in the browser.
|
||||
*
|
||||
* @param string $msg Message to send to the client
|
||||
*/
|
||||
static function fatal($msg) {
|
||||
echo json_encode(array(
|
||||
"error" => $msg
|
||||
));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PDO binding key which can be used for escaping variables safely
|
||||
* when executing a query with sql_exec()
|
||||
*
|
||||
* @param array &$a Array of bindings
|
||||
* @param * $val Value to bind
|
||||
* @param int $type PDO field type
|
||||
* @return string Bound key to be used in the SQL where this parameter
|
||||
* would be used.
|
||||
*/
|
||||
static function bind(&$a, $val, $type) {
|
||||
$key = ':binding_' . count($a);
|
||||
|
||||
$a[] = array(
|
||||
'key' => $key,
|
||||
'val' => $val,
|
||||
'type' => $type
|
||||
);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pull a particular property from each assoc. array in a numeric array,
|
||||
* returning and array of the property values from each item.
|
||||
*
|
||||
* @param array $a Array to get data from
|
||||
* @param string $prop Property to read
|
||||
* @return array Array of property values
|
||||
*/
|
||||
static function pluck($a, $prop) {
|
||||
$out = array();
|
||||
|
||||
for ($i = 0, $len = count($a); $i < $len; $i++) {
|
||||
$out[] = $a[$i][$prop];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") {
|
||||
header("Location: http://ponepaste.org/SVOtaKqJZh4nT9Z");
|
||||
die();
|
||||
}
|
|
@ -327,7 +327,5 @@ if ($last_ip == $ip) {
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -184,8 +184,6 @@ require_once(__DIR__ . '/common.php');
|
|||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.js"></script>
|
||||
<script type="text/javascript" language="javascript" class="init">
|
||||
$(document).ready(function () {
|
||||
$('#usersTable').dataTable({
|
||||
|
|
|
@ -10,7 +10,7 @@ $date = date('jS F Y');
|
|||
// Temp count for untagged pastes
|
||||
$total_untagged = Paste::doesntHave('tags')->count();
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
// Theme
|
||||
$page_template = 'archive';
|
||||
|
|
8
includes/Models/Page.php
Normal file
8
includes/Models/Page.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
namespace PonePaste\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Page extends Model {
|
||||
protected $table = 'pages';
|
||||
}
|
|
@ -14,7 +14,7 @@ class User extends Model {
|
|||
}
|
||||
|
||||
public function favourites() {
|
||||
return $this->belongsToMany(Paste::class, 'user_favourites');
|
||||
return $this->belongsToMany(Paste::class, 'user_favourites')->withPivot('f_time');
|
||||
}
|
||||
|
||||
public function pastes() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class NonRetardedSSP {
|
||||
public static function run(DatabaseHandle $conn, array $request, Builder $builder) {
|
||||
public static function run(array $request, Builder $builder) {
|
||||
/* Some of these parameters might not be passed; zero is an OK default */
|
||||
$draw = (int) @$request['draw'];
|
||||
$start = (int) @$request['start'];
|
||||
|
|
|
@ -47,6 +47,9 @@ function urlForMember(User $user) : string {
|
|||
return '/user.php?name=' . urlencode($user->username);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception if the names and values aren't the same length
|
||||
*/
|
||||
function optionsForSelect(array $displays, array $values, string $currentSelection = null) : string {
|
||||
$size = count($displays);
|
||||
|
||||
|
@ -69,6 +72,9 @@ function optionsForSelect(array $displays, array $values, string $currentSelecti
|
|||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception if the flash level is invalid
|
||||
*/
|
||||
function flash(string $level, string $message) {
|
||||
if (!isset($_SESSION['flashes'])) {
|
||||
$_SESSION['flashes'] = [
|
||||
|
@ -121,7 +127,7 @@ function pp_html_escape(string $unescaped) : string {
|
|||
}
|
||||
|
||||
/* I think there is one row for each day, and in that row, tpage = non-unique, tvisit = unique page views for that day */
|
||||
function updatePageViews(DatabaseHandle $conn) : void {
|
||||
function updatePageViews() : void {
|
||||
global $redis;
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
|
@ -130,8 +136,6 @@ function updatePageViews(DatabaseHandle $conn) : void {
|
|||
$last_page_view = PageView::orderBy('id', 'desc')->limit(1)->first();
|
||||
|
||||
if ($last_page_view && $last_page_view->date == $date) {
|
||||
$last_tpage = intval($last_page_view->tpage) + 1;
|
||||
|
||||
if (!$redis->sIsMember('page_view_ips', $ip)) {
|
||||
$last_page_view->tvisit++;
|
||||
$redis->sAdd('page_view_ips', $ip);
|
||||
|
@ -153,7 +157,6 @@ function updatePageViews(DatabaseHandle $conn) : void {
|
|||
session_start();
|
||||
|
||||
/* Set up the database and Eloquent ORM */
|
||||
$conn = new DatabaseHandle("mysql:host=$db_host;dbname=$db_schema;charset=utf8mb4", $db_user, $db_pass);
|
||||
$capsule = new Capsule();
|
||||
|
||||
$capsule->addConnection([
|
||||
|
@ -168,6 +171,12 @@ $capsule->addConnection([
|
|||
$capsule->setAsGlobal();
|
||||
$capsule->bootEloquent();
|
||||
|
||||
// Check if IP is banned
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
if (IPBan::where('ip', $ip)->first()) {
|
||||
die('You have been banned.');
|
||||
}
|
||||
|
||||
/* Set up Redis */
|
||||
$redis = new Redis();
|
||||
$redis->pconnect(PP_REDIS_HOST);
|
||||
|
@ -200,11 +209,7 @@ if ($site_permissions) {
|
|||
$captcha_config = $site_info['captcha'];
|
||||
$captcha_enabled = (bool) $captcha_config['enabled'];
|
||||
|
||||
// Check if IP is banned
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
if (IPBan::where('ip', $ip)->first()) {
|
||||
die('You have been banned.');
|
||||
}
|
||||
|
||||
|
||||
$total_pastes = Paste::count();
|
||||
$total_page_views = PageView::select('tpage')->orderBy('id', 'desc')->first()->tpage;
|
||||
|
|
|
@ -226,22 +226,14 @@ function embedView($paste_id, $p_title, $content, $p_code, $title, $baseurl, $la
|
|||
return $stats;
|
||||
}
|
||||
|
||||
function addToSitemap($paste_id, $priority, $changefreq, $mod_rewrite) {
|
||||
function addToSitemap(\PonePaste\Models\Paste $paste, $priority, $changefreq) {
|
||||
$c_date = date('Y-m-d');
|
||||
$site_data = file_get_contents("sitemap.xml");
|
||||
$site_data = str_replace("</urlset>", "", $site_data);
|
||||
// which protocol are we on
|
||||
$protocol = paste_protocol();
|
||||
|
||||
if (PP_MOD_REWRITE) {
|
||||
$server_name = $protocol . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/" . $paste_id;
|
||||
} else {
|
||||
$server_name = $protocol . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/paste.php?id=" . $paste_id;
|
||||
}
|
||||
|
||||
$c_sitemap =
|
||||
' <url>
|
||||
<loc>' . $server_name . '</loc>
|
||||
<loc>' . urlForPaste($paste) . '</loc>
|
||||
<priority>' . $priority . '</priority>
|
||||
<changefreq>' . $changefreq . '</changefreq>
|
||||
<lastmod>' . $c_date . '</lastmod>
|
||||
|
|
|
@ -42,4 +42,4 @@ function pp_random_password() : string {
|
|||
* can reasonably be handled by a user.
|
||||
*/
|
||||
return hash('MD5', pp_random_bytes(64));
|
||||
}
|
||||
}
|
||||
|
|
13
index.php
13
index.php
|
@ -35,7 +35,7 @@ function verifyCaptcha() : string|bool {
|
|||
function calculatePasteExpiry(string $expiry) {
|
||||
// used to use mktime
|
||||
if ($expiry === 'self') {
|
||||
return 'SELF'; // What does this do?
|
||||
return 'SELF';
|
||||
}
|
||||
|
||||
$valid_expiries = ['10M', '1H', '1D', '1W', '2W', '1M'];
|
||||
|
@ -62,11 +62,8 @@ function validatePasteFields() : string|null {
|
|||
}
|
||||
|
||||
// Sitemap
|
||||
$site_sitemap_rows = $conn->query('SELECT * FROM sitemap_options LIMIT 1');
|
||||
if ($row = $site_sitemap_rows->fetch()) {
|
||||
$priority = $row['priority'];
|
||||
$changefreq = $row['changefreq'];
|
||||
}
|
||||
$priority = 0.9;
|
||||
$changefreq = 'weekly';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
if ($captcha_config['enabled']) {
|
||||
|
@ -74,7 +71,7 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
// POST Handler
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
@ -164,7 +161,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
$paste_id = $new_paste->id;
|
||||
|
||||
if ($p_visible == '0') {
|
||||
addToSitemap($paste_id, $priority, $changefreq, $mod_rewrite);
|
||||
addToSitemap($paste, $priority, $changefreq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { escape, whenReady } from './dom';
|
||||
import { DataTable } from './data_tables';
|
||||
import { DataTable, dumbFilterCallback } from './data_tables';
|
||||
import { globalSetup } from './main';
|
||||
|
||||
whenReady(() => {
|
||||
|
@ -39,20 +39,7 @@ whenReady(() => {
|
|||
<td>${tags}</td>
|
||||
</tr>`;
|
||||
},
|
||||
filterCallback: (datum, query) => {
|
||||
if (datum.title.indexOf(query) !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* this is inefficient */
|
||||
for (const tag of datum.tags) {
|
||||
if (tag.name.toLowerCase() === query.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
filterCallback: dumbFilterCallback,
|
||||
preFilter: myParam
|
||||
});
|
||||
table.attach();
|
||||
|
|
|
@ -21,6 +21,10 @@ class SimplePaginator {
|
|||
const lastPage = Math.floor(totalRecords / perPage); // ish?
|
||||
const numPagesToShow = 2;
|
||||
|
||||
if (lastPage === firstPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* First and last page the main paginator will show */
|
||||
const firstPageShow = (currentPage - firstPage) < numPagesToShow ? firstPage : ((currentPage - numPagesToShow < 0) ? currentPage : currentPage - numPagesToShow);
|
||||
const lastPageShow = (firstPageShow + numPagesToShow) > lastPage ? lastPage : (firstPageShow + numPagesToShow + numPagesToShow);
|
||||
|
@ -86,6 +90,9 @@ class DataTable {
|
|||
this.paginator = new SimplePaginator(this.container.querySelector('.paginator'));
|
||||
|
||||
this.filterCallback = options.filterCallback;
|
||||
this.sortField = null;
|
||||
this.sortDir = true;
|
||||
this.reverseRowCallback = options.reverseRowCallback;
|
||||
}
|
||||
|
||||
attach() {
|
||||
|
@ -102,17 +109,44 @@ class DataTable {
|
|||
}
|
||||
}
|
||||
|
||||
const header = this.element.querySelector('tr.paginator__sort');
|
||||
|
||||
if (header) {
|
||||
header.addEventListener('click', evt => {
|
||||
const target = evt.target;
|
||||
|
||||
if (!target.dataset.sortField) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sortField) {
|
||||
const elem = this.element.querySelector(`th[data-sort-field=${this.sortField}]`)
|
||||
elem.classList.remove('paginator__sort--down');
|
||||
elem.classList.remove('paginator__sort--up');
|
||||
}
|
||||
|
||||
this._updateSort(target.dataset.sortField, !this.sortDir);
|
||||
|
||||
target.classList.add(this.sortDir ? 'paginator__sort--up' : 'paginator__sort--down');
|
||||
});
|
||||
}
|
||||
|
||||
this.paginator.attach(this._updatePage.bind(this));
|
||||
this._loadEntries();
|
||||
}
|
||||
|
||||
/* Load the requested data from the server, and when done, update the DOM. */
|
||||
_loadEntries() {
|
||||
new Promise(this.ajaxCallback)
|
||||
.then(data => {
|
||||
this.unfilteredData = data.data;
|
||||
this._updateFilter(this.options.preFilter);
|
||||
});
|
||||
if (this.ajaxCallback) {
|
||||
new Promise(this.ajaxCallback)
|
||||
.then(data => {
|
||||
this.unfilteredData = data.data;
|
||||
this._updateFilter(this.options.preFilter);
|
||||
});
|
||||
} else if (this.reverseRowCallback) {
|
||||
this.unfilteredData = Array.prototype.map.call(this.element.querySelectorAll('tr'), this.reverseRowCallback).filter(row => row);
|
||||
this._updateFilter(this.options.preFilter);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the DOM to reflect the current state of the data we have loaded */
|
||||
|
@ -162,8 +196,43 @@ class DataTable {
|
|||
}
|
||||
|
||||
_updateSort(field, direction) {
|
||||
this.sortField = field;
|
||||
this.sortDir = direction;
|
||||
|
||||
let newEntries = [...this.data].sort((a, b) => {
|
||||
let sorter = 0;
|
||||
|
||||
if (a[field] > b[field]) {
|
||||
sorter = 1;
|
||||
} else if (a[field] < b[field]) {
|
||||
sorter = -1;
|
||||
}
|
||||
|
||||
if (!direction) {
|
||||
sorter = -sorter;
|
||||
}
|
||||
|
||||
return sorter;
|
||||
});
|
||||
|
||||
this._updatePage(0);
|
||||
this._updateEntries(newEntries);
|
||||
}
|
||||
}
|
||||
|
||||
export { DataTable };
|
||||
const dumbFilterCallback = (datum, query) => {
|
||||
if (datum.title.indexOf(query) !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* this is inefficient */
|
||||
for (const tag of datum.tags) {
|
||||
if (tag.name.toLowerCase() === query.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export { DataTable, dumbFilterCallback };
|
||||
|
|
87
js/user_profile.js
Normal file
87
js/user_profile.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
import { escape, whenReady } from './dom';
|
||||
import { DataTable, dumbFilterCallback } from './data_tables';
|
||||
import { globalSetup } from './main';
|
||||
|
||||
const parsePasteInfo = (elem) => {
|
||||
if (!elem.dataset.pasteInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return JSON.parse(elem.dataset.pasteInfo);
|
||||
};
|
||||
|
||||
whenReady(() => {
|
||||
globalSetup();
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const myParam = urlParams.get('q');
|
||||
const table = new DataTable(document.getElementById('archive'), {
|
||||
reverseRowCallback: parsePasteInfo,
|
||||
rowCallback: (rowData) => {
|
||||
const tags = rowData.tags.map((tagData) => {
|
||||
let tagColorClass;
|
||||
if (tagData.name.indexOf('nsfw') !== -1) {
|
||||
tagColorClass = 'is-danger';
|
||||
} else if (tagData.name.indexOf('safe') !== -1) {
|
||||
tagColorClass = 'is-success';
|
||||
} else if (tagData.name.indexOf('/') !== -1) {
|
||||
tagColorClass = 'is-primary';
|
||||
} else {
|
||||
tagColorClass = 'is-info';
|
||||
}
|
||||
|
||||
return `<a href="/archive?q=${tagData.slug}">
|
||||
<span class="tag ${tagColorClass}">${escape(tagData.name)}</span>
|
||||
</a>`;
|
||||
}).join('');
|
||||
|
||||
return `<tr>
|
||||
<td><a href="/${rowData.id}">${escape(rowData.title)}</a></td>
|
||||
<td>${rowData.created_at}</td>
|
||||
<td>${rowData.visibility}</td>
|
||||
<td>${rowData.views || 0}</td>
|
||||
<td>${tags}</td>
|
||||
</tr>`;
|
||||
},
|
||||
filterCallback: dumbFilterCallback,
|
||||
preFilter: myParam
|
||||
});
|
||||
table.attach();
|
||||
|
||||
const faveTable = new DataTable(document.getElementById('favs'), {
|
||||
reverseRowCallback: parsePasteInfo,
|
||||
rowCallback: (rowData) => {
|
||||
const tags = rowData.tags.map((tagData) => {
|
||||
let tagColorClass;
|
||||
if (tagData.name.indexOf('nsfw') !== -1) {
|
||||
tagColorClass = 'is-danger';
|
||||
} else if (tagData.name.indexOf('safe') !== -1) {
|
||||
tagColorClass = 'is-success';
|
||||
} else if (tagData.name.indexOf('/') !== -1) {
|
||||
tagColorClass = 'is-primary';
|
||||
} else {
|
||||
tagColorClass = 'is-info';
|
||||
}
|
||||
|
||||
return `<a href="/archive?q=${tagData.slug}">
|
||||
<span class="tag ${tagColorClass}">${escape(tagData.name)}</span>
|
||||
</a>`;
|
||||
}).join('');
|
||||
|
||||
const recentUpdate = rowData.recently_updated ?
|
||||
`<i class='far fa-check-square fa-lg' aria-hidden='true'></i>` :
|
||||
`<i class='far fa-minus-square fa-lg' aria-hidden='true'></i>`;
|
||||
|
||||
// <td><a href="/user/${escape(rowData.author)}">${escape(rowData.author)}</a></td>
|
||||
return `<tr>
|
||||
<td><a href="/${rowData.id}">${escape(rowData.title)}</a></td>
|
||||
<td>${rowData.favourited_at}</td>
|
||||
<td>${recentUpdate}</td>
|
||||
<td>${tags}</td>
|
||||
</tr>`;
|
||||
},
|
||||
filterCallback: dumbFilterCallback,
|
||||
preFilter: myParam
|
||||
});
|
||||
faveTable.attach();
|
||||
});
|
|
@ -19,7 +19,7 @@ if ($current_user !== null) {
|
|||
die();
|
||||
}
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
if (isset($_POST['forgot'])) {
|
||||
if (!empty($_POST['username']) && !empty($_POST['recovery_code'])) {
|
||||
|
|
|
@ -3,13 +3,15 @@ define('IN_PONEPASTE', 1);
|
|||
require_once('includes/common.php');
|
||||
require_once('includes/functions.php');
|
||||
|
||||
use PonePaste\Helpers\SessionHelper;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || $current_user === null) {
|
||||
header('Location: ' . $_SERVER['HTTP_REFERER']);
|
||||
die();
|
||||
}
|
||||
|
||||
/* Destroy remember token */
|
||||
\PonePaste\Helpers\SessionHelper::destroySession();
|
||||
SessionHelper::destroySession();
|
||||
|
||||
/* Destroy PHP session */
|
||||
unset($_SESSION['user_id']);
|
||||
|
|
23
pages.php
23
pages.php
|
@ -3,24 +3,19 @@ define('IN_PONEPASTE', 1);
|
|||
require_once('includes/common.php');
|
||||
require_once('includes/functions.php');
|
||||
|
||||
updatePageViews($conn);
|
||||
use PonePaste\Models\Page;
|
||||
|
||||
updatePageViews();
|
||||
|
||||
if (isset($_GET['page'])) {
|
||||
$page_name = htmlspecialchars(trim($_GET['page']));
|
||||
|
||||
$query = $conn->prepare('SELECT page_title, page_content, last_date FROM pages WHERE page_name = ?');
|
||||
$query->execute([$page_name]);
|
||||
if ($row = $query->fetch()) {
|
||||
$page_title = $row['page_title'];
|
||||
$page_content = $row['page_content'];
|
||||
$last_date = $row['last_date'];
|
||||
$stats = "OK";
|
||||
$p_title = $page_title;
|
||||
}
|
||||
$page = Page::select('page_title', 'page_content', 'last_date')
|
||||
->where('page_name', $_GET['page'])
|
||||
->first();
|
||||
$page_title = $page->page_title;
|
||||
} else {
|
||||
$page_title = 'Page not found';
|
||||
}
|
||||
|
||||
// Theme
|
||||
$page_template = 'pages';
|
||||
require_once('theme/' . $default_theme . '/common.php');
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ function getUserRecommended(User $user) {
|
|||
|
||||
$paste_id = intval(trim($_REQUEST['id']));
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
// This is used in the theme files.
|
||||
$totalpastes = Paste::count();
|
||||
|
|
|
@ -37,7 +37,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
$total_user_pastes = Paste::where('user_id', $current_user->id)->count();
|
||||
|
||||
|
|
|
@ -23,5 +23,6 @@ const output = (name) => {
|
|||
|
||||
export default [
|
||||
output('generic'),
|
||||
output('archive')
|
||||
output('archive'),
|
||||
output('user_profile')
|
||||
];
|
|
@ -7,6 +7,24 @@
|
|||
pointer-events: none;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.paginator__sort > th {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.paginator__sort--down, .paginator__sort--up {
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
.paginator__sort--down:after {
|
||||
padding-left: 0.25rem;
|
||||
content: '▼';
|
||||
}
|
||||
|
||||
.paginator__sort--up:after {
|
||||
padding-left: 0.25rem;
|
||||
content: '▲';
|
||||
}
|
||||
</style>
|
||||
|
||||
<main class="bd-main">
|
||||
|
@ -31,10 +49,10 @@
|
|||
</div>
|
||||
<table id="archive" class="table is-fullwidth is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Author</th>
|
||||
<th>Tags</th>
|
||||
<tr class="paginator__sort">
|
||||
<th data-sort-field="title">Title</th>
|
||||
<th data-sort-field="author">Author</th>
|
||||
<th data-sort-field="tags">Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
<div class="bd-main-container container">
|
||||
<div class="bd-duo">
|
||||
<div class="bd-lead">
|
||||
<h1 class="title is-4"><?php echo $page_title; ?><h1>
|
||||
<?php
|
||||
if (isset($stats)) {
|
||||
echo $page_content;
|
||||
} else {
|
||||
echo '<p class="help is-danger subtitle is-6">Not Found</p>';
|
||||
}
|
||||
?>
|
||||
<?php if (isset($page)): ?>
|
||||
<h1 class="title is-4"><?= pp_html_escape($page->page_title); ?><h1>
|
||||
<?= $page->page_content; ?>
|
||||
<?php else: ?>
|
||||
<h1 class="title is-4">Page not found.</h1>
|
||||
<p class="help is-danger subtitle is-6">A page with that name doesn't seem to exist.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,46 +1,3 @@
|
|||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#archive").dataTable({
|
||||
rowReorder: {selector: 'td:nth-child(2)'},
|
||||
responsive: true,
|
||||
pageLength: 50,
|
||||
order: [[ 1, "desc" ]],
|
||||
autoWidth: false,
|
||||
initComplete: function () {
|
||||
var search = new URLSearchParams(window.location.search);
|
||||
var query = search.get('q');
|
||||
if (query) {
|
||||
$("#archive_filter input")
|
||||
.val(query)
|
||||
.trigger("input");
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<?php if ($current_user) { ?>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#favs").dataTable({
|
||||
rowReorder: { selector: 'td:nth-child(2)'},
|
||||
responsive: true,
|
||||
order: [[ 2, "desc" ]],
|
||||
pageLength: 50,
|
||||
autoWidth: false,
|
||||
initComplete: function () {
|
||||
var search = new URLSearchParams(window.location.search);
|
||||
var query = search.get('q');
|
||||
if (query) {
|
||||
$("#archive_filter input")
|
||||
.val(query)
|
||||
.trigger("input");
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
$public_paste_badges = [
|
||||
50 => '[ProbablyAutistic] Have more than Fifty pastes',
|
||||
|
@ -87,11 +44,11 @@
|
|||
<h2 class="title is-5">Badges</h2>
|
||||
<?php
|
||||
if (strtotime($profile_join_date) <= 1604188800) {
|
||||
echo '<img src = "/img/badges/adopter.png" title="[EarlyAdopter] Joined during the first wave " style="margin:5px">';
|
||||
echo '<img src="/img/badges/adopter.png" title="[EarlyAdopter] Joined during the first wave " style="margin:5px">';
|
||||
} elseif (strtotime($profile_join_date) <= 1608422400) {
|
||||
echo '<img src = "/img/badges/pioneer.png" title="[EarlyPioneer] Joined during the Second wave " style="margin:5px">';
|
||||
echo '<img src="/img/badges/pioneer.png" title="[EarlyPioneer] Joined during the Second wave " style="margin:5px">';
|
||||
} elseif (strtotime($profile_join_date) <= 1609459200) {
|
||||
echo '<img src = "/img/badges/strag.png" title="[EarlyStraggeler] Joined after the Second wave " style="margin:5px">';
|
||||
echo '<img src="/img/badges/strag.png" title="[EarlyStraggeler] Joined after the Second wave " style="margin:5px">';
|
||||
}
|
||||
if (!str_contains($profile_badge, '0')) {
|
||||
echo $profile_badge;
|
||||
|
@ -143,15 +100,15 @@
|
|||
<table id="archive" class="table is-fullwidth is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="td-right">Title</td>
|
||||
<td class="td-center">Paste Time</td>
|
||||
<th class="td-right">Title</th>
|
||||
<th class="td-center">Paste Time</th>
|
||||
<?php if ($is_current_user) {
|
||||
echo "<td class='td-center'>Visibility</td>";
|
||||
echo "<th class='td-center'>Visibility</th>";
|
||||
} ?>
|
||||
<td class="td-center">Views</td>
|
||||
<td class="td-center">Tags</td>
|
||||
<th class="td-center">Views</th>
|
||||
<th class="td-center">Tags</th>
|
||||
<?php if ($is_current_user) {
|
||||
echo "<td class='td-center'>Delete</td>";
|
||||
echo "<th class='td-center'>Delete</th>";
|
||||
} ?>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -165,9 +122,13 @@
|
|||
1 => 'Unlisted',
|
||||
2 => 'Private'
|
||||
};
|
||||
$pasteJson = array_merge(
|
||||
$paste->only('id', 'title', 'tags', 'views', 'created_at'),
|
||||
['visibility' => $p_visible]
|
||||
);
|
||||
?>
|
||||
<?php if ($is_current_user || $row['visible'] == Paste::VISIBILITY_PUBLIC): ?>
|
||||
<tr>
|
||||
<tr data-paste-info="<?= pp_html_escape(json_encode($pasteJson)); ?>">
|
||||
<td><a href="<?= urlForPaste($paste) ?>" title="<?= $escaped_title ?>"><?= $escaped_title ?></a></td>
|
||||
<td data-sort="<?= $p_date->format('U') ?>" class="td-center"><?= $p_date->format('d F Y') ?></td>
|
||||
<td class="td-center"><?= $p_visible; ?></td>
|
||||
|
@ -180,29 +141,30 @@
|
|||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class="td-center">Title</td>
|
||||
<td class="td-center">Paste Time</td>
|
||||
<th class="td-center">Title</th>
|
||||
<th class="td-center">Paste Time</th>
|
||||
<?php if ($is_current_user) {
|
||||
echo "<td class='td-center'>Visibility</td>";
|
||||
} ?>
|
||||
<td class="td-center">Views</td>
|
||||
<td class="td-center">Tags</td>
|
||||
<th class="td-center">Views</th>
|
||||
<th class="td-center">Tags</th>
|
||||
<?php if ($is_current_user) {
|
||||
echo "<td class='td-center'>Delete</td>";
|
||||
} ?>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="paginator"></div>
|
||||
</div>
|
||||
<?php if ($is_current_user) { ?>
|
||||
<div class="tab-content" id="second-tab">
|
||||
<table id="favs" class="table is-fullwidth is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="td-right">Title</td>
|
||||
<td class="td-center">Date Favourited</td>
|
||||
<td class="td-center">Status</td>
|
||||
<td class="td-center">Tags</td>
|
||||
<th class="td-right">Title</th>
|
||||
<th class="td-center">Date Favourited</th>
|
||||
<th class="td-center">Status</th>
|
||||
<th class="td-center">Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -212,11 +174,15 @@
|
|||
$f_date = new DateTime($paste->pivot->f_time);
|
||||
$update_date = new DateTime($paste->updated_at);
|
||||
$delta = $update_date->diff(new DateTime(), true);
|
||||
$pasteJson = array_merge(
|
||||
$paste->only('id', 'title', 'tags', 'views', 'created_at'),
|
||||
['recently_updated' => ($delta->days <= 2), 'favourited_at' => $f_date->format('d F Y')]
|
||||
);
|
||||
?>
|
||||
<?php if ($is_current_user || $row['visible'] == Paste::VISIBILITY_PUBLIC): ?>
|
||||
<tr>
|
||||
<tr data-paste-info="<?= pp_html_escape(json_encode($pasteJson)); ?>">
|
||||
<td><a href="<?= urlForPaste($paste) ?>" title="<?= $escaped_title ?>"><?= $escaped_title ?></a></td>
|
||||
<td data-sort="<?= $p_date->format('U') ?>" class="td-center"><?= $p_date->format('d F Y') ?></td>
|
||||
<td data-sort="<?= $p_date->format('U') ?>" class="td-center"><?= $f_date->format('d F Y') ?></td>
|
||||
<td class="td-center">
|
||||
<?php if ($delta->days <= 2): ?>
|
||||
<i class='far fa-check-square fa-lg' aria-hidden='true'></i>
|
||||
|
@ -239,6 +205,7 @@
|
|||
</tfoot>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<div class="paginator"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
8
user.php
8
user.php
|
@ -14,7 +14,10 @@ if (empty($_GET['user'])) {
|
|||
|
||||
$profile_username = trim($_GET['user']);
|
||||
|
||||
$profile_info = User::with('favourites')->where('username', $profile_username)->select('id', 'date', 'badge')->first();
|
||||
$profile_info = User::with('favourites')
|
||||
->where('username', $profile_username)
|
||||
->select('id', 'date', 'badge')
|
||||
->first();
|
||||
|
||||
if (!$profile_info) {
|
||||
// Invalid username
|
||||
|
@ -50,7 +53,7 @@ $profile_pastes = $profile_info->pastes;
|
|||
$profile_favs = $profile_info->favourites;
|
||||
$is_current_user = ($current_user !== null) && ($profile_info->id == $current_user->id);
|
||||
|
||||
updatePageViews($conn);
|
||||
updatePageViews();
|
||||
|
||||
if (isset($_GET['del'])) {
|
||||
if ($current_user !== null) { // Prevent unauthorized deletes
|
||||
|
@ -70,4 +73,5 @@ if (isset($_GET['del'])) {
|
|||
|
||||
// Theme
|
||||
$page_template = 'user_profile';
|
||||
array_push($script_bundles, 'user_profile');
|
||||
require_once('theme/' . $default_theme . '/common.php');
|
||||
|
|
Loading…
Add table
Reference in a new issue