From 65bbc9e21152090407364fd7f2e0223a396466e8 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 26 Aug 2012 17:48:27 +0200
Subject: [PATCH 001/241] block marking a library as stdlib
---
HttpException.php | 1 +
items/modify.php | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/HttpException.php b/HttpException.php
index 0cc51db..2252edf 100644
--- a/HttpException.php
+++ b/HttpException.php
@@ -30,6 +30,7 @@ public static function getStatusMessage($code)
case 406: return "Not Acceptable";
case 409: return "Conflict";
case 413: return "Request Entity Too Large";
+ case 423: return "Locked";
case 500: return "Internal Server Error";
case 501: return "Not Implemented";
case 503: return "Service Unavailable";
diff --git a/items/modify.php b/items/modify.php
index aab9f2f..d63fabd 100644
--- a/items/modify.php
+++ b/items/modify.php
@@ -93,6 +93,9 @@
}
if (isset($_POST["default"]))
{
+ throw new HttpException(423); # block
+
+ /*
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
{
throw new HttpException(403);
@@ -111,6 +114,7 @@
{
throw new HttpException(404);
}
+ */
}
header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
}
From 0dd0eaf6ff764c63c66122d52d22c3b6d30c34ad Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 26 Aug 2012 20:18:13 +0200
Subject: [PATCH 002/241] remove 'default' from item description
---
items/describe.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/items/describe.php b/items/describe.php
index 03bd5bf..153db39 100644
--- a/items/describe.php
+++ b/items/describe.php
@@ -103,7 +103,6 @@
$output["uploaded"] = $db_entry["uploaded"];
$output["user"] = array("name" => User::getName($db_entry["HEX(user)"]), "id" => $db_entry["HEX(user)"]);
$output["reviewed"] = $db_entry["reviewed"] == 1;
- $output["default"] = $db_entry["default_include"] == 1;
$tag_list = array();
foreach ($data["tags"] AS $tag)
{
From 6c7462eeab0b1d96f366c5c19f6c883eb5342472 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 26 Aug 2012 20:19:04 +0200
Subject: [PATCH 003/241] remove 'stdlib' filter from item listing
---
items/list.php | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/items/list.php b/items/list.php
index 3083cde..9dce41c 100644
--- a/items/list.php
+++ b/items/list.php
@@ -39,21 +39,6 @@
$db_cond .= " tags REGEXP '(^|;)" . mysql_real_escape_string($_GET["tags"], $db_connection) . "($|;)'";
}
- # items in or not in the stdlib
- # ================================ #
- if (isset($_GET["stdlib"]) && in_array(strtolower($_GET["stdlib"]), array("no", "false", "-1")))
- {
- $db_cond .= ($db_cond) ? " AND " : " WHERE ";
- $db_cond .= "default_include = '0'";
- }
- else if (isset($_GET["stdlib"]) && in_array(strtolower($_GET["stdlib"]), array("yes", "true", "+1", "1")))
- {
- $db_cond .= ($db_cond) ? " AND " : " WHERE ";
- $db_cond .= "default_include = '1'";
- }
- /* else {} */ # default (use "both" or "0") - leave empty so both match
- # ================================ #
-
# reviewed and unreviewed items
# ================================ #
$db_cond .= ($db_cond) ? " AND " : " WHERE ";
From 0a74e7c61191bfa27c49d6421533d9cf2ce0c9a3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 26 Aug 2012 21:56:59 +0200
Subject: [PATCH 004/241] add config for some more new DB tables
---
config/database.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/config/database.php b/config/database.php
index e77d849..c9bbfae 100644
--- a/config/database.php
+++ b/config/database.php
@@ -8,6 +8,11 @@
# the names of the database tables
define('DB_TABLE_ITEMS', 'data'); #
define('DB_TABLE_USERS', 'users'); #
+ define('DB_TABLE_STDLIB', 'stdlib'); #
+ define('DB_TABLE_STDLIB_RELEASES', 'stdlib_releases'); #
+ define('DB_TABLE_STDLIB_PENDING', 'stdlib_pending'); #
+ define('DB_TABLE_STDLIB_ACTIONS', 'stdlib_actions'); #
+ define('DB_TABLE_UPDATE_TYPE', 'update_type'); #
# the credentials for accessing the database
define('DB_USERNAME', 'root'); # the user name
From 21c8bf5a8f645397734133970b2abb5046747496 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 26 Aug 2012 21:57:24 +0200
Subject: [PATCH 005/241] begin code for listing stdlib releases
---
stdlib/releases/list.php | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 stdlib/releases/list.php
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
new file mode 100644
index 0000000..9469207
--- /dev/null
+++ b/stdlib/releases/list.php
@@ -0,0 +1,63 @@
+release;
+ }
+
+ if ($content_type == "application/json")
+ {
+ $content = json_encode($data);
+ }
+ else if ($content_type == "text/xml" || $content_type == "application/xml")
+ {
+ $content = "";
+ foreach ($releases AS $release)
+ {
+ $content .= "";
+ }
+ $content .= "";
+ }
+
+ header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
+ header("Content-type: $content_type");
+ echo $content;
+ exit;
+ }
+ else
+ {
+ throw new HttpException(405, array("Allow" => "GET"));
+ }
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+?>
\ No newline at end of file
From c3803d7c09fbc45eefe9c6809360a024c4e9dd56 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 31 Aug 2012 02:20:31 +0200
Subject: [PATCH 006/241] fix reserved word in MySQL syntax
---
stdlib/releases/list.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 9469207..3e64253 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -19,11 +19,11 @@
## if not auth & review team: only released (isset(date))
## filter: only stable / unstable
- $db_query = "SELECT release FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond";
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, mysql_error() . " - \"" . $db_query . "\"");
}
$releases = array();
From 3a339365f4d5a7c6b3da136ce8e176db92c593ab Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 31 Aug 2012 02:22:21 +0200
Subject: [PATCH 007/241] fix incorrect variable name
---
stdlib/releases/list.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 3e64253..8c7f67f 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -34,7 +34,7 @@
if ($content_type == "application/json")
{
- $content = json_encode($data);
+ $content = json_encode($releases);
}
else if ($content_type == "text/xml" || $content_type == "application/xml")
{
From 83fd43c86e8fbf7eea285e2ce909a096ccbd1114 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 31 Aug 2012 02:25:00 +0200
Subject: [PATCH 008/241] fix syntax error
---
stdlib/releases/list.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 8c7f67f..2841e75 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -29,7 +29,7 @@
$releases = array();
while ($release = mysql_fetch_assoc($db_result))
{
- $releases[] = $release->release;
+ $releases[] = $release["release"];
}
if ($content_type == "application/json")
From 0f237e9656599d7903d6df86eb1eebb70a7fb555 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 3 Sep 2012 22:51:04 +0200
Subject: [PATCH 009/241] add SQL files for new DB tables
---
MySQL/DB_TABLE_STDLIB.sql | 19 +++++++++++++++++++
MySQL/DB_TABLE_STDLIB_ACTIONS.sql | 19 +++++++++++++++++++
MySQL/DB_TABLE_STDLIB_PENDING.sql | 17 +++++++++++++++++
MySQL/DB_TABLE_STDLIB_RELEASES.sql | 19 +++++++++++++++++++
MySQL/DB_TABLE_UPDATE_TYPE.sql | 21 +++++++++++++++++++++
5 files changed, 95 insertions(+)
create mode 100644 MySQL/DB_TABLE_STDLIB.sql
create mode 100644 MySQL/DB_TABLE_STDLIB_ACTIONS.sql
create mode 100644 MySQL/DB_TABLE_STDLIB_PENDING.sql
create mode 100644 MySQL/DB_TABLE_STDLIB_RELEASES.sql
create mode 100644 MySQL/DB_TABLE_UPDATE_TYPE.sql
diff --git a/MySQL/DB_TABLE_STDLIB.sql b/MySQL/DB_TABLE_STDLIB.sql
new file mode 100644
index 0000000..a75d809
--- /dev/null
+++ b/MySQL/DB_TABLE_STDLIB.sql
@@ -0,0 +1,19 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `stdlib` (
+ `release` tinytext NOT NULL,
+ `lib` binary(16) NOT NULL,
+ `user` binary(16) NOT NULL,
+ `comment` text NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/MySQL/DB_TABLE_STDLIB_ACTIONS.sql b/MySQL/DB_TABLE_STDLIB_ACTIONS.sql
new file mode 100644
index 0000000..b4cac4e
--- /dev/null
+++ b/MySQL/DB_TABLE_STDLIB_ACTIONS.sql
@@ -0,0 +1,19 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `stdlib_actions` (
+ `type` int(11) NOT NULL,
+ `item` binary(16) NOT NULL,
+ `user` binary(16) NOT NULL,
+ `accept` tinyint(1) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/MySQL/DB_TABLE_STDLIB_PENDING.sql b/MySQL/DB_TABLE_STDLIB_PENDING.sql
new file mode 100644
index 0000000..2a03c48
--- /dev/null
+++ b/MySQL/DB_TABLE_STDLIB_PENDING.sql
@@ -0,0 +1,17 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `stdlib_pending` (
+ `lib` binary(16) NOT NULL,
+ `update` enum('new','patch','minor','major') NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/MySQL/DB_TABLE_STDLIB_RELEASES.sql b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
new file mode 100644
index 0000000..19cf33f
--- /dev/null
+++ b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
@@ -0,0 +1,19 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `stdlib_releases` (
+ `release` tinytext NOT NULL,
+ `update` int(11) NOT NULL,
+ `date` date NOT NULL,
+ `description` text NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/MySQL/DB_TABLE_UPDATE_TYPE.sql b/MySQL/DB_TABLE_UPDATE_TYPE.sql
new file mode 100644
index 0000000..47e292d
--- /dev/null
+++ b/MySQL/DB_TABLE_UPDATE_TYPE.sql
@@ -0,0 +1,21 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `update_type` (
+ `id` int(11) NOT NULL,
+ `name` tinytext NOT NULL,
+ `items` tinyint(1) NOT NULL,
+ `stdlib` tinyint(1) NOT NULL,
+ `stdlib_releases` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
From 5d00883fda96e2e91cffc1e5c0fc59d544528e1a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 3 Sep 2012 22:52:52 +0200
Subject: [PATCH 010/241] add better exception handling for stdlib release
listing
Catch ALL exceptions and enwrap them
---
stdlib/releases/list.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 2841e75..d6162b7 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -60,4 +60,8 @@
{
handleHttpException($e);
}
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
?>
\ No newline at end of file
From 4f77dc518728e4894dc4e67fd058980a8de5cf7c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 29 Oct 2012 20:24:54 +0100
Subject: [PATCH 011/241] use Assert class for stdlib release listing
---
stdlib/releases/list.php | 77 +++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 41 deletions(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index d6162b7..0901361 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -2,59 +2,54 @@
require_once("../../HttpException.php");
require_once("../../db.php");
require_once("../../util.php");
+ require_once("../../Assert.php");
try
{
- $request_method = strtoupper($_SERVER['REQUEST_METHOD']);
- if ($request_method == "GET")
- {
- # validate accept header of request
- $content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
+ Assert::RequestMethod("GET");
- # connect to database server
- $db_connection = db_ensure_connection();
+ # validate accept header of request
+ $content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
- # TODO: any conditions here
- $db_cond = "";
- ## if not auth & review team: only released (isset(date))
- ## filter: only stable / unstable
+ # connect to database server
+ $db_connection = db_ensure_connection();
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error() . " - \"" . $db_query . "\"");
- }
+ # TODO: any conditions here
+ $db_cond = "";
+ ## if not auth & review team: only released (isset(date))
+ ## filter: only stable / unstable
- $releases = array();
- while ($release = mysql_fetch_assoc($db_result))
- {
- $releases[] = $release["release"];
- }
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error() . " - \"" . $db_query . "\"");
+ }
- if ($content_type == "application/json")
- {
- $content = json_encode($releases);
- }
- else if ($content_type == "text/xml" || $content_type == "application/xml")
- {
- $content = "";
- foreach ($releases AS $release)
- {
- $content .= "";
- }
- $content .= "";
- }
+ $releases = array();
+ while ($release = mysql_fetch_assoc($db_result))
+ {
+ $releases[] = $release["release"];
+ }
- header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
- header("Content-type: $content_type");
- echo $content;
- exit;
+ if ($content_type == "application/json")
+ {
+ $content = json_encode($releases);
}
- else
+ else if ($content_type == "text/xml" || $content_type == "application/xml")
{
- throw new HttpException(405, array("Allow" => "GET"));
+ $content = "";
+ foreach ($releases AS $release)
+ {
+ $content .= "";
+ }
+ $content .= "";
}
+
+ header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
+ header("Content-type: $content_type");
+ echo $content;
+ exit;
}
catch (HttpException $e)
{
From 6b20a2949f9690b79df7f566ff2644331f08ff4a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 29 Oct 2012 20:28:20 +0100
Subject: [PATCH 012/241] add basic .htaccess file
---
stdlib/releases/.htaccess | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 stdlib/releases/.htaccess
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
new file mode 100644
index 0000000..ed63197
--- /dev/null
+++ b/stdlib/releases/.htaccess
@@ -0,0 +1,5 @@
+Options -Multiviews
+
+RewriteEngine On
+
+RewriteRule ^list$ list.php [L]
\ No newline at end of file
From eeef99744f86c0baa0293541d7c5322d35506f0b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 29 Oct 2012 21:02:45 +0100
Subject: [PATCH 013/241] begin: stdlib release description API
---
stdlib/releases/.htaccess | 3 +-
stdlib/releases/describe.php | 107 +++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+), 1 deletion(-)
create mode 100644 stdlib/releases/describe.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index ed63197..25a170a 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -2,4 +2,5 @@ Options -Multiviews
RewriteEngine On
-RewriteRule ^list$ list.php [L]
\ No newline at end of file
+RewriteRule ^list$ list.php [L]
+RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
\ No newline at end of file
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
new file mode 100644
index 0000000..4e63160
--- /dev/null
+++ b/stdlib/releases/describe.php
@@ -0,0 +1,107 @@
+ date";
+
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond ORDER BY `release` " . ($version = "latest" ? "DESC" : "ASC") . " LIMIT 1";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) != 1)
+ {
+ throw new HttpException(404);
+ }
+
+ $db_entry = mysql_fetch_assoc($db_result);
+ $version = $db_entry["release"];
+ }
+
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$version'";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) != 1)
+ {
+ throw new HttpException(404);
+ }
+
+ $release = mysql_fetch_assoc($db_result);
+
+ # handle update type
+ $db_query = "SELECT name FROM " . DB_TABLE_UPDATE_TYPE . " WHERE id = '$release[update]'";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) != 1)
+ {
+ throw new HttpException(500, NULL, "unknown update type");
+ }
+ $db_entry = mysql_fetch_assoc($db_result);
+ $release["update"] = $db_entry["name"];
+
+ # get libs in the release
+ $db_query = "SELECT lib FROM " . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+
+ $release["libs"] = array();
+ while ($lib = mysql_fetch_assoc($db_result))
+ $release["libs"][] = $lib;
+
+ # todo later: get frameworks in the release
+
+ # todo: get last prerelease and last stable version
+ # todo: compile changelog (since latest prerelease + since latest stable)
+
+ if ($content_type == "application/json")
+ {
+ $content = json_encode($release);
+ }
+ else if ($content_type == "text/xml" || $content_type == "application/xml")
+ {
+ throw new HttpException(501);
+ }
+
+ header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
+ header("Content-type: $content_type");
+ echo $content;
+ exit;
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
+?>
\ No newline at end of file
From 2216566ba21cb057c6e7e454edd00c24e73520b0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 21:44:54 +0100
Subject: [PATCH 014/241] add a new semver method: parse array to string
---
semver.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/semver.php b/semver.php
index 27fbf18..368f3b5 100644
--- a/semver.php
+++ b/semver.php
@@ -7,6 +7,15 @@ function semver_parts($version, &$parts)
{
return !!preg_match('/^(?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P([0-9A-Za-z\-]+\.)*[0-9A-Za-z\-]+))?(\+(?P([0-9A-Za-z\-]+\.)*[0-9A-Za-z\-]+))?$/', $version, $parts);
}
+function semver_string(array $parts)
+{
+ $str = "$parts[major].$parts[minor].$parts[patch]";
+ if (!empty($parts["prerelease"]))
+ $str .= "-$parts[prerelease]";
+ if (!empty($parts["build"]))
+ $str .= "+$parts[build]";
+ return $str;
+}
function semver_compare($version1, $version2)
{
if (!semver_parts($version1, $parts1))
From 53d9d6dff9529f9049a9589639ca3de2438d6643 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 21:45:16 +0100
Subject: [PATCH 015/241] add basic class for update type handling
---
UpdateType.php | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 UpdateType.php
diff --git a/UpdateType.php b/UpdateType.php
new file mode 100644
index 0000000..825965c
--- /dev/null
+++ b/UpdateType.php
@@ -0,0 +1,29 @@
+
\ No newline at end of file
From ab449494ae82365fbc0a2479a9182ad6577a8f9c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 21:51:47 +0100
Subject: [PATCH 016/241] begin implementing stdlib release creation
---
stdlib/releases/.htaccess | 3 +-
stdlib/releases/create.php | 158 +++++++++++++++++++++++++++++++++++++
2 files changed, 160 insertions(+), 1 deletion(-)
create mode 100644 stdlib/releases/create.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index 25a170a..d06db5f 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -3,4 +3,5 @@ Options -Multiviews
RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
\ No newline at end of file
+RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
+RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L]
\ No newline at end of file
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
new file mode 100644
index 0000000..9651bba
--- /dev/null
+++ b/stdlib/releases/create.php
@@ -0,0 +1,158 @@
+ $release, "update" => $type);
+ if (isset($_POST["version"]))
+ {
+ try {
+ $result = semver_compare($_POST["version"], $release);
+ } catch (Exception $e) {
+ throw new HttpException(400, NULL, "Bad release version!"); # semver could not validate
+ }
+ if ($result != 1)
+ throw new HttpException(400, NULL, "Bad release version!"); # version is smaller then minimum
+
+ $data["release"] = mysql_real_escape_string($_POST["version"], $db_connection);
+ }
+ if (isset($_POST["date"]))
+ {
+ $data["date"] = mysql_real_escape_string($_POST["description"], $db_connection);
+ }
+ if (isset($_POST["description"]))
+ {
+ $data["description"] = mysql_real_escape_string($_POST["description"], $db_connection);
+ }
+
+ $db_query = "INSERT INTO " . DB_TABLE_STDLIB_RELEASES
+ . " ("
+ . implode(", ", array_map(function($item) { return "`$item`"; }, array_keys($data)))
+ . ") VALUES ("
+ . implode(", ", array_map(function($item) { return "'$item'"; }, array_values($data)))
+ . ")";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ if (mysql_affected_rows() != 1)
+ {
+ throw new HttpException(500);
+ }
+
+ if ($content_type == "application/json")
+ {
+ $content = json_encode(array("release" => $data["release"]));
+ }
+ else if ($content_type == "text/xml" || $content_type == "application/xml")
+ {
+ $content = "$data[release]";
+ }
+ header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
+ header("Content-type: $content_type");
+ echo $content;
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
+
+ function semver_bump_version(array &$release, $type)
+ {
+ if ($type == UPDATE_TYPE_PATCH || $type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
+ {
+ unset($release["prerelease"]);
+ unset($release["build"]);
+ $release["patch"]++;
+
+ if ($type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
+ {
+ $release["patch"] = 0;
+ $release["minor"]++;
+
+ if ($type == UPDATE_TYPE_MAJOR)
+ {
+ $release["minor"] = 0;
+ $release["major"]++;
+ }
+ }
+ }
+ }
+?>
\ No newline at end of file
From 2e5602fda5b6801c6a7d49b5f9725c37273fe692 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 22:22:10 +0100
Subject: [PATCH 017/241] fix release creation: retrieve latest release even
when unpublished
---
stdlib/releases/create.php | 52 ++++++++++----------------------------
1 file changed, 13 insertions(+), 39 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 9651bba..2c50e01 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -18,20 +18,27 @@
$db_connection = db_ensure_connection();
- # get latest release # TODO: fix for non-published
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " ORDER BY date DESC LIMIT 1";
+ # get latest release
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
throw new HttpException(500, NULL, mysql_error());
}
- if (mysql_num_rows($db_result) != 1)
+ if (mysql_num_rows($db_result) < 1)
{
$prev_release = "0.0.0";
}
else
{
- $db_entry = mysql_fetch_assoc($db_result);
+ $releases = array();
+ while ($release = mysql_fetch_assoc($db_result))
+ {
+ $releases[] = $release;
+ }
+ usort($releases, "semver_sort"); # sort by "release" field, following semver rules
+
+ $db_entry = $releases[count($releases) - 1]; # latest release
$prev_release = $db_entry["release"];
}
@@ -39,7 +46,6 @@
$release = array();
semver_parts($prev_release, $release);
- /*
if ($type == UPDATE_TYPE_PATCH || $type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
{
unset($release["prerelease"]);
@@ -58,21 +64,6 @@
}
}
}
- */
- while (true)
- {
- semver_bump_version($release, $type);
- $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . semver_string($release) . "'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
- if (mysql_num_rows($db_result) != 1)
- {
- break;
- }
- }
$release = semver_string($release);
$data = array("release" => $release, "update" => $type);
@@ -134,25 +125,8 @@
handleHttpException(new HttpException(500, NULL, $e->getMessage()));
}
- function semver_bump_version(array &$release, $type)
+ function semver_sort($a, $b)
{
- if ($type == UPDATE_TYPE_PATCH || $type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
- {
- unset($release["prerelease"]);
- unset($release["build"]);
- $release["patch"]++;
-
- if ($type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
- {
- $release["patch"] = 0;
- $release["minor"]++;
-
- if ($type == UPDATE_TYPE_MAJOR)
- {
- $release["minor"] = 0;
- $release["major"]++;
- }
- }
- }
+ return semver_compare($a["release"], $b["release"]);
}
?>
\ No newline at end of file
From 8f80a722c6e610140086dd2db9cc24383d322688 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 22:22:23 +0100
Subject: [PATCH 018/241] release creation: require authentication
---
stdlib/releases/create.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 2c50e01..c4c5b0f 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -4,6 +4,7 @@
require_once("../../HttpException.php");
require_once("../../UpdateType.php");
require_once("../../semver.php");
+ require_once("../../User.php");
define('UPDATE_TYPE_PATCH', 2);
define('UPDATE_TYPE_MINOR', 3);
@@ -16,6 +17,10 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
+ user_basic_auth("Restricted API");
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ throw new HttpException(403);
+
$db_connection = db_ensure_connection();
# get latest release
From 224d14b939c93700273a3ee7cbf0e48044da1a43 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 22:22:45 +0100
Subject: [PATCH 019/241] uncomment HTTP method check
---
stdlib/releases/create.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index c4c5b0f..5d22daf 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -12,7 +12,7 @@
try
{
- #Assert::RequestMethod("POST");
+ Assert::RequestMethod("POST");
Assert::GetParameters("type");
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
From 4ca4b5c58df092d6951da785527042a48a172242 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 31 Oct 2012 22:50:38 +0100
Subject: [PATCH 020/241] implement deletion of release
---
stdlib/releases/.htaccess | 3 ++-
stdlib/releases/delete.php | 39 ++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 stdlib/releases/delete.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index d06db5f..c306f4b 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -4,4 +4,5 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
-RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L]
\ No newline at end of file
+RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L]
+RewriteRule ^delete/(.+)$ delete.php?version=$1 [L]
\ No newline at end of file
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
new file mode 100644
index 0000000..dd60ccd
--- /dev/null
+++ b/stdlib/releases/delete.php
@@ -0,0 +1,39 @@
+getMessage()));
+ }
+?>
\ No newline at end of file
From 5d4776afb444ec6f8bbf56100886403fdc68d0cc Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 15:48:32 +0100
Subject: [PATCH 021/241] release creation: support basing on latest published
release
By default, a release is based on the latest created release
(the version number is based on it). Now the base can be spe-
cified to be all releases (default) or the latest published
release.
---
stdlib/releases/.htaccess | 2 +-
stdlib/releases/create.php | 61 ++++++++++++++++++++++++++++++++++++--
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index c306f4b..cbc6545 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -4,5 +4,5 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
-RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L]
+RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
RewriteRule ^delete/(.+)$ delete.php?version=$1 [L]
\ No newline at end of file
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 5d22daf..234eef2 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -10,6 +10,9 @@
define('UPDATE_TYPE_MINOR', 3);
define('UPDATE_TYPE_MAJOR', 4);
+ define('RELEASE_BASE_ALL', 1);
+ define('RELEASE_BASE_PUBLISHED', 2);
+
try
{
Assert::RequestMethod("POST");
@@ -17,14 +20,41 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
+ $base = RELEASE_BASE_ALL;
+ if (!empty($_GET["base"]))
+ {
+ $base = strtolower($_GET["base"]);
+ if (!in_array($base, array("all", "published")))
+ throw new HttpException(400);
+ switch ($base)
+ {
+ case "published":
+ $base = RELEASE_BASE_PUBLISHED;
+ break;
+ default:
+ case "all":
+ $base = RELEASE_BASE_ALL;
+ break;
+ }
+ }
+
user_basic_auth("Restricted API");
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
$db_connection = db_ensure_connection();
+ switch ($base)
+ {
+ case RELEASE_BASE_PUBLISHED:
+ $db_cond = " WHERE date AND NOW() > date";
+ break;
+ default:
+ $db_cond = "";
+ }
+
# get latest release
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES;
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -47,7 +77,7 @@
$prev_release = $db_entry["release"];
}
- # todo: bump version number according to $type
+ # bump version number according to $type
$release = array();
semver_parts($prev_release, $release);
@@ -71,6 +101,15 @@
}
$release = semver_string($release);
+ if ($base == RELEASE_BASE_PUBLISHED)
+ {
+ # check if (unpublished) release already exists
+ if (release_exists($release))
+ {
+ throw new HttpException(409, NULL, "Release '$release' has already been created!");
+ }
+ }
+
$data = array("release" => $release, "update" => $type);
if (isset($_POST["version"]))
{
@@ -82,6 +121,12 @@
if ($result != 1)
throw new HttpException(400, NULL, "Bad release version!"); # version is smaller then minimum
+ # check if release already exists
+ if (release_exists($_POST["version"]))
+ {
+ throw new HttpException(409, NULL, "Release '$_POST[version]' has already been created!");
+ }
+
$data["release"] = mysql_real_escape_string($_POST["version"], $db_connection);
}
if (isset($_POST["date"]))
@@ -134,4 +179,16 @@ function semver_sort($a, $b)
{
return semver_compare($a["release"], $b["release"]);
}
+
+ function release_exists($release)
+ {
+ $db_connection = db_ensure_connection();
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ return mysql_num_rows($db_result) > 0;
+ }
?>
\ No newline at end of file
From da4132732c6372de259983a997e52b3acc7987fb Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:10:14 +0100
Subject: [PATCH 022/241] shorten some code by adding a new method to the
UpdateType class
---
UpdateType.php | 20 ++++++++++++++++++++
stdlib/releases/describe.php | 14 ++------------
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index 825965c..8e66ca9 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -25,5 +25,25 @@ public static function getCode($str, $usage)
$db_entry = mysql_fetch_assoc($db_result);
return $db_entry["id"];
}
+
+ public static function getName($id)
+ {
+ $db_connection = db_ensure_connection();
+ $id = mysql_real_escape_string($id, $db_connection);
+
+ $db_query = "SELECT name FROM " . DB_TABLE_UPDATE_TYPE . " WHERE id = '$id'";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) != 1)
+ {
+ throw new HttpException(500, NULL, "unknown update type");
+ }
+
+ $db_entry = mysql_fetch_assoc($db_result);
+ return $db_entry["name"];
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 4e63160..ddd9fe4 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -4,6 +4,7 @@
require_once("../../util.php");
require_once("../../semver.php");
require_once("../../Assert.php");
+ require_once("../../UpdateType.php");
try
{
@@ -52,18 +53,7 @@
$release = mysql_fetch_assoc($db_result);
# handle update type
- $db_query = "SELECT name FROM " . DB_TABLE_UPDATE_TYPE . " WHERE id = '$release[update]'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500);
- }
- if (mysql_num_rows($db_result) != 1)
- {
- throw new HttpException(500, NULL, "unknown update type");
- }
- $db_entry = mysql_fetch_assoc($db_result);
- $release["update"] = $db_entry["name"];
+ $release["update"] = UpdateType::getName($release["update"]);
# get libs in the release
$db_query = "SELECT lib FROM " . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
From c6f4a4c33ba7a28e6c6d60d284973182f5cd4ce1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:39:14 +0100
Subject: [PATCH 023/241] add StdlibRelease class
New class to handle stdlib releases in one central place.
---
stdlib/releases/StdlibRelease.php | 100 ++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 stdlib/releases/StdlibRelease.php
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
new file mode 100644
index 0000000..5e8c898
--- /dev/null
+++ b/stdlib/releases/StdlibRelease.php
@@ -0,0 +1,100 @@
+ date)";
+ }
+
+ $db_connection = db_ensure_connection();
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ return mysql_num_rows($db_result) > 0;
+ }
+
+ const SPECIAL_VERSION_LATEST = "latest";
+ const SPECIAL_VERSION_FIRST = "first";
+
+ public static function getVersion($special_version, $published_only = false)
+ {
+ $db_connection = db_ensure_connection();
+ $special_version = strtolower($special_version);
+
+ if (in_array($special_version, array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
+ {
+ # get all releases
+ $db_cond = $published_only ? " WHERE date AND NOW() > date" : "";
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+
+ # no latest release
+ if (mysql_num_rows($db_result) < 1)
+ {
+ return FALSE;
+ }
+
+ # fetch releases in array
+ $releases = array();
+ while ($release = mysql_fetch_assoc($db_result))
+ {
+ $releases[] = $release;
+ }
+
+ usort($releases, array("StdlibRelease", "semver_sort")); # sort by "release" field, following semver rules
+ $db_entry = $releases[$special_version == self::SPECIAL_VERSION_LATEST ? count($releases) - 1 : 0]; # latest / first release
+ return $db_entry["release"];
+ }
+ return FALSE;
+ }
+
+ public static function describe($release, $published_only = false)
+ {
+ $db_connection = db_ensure_connection();
+
+ # resolve special release versions
+ if (in_array(strtolower($release), array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
+ {
+ $release = self::getVersion($release, $published_only);
+ if (!$release)
+ throw new HttpException(404);
+ }
+
+ $db_cond = $published_only ? " AND (date AND NOW() > date)" : "";
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) != 1)
+ {
+ throw new HttpException(404);
+ }
+ return mysql_fetch_assoc($db_result);
+ }
+
+ static function semver_sort($a, $b)
+ {
+ return semver_compare($a["release"], $b["release"]);
+ }
+}
+
+?>
\ No newline at end of file
From d1afffe7f13fc4c52fecdc567ac6d299d007540a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:40:19 +0100
Subject: [PATCH 024/241] simplify code with new class
Use new StdlibRelease class to simplify code for release
description and creation.
---
stdlib/releases/create.php | 57 +++++++-----------------------------
stdlib/releases/describe.php | 37 +++--------------------
2 files changed, 15 insertions(+), 79 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 234eef2..56481ea 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -5,14 +5,12 @@
require_once("../../UpdateType.php");
require_once("../../semver.php");
require_once("../../User.php");
+ require_once("StdlibRelease.php");
define('UPDATE_TYPE_PATCH', 2);
define('UPDATE_TYPE_MINOR', 3);
define('UPDATE_TYPE_MAJOR', 4);
- define('RELEASE_BASE_ALL', 1);
- define('RELEASE_BASE_PUBLISHED', 2);
-
try
{
Assert::RequestMethod("POST");
@@ -20,7 +18,7 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
- $base = RELEASE_BASE_ALL;
+ $base = StdlibRelease::RELEASE_BASE_ALL;
if (!empty($_GET["base"]))
{
$base = strtolower($_GET["base"]);
@@ -29,11 +27,11 @@
switch ($base)
{
case "published":
- $base = RELEASE_BASE_PUBLISHED;
+ $base = StdlibRelease::RELEASE_BASE_PUBLISHED;
break;
default:
case "all":
- $base = RELEASE_BASE_ALL;
+ $base = StdlibRelease::RELEASE_BASE_ALL;
break;
}
}
@@ -46,36 +44,15 @@
switch ($base)
{
- case RELEASE_BASE_PUBLISHED:
- $db_cond = " WHERE date AND NOW() > date";
+ case StdlibRelease::RELEASE_BASE_PUBLISHED:
+ $published_only = true;
break;
default:
- $db_cond = "";
+ $published_only = false;
}
# get latest release
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
- if (mysql_num_rows($db_result) < 1)
- {
- $prev_release = "0.0.0";
- }
- else
- {
- $releases = array();
- while ($release = mysql_fetch_assoc($db_result))
- {
- $releases[] = $release;
- }
- usort($releases, "semver_sort"); # sort by "release" field, following semver rules
-
- $db_entry = $releases[count($releases) - 1]; # latest release
- $prev_release = $db_entry["release"];
- }
+ $prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $published_only);
# bump version number according to $type
$release = array();
@@ -101,10 +78,10 @@
}
$release = semver_string($release);
- if ($base == RELEASE_BASE_PUBLISHED)
+ if ($base == StdlibRelease::RELEASE_BASE_PUBLISHED)
{
# check if (unpublished) release already exists
- if (release_exists($release))
+ if (StdlibRelease::exists($release))
{
throw new HttpException(409, NULL, "Release '$release' has already been created!");
}
@@ -122,7 +99,7 @@
throw new HttpException(400, NULL, "Bad release version!"); # version is smaller then minimum
# check if release already exists
- if (release_exists($_POST["version"]))
+ if (StdlibRelease::exists($_POST["version"]))
{
throw new HttpException(409, NULL, "Release '$_POST[version]' has already been created!");
}
@@ -179,16 +156,4 @@ function semver_sort($a, $b)
{
return semver_compare($a["release"], $b["release"]);
}
-
- function release_exists($release)
- {
- $db_connection = db_ensure_connection();
- $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
- return mysql_num_rows($db_result) > 0;
- }
?>
\ No newline at end of file
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index ddd9fe4..6bfab67 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -4,6 +4,7 @@
require_once("../../util.php");
require_once("../../semver.php");
require_once("../../Assert.php");
+ require_once("StdlibRelease.php");
require_once("../../UpdateType.php");
try
@@ -17,40 +18,10 @@
# connect to database server
$db_connection = db_ensure_connection();
- $version = mysql_real_escape_string(strtolower($_GET["version"]), $db_connection);
- $special_version = in_array($version, array("latest", "first"));
- if ($special_version)
- {
- # unless auth
- $db_cond = "WHERE NOW() > date";
-
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond ORDER BY `release` " . ($version = "latest" ? "DESC" : "ASC") . " LIMIT 1";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500);
- }
- if (mysql_num_rows($db_result) != 1)
- {
- throw new HttpException(404);
- }
-
- $db_entry = mysql_fetch_assoc($db_result);
- $version = $db_entry["release"];
- }
-
- $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$version'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500);
- }
- if (mysql_num_rows($db_result) != 1)
- {
- throw new HttpException(404);
- }
+ # todo!
+ $published_only = true;
- $release = mysql_fetch_assoc($db_result);
+ $release = StdlibRelease::describe($_GET["version"], $published_only);
# handle update type
$release["update"] = UpdateType::getName($release["update"]);
From 4c4273aa85de188ccb1b8f7ca74b44fcb14901f7 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:44:20 +0100
Subject: [PATCH 025/241] minor creation improvement
Do not declare update types statically - use UpdateType::getCode().
---
stdlib/releases/create.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 56481ea..764cb06 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -7,9 +7,9 @@
require_once("../../User.php");
require_once("StdlibRelease.php");
- define('UPDATE_TYPE_PATCH', 2);
- define('UPDATE_TYPE_MINOR', 3);
- define('UPDATE_TYPE_MAJOR', 4);
+ define('UPDATE_TYPE_PATCH', UpdateType::getCode("patch", "stdlib_releases"));
+ define('UPDATE_TYPE_MINOR', UpdateType::getCode("minor", "stdlib_releases"));
+ define('UPDATE_TYPE_MAJOR', UpdateType::getCode("major", "stdlib_releases"));
try
{
From d817f7f28a274839654a0f54dd52475aad2663f5 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:46:43 +0100
Subject: [PATCH 026/241] remove no longer used function
---
stdlib/releases/create.php | 5 -----
1 file changed, 5 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 764cb06..bc6455c 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -151,9 +151,4 @@
{
handleHttpException(new HttpException(500, NULL, $e->getMessage()));
}
-
- function semver_sort($a, $b)
- {
- return semver_compare($a["release"], $b["release"]);
- }
?>
\ No newline at end of file
From 0ee6ddec5b71c521e41b9d59fdcbf50209cb5be7 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 16:52:11 +0100
Subject: [PATCH 027/241] move release creation to StdlibRelease class
---
stdlib/releases/StdlibRelease.php | 17 +++++++++++++++++
stdlib/releases/delete.php | 15 ++-------------
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 5e8c898..0500e7e 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -91,6 +91,23 @@ public static function describe($release, $published_only = false)
return mysql_fetch_assoc($db_result);
}
+ public static function delete($release)
+ {
+ $db_connection = db_ensure_connection();
+ $release = mysql_real_escape_string($release, $db_connection);
+
+ $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND (!date OR NOW() < date)";
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ else if (mysql_affected_rows($db_connection) < 1)
+ {
+ throw new HttpException(400, NULL, "Release doesn't exist or is already published.");
+ }
+ }
+
static function semver_sort($a, $b)
{
return semver_compare($a["release"], $b["release"]);
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
index dd60ccd..4ab3d92 100644
--- a/stdlib/releases/delete.php
+++ b/stdlib/releases/delete.php
@@ -3,6 +3,7 @@
require_once("../../Assert.php");
require_once("../../HttpException.php");
require_once("../../User.php");
+ require_once("StdlibRelease.php");
try
{
@@ -13,19 +14,7 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
- $db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($_GET["version"], $db_connection);
-
- $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND (!date OR NOW() < date)";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
- else if (mysql_affected_rows($db_connection) < 1)
- {
- throw new HttpException(400, NULL, "Release doesn't exist or is already published.");
- }
+ StdlibRelease::delete($_GET["version"]);
header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
}
catch (HttpException $e)
From 688c215b982ae4cf168b747f71d4541a2bbe1a11 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 17:00:37 +0100
Subject: [PATCH 028/241] further simplification of release creation
---
stdlib/releases/StdlibRelease.php | 4 ++--
stdlib/releases/create.php | 36 ++++++++++---------------------
2 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 0500e7e..990b4c0 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -5,8 +5,8 @@
class StdlibRelease
{
- const RELEASE_BASE_ALL = 1;
- const RELEASE_BASE_PUBLISHED = 2;
+ const RELEASE_BASE_ALL = "all";
+ const RELEASE_BASE_PUBLISHED = "published";
public static function exists($release, $published_only = false)
{
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index bc6455c..8bea60a 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -18,21 +18,19 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
- $base = StdlibRelease::RELEASE_BASE_ALL;
+ $published_only = false;
if (!empty($_GET["base"]))
{
- $base = strtolower($_GET["base"]);
- if (!in_array($base, array("all", "published")))
- throw new HttpException(400);
- switch ($base)
+ switch (strtolower($_GET["base"]))
{
- case "published":
- $base = StdlibRelease::RELEASE_BASE_PUBLISHED;
+ case StdlibRelease::RELEASE_BASE_PUBLISHED:
+ $published_only = true;
break;
- default:
- case "all":
- $base = StdlibRelease::RELEASE_BASE_ALL;
+ case StdlibRelease::RELEASE_BASE_ALL:
+ $published_only = false;
break;
+ default:
+ throw new HttpException(400, NULL, "Unsupported release base '$_GET[base]'!");
}
}
@@ -42,15 +40,6 @@
$db_connection = db_ensure_connection();
- switch ($base)
- {
- case StdlibRelease::RELEASE_BASE_PUBLISHED:
- $published_only = true;
- break;
- default:
- $published_only = false;
- }
-
# get latest release
$prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $published_only);
@@ -78,13 +67,10 @@
}
$release = semver_string($release);
- if ($base == StdlibRelease::RELEASE_BASE_PUBLISHED)
+ # check if (unpublished) release already exists
+ if ($published_only && StdlibRelease::exists($release))
{
- # check if (unpublished) release already exists
- if (StdlibRelease::exists($release))
- {
- throw new HttpException(409, NULL, "Release '$release' has already been created!");
- }
+ throw new HttpException(409, NULL, "Release '$release' has already been created!");
}
$data = array("release" => $release, "update" => $type);
From bff0ff189995586734b654f377922872b4efcc51 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 1 Nov 2012 17:07:28 +0100
Subject: [PATCH 029/241] shorten code: do escaping for all items in one place
---
stdlib/releases/create.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 8bea60a..91060c2 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -90,22 +90,22 @@
throw new HttpException(409, NULL, "Release '$_POST[version]' has already been created!");
}
- $data["release"] = mysql_real_escape_string($_POST["version"], $db_connection);
+ $data["release"] = $_POST["version"];
}
if (isset($_POST["date"]))
{
- $data["date"] = mysql_real_escape_string($_POST["description"], $db_connection);
+ $data["date"] = $_POST["description"];
}
if (isset($_POST["description"]))
{
- $data["description"] = mysql_real_escape_string($_POST["description"], $db_connection);
+ $data["description"] = $_POST["description"];
}
$db_query = "INSERT INTO " . DB_TABLE_STDLIB_RELEASES
. " ("
. implode(", ", array_map(function($item) { return "`$item`"; }, array_keys($data)))
. ") VALUES ("
- . implode(", ", array_map(function($item) { return "'$item'"; }, array_values($data)))
+ . implode(", ", array_map(function($item) { return "'" . mysql_real_escape_string($item, $db_connection) . "'"; }, array_values($data)))
. ")";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
From b41e3af73ea57ce1aca1ca7bce33ef7677190475 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 2 Nov 2012 20:48:37 +0100
Subject: [PATCH 030/241] release listing: implement "published" filter
---
stdlib/releases/list.php | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 0901361..ca5c5c6 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -2,6 +2,7 @@
require_once("../../HttpException.php");
require_once("../../db.php");
require_once("../../util.php");
+ require_once("../../User.php");
require_once("../../Assert.php");
try
@@ -14,12 +15,30 @@
# connect to database server
$db_connection = db_ensure_connection();
- # TODO: any conditions here
- $db_cond = "";
- ## if not auth & review team: only released (isset(date))
- ## filter: only stable / unstable
+ $db_cond = " WHERE (date AND NOW() > date)";
+ if (!empty($_GET["published"]))
+ {
+ $published = strtolower($_GET["published"]);
+ if (in_array($published, array(-1, "no", "false"), true))
+ {
+ # check auth
+ user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ throw new HttpException(403);
+ $db_cond = " WHERE (!date OR NOW() < date)";
+ }
+ else if (in_array($published, array(0, "both"), true))
+ {
+ # check auth
+ user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ throw new HttpException(403);
+ $db_cond = "";
+ }
+ # else if (in_array($published, array(1, "+1", "true", "yes"))) # the default
+ }
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . " $db_cond";
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
From b87f68c68849733391d75169dfe20f00e6b91db0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 2 Nov 2012 21:24:58 +0100
Subject: [PATCH 031/241] begin implementing release metadata modification
---
stdlib/releases/.htaccess | 8 +++-
stdlib/releases/StdlibRelease.php | 26 +++++++++++++
stdlib/releases/modify.php | 61 +++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+), 2 deletions(-)
create mode 100644 stdlib/releases/modify.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index cbc6545..2c9039f 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -3,6 +3,10 @@ Options -Multiviews
RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
+
RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
-RewriteRule ^delete/(.+)$ delete.php?version=$1 [L]
\ No newline at end of file
+
+#RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
+#RewriteRule ^delete/(.+)$ delete.php?version=$1 [L]
+#RewriteRule ^modify/(.+)$ modify.php?version=$1 [L]
+RewriteRule ^(describe|delete|modify)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 990b4c0..eb3f27f 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -108,6 +108,32 @@ public static function delete($release)
}
}
+ public static function update($release, $data)
+ {
+ $db_connection = db_ensure_connection();
+ $release = mysql_real_escape_string($release, $db_connection);
+
+ $db_query = "UPDATE " . DB_TABLE_STDLIB_RELEASES . " Set "
+ . implode(", ",
+ array_map(
+ function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'"; },
+ array_keys($data),
+ array_values($data)
+ )
+ )
+ . " WHERE `release` = '$release'";
+
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ else if (mysql_affected_rows($db_connection) != 1)
+ {
+ throw new HttpException(400, NULL, "Release doesn't exist or is already published.");
+ }
+ }
+
static function semver_sort($a, $b)
{
return semver_compare($a["release"], $b["release"]);
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
new file mode 100644
index 0000000..0c6cab2
--- /dev/null
+++ b/stdlib/releases/modify.php
@@ -0,0 +1,61 @@
+ "release", "description" => "description", "date" => "date") AS $key => $col)
+ {
+ if (!empty($_POST[$key]))
+ $data[$col] = $_POST[$key];
+ }
+
+ # verify release
+ if (isset($data["release"]))
+ {
+ if (!semver_validate($data["release"])) # check if valid semver
+ throw new HttpException(400, NULL, "Incorrect release version!");
+ if (!StdlibRelease::exists($data["release"])) # check if not already existing
+ throw new HttpException(409, NULL, "Release '$data[release]' already exists!");
+ }
+
+ # verify date
+ if (isset($data["date"]))
+ {
+ # todo: check stdlib admin
+ # check valid date
+ # check not already over
+ }
+
+ if (count($data) > 0)
+ StdlibRelease::update($_GET["version"], $data);
+
+ header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
+?>
\ No newline at end of file
From bbf9c8b58914e5d21389762522963e658ef54b7c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 2 Nov 2012 21:37:57 +0100
Subject: [PATCH 032/241] show unpublished releases to stdlib team
---
stdlib/releases/describe.php | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 6bfab67..e41866b 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -4,6 +4,7 @@
require_once("../../util.php");
require_once("../../semver.php");
require_once("../../Assert.php");
+ require_once("../../User.php");
require_once("StdlibRelease.php");
require_once("../../UpdateType.php");
@@ -18,8 +19,12 @@
# connect to database server
$db_connection = db_ensure_connection();
- # todo!
$published_only = true;
+ if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"]))
+ {
+ user_basic_auth("");
+ $published_only = !User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE);
+ }
$release = StdlibRelease::describe($_GET["version"], $published_only);
From fc18e8e3538367d6f891a8cb9bb2cbcdeb0c1310 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 2 Nov 2012 23:23:32 +0100
Subject: [PATCH 033/241] delete old rewrites
---
stdlib/releases/.htaccess | 3 ---
1 file changed, 3 deletions(-)
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index 2c9039f..1c7635a 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -6,7 +6,4 @@ RewriteRule ^list$ list.php [L]
RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
-#RewriteRule ^describe/(.+)$ describe.php?version=$1 [L]
-#RewriteRule ^delete/(.+)$ delete.php?version=$1 [L]
-#RewriteRule ^modify/(.+)$ modify.php?version=$1 [L]
RewriteRule ^(describe|delete|modify)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
From b75a10a72c975bb0755de177f69136d1f6b9e10d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 4 Nov 2012 17:00:14 +0100
Subject: [PATCH 034/241] small fix to StdlibRelease: do not update published
releases
---
stdlib/releases/StdlibRelease.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index eb3f27f..8f8607d 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -121,7 +121,7 @@ function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'
array_values($data)
)
)
- . " WHERE `release` = '$release'";
+ . " WHERE `release` = '$release' AND (!date OR date > NOW())";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -130,7 +130,7 @@ function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'
}
else if (mysql_affected_rows($db_connection) != 1)
{
- throw new HttpException(400, NULL, "Release doesn't exist or is already published.");
+ throw new HttpException(400, NULL, "Release '$release' doesn't exist or is already published.");
}
}
From e5b1798a5dc169e607f125a0ae95e4349c94fe2e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 4 Nov 2012 17:01:06 +0100
Subject: [PATCH 035/241] release metadata modification: validate specified
date / time
---
stdlib/releases/modify.php | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index 0c6cab2..dcc563b 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -41,8 +41,25 @@
if (isset($data["date"]))
{
# todo: check stdlib admin
+
# check valid date
+ $date = array();
+ if (!preg_match("/^(?\d{4})\-(?\d{2})\-(?\d{2})(T(?\d{2})(:(?\d{2})(:(?\d{2}))))?$/", $data["date"], $date))
+ {
+ throw new HttpException(400, NULL, "Invalid date format!");
+ }
+ if (!checkdate($date["month"], $date["day"], $date["year"]))
+ {
+ throw new HttpException(400, NULL, "Invalid date specified!");
+ }
+
# check not already over
+ $datetime = new DateTime($data["date"]);
+ $now = new DateTime();
+ if ($datetime <= $now)
+ {
+ throw new HttpException(400, NULL, "Specified date already over!");
+ }
}
if (count($data) > 0)
From 36abb1f6604228d00482973bf148258495fb57e1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 16 Nov 2012 18:18:08 +0100
Subject: [PATCH 036/241] change DB table: use timestamp to include time
---
MySQL/DB_TABLE_STDLIB_RELEASES.sql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MySQL/DB_TABLE_STDLIB_RELEASES.sql b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
index 19cf33f..728d849 100644
--- a/MySQL/DB_TABLE_STDLIB_RELEASES.sql
+++ b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
@@ -10,7 +10,7 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_releases` (
`release` tinytext NOT NULL,
`update` int(11) NOT NULL,
- `date` date NOT NULL,
+ `date` timestamp NOT NULL,
`description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
From 992a4e53be4c63b57b1bb2b1791b824411dedcbe Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 16 Nov 2012 18:53:05 +0100
Subject: [PATCH 037/241] implement stdlib release publishing
---
stdlib/releases/.htaccess | 2 +-
stdlib/releases/publish.php | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
create mode 100644 stdlib/releases/publish.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index 1c7635a..7890a18 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -6,4 +6,4 @@ RewriteRule ^list$ list.php [L]
RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
-RewriteRule ^(describe|delete|modify)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
+RewriteRule ^(describe|delete|modify|publish)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
new file mode 100644
index 0000000..3764046
--- /dev/null
+++ b/stdlib/releases/publish.php
@@ -0,0 +1,34 @@
+ date("c")));
+ header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
+?>
\ No newline at end of file
From 875af53af29510d4473312350ef10cd6208ecb45 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 17 Nov 2012 23:09:34 +0100
Subject: [PATCH 038/241] new ListReleases() method to StdlibRelease class
Use the new method to simplify StdlibRelease::getVersion().
---
stdlib/releases/StdlibRelease.php | 53 ++++++++++++++++---------------
1 file changed, 28 insertions(+), 25 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 8f8607d..e5c98f3 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -31,37 +31,18 @@ public static function exists($release, $published_only = false)
public static function getVersion($special_version, $published_only = false)
{
- $db_connection = db_ensure_connection();
$special_version = strtolower($special_version);
if (in_array($special_version, array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
{
- # get all releases
- $db_cond = $published_only ? " WHERE date AND NOW() > date" : "";
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
-
- # no latest release
- if (mysql_num_rows($db_result) < 1)
+ $releases = self::ListReleases($published_only);
+ if (count($releases > 0))
{
- return FALSE;
+ usort($releases, array("StdlibRelease", "semver_sort")); # sort following the semver rules
+ return $releases[$special_version == self::SPECIAL_VERSION_LATEST ? count($releases) - 1 : 0]; # latest / first release
}
-
- # fetch releases in array
- $releases = array();
- while ($release = mysql_fetch_assoc($db_result))
- {
- $releases[] = $release;
- }
-
- usort($releases, array("StdlibRelease", "semver_sort")); # sort by "release" field, following semver rules
- $db_entry = $releases[$special_version == self::SPECIAL_VERSION_LATEST ? count($releases) - 1 : 0]; # latest / first release
- return $db_entry["release"];
}
+
return FALSE;
}
@@ -136,7 +117,29 @@ function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'
static function semver_sort($a, $b)
{
- return semver_compare($a["release"], $b["release"]);
+ return semver_compare($a, $b);
+ }
+
+ public static function ListReleases($published_only = false)
+ {
+ $db_connection = db_ensure_connection();
+
+ # get all releases from DB
+ $db_cond = $published_only ? " WHERE date AND NOW() > date" : "";
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
+ $db_result = mysql_query($db_query, $db_connection);
+ if (!$db_result)
+ {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+
+ # fetch releases in array
+ $releases = array();
+ while ($release = mysql_fetch_assoc($db_result))
+ {
+ $releases[] = $release["release"];
+ }
+ return $releases;
}
}
From d46139553a22ebea3960e0602acdfa8c137309f2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 17 Nov 2012 23:56:09 +0100
Subject: [PATCH 039/241] change system for publish status
Instead of a boolean $published_only, the methods in the StdlibRelease
class now take one of three constants which allow greater flexibility.
All usages of the classes have been modified accordingly.
Also, for easier maintainability, the SQL conditions for published or
unpublished releases have been centralized in one place.
---
stdlib/releases/StdlibRelease.php | 52 ++++++++++++++++++++-----------
stdlib/releases/create.php | 15 +++++----
stdlib/releases/describe.php | 7 +++--
stdlib/releases/modify.php | 6 ++--
stdlib/releases/publish.php | 4 +--
5 files changed, 50 insertions(+), 34 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index e5c98f3..748eadb 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -8,15 +8,11 @@ class StdlibRelease
const RELEASE_BASE_ALL = "all";
const RELEASE_BASE_PUBLISHED = "published";
- public static function exists($release, $published_only = false)
+ public static function exists($release, $published)
{
- $db_cond = "";
- if ($published_only)
- {
- $db_cond = " AND (date AND NOW() > date)";
- }
-
+ $db_cond = ($t = self::get_publish_cond($published)) == NULL ? '' : " AND $t";
$db_connection = db_ensure_connection();
+
$db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -29,13 +25,13 @@ public static function exists($release, $published_only = false)
const SPECIAL_VERSION_LATEST = "latest";
const SPECIAL_VERSION_FIRST = "first";
- public static function getVersion($special_version, $published_only = false)
+ public static function getVersion($special_version, $published)
{
$special_version = strtolower($special_version);
if (in_array($special_version, array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
{
- $releases = self::ListReleases($published_only);
+ $releases = self::ListReleases($published);
if (count($releases > 0))
{
usort($releases, array("StdlibRelease", "semver_sort")); # sort following the semver rules
@@ -46,19 +42,19 @@ public static function getVersion($special_version, $published_only = false)
return FALSE;
}
- public static function describe($release, $published_only = false)
+ public static function describe($release, $published)
{
- $db_connection = db_ensure_connection();
-
# resolve special release versions
if (in_array(strtolower($release), array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
{
- $release = self::getVersion($release, $published_only);
+ $release = self::getVersion($release, $published);
if (!$release)
throw new HttpException(404);
}
- $db_cond = $published_only ? " AND (date AND NOW() > date)" : "";
+ $db_cond = ($t = self::get_publish_cond($published)) == NULL ? '' : " AND $t";
+ $db_connection = db_ensure_connection();
+
$db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -77,7 +73,7 @@ public static function delete($release)
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
- $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND (!date OR NOW() < date)";
+ $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND " . self::get_publish_cond(self::PUBLISHED_NO);
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -102,7 +98,7 @@ function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'
array_values($data)
)
)
- . " WHERE `release` = '$release' AND (!date OR date > NOW())";
+ . " WHERE `release` = '$release' AND " . self::get_publish_cond(self::PUBLISHED_NO);
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -120,12 +116,13 @@ static function semver_sort($a, $b)
return semver_compare($a, $b);
}
- public static function ListReleases($published_only = false)
+ public static function ListReleases($published)
{
+ # take publishing status into account
+ $db_cond = ($t = self::get_publish_cond($published)) == NULL ? '' : " WHERE $t";
$db_connection = db_ensure_connection();
# get all releases from DB
- $db_cond = $published_only ? " WHERE date AND NOW() > date" : "";
$db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -141,6 +138,25 @@ public static function ListReleases($published_only = false)
}
return $releases;
}
+
+ const PUBLISHED_YES = 1;
+ const PUBLISHED_NO = 2;
+ const PUBLISHED_BOTH = 3; # self::PUBLISHED_YES | self::PUBLISHED_NO
+
+ static function get_publish_cond($published)
+ {
+ switch ($published)
+ {
+ case self::PUBLISHED_YES:
+ return '(`date` AND NOW() > `date`)';
+ case self::PUBLISHED_NO:
+ return '(!`date` OR NOW() < `date`)';
+ case self::PUBLISHED_BOTH:
+ return NULL;
+ default:
+ throw new HttpException(400);
+ }
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 91060c2..302f732 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -18,16 +18,16 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
- $published_only = false;
+ $publish_status = StdlibRelease::PUBLISHED_BOTH;
if (!empty($_GET["base"]))
{
switch (strtolower($_GET["base"]))
{
case StdlibRelease::RELEASE_BASE_PUBLISHED:
- $published_only = true;
+ $publish_status = StdlibRelease::PUBLISHED_YES;
break;
case StdlibRelease::RELEASE_BASE_ALL:
- $published_only = false;
+ $publish_status = StdlibRelease::PUBLISHED_BOTH;
break;
default:
throw new HttpException(400, NULL, "Unsupported release base '$_GET[base]'!");
@@ -38,10 +38,8 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
- $db_connection = db_ensure_connection();
-
# get latest release
- $prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $published_only);
+ $prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $publish_status);
# bump version number according to $type
$release = array();
@@ -68,7 +66,7 @@
$release = semver_string($release);
# check if (unpublished) release already exists
- if ($published_only && StdlibRelease::exists($release))
+ if ($publish_status == StdlibRelease::PUBLISHED_YES && StdlibRelease::exists($release, StdlibRelease::PUBLISHED_BOTH))
{
throw new HttpException(409, NULL, "Release '$release' has already been created!");
}
@@ -85,7 +83,7 @@
throw new HttpException(400, NULL, "Bad release version!"); # version is smaller then minimum
# check if release already exists
- if (StdlibRelease::exists($_POST["version"]))
+ if (StdlibRelease::exists($_POST["version"], StdlibRelease::PUBLISHED_BOTH))
{
throw new HttpException(409, NULL, "Release '$_POST[version]' has already been created!");
}
@@ -101,6 +99,7 @@
$data["description"] = $_POST["description"];
}
+ $db_connection = db_ensure_connection();
$db_query = "INSERT INTO " . DB_TABLE_STDLIB_RELEASES
. " ("
. implode(", ", array_map(function($item) { return "`$item`"; }, array_keys($data)))
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index e41866b..c972e22 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -19,14 +19,15 @@
# connect to database server
$db_connection = db_ensure_connection();
- $published_only = true;
+ $publish_status = StdlibRelease::PUBLISHED_YES;
if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"]))
{
user_basic_auth("");
- $published_only = !User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE);
+ if (User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ $publish_status = StdlibRelease::PUBLISHED_BOTH;
}
- $release = StdlibRelease::describe($_GET["version"], $published_only);
+ $release = StdlibRelease::describe($_GET["version"], $publish_status);
# handle update type
$release["update"] = UpdateType::getName($release["update"]);
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index dcc563b..ef0a00d 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -15,10 +15,10 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
- if (!StdlibRelease::exists($_GET["version"])) # check if release exists
+ if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
throw new HttpException(404, NULL, "Release does not exist!");
- if (StdlibRelease::exists($_GET["version"], true)) # check if already published
+ if (StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_YES)) # check if already published
throw new HttpException(403, NULL, "Must not change published release!");
$data = array();
@@ -33,7 +33,7 @@
{
if (!semver_validate($data["release"])) # check if valid semver
throw new HttpException(400, NULL, "Incorrect release version!");
- if (!StdlibRelease::exists($data["release"])) # check if not already existing
+ if (!StdlibRelease::exists($data["release"], StdlibRelease::PUBLISHED_BOTH)) # check if not already existing
throw new HttpException(409, NULL, "Release '$data[release]' already exists!");
}
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index 3764046..219e0e7 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -14,10 +14,10 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
- if (!StdlibRelease::exists($_GET["version"])) # check if release exists
+ if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
throw new HttpException(404, NULL, "Release does not exist!");
- if (StdlibRelease::exists($_GET["version"], true)) # check if already published
+ if (StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_YES)) # check if already published
throw new HttpException(403, NULL, "Must not change published release!");
StdlibRelease::update($_GET["version"], array("date" => date("c")));
From 45c13ff7c603497ed7c9d0b10ee84022c66c96df Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 17 Nov 2012 23:56:54 +0100
Subject: [PATCH 040/241] change release listing to use StdlibRelease class
---
stdlib/releases/list.php | 24 +++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index ca5c5c6..5e69e23 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -1,9 +1,9 @@
date)";
+ $publish_status = StdlibRelease::PUBLISHED_YES;
if (!empty($_GET["published"]))
{
$published = strtolower($_GET["published"]);
@@ -25,7 +22,7 @@
user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
- $db_cond = " WHERE (!date OR NOW() < date)";
+ $publish_status = StdlibRelease::PUBLISHED_NO;
}
else if (in_array($published, array(0, "both"), true))
{
@@ -33,23 +30,12 @@
user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
- $db_cond = "";
+ $publish_status = StdlibRelease::PUBLISHED_BOTH;
}
# else if (in_array($published, array(1, "+1", "true", "yes"))) # the default
}
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error() . " - \"" . $db_query . "\"");
- }
-
- $releases = array();
- while ($release = mysql_fetch_assoc($db_result))
- {
- $releases[] = $release["release"];
- }
+ $releases = StdlibRelease::ListReleases($publish_status);
if ($content_type == "application/json")
{
From 9536a67fcec280e00a3783d1c1169915723778db Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 18 Nov 2012 00:38:03 +0100
Subject: [PATCH 041/241] DB change: drop `user` from DB_TABLE_STDLIB
---
MySQL/DB_TABLE_STDLIB.sql | 1 -
1 file changed, 1 deletion(-)
diff --git a/MySQL/DB_TABLE_STDLIB.sql b/MySQL/DB_TABLE_STDLIB.sql
index a75d809..f33e1db 100644
--- a/MySQL/DB_TABLE_STDLIB.sql
+++ b/MySQL/DB_TABLE_STDLIB.sql
@@ -10,7 +10,6 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib` (
`release` tinytext NOT NULL,
`lib` binary(16) NOT NULL,
- `user` binary(16) NOT NULL,
`comment` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
From 174ffd6e7d422c7c504801d420c26d66a2aec892 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 18 Nov 2012 20:36:43 +0100
Subject: [PATCH 042/241] begin "update" API
Start writing code that collects the pending changes
for a new to-be-published release. To do so, add a few
new helper classes, Stdlib and StdlibPending.
---
stdlib/Stdlib.php | 30 +++++++++++++
stdlib/StdlibPending.php | 44 ++++++++++++++++++
stdlib/releases/.htaccess | 2 +-
stdlib/releases/update.php | 92 ++++++++++++++++++++++++++++++++++++++
4 files changed, 167 insertions(+), 1 deletion(-)
create mode 100644 stdlib/Stdlib.php
create mode 100644 stdlib/StdlibPending.php
create mode 100644 stdlib/releases/update.php
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
new file mode 100644
index 0000000..d61f9ba
--- /dev/null
+++ b/stdlib/Stdlib.php
@@ -0,0 +1,30 @@
+
\ No newline at end of file
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
new file mode 100644
index 0000000..ebc31ee
--- /dev/null
+++ b/stdlib/StdlibPending.php
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index 7890a18..599580b 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -6,4 +6,4 @@ RewriteRule ^list$ list.php [L]
RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
-RewriteRule ^(describe|delete|modify|publish)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
+RewriteRule ^(describe|delete|modify|publish|update)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
new file mode 100644
index 0000000..9c2641a
--- /dev/null
+++ b/stdlib/releases/update.php
@@ -0,0 +1,92 @@
+ $id); }, StdlibPending::GetEntries($release));
+
+ $lib_version = array();
+ foreach ($libs AS $i => &$lib)
+ {
+ $lib = array_merge($lib, Item::get($lib['id'], array('name', 'version'))); # get info on lib, especially name & version
+
+ # assign the corresponding update types, comparing to the $old_items array
+ #################################################
+ $old = searchSubArray($old_items, array('name' => $lib['name']));
+
+ # if any of them means a downgrade, delete the entry
+ if ($old && semver_compare($old['version'], $lib['version']) < 0)
+ {
+ StdlibPending::DeleteEntry($lib['id']);
+ break;
+ }
+
+ # todo: update type
+ $update_type = 0;
+ #################################################
+
+ # filter according to release update type
+ #################################################
+ if ($release_update == $update_type)
+ {
+ # if duplicates: take higher, delete lower
+ if (!isset($lib_version[$lib['name']]) || semver_compare($lib_version[$lib['name']], $lib['version']) < 0)
+ {
+ $lib_version[$lib['name']] = $lib['version'];
+ }
+ }
+ else
+ {
+ unset($libs[$i]);
+ }
+ #################################################
+ }
+
+ # write to 'stdlib' table (deleting old entries for that release first)
+
+ # stdlib_actions > stdlib_pending > stdlib > release published
+ }
+ catch (HttpException $e)
+ {
+ handleHttpException($e);
+ }
+ catch (Exception $e)
+ {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+ }
+?>
\ No newline at end of file
From 35cdc9cf00868214ddf336716c9ff1291306719c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:07:16 +0100
Subject: [PATCH 043/241] change how update types work
Remove the useless DB table. Hardcode types and their 'names'
in the UpdateType class, as well as the usage. Also add new
update types 'prerelease-increase' and 'build-increase'.
---
MySQL/DB_TABLE_UPDATE_TYPE.sql | 21 ------------
UpdateType.php | 63 ++++++++++++++++++----------------
2 files changed, 33 insertions(+), 51 deletions(-)
delete mode 100644 MySQL/DB_TABLE_UPDATE_TYPE.sql
diff --git a/MySQL/DB_TABLE_UPDATE_TYPE.sql b/MySQL/DB_TABLE_UPDATE_TYPE.sql
deleted file mode 100644
index 47e292d..0000000
--- a/MySQL/DB_TABLE_UPDATE_TYPE.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-SET time_zone = "+00:00";
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-
-
-CREATE TABLE IF NOT EXISTS `update_type` (
- `id` int(11) NOT NULL,
- `name` tinytext NOT NULL,
- `items` tinyint(1) NOT NULL,
- `stdlib` tinyint(1) NOT NULL,
- `stdlib_releases` int(11) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/UpdateType.php b/UpdateType.php
index 8e66ca9..c323f84 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -1,49 +1,52 @@
'major', self::MINOR => 'minor', self::PATCH => 'patch',
+ self::BUILD_INCREASE => 'build-increase', self::PRERELEASE_INCREASE => 'prerelease-increase',
+ self::ADD => 'add', self::REMOVE => 'remove');
- $db_query = "SELECT id FROM " . DB_TABLE_UPDATE_TYPE . " WHERE name = '$str' AND `$usage` = TRUE";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
+ const USAGE_ITEMS = 'items';
+ const USAGE_STDLIB = 'stdlib';
+ const USAGE_STDLIB_RELEASES = 'stdlib_releases';
+
+ private static $usage = array(self::USAGE_ITEMS => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE, self::ADD),
+ self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE, self::ADD, self::REMOVE),
+ self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE));
+
+ public static function getCode($str, $usage)
+ {
+ $code = array_search(strtolower($str), self::$map);
+ if (!$code)
{
- throw new HttpException(500);
+ throw new HttpException(400);
}
- if (mysql_num_rows($db_result) != 1)
+
+ if (!isset(self::$usage[$usage]) || !array_search($code, self::$usage[$usage]))
{
throw new HttpException(400);
}
- $db_entry = mysql_fetch_assoc($db_result);
- return $db_entry["id"];
+ return $code;
}
public static function getName($id)
{
- $db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
-
- $db_query = "SELECT name FROM " . DB_TABLE_UPDATE_TYPE . " WHERE id = '$id'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500);
- }
- if (mysql_num_rows($db_result) != 1)
- {
- throw new HttpException(500, NULL, "unknown update type");
- }
-
- $db_entry = mysql_fetch_assoc($db_result);
- return $db_entry["name"];
+ if (isset(self::$map[$id]))
+ return self::$map[$id];
+ throw new HttpException(500, NULL, 'Unknown update type!');
}
}
?>
\ No newline at end of file
From 1ad829e34b3bc6f84aa61adac66929b3b7c3050c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:08:58 +0100
Subject: [PATCH 044/241] remove config for removed DB table
---
config/database.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/config/database.php b/config/database.php
index c9bbfae..d8acd94 100644
--- a/config/database.php
+++ b/config/database.php
@@ -12,7 +12,6 @@
define('DB_TABLE_STDLIB_RELEASES', 'stdlib_releases'); #
define('DB_TABLE_STDLIB_PENDING', 'stdlib_pending'); #
define('DB_TABLE_STDLIB_ACTIONS', 'stdlib_actions'); #
- define('DB_TABLE_UPDATE_TYPE', 'update_type'); #
# the credentials for accessing the database
define('DB_USERNAME', 'root'); # the user name
From 134b1f47d803da87f03b9242b64c2136ff0066e5 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:11:30 +0100
Subject: [PATCH 045/241] fix typo
---
UpdateType.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index c323f84..b46da43 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -22,9 +22,9 @@ class UpdateType
const USAGE_STDLIB = 'stdlib';
const USAGE_STDLIB_RELEASES = 'stdlib_releases';
- private static $usage = array(self::USAGE_ITEMS => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE, self::ADD),
- self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE, self::ADD, self::REMOVE),
- self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::RELEASE_INCREASE));
+ private static $usage = array(self::USAGE_ITEMS => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE, self::ADD),
+ self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE, self::ADD, self::REMOVE),
+ self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE));
public static function getCode($str, $usage)
{
From 3361e03e1a026dfff6a17b963a079c7c03169a57 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:15:55 +0100
Subject: [PATCH 046/241] fix syntax errors and path problems in Stdlib class
---
stdlib/Stdlib.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index d61f9ba..07b308b 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -1,10 +1,10 @@
Date: Thu, 22 Nov 2012 15:16:55 +0100
Subject: [PATCH 047/241] fix StdlibPending class
---
stdlib/StdlibPending.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index ebc31ee..fa2a6d4 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -1,14 +1,12 @@
Date: Thu, 22 Nov 2012 15:22:20 +0100
Subject: [PATCH 048/241] write code to retrieve update type for two semver
versions
Use it in "update" API to retrieve the update type for
a release and the possibly to-be-included items versions.
---
stdlib/releases/get_update.php | 66 ++++++++++++++++++++++++++++++++++
stdlib/releases/update.php | 9 +++--
2 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 stdlib/releases/get_update.php
diff --git a/stdlib/releases/get_update.php b/stdlib/releases/get_update.php
new file mode 100644
index 0000000..a9bd88e
--- /dev/null
+++ b/stdlib/releases/get_update.php
@@ -0,0 +1,66 @@
+ -1)
+ {
+ throw new HttpException(500);
+ }
+
+ foreach (array('major' => UpdateType::MAJOR, 'minor' => UpdateType::MINOR, 'patch' => UpdateType::PATCH) AS $part => $type)
+ {
+ $new_value = (int)$new_parts[$part];
+ $old_value = (int)$old_parts[$part];
+
+ if ($new_value > $old_value)
+ return $type;
+ }
+
+ foreach (array('prerelease' => UpdateType::PRERELEASE_INCREASE, 'build' => UpdateType::BUILD_INCREASE) AS $part => $type)
+ {
+ if (!empty($new_parts[$part]) && !empty($old_parts[$part])) # optional parts
+ {
+ $new_fragments = explode('.', $new_parts[$part]);
+ $old_fragments = explode('.', $old_parts[$part]);
+
+ for ($index = 0; $index < min(count($new_fragments), count($old_fragments)); $index++) # use the smaller amount of parts
+ {
+ $new_frag = $new_fragments[$index]; $old_frag = $old_fragments[$index];
+ if (ctype_digit($new_frag) && ctype_digit($old_frag))
+ {
+ $new_frag = (int)$new_frag; $old_frag = (int)$old_frag; # convert to numbers
+ if ($new_frag != $old_frag)
+ return $type;
+ continue;
+ }
+ # at least one is non-numeric: compare by characters
+ else if ($new_frag < $old_frag || $new_frag > $old_frag)
+ return $type;
+ }
+
+ if (count($new_fragments) != count($old_fragments))
+ return $type;
+ }
+ else if (!empty($new_parts[$part]))
+ return $type;
+ }
+
+ throw new HttpException(500);
+}
+
+?>
\ No newline at end of file
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 9c2641a..6b5a3cc 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -9,6 +9,7 @@
require_once('StdlibRelease.php');
require_once('../../User.php');
require_once('../../util.php');
+ require_once('get_update.php');
try
{
@@ -27,8 +28,8 @@
# get latest published release
$latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
- # todo: get release update type
- $release_update = 0;
+ # get release update type
+ $release_update = get_update($latest_release, $release);
$old_items = Stdlib::GetItems($latest_release);
foreach ($old_items AS &$item)
@@ -55,9 +56,7 @@
StdlibPending::DeleteEntry($lib['id']);
break;
}
-
- # todo: update type
- $update_type = 0;
+ $update_type = get_update($old['version'], $lib['version']); # update type
#################################################
# filter according to release update type
From e3d0c9c26eb33d7b4efa14313a7647629a2be6d2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:27:07 +0100
Subject: [PATCH 049/241] correct usage mapping for update types
---
UpdateType.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index b46da43..a7fb1ba 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -23,8 +23,8 @@ class UpdateType
const USAGE_STDLIB_RELEASES = 'stdlib_releases';
private static $usage = array(self::USAGE_ITEMS => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE, self::ADD),
- self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE, self::ADD, self::REMOVE),
- self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE));
+ self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::ADD, self::REMOVE),
+ self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH));
public static function getCode($str, $usage)
{
From f5c26ea6e6bd6a8467cf41bd827ba7c21a0971ea Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 22 Nov 2012 15:37:34 +0100
Subject: [PATCH 050/241] supporting addition and removal from / to stdlib
Set correct update type for new items to be added and to be removed.
Also tweak filter checking for matching release update type to allow
item addition / removal for stdlib releases of type 'major'.
Last but not least, when a downgrade is deleted, also remove it from
the current array, not only the DB.
---
stdlib/releases/update.php | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 6b5a3cc..126c161 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -50,18 +50,32 @@
#################################################
$old = searchSubArray($old_items, array('name' => $lib['name']));
- # if any of them means a downgrade, delete the entry
- if ($old && semver_compare($old['version'], $lib['version']) < 0)
+ if ($old && semver_compare($old['version'], $lib['version']) != 0)
{
- StdlibPending::DeleteEntry($lib['id']);
- break;
+ if (semver_compare($old['version'], $lib['version']) == 0) # same version means removal
+ {
+ $update_type = UpdateType::REMOVE;
+ }
+ else if (semver_compare($old['version'], $lib['version']) == 1) # if any of them means a downgrade (old > new), delete the entry
+ {
+ StdlibPending::DeleteEntry($lib['id']);
+ unset($libs[$i]);
+ break;
+ }
+ else # actually an upgrade
+ {
+ $update_type = get_update($old['version'], $lib['version']); # update type
+ }
+ }
+ else # not in latest release - must be new
+ {
+ $update_type = UpdateType::ADD;
}
- $update_type = get_update($old['version'], $lib['version']); # update type
#################################################
# filter according to release update type
#################################################
- if ($release_update == $update_type)
+ if ($release_update == $update_type || (($update_type == UpdateType::ADD || $update_type == UpdateType::REMOVE) && $release_update == UpdateType::MAJOR))
{
# if duplicates: take higher, delete lower
if (!isset($lib_version[$lib['name']]) || semver_compare($lib_version[$lib['name']], $lib['version']) < 0)
From e9a4c25cb21fed366cfe40354631a6374a38a538 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 17 Jan 2013 17:59:39 +0100
Subject: [PATCH 051/241] release modification: require min. version
If the version number of an unpublished release is changed,
ensure it is not below the latest published release as this
would cause inconsistencies.
---
stdlib/releases/modify.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index ef0a00d..44389c1 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -35,6 +35,9 @@
throw new HttpException(400, NULL, "Incorrect release version!");
if (!StdlibRelease::exists($data["release"], StdlibRelease::PUBLISHED_BOTH)) # check if not already existing
throw new HttpException(409, NULL, "Release '$data[release]' already exists!");
+ $latest = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ if (semver_compare($latest, $data['release']) != -1) # check if not below latest published release
+ throw new HttpException(400, NULL, "Can't modify release version: Newer release $latest already published!");
}
# verify date
From 31f690edae6cd80912dae6a274d815893c474526 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 18 Feb 2013 23:07:28 +0100
Subject: [PATCH 052/241] pull changes from submodules
---
modules/HttpException | 2 +-
modules/semver | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/HttpException b/modules/HttpException
index 15ea60a..9c87a5b 160000
--- a/modules/HttpException
+++ b/modules/HttpException
@@ -1 +1 @@
-Subproject commit 15ea60a273f80aa8b101de92671dbbeadacdf9b2
+Subproject commit 9c87a5b5c761ee116ea5e8ca2c637e26c364b0c4
diff --git a/modules/semver b/modules/semver
index c9aa299..fd56d92 160000
--- a/modules/semver
+++ b/modules/semver
@@ -1 +1 @@
-Subproject commit c9aa29950d39f652320f4dfc2013074fd15df1ca
+Subproject commit fd56d9265cf87e091e8acc25051cd6edd958d685
From ecdc94e8c904a00270d51dfe82a3d86d0cf1cb88 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 18 Feb 2013 23:09:35 +0100
Subject: [PATCH 053/241] PHP 5.2 compatibility: remove usages of __DIR__
---
UpdateType.php | 4 ++--
stdlib/Stdlib.php | 4 ++--
stdlib/StdlibPending.php | 4 ++--
stdlib/releases/get_update.php | 6 +++---
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index a7fb1ba..814bd61 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -1,6 +1,6 @@
Date: Mon, 18 Feb 2013 23:14:48 +0100
Subject: [PATCH 054/241] fix paths for HttpException and semver
---
UpdateType.php | 2 +-
stdlib/Stdlib.php | 2 +-
stdlib/StdlibPending.php | 2 +-
stdlib/releases/StdlibRelease.php | 4 ++--
stdlib/releases/create.php | 4 ++--
stdlib/releases/delete.php | 2 +-
stdlib/releases/describe.php | 4 ++--
stdlib/releases/get_update.php | 4 ++--
stdlib/releases/list.php | 2 +-
stdlib/releases/modify.php | 4 ++--
stdlib/releases/publish.php | 2 +-
stdlib/releases/update.php | 4 ++--
12 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index 814bd61..25dc75b 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -1,6 +1,6 @@
Date: Mon, 18 Feb 2013 23:25:20 +0100
Subject: [PATCH 055/241] use Assert class constants
---
stdlib/releases/create.php | 2 +-
stdlib/releases/delete.php | 2 +-
stdlib/releases/describe.php | 2 +-
stdlib/releases/list.php | 2 +-
stdlib/releases/modify.php | 2 +-
stdlib/releases/publish.php | 2 +-
stdlib/releases/update.php | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 73f0fe4..dde3012 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -13,7 +13,7 @@
try
{
- Assert::RequestMethod("POST");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
Assert::GetParameters("type");
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
index 3c963ff..c16ce77 100644
--- a/stdlib/releases/delete.php
+++ b/stdlib/releases/delete.php
@@ -7,7 +7,7 @@
try
{
- Assert::RequestMethod("DELETE");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_DELETE);
Assert::GetParameters("version");
user_basic_auth("Restricted API");
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 771f84a..7ccd3c6 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -10,7 +10,7 @@
try
{
- Assert::RequestMethod("GET");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
Assert::GetParameters("version");
# validate accept header of request
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 74ca83e..71f9e28 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -7,7 +7,7 @@
try
{
- Assert::RequestMethod("GET");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
# validate accept header of request
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index b082ea6..1d846c4 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -8,7 +8,7 @@
try
{
- Assert::RequestMethod("POST");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
Assert::GetParameters("version");
user_basic_auth("You must be part of the stdlib team!");
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index c5dce25..ae343e9 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -7,7 +7,7 @@
try
{
- Assert::RequestMethod("POST");
+ Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
Assert::GetParameters("version");
user_basic_auth("You must be part of the stdlib team!");
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 586f0eb..757c248 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -13,7 +13,7 @@
try
{
- Assert::RequestMethod('POST');
+ Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
Assert::GetParameters('version');
# todo: user validation
From 5bfb900aa5c36c63be7400362eed068e7e7b6408 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 18 Feb 2013 23:31:29 +0100
Subject: [PATCH 056/241] shorten code with sql2array()
---
stdlib/Stdlib.php | 13 +++----------
stdlib/StdlibPending.php | 9 ++-------
stdlib/releases/StdlibRelease.php | 7 +------
stdlib/releases/describe.php | 5 ++---
4 files changed, 8 insertions(+), 26 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 72bdd6b..b95375d 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -1,5 +1,6 @@
\ No newline at end of file
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index df2fa3b..2c404dd 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -7,19 +7,14 @@ class StdlibPending
public static function GetEntries()
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT HEX(`lib`) FROM ' . DB_TABLE_STDLIB_PENDING;
+ $db_query = 'SELECT HEX(`lib`) AS lib FROM ' . DB_TABLE_STDLIB_PENDING;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
throw new HttpException(500);
}
- $libs = array();
- while ($lib = mysql_fetch_assoc($db_result))
- {
- $libs[] = $lib['HEX(`lib`)'];
- }
- return $libs;
+ return sql2array($db_result, create_function('$lib', 'return $lib[\'lib\'];'));
}
public static function AddEntry($id)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 567d17d..3b4f662 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -131,12 +131,7 @@ public static function ListReleases($published)
}
# fetch releases in array
- $releases = array();
- while ($release = mysql_fetch_assoc($db_result))
- {
- $releases[] = $release["release"];
- }
- return $releases;
+ return sql2array($db_result, create_function('$release', 'return $release[\'release\'];'));
}
const PUBLISHED_YES = 1;
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 7ccd3c6..b27cff3 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -1,6 +1,7 @@
Date: Mon, 18 Feb 2013 23:34:18 +0100
Subject: [PATCH 057/241] fix SQL with binary
---
stdlib/releases/describe.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index b27cff3..83c3683 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -34,7 +34,7 @@
$release["update"] = UpdateType::getName($release["update"]);
# get libs in the release
- $db_query = "SELECT lib FROM " . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
+ $db_query = "SELECT HEX(`lib`) AS lib FROM " . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
From 3772afcc0e906dc05bc6f2e05f579f2f809bbd43 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Tue, 19 Feb 2013 15:50:06 +0100
Subject: [PATCH 058/241] fix UpdateType class for array index 0
---
UpdateType.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/UpdateType.php b/UpdateType.php
index 25dc75b..ec88ac5 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -34,7 +34,7 @@ public static function getCode($str, $usage)
throw new HttpException(400);
}
- if (!isset(self::$usage[$usage]) || !array_search($code, self::$usage[$usage]))
+ if (!isset(self::$usage[$usage]) || array_search($code, self::$usage[$usage]) === FALSE)
{
throw new HttpException(400);
}
From 07eaf5e99de4ea32371dd337c2aa0e25ccb66229 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Tue, 19 Feb 2013 15:55:51 +0100
Subject: [PATCH 059/241] PHP 5.2: no anonymous functions
---
stdlib/releases/StdlibRelease.php | 4 ++--
stdlib/releases/create.php | 4 ++--
stdlib/releases/update.php | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 3b4f662..92f3520 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -93,9 +93,9 @@ public static function update($release, $data)
$db_query = "UPDATE " . DB_TABLE_STDLIB_RELEASES . " Set "
. implode(", ",
array_map(
- function($col, $val) { return "`$col` = '" . mysql_real_escape_string($val) . "'"; },
+ create_function('$col, $val', 'return "`$col` = \'$val\'";'),
array_keys($data),
- array_values($data)
+ array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))
)
)
. " WHERE `release` = '$release' AND " . self::get_publish_cond(self::PUBLISHED_NO);
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index dde3012..d4d161d 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -102,9 +102,9 @@
$db_connection = db_ensure_connection();
$db_query = "INSERT INTO " . DB_TABLE_STDLIB_RELEASES
. " ("
- . implode(", ", array_map(function($item) { return "`$item`"; }, array_keys($data)))
+ . implode(", ", array_map(create_function('$item', 'return "`$item`";'), array_keys($data)))
. ") VALUES ("
- . implode(", ", array_map(function($item) { return "'" . mysql_real_escape_string($item, $db_connection) . "'"; }, array_values($data)))
+ . implode(", ", array_map(create_function('$item', 'return "\'$item\'";'), array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))))
. ")";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 757c248..1fbd756 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -39,7 +39,7 @@
# get all pending changes (stdlib_pending)
# * several versions of a lib / framework might occur in them
- $libs = array_map(function($id) { return array('id' => $id); }, StdlibPending::GetEntries($release));
+ $libs = array_map(create_function('$id', 'return array(\'id\' => $id);'), StdlibPending::GetEntries($release));
$lib_version = array();
foreach ($libs AS $i => &$lib)
From f16ae2aee8b3d8dae8a5b09cc065fa814a672195 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 00:04:26 +0100
Subject: [PATCH 060/241] First work on sorting support for item listing
---
items/list.php | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/items/list.php b/items/list.php
index b9e6506..f914b5b 100644
--- a/items/list.php
+++ b/items/list.php
@@ -23,6 +23,7 @@
$db_having = '';
$db_join = '';
$db_limit = "";
+ $db_order = '';
if (isset($_GET["type"]))
{
@@ -91,8 +92,27 @@
}
}
+ # retrieve sorting parameters
+ $sort_by_rating = false;
+ if (isset($_GET['sort'])) {
+ $sort_keys = explode(' ', $_GET['sort']);
+ $sort_dirs = array_map(function($item) { return substr($item, 0, 1) != '!'; }, $sort_keys);
+ $sort_keys = array_map(function($item) { return substr($item, 0, 1) == '!' ? substr($item, 1, strlen($item) - 1 ) : $item; }, $sort_keys);
+ $sorting = array_combine($sort_keys, $sort_dirs);
+
+ # can sort by:
+ $allowed_sorting = array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => 'SUM(`rating`)');
+ foreach ($sorting AS $key => $dir) {
+ if (array_key_exists($key, $allowed_sorting)) {
+ $db_order .= ($db_order) ? ', ' : 'ORDER BY ';
+ $db_order .= $allowed_sorting[$key] . ' ' . ($dir ? 'ASC' : 'DESC');
+ $sort_by_rating = $sort_by_rating || $key == 'rating';
+ }
+ }
+ }
+
# enable rating filters if necessary
- if ($get_rating = isset($_GET['rating']) || isset($_GET['rating-min']) || isset($_GET['rating-max'])) {
+ if ($get_rating = isset($_GET['rating']) || isset($_GET['rating-min']) || isset($_GET['rating-max']) || $sort_by_rating) {
$db_join = 'LEFT JOIN ' . DB_TABLE_RATINGS . ' ON item = id';
# this complicated query ensures items without any ratings are considered to be rated 0
@@ -129,7 +149,7 @@
# query data
$db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, type, HEX(" . DB_TABLE_ITEMS . ".id) AS id, version, HEX(" . DB_TABLE_ITEMS . ".user) AS userID, " . DB_TABLE_USERS . ".name AS userName"
. " FROM " . DB_TABLE_ITEMS . ' ' . $db_join . ', ' . DB_TABLE_USERS
- . " WHERE " . DB_TABLE_ITEMS . ".user = " . DB_TABLE_USERS . ".id $db_cond $db_having $db_limit";
+ . " WHERE " . DB_TABLE_ITEMS . ".user = " . DB_TABLE_USERS . ".id $db_cond $db_having $db_order $db_limit";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
From 224bf81a6a67b9a48f0ea9b8ad2b448da4f83660 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 17:35:39 +0100
Subject: [PATCH 061/241] shorten code for listing authentication
---
stdlib/releases/list.php | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 71f9e28..5deb5ea 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -16,21 +16,13 @@
if (!empty($_GET["published"]))
{
$published = strtolower($_GET["published"]);
- if (in_array($published, array(-1, "no", "false"), true))
- {
- # check auth
- user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
- throw new HttpException(403);
- $publish_status = StdlibRelease::PUBLISHED_NO;
- }
- else if (in_array($published, array(0, "both"), true))
- {
- # check auth
- user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!");
+ $both = false;
+
+ if (in_array($published, array(-1, "no", "false"), true) || ($both = in_array($published, array(0, "both"), true))) {
+ user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!"); # check auth
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
throw new HttpException(403);
- $publish_status = StdlibRelease::PUBLISHED_BOTH;
+ $publish_status = $both ? StdlibRelease::PUBLISHED_BOTH : StdlibRelease::PUBLISHED_NO;
}
# else if (in_array($published, array(1, "+1", "true", "yes"))) # the default
}
From 72dcd55f27d2d5215e5f88cd9b3ec1bac129f623 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 17:41:03 +0100
Subject: [PATCH 062/241] remove unnecessary constant definitions
---
stdlib/releases/create.php | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index d4d161d..1064468 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -7,10 +7,6 @@
require_once("../../User.php");
require_once("StdlibRelease.php");
- define('UPDATE_TYPE_PATCH', UpdateType::getCode("patch", "stdlib_releases"));
- define('UPDATE_TYPE_MINOR', UpdateType::getCode("minor", "stdlib_releases"));
- define('UPDATE_TYPE_MAJOR', UpdateType::getCode("major", "stdlib_releases"));
-
try
{
Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
@@ -45,18 +41,18 @@
$release = array();
semver_parts($prev_release, $release);
- if ($type == UPDATE_TYPE_PATCH || $type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
+ if ($type == UpdateType::PATCH || $type == UpdateType::MINOR || $type == UpdateType::MAJOR)
{
unset($release["prerelease"]);
unset($release["build"]);
$release["patch"]++;
- if ($type == UPDATE_TYPE_MINOR || $type == UPDATE_TYPE_MAJOR)
+ if ($type == UpdateType::TYPE_MINOR || $type == UpdateType::MAJOR)
{
$release["patch"] = 0;
$release["minor"]++;
- if ($type == UPDATE_TYPE_MAJOR)
+ if ($type == UpdateType::MAJOR)
{
$release["minor"] = 0;
$release["major"]++;
From 9e5e1481fe0e987459b46bb467435169644308b4 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 17:50:15 +0100
Subject: [PATCH 063/241] add small comment
---
stdlib/releases/create.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 1064468..581b360 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -11,6 +11,7 @@
{
Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
Assert::GetParameters("type");
+
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
$type = UpdateType::getCode($_GET["type"], "stdlib_releases");
@@ -61,7 +62,8 @@
}
$release = semver_string($release);
- # check if (unpublished) release already exists
+ # check if (unpublished) release already exists (unpublished because the latest published is always >= the base for $release)
+ # only check for PUBLISHED_YES as otherwise, $release must be based on the latest release anyway
if ($publish_status == StdlibRelease::PUBLISHED_YES && StdlibRelease::exists($release, StdlibRelease::PUBLISHED_BOTH))
{
throw new HttpException(409, NULL, "Release '$release' has already been created!");
From a28e8471748b474496ef97a7ea9b75df0b4d6788 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 17:57:40 +0100
Subject: [PATCH 064/241] work on release creation version checks
Compare a given version with the previous (release base) version number.
Only calculate version number if none was given.
---
stdlib/releases/create.php | 71 ++++++++++++++++++++------------------
1 file changed, 37 insertions(+), 34 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 581b360..9aaaf82 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -38,47 +38,16 @@
# get latest release
$prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $publish_status);
- # bump version number according to $type
- $release = array();
- semver_parts($prev_release, $release);
-
- if ($type == UpdateType::PATCH || $type == UpdateType::MINOR || $type == UpdateType::MAJOR)
- {
- unset($release["prerelease"]);
- unset($release["build"]);
- $release["patch"]++;
-
- if ($type == UpdateType::TYPE_MINOR || $type == UpdateType::MAJOR)
- {
- $release["patch"] = 0;
- $release["minor"]++;
-
- if ($type == UpdateType::MAJOR)
- {
- $release["minor"] = 0;
- $release["major"]++;
- }
- }
- }
- $release = semver_string($release);
-
- # check if (unpublished) release already exists (unpublished because the latest published is always >= the base for $release)
- # only check for PUBLISHED_YES as otherwise, $release must be based on the latest release anyway
- if ($publish_status == StdlibRelease::PUBLISHED_YES && StdlibRelease::exists($release, StdlibRelease::PUBLISHED_BOTH))
- {
- throw new HttpException(409, NULL, "Release '$release' has already been created!");
- }
-
- $data = array("release" => $release, "update" => $type);
+ $data = array("update" => $type);
if (isset($_POST["version"]))
{
try {
- $result = semver_compare($_POST["version"], $release);
+ $result = semver_compare($_POST["version"], $prev_release); # compare against previous release
} catch (Exception $e) {
throw new HttpException(400, NULL, "Bad release version!"); # semver could not validate
}
if ($result != 1)
- throw new HttpException(400, NULL, "Bad release version!"); # version is smaller then minimum
+ throw new HttpException(400, NULL, "Bad release version!"); # version <= previous release
# check if release already exists
if (StdlibRelease::exists($_POST["version"], StdlibRelease::PUBLISHED_BOTH))
@@ -87,7 +56,41 @@
}
$data["release"] = $_POST["version"];
+ } else {
+ # bump version number according to $type
+ $release = array();
+ semver_parts($prev_release, $release);
+
+ if ($type == UpdateType::PATCH || $type == UpdateType::MINOR || $type == UpdateType::MAJOR)
+ {
+ unset($release["prerelease"]);
+ unset($release["build"]);
+ $release["patch"]++;
+
+ if ($type == UpdateType::TYPE_MINOR || $type == UpdateType::MAJOR)
+ {
+ $release["patch"] = 0;
+ $release["minor"]++;
+
+ if ($type == UpdateType::MAJOR)
+ {
+ $release["minor"] = 0;
+ $release["major"]++;
+ }
+ }
+ }
+ $release = semver_string($release);
+
+ # check if (unpublished) release already exists (unpublished because the latest published is always >= the base for $release)
+ # only check for PUBLISHED_YES as otherwise, $release must be based on the latest release anyway.
+ if ($publish_status == StdlibRelease::PUBLISHED_YES && StdlibRelease::exists($release, StdlibRelease::PUBLISHED_BOTH))
+ {
+ throw new HttpException(409, NULL, "Release '$release' has already been created!");
+ }
+
+ $data["release"] = $release;
}
+
if (isset($_POST["date"]))
{
$data["date"] = $_POST["description"];
From 19214bdf37d500facfb9f660d04dec21471fa58c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 17:58:09 +0100
Subject: [PATCH 065/241] fix old copy-paste error
---
stdlib/releases/create.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 9aaaf82..290940d 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -93,7 +93,7 @@
if (isset($_POST["date"]))
{
- $data["date"] = $_POST["description"];
+ $data["date"] = $_POST["date"];
}
if (isset($_POST["description"]))
{
From 15c25283a6a706c032f981230726f5451dff3069 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 18:00:01 +0100
Subject: [PATCH 066/241] fix typo from 72dcd55f2
---
stdlib/releases/create.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 290940d..4aacb61 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -67,7 +67,7 @@
unset($release["build"]);
$release["patch"]++;
- if ($type == UpdateType::TYPE_MINOR || $type == UpdateType::MAJOR)
+ if ($type == UpdateType::MINOR || $type == UpdateType::MAJOR)
{
$release["patch"] = 0;
$release["minor"]++;
From dcdd6a0634cd9af1445c2bd357e807cb79d2a9f3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 18:12:32 +0100
Subject: [PATCH 067/241] change release table: allow date to be NULL
Fix MySQL conditions accordingly.
---
MySQL/DB_TABLE_STDLIB_RELEASES.sql | 2 +-
stdlib/releases/StdlibRelease.php | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/MySQL/DB_TABLE_STDLIB_RELEASES.sql b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
index 728d849..a8a0890 100644
--- a/MySQL/DB_TABLE_STDLIB_RELEASES.sql
+++ b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
@@ -10,7 +10,7 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_releases` (
`release` tinytext NOT NULL,
`update` int(11) NOT NULL,
- `date` timestamp NOT NULL,
+ `date` timestamp NULL DEFAULT NULL,
`description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 92f3520..fcf408f 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -143,9 +143,9 @@ static function get_publish_cond($published)
switch ($published)
{
case self::PUBLISHED_YES:
- return '(`date` AND NOW() > `date`)';
+ return '(`date` IS NOT NULL AND `date` AND NOW() >= `date`)';
case self::PUBLISHED_NO:
- return '(!`date` OR NOW() < `date`)';
+ return '(`date` IS NULL OR !`date` OR NOW() < `date`)';
case self::PUBLISHED_BOTH:
return NULL;
default:
From 77af0d79e34309b8e952f2eef6ce44c5dc0963fb Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 18:26:04 +0100
Subject: [PATCH 068/241] move release creation to a new
StdlibRelease::create() method
---
stdlib/releases/StdlibRelease.php | 15 +++++++++++++
stdlib/releases/create.php | 36 ++++++-------------------------
2 files changed, 21 insertions(+), 30 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index fcf408f..e6392b3 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -68,6 +68,21 @@ public static function describe($release, $published)
return mysql_fetch_assoc($db_result);
}
+ public static function create($update, $release, $date = NULL, $description = '') {
+ $db_connection = db_ensure_connection();
+
+ $update = mysql_real_escape_string($update, $db_connection);
+ $release = mysql_real_escape_string($release, $db_connection);
+ $description = mysql_real_escape_string($description, $db_connection);
+ $date = $date !== NULL ? '"' . mysql_real_escape_string($date, $db_connection) . '"' : 'NULL';
+
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_RELEASES . ' (`update`, `release`, `description`, `date`) VALUES ("' . $update . '", "' . $release . '", "' . $description . '", ' . $date . ')';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE || mysql_affected_rows() != 1) {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+ }
+
public static function delete($release)
{
$db_connection = db_ensure_connection();
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 4aacb61..b7aa684 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -38,7 +38,6 @@
# get latest release
$prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $publish_status);
- $data = array("update" => $type);
if (isset($_POST["version"]))
{
try {
@@ -55,7 +54,7 @@
throw new HttpException(409, NULL, "Release '$_POST[version]' has already been created!");
}
- $data["release"] = $_POST["version"];
+ $release = $_POST["version"];
} else {
# bump version number according to $type
$release = array();
@@ -87,43 +86,20 @@
{
throw new HttpException(409, NULL, "Release '$release' has already been created!");
}
-
- $data["release"] = $release;
}
- if (isset($_POST["date"]))
- {
- $data["date"] = $_POST["date"];
- }
- if (isset($_POST["description"]))
- {
- $data["description"] = $_POST["description"];
- }
+ $date = isset($_POST['date']) ? $_POST['date'] : NULL;
+ $description = isset($_POST['description']) ? $_POST['description'] : '';
- $db_connection = db_ensure_connection();
- $db_query = "INSERT INTO " . DB_TABLE_STDLIB_RELEASES
- . " ("
- . implode(", ", array_map(create_function('$item', 'return "`$item`";'), array_keys($data)))
- . ") VALUES ("
- . implode(", ", array_map(create_function('$item', 'return "\'$item\'";'), array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))))
- . ")";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500, NULL, mysql_error());
- }
- if (mysql_affected_rows() != 1)
- {
- throw new HttpException(500);
- }
+ StdlibRelease::create($type, $release, $date, $description);
if ($content_type == "application/json")
{
- $content = json_encode(array("release" => $data["release"]));
+ $content = json_encode(array("release" => $release));
}
else if ($content_type == "text/xml" || $content_type == "application/xml")
{
- $content = "$data[release]";
+ $content = "$release";
}
header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
header("Content-type: $content_type");
From 4519bcb40ada71431240355754de49e86fcdc7e3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 18:36:17 +0100
Subject: [PATCH 069/241] entirely delete obsolete item modification code
---
items/modify.php | 25 -------------------------
1 file changed, 25 deletions(-)
diff --git a/items/modify.php b/items/modify.php
index 2b5878c..e30f2c0 100644
--- a/items/modify.php
+++ b/items/modify.php
@@ -68,31 +68,6 @@
throw new HttpException(404);
}
}
- if (isset($_POST["default"]))
- {
- throw new HttpException(423); # block
-
- /*
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
- {
- throw new HttpException(403);
- }
- if (!in_array((int)$_POST["default"], array(0, 1)))
- {
- throw new HttpException(400);
- }
-
- $db_query = "UPDATE " . DB_TABLE_ITEMS . " Set default_include = '" . mysql_real_escape_string($_POST["default"]) . "' WHERE id = UNHEX('$id')";
- if (!mysql_query($db_query, $db_connection))
- {
- throw new HttpException(500);
- }
- if (mysql_affected_rows() != 1)
- {
- throw new HttpException(404);
- }
- */
- }
header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
}
catch (HttpException $e)
From 621f6993c5451009144d62a86376891681965508 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 20:14:02 +0100
Subject: [PATCH 070/241] item description: item list
Use the Stdlib class instead of direct DB access.
Also change the generated output.
---
stdlib/releases/describe.php | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 83c3683..7eb9e81 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -7,6 +7,7 @@
require_once("../../Assert.php");
require_once("../../User.php");
require_once("StdlibRelease.php");
+ require_once("../Stdlib.php");
require_once("../../UpdateType.php");
try
@@ -17,9 +18,6 @@
# validate accept header of request
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
- # connect to database server
- $db_connection = db_ensure_connection();
-
$publish_status = StdlibRelease::PUBLISHED_YES;
if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"]))
{
@@ -33,15 +31,17 @@
# handle update type
$release["update"] = UpdateType::getName($release["update"]);
- # get libs in the release
- $db_query = "SELECT HEX(`lib`) AS lib FROM " . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- throw new HttpException(500);
- }
+ # get libs in release
+ if ($release['date']) { # published
+ $libs = Stdlib::GetItems($release['release']);
+ $release['libs'] = array();
- $release["libs"] = sql2array($db_result);
+ foreach ($libs AS $lib) {
+ $release['libs'][$lib['id']] = $lib['comment'];
+ }
+ } else { # unpublished
+ # ... todo
+ }
# todo later: get frameworks in the release
From 9ab3ceb7c958292364c5219da605f6e1fb929c19 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 20:19:31 +0100
Subject: [PATCH 071/241] update STDLIB_PENDING table
* use int for `update` instead of enum (UpdateType class constants)
* add a `comment` attribute
* make `lib` the PRIMARY KEY
---
MySQL/DB_TABLE_STDLIB_PENDING.sql | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/MySQL/DB_TABLE_STDLIB_PENDING.sql b/MySQL/DB_TABLE_STDLIB_PENDING.sql
index 2a03c48..b0c0f9d 100644
--- a/MySQL/DB_TABLE_STDLIB_PENDING.sql
+++ b/MySQL/DB_TABLE_STDLIB_PENDING.sql
@@ -9,7 +9,9 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_pending` (
`lib` binary(16) NOT NULL,
- `update` enum('new','patch','minor','major') NOT NULL
+ `update` int(11) NOT NULL,
+ `comment` text NOT NULL,
+ PRIMARY KEY (`lib`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
From 5946b55bc3ba54d5d8d8f4ba973c46f5ce2b65e3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 20:22:55 +0100
Subject: [PATCH 072/241] rename StdlibPending method
---
stdlib/StdlibPending.php | 2 +-
stdlib/releases/update.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 2c404dd..1e16637 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -4,7 +4,7 @@
class StdlibPending
{
- public static function GetEntries()
+ public static function GetAllEntries()
{
$db_connection = db_ensure_connection();
$db_query = 'SELECT HEX(`lib`) AS lib FROM ' . DB_TABLE_STDLIB_PENDING;
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 1fbd756..18b9bda 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -39,7 +39,7 @@
# get all pending changes (stdlib_pending)
# * several versions of a lib / framework might occur in them
- $libs = array_map(create_function('$id', 'return array(\'id\' => $id);'), StdlibPending::GetEntries($release));
+ $libs = array_map(create_function('$id', 'return array(\'id\' => $id);'), StdlibPending::GetAllEntries($release));
$lib_version = array();
foreach ($libs AS $i => &$lib)
From 697e50866072b8c2aa677379a1808f06b5551903 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 20:59:59 +0100
Subject: [PATCH 073/241] move get_update function into UpdateType class
---
UpdateType.php | 47 ++++++++++++++++++++++++
stdlib/releases/get_update.php | 66 ----------------------------------
stdlib/releases/update.php | 6 ++--
3 files changed, 50 insertions(+), 69 deletions(-)
delete mode 100644 stdlib/releases/get_update.php
diff --git a/UpdateType.php b/UpdateType.php
index ec88ac5..e69b689 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -1,6 +1,7 @@
-1) { # ensure correct version order
+ throw new HttpException(500);
+ }
+
+ foreach (array('major' => self::MAJOR, 'minor' => self::MINOR, 'patch' => self::PATCH) AS $part => $type) {
+ if ((int)$new_parts[$part] > (int)$old_parts[$part])
+ return $type;
+ }
+
+ foreach (array('prerelease' => self::PRERELEASE_INCREASE, 'build' => self::BUILD_INCREASE) AS $part => $type) {
+ if (!empty($new_parts[$part]) && !empty($old_parts[$part])) { # optional parts
+ $new_fragments = explode('.', $new_parts[$part]);
+ $old_fragments = explode('.', $old_parts[$part]);
+
+ for ($index = 0; $index < min(count($new_fragments), count($old_fragments)); $index++) { # use the smaller amount of parts
+ $new_frag = $new_fragments[$index]; $old_frag = $old_fragments[$index];
+ if (ctype_digit($new_frag) && ctype_digit($old_frag)) {
+ if ((int)$new_frag != (int)$old_frag)
+ return $type;
+ continue;
+ }
+ # at least one is non-numeric: compare by characters (chars > numeric is still ensured)
+ else if ($new_frag < $old_frag || $new_frag > $old_frag)
+ return $type;
+ }
+
+ if (count($new_fragments) != count($old_fragments))
+ return $type;
+ }
+ else if ($type == self::PRERELEASE_INCREASE && empty($new_parts[$part]) && !empty($old_parts[$part])) # no prerelease > any prerelease
+ return $type;
+ else if ($type == self::BUILD_INCREASE && !empty($new_parts[$part]) && empty($old_parts[$part])) # any build > no build
+ return $type;
+ }
+
+ throw new HttpException(500);
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/releases/get_update.php b/stdlib/releases/get_update.php
deleted file mode 100644
index f1e416d..0000000
--- a/stdlib/releases/get_update.php
+++ /dev/null
@@ -1,66 +0,0 @@
- -1)
- {
- throw new HttpException(500);
- }
-
- foreach (array('major' => UpdateType::MAJOR, 'minor' => UpdateType::MINOR, 'patch' => UpdateType::PATCH) AS $part => $type)
- {
- $new_value = (int)$new_parts[$part];
- $old_value = (int)$old_parts[$part];
-
- if ($new_value > $old_value)
- return $type;
- }
-
- foreach (array('prerelease' => UpdateType::PRERELEASE_INCREASE, 'build' => UpdateType::BUILD_INCREASE) AS $part => $type)
- {
- if (!empty($new_parts[$part]) && !empty($old_parts[$part])) # optional parts
- {
- $new_fragments = explode('.', $new_parts[$part]);
- $old_fragments = explode('.', $old_parts[$part]);
-
- for ($index = 0; $index < min(count($new_fragments), count($old_fragments)); $index++) # use the smaller amount of parts
- {
- $new_frag = $new_fragments[$index]; $old_frag = $old_fragments[$index];
- if (ctype_digit($new_frag) && ctype_digit($old_frag))
- {
- $new_frag = (int)$new_frag; $old_frag = (int)$old_frag; # convert to numbers
- if ($new_frag != $old_frag)
- return $type;
- continue;
- }
- # at least one is non-numeric: compare by characters
- else if ($new_frag < $old_frag || $new_frag > $old_frag)
- return $type;
- }
-
- if (count($new_fragments) != count($old_fragments))
- return $type;
- }
- else if (!empty($new_parts[$part]))
- return $type;
- }
-
- throw new HttpException(500);
-}
-
-?>
\ No newline at end of file
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 18b9bda..4132ac9 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -9,7 +9,7 @@
require_once('StdlibRelease.php');
require_once('../../User.php');
require_once('../../util.php');
- require_once('get_update.php');
+ require_once('../../UpdateType.php');
try
{
@@ -29,7 +29,7 @@
$latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
# get release update type
- $release_update = get_update($latest_release, $release);
+ $release_update = UpdateType::getUpdate($latest_release, $release);
$old_items = Stdlib::GetItems($latest_release);
foreach ($old_items AS &$item)
@@ -64,7 +64,7 @@
}
else # actually an upgrade
{
- $update_type = get_update($old['version'], $lib['version']); # update type
+ $update_type = UpdateType::getUpdate($old['version'], $lib['version']); # update type
}
}
else # not in latest release - must be new
From 3122e7a4b0bca0617ae418bb701d0177dd989db2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 21:05:15 +0100
Subject: [PATCH 074/241] fix relative require_once() calls in
StdlibRelease.php
---
stdlib/releases/StdlibRelease.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index e6392b3..34e7da8 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -1,7 +1,7 @@
Date: Sat, 23 Feb 2013 21:52:48 +0100
Subject: [PATCH 075/241] move logic for finding pending entries for a release
Move the code from update.php to the StdlibPending class. Fix,
refine and shorten it.
---
stdlib/StdlibPending.php | 65 +++++++++++++++++++++++++++++++
stdlib/releases/update.php | 79 +-------------------------------------
2 files changed, 66 insertions(+), 78 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 1e16637..c4f5633 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -1,6 +1,11 @@
$id);'), self::GetAllEntries()); # get all pending changes
+ $lib_version = array();
+
+ foreach ($libs AS $i => &$lib) {
+ $lib = array_merge($lib, Item::get($lib['id'], array('name', 'version'))); # get info on lib, especially name & version
+
+ # assign the corresponding update types, comparing to the $old_items array
+ #################################################
+ $old = searchSubArray($old_items, array('name' => $lib['name'])); # what version of this item is in the old release?
+ if ($old !== NULL) {
+ if (semver_compare($old_items[$old]['version'], $lib['version']) == 0) { # same version means removal
+ $update_type = UpdateType::REMOVE;
+ } else if (semver_compare($old_items[$old]['version'], $lib['version']) == 1) { # if any of them means a downgrade (old > new), delete the entry
+ self::DeleteEntry($lib['id']);
+ unset($libs[$i]);
+ } else { # actually an update
+ $update_type = UpdateType::getUpdate($old_items[$old]['version'], $lib['version']); # retrieve update type
+ }
+ } else { # not in latest release - must be new
+ $update_type = UpdateType::ADD;
+ }
+ $lib['update'] = $update_type;
+ #################################################
+
+ # filter according to release update type
+ #################################################
+ $include = false;
+ switch ($release_update) {
+ case UpdateType::MAJOR: $include = true; # everything can go in a major release
+ break;
+ case UpdateType::MINOR: $include = $update_type == UpdateType::MINOR || $update_type == UpdateType::PATCH;
+ break;
+ case UpdateType::PATCH: $include = $update_type == UpdateType::PATCH;
+ break;
+ }
+
+ if ($include) {
+ if (!isset($lib_version[$lib['name']]) || semver_compare($lib_version[$lib['name']], $lib['version']) < 0) { # if not duplicate, always take it || if duplicate: higher overwrites lower
+ $lib_version[$lib['name']] = $lib['version'];
+ }
+ } else { # item update type does not fit stdlib release update
+ unset($libs[$i]);
+ }
+ #################################################
+ }
+ return $libs;
+ }
+
public static function AddEntry($id)
{
}
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
index 4132ac9..eac34be 100644
--- a/stdlib/releases/update.php
+++ b/stdlib/releases/update.php
@@ -1,15 +1,8 @@
$id);'), StdlibPending::GetAllEntries($release));
-
- $lib_version = array();
- foreach ($libs AS $i => &$lib)
- {
- $lib = array_merge($lib, Item::get($lib['id'], array('name', 'version'))); # get info on lib, especially name & version
-
- # assign the corresponding update types, comparing to the $old_items array
- #################################################
- $old = searchSubArray($old_items, array('name' => $lib['name']));
-
- if ($old && semver_compare($old['version'], $lib['version']) != 0)
- {
- if (semver_compare($old['version'], $lib['version']) == 0) # same version means removal
- {
- $update_type = UpdateType::REMOVE;
- }
- else if (semver_compare($old['version'], $lib['version']) == 1) # if any of them means a downgrade (old > new), delete the entry
- {
- StdlibPending::DeleteEntry($lib['id']);
- unset($libs[$i]);
- break;
- }
- else # actually an upgrade
- {
- $update_type = UpdateType::getUpdate($old['version'], $lib['version']); # update type
- }
- }
- else # not in latest release - must be new
- {
- $update_type = UpdateType::ADD;
- }
- #################################################
-
- # filter according to release update type
- #################################################
- if ($release_update == $update_type || (($update_type == UpdateType::ADD || $update_type == UpdateType::REMOVE) && $release_update == UpdateType::MAJOR))
- {
- # if duplicates: take higher, delete lower
- if (!isset($lib_version[$lib['name']]) || semver_compare($lib_version[$lib['name']], $lib['version']) < 0)
- {
- $lib_version[$lib['name']] = $lib['version'];
- }
- }
- else
- {
- unset($libs[$i]);
- }
- #################################################
- }
+ $libs = StdlibPending::GetEntries($_GET['version']);
# write to 'stdlib' table (deleting old entries for that release first)
From ac0cdcabe2fd7cf39c61003b516a8a9272ce43bb Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 21:57:19 +0100
Subject: [PATCH 076/241] support release description item list for unpublished
releases
Also slightly modify output.
---
stdlib/releases/describe.php | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 7eb9e81..5e9343c 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -8,6 +8,7 @@
require_once("../../User.php");
require_once("StdlibRelease.php");
require_once("../Stdlib.php");
+ require_once("../StdlibPending.php");
require_once("../../UpdateType.php");
try
@@ -34,13 +35,13 @@
# get libs in release
if ($release['date']) { # published
$libs = Stdlib::GetItems($release['release']);
- $release['libs'] = array();
-
- foreach ($libs AS $lib) {
- $release['libs'][$lib['id']] = $lib['comment'];
- }
} else { # unpublished
- # ... todo
+ $libs = StdlibPending::GetEntries($release['release']);
+ }
+
+ $release['libs'] = array();
+ foreach ($libs AS $lib) {
+ $release['libs'][] = $lib['id'];
}
# todo later: get frameworks in the release
From 587f5bfed55b5f18f4c2945369eaedd29c0c4a15 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 22:32:39 +0100
Subject: [PATCH 077/241] Stdlib::GetItems() - support unpublished releases
Check if a release is unpublished. If so, get the latest
published release and filter them by the pending changes
for the given release. Adjust the code describing stdlib
releases.
---
stdlib/Stdlib.php | 55 ++++++++++++++++++++++++++++++------
stdlib/releases/describe.php | 12 +-------
2 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index b95375d..506e249 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -1,23 +1,60 @@
$entry['id']));
+ if ($index === NULL)
+ throw new HttpException(500);
+ unset($old_items[$index]);
+ break;
+ case UpdateType::ADD:
+ unset($entry['update']);
+ $old_items[] = $entry;
+ break;
+ default:
+ unset($entry['update']);
+ $index = searchSubArray($old_items, array('name' => $entry['name']));
+ if ($index === NULL)
+ throw new HttpException(500);
+ $old_items[$index] = $entry;
+ break;
+ }
+ }
+
+ sort($old_items); # make array continuous
+ return $old_items;
+ }
}
}
?>
\ No newline at end of file
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 5e9343c..601af0e 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -32,17 +32,7 @@
# handle update type
$release["update"] = UpdateType::getName($release["update"]);
- # get libs in release
- if ($release['date']) { # published
- $libs = Stdlib::GetItems($release['release']);
- } else { # unpublished
- $libs = StdlibPending::GetEntries($release['release']);
- }
-
- $release['libs'] = array();
- foreach ($libs AS $lib) {
- $release['libs'][] = $lib['id'];
- }
+ $release['libs'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
# todo later: get frameworks in the release
From 9eed1f8f716ddc422d8dcb06f8c546037c2d1486 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 22:37:50 +0100
Subject: [PATCH 078/241] modify StdlibPending::GetAllEntries() output
---
stdlib/StdlibPending.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index c4f5633..7fec10e 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -12,14 +12,14 @@ class StdlibPending
public static function GetAllEntries()
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT HEX(`lib`) AS lib FROM ' . DB_TABLE_STDLIB_PENDING;
+ $db_query = 'SELECT HEX(`lib`) AS id, comment FROM ' . DB_TABLE_STDLIB_PENDING;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
throw new HttpException(500);
}
- return sql2array($db_result, create_function('$lib', 'return $lib[\'lib\'];'));
+ return sql2array($db_result);
}
public static function GetEntries($release) {
@@ -34,7 +34,7 @@ public static function GetEntries($release) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
- $libs = array_map(create_function('$id', 'return array(\'id\' => $id);'), self::GetAllEntries()); # get all pending changes
+ $libs = self::GetAllEntries(); # get all pending changes
$lib_version = array();
foreach ($libs AS $i => &$lib) {
From 535652e9e751403cd332e0b26f15b4b1d127c122 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 22:38:40 +0100
Subject: [PATCH 079/241] support changelog for unpublished releases
---
stdlib/releases/describe.php | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 601af0e..ee6a96f 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -38,6 +38,16 @@
# todo: get last prerelease and last stable version
# todo: compile changelog (since latest prerelease + since latest stable)
+ if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
+ # for published releases - TODO
+
+ } else {
+ $pending = StdlibPending::GetEntries($release['release']);
+ $release['changelog'] = array();
+ foreach ($pending AS $entry) {
+ $release['changelog'][$entry['name']] = $entry['comment'];
+ }
+ }
if ($content_type == "application/json")
{
From 333e625be67f8be72a9bd6ce48711a6e67901a63 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Feb 2013 23:47:32 +0100
Subject: [PATCH 080/241] remove update type from release description
---
stdlib/releases/describe.php | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index ee6a96f..f59d013 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -28,9 +28,7 @@
}
$release = StdlibRelease::describe($_GET["version"], $publish_status);
-
- # handle update type
- $release["update"] = UpdateType::getName($release["update"]);
+ unset($release['update']);
$release['libs'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
From 547588f277d56285b9ecf0596dbca2820940e7ac Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 01:53:43 +0100
Subject: [PATCH 081/241] add a method for getting the diff between 2 releases
---
stdlib/Stdlib.php | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 506e249..e5a22a6 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -56,5 +56,37 @@ public static function GetItems($release)
return $old_items;
}
}
+
+ public static function diff($old, $new) {
+ $old_items = self::GetItems($old);
+ foreach ($old_items AS &$item) {
+ $item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
+ }
+
+ $new_items = self::GetItems($new);
+ foreach ($new_items AS &$item) {
+ $item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
+ }
+
+ $diff = array();
+
+ foreach ($new_items AS &$item) {
+ $old_index = searchSubArray($old_items, array('name' => $item['name']));
+
+ if ($old_index === NULL) {
+ $diff[] = array('id' => $item['id'], 'comment' => $item['comment'], 'name' => $item['name'], 'version' => $item['version'], 'update' => UpdateType::ADD);
+ } else if ($old_items[$old_index]['version'] != $item['version']) {
+ $diff[] = array('id' => $item['id'], 'comment' => $item['comment'], 'name' => $item['name'], 'version' => $item['version'], 'update' => UpdateType::getUpdate($old_items[$old_index]['version'], $item['version']));
+ unset($old_items[$old_index]);
+ } else {
+ unset($old_items[$old_index]);
+ }
+ }
+ foreach ($old_items AS $item) {
+ $diff[] = array('id' => $item['id'], 'comment' => 'Removing ' . $item['name'] . ' v' . $item['version'], 'name' => $item['name'], 'version' => $item['version'], 'update' => UpdateType::REMOVE);
+ }
+
+ return $diff;
+ }
}
?>
\ No newline at end of file
From b9a08d44576ac1a686d92261352229015e90e2db Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 01:54:16 +0100
Subject: [PATCH 082/241] support changelogs for published releases
---
stdlib/releases/describe.php | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index f59d013..59b4d81 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -34,15 +34,20 @@
# todo later: get frameworks in the release
- # todo: get last prerelease and last stable version
- # todo: compile changelog (since latest prerelease + since latest stable)
if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
- # for published releases - TODO
-
+ $releases = StdlibRelease::ListReleases(StdlibRelease::PUBLISHED_YES);
+ usort($releases, 'semver_sort');
+ $index = array_search($release['release'], $releases) - 1;
+ if ($index >= 0) {
+ $changeset = Stdlib::diff($releases[$index], $release['release']);
+ }
} else {
- $pending = StdlibPending::GetEntries($release['release']);
- $release['changelog'] = array();
- foreach ($pending AS $entry) {
+ $changeset = StdlibPending::GetEntries($release['release']);
+ }
+
+ $release['changelog'] = array();
+ if (isset($changeset)) {
+ foreach ($changeset AS $entry) {
$release['changelog'][$entry['name']] = $entry['comment'];
}
}
@@ -69,4 +74,8 @@
{
handleHttpException(new HttpException(500, NULL, $e->getMessage()));
}
+
+ function semver_sort($a, $b) {
+ return semver_compare($a, $b);
+ }
?>
\ No newline at end of file
From 70117582079028d74bf19d8db4807f7f1a08d949 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 13:56:43 +0100
Subject: [PATCH 083/241] remove unused `update` DB columns
Instead of saving and relying on them,
they are always calculated when needed.
---
MySQL/DB_TABLE_STDLIB_PENDING.sql | 1 -
MySQL/DB_TABLE_STDLIB_RELEASES.sql | 1 -
stdlib/releases/StdlibRelease.php | 5 ++---
stdlib/releases/create.php | 5 +++--
stdlib/releases/describe.php | 2 --
5 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/MySQL/DB_TABLE_STDLIB_PENDING.sql b/MySQL/DB_TABLE_STDLIB_PENDING.sql
index b0c0f9d..746dfe0 100644
--- a/MySQL/DB_TABLE_STDLIB_PENDING.sql
+++ b/MySQL/DB_TABLE_STDLIB_PENDING.sql
@@ -9,7 +9,6 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_pending` (
`lib` binary(16) NOT NULL,
- `update` int(11) NOT NULL,
`comment` text NOT NULL,
PRIMARY KEY (`lib`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/MySQL/DB_TABLE_STDLIB_RELEASES.sql b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
index a8a0890..ce87ba6 100644
--- a/MySQL/DB_TABLE_STDLIB_RELEASES.sql
+++ b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
@@ -9,7 +9,6 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_releases` (
`release` tinytext NOT NULL,
- `update` int(11) NOT NULL,
`date` timestamp NULL DEFAULT NULL,
`description` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 34e7da8..87e7b25 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -68,15 +68,14 @@ public static function describe($release, $published)
return mysql_fetch_assoc($db_result);
}
- public static function create($update, $release, $date = NULL, $description = '') {
+ public static function create($release, $date = NULL, $description = '') {
$db_connection = db_ensure_connection();
- $update = mysql_real_escape_string($update, $db_connection);
$release = mysql_real_escape_string($release, $db_connection);
$description = mysql_real_escape_string($description, $db_connection);
$date = $date !== NULL ? '"' . mysql_real_escape_string($date, $db_connection) . '"' : 'NULL';
- $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_RELEASES . ' (`update`, `release`, `description`, `date`) VALUES ("' . $update . '", "' . $release . '", "' . $description . '", ' . $date . ')';
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_RELEASES . ' (`release`, `description`, `date`) VALUES ("' . $release . '", "' . $description . '", ' . $date . ')';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE || mysql_affected_rows() != 1) {
throw new HttpException(500, NULL, mysql_error());
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index b7aa684..b82cf38 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -13,7 +13,6 @@
Assert::GetParameters("type");
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml"), "application/json");
- $type = UpdateType::getCode($_GET["type"], "stdlib_releases");
$publish_status = StdlibRelease::PUBLISHED_BOTH;
if (!empty($_GET["base"]))
@@ -56,6 +55,8 @@
$release = $_POST["version"];
} else {
+ $type = UpdateType::getCode($_GET["type"], "stdlib_releases");
+
# bump version number according to $type
$release = array();
semver_parts($prev_release, $release);
@@ -91,7 +92,7 @@
$date = isset($_POST['date']) ? $_POST['date'] : NULL;
$description = isset($_POST['description']) ? $_POST['description'] : '';
- StdlibRelease::create($type, $release, $date, $description);
+ StdlibRelease::create($release, $date, $description);
if ($content_type == "application/json")
{
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 59b4d81..9fb7198 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -28,8 +28,6 @@
}
$release = StdlibRelease::describe($_GET["version"], $publish_status);
- unset($release['update']);
-
$release['libs'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
# todo later: get frameworks in the release
From 47187a769eb7c7675877e238a5300a52a70b6132 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 14:06:26 +0100
Subject: [PATCH 084/241] StdlibPending::GetEntries() - remove check for
published release
This must be and is ensured by the caller.
---
stdlib/StdlibPending.php | 3 ---
1 file changed, 3 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 7fec10e..44e2188 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -23,9 +23,6 @@ public static function GetAllEntries()
}
public static function GetEntries($release) {
- if (StdlibRelease::exists($release, StdlibRelease::PUBLISHED_YES)) # check if not yet released
- throw new HttpException(400, NULL, 'No pending entries for a published release!');
-
$base = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
$release_update = UpdateType::getUpdate($base, $release); # get release update type
From 693166251efaf6a93ffafd63caa94e19b7b3033b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 14:08:04 +0100
Subject: [PATCH 085/241] remove obsolete and useless API
---
stdlib/releases/.htaccess | 2 +-
stdlib/releases/update.php | 28 ----------------------------
2 files changed, 1 insertion(+), 29 deletions(-)
delete mode 100644 stdlib/releases/update.php
diff --git a/stdlib/releases/.htaccess b/stdlib/releases/.htaccess
index 599580b..7890a18 100644
--- a/stdlib/releases/.htaccess
+++ b/stdlib/releases/.htaccess
@@ -6,4 +6,4 @@ RewriteRule ^list$ list.php [L]
RewriteRule ^create/(major|minor|patch)$ create.php?type=$1 [L,QSA]
-RewriteRule ^(describe|delete|modify|publish|update)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
+RewriteRule ^(describe|delete|modify|publish)/(.+)$ $1.php?version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/releases/update.php b/stdlib/releases/update.php
deleted file mode 100644
index eac34be..0000000
--- a/stdlib/releases/update.php
+++ /dev/null
@@ -1,28 +0,0 @@
- stdlib_pending > stdlib > release published
- }
- catch (HttpException $e)
- {
- handleHttpException($e);
- }
- catch (Exception $e)
- {
- handleHttpException(new HttpException(500, NULL, $e->getMessage()));
- }
-?>
\ No newline at end of file
From d71596a47b9117908b34a953c8398d4055d44002 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 14:16:47 +0100
Subject: [PATCH 086/241] Add Stdlib::writeEntry()
---
stdlib/Stdlib.php | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index e5a22a6..2aa69de 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -88,5 +88,18 @@ public static function diff($old, $new) {
return $diff;
}
+
+ public static function writeEntry($release, $lib, $comment) {
+ $db_connection = db_ensure_connection();
+ $release = mysql_real_escape_string($release, $db_connection);
+ $lib = mysql_real_escape_string($lib, $db_connection);
+ $comment = mysql_real_escape_string($comment, $db_connection);
+
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `lib`, `comment`) VALUES ("' . $release . '", UNHEX("' . $lib . '"), "' . $comment . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ throw new HttpException(500);
+ }
+ }
}
?>
\ No newline at end of file
From 0ce0a7f370713dbb446a5e7d68d8b446b88cb0e3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 14:25:48 +0100
Subject: [PATCH 087/241] Add Stdlib::GetItemsUnpublished()
Move the logic for merging base release and
pending changes from Stdlib::GetItems() to a
new separate method Stdlib::GetItemsUnpublished()
---
stdlib/Stdlib.php | 60 +++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 28 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 2aa69de..80cae26 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -23,38 +23,42 @@ public static function GetItems($release)
return sql2array($db_result);
} else {
- $old_items = Stdlib::GetItems(StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES));
- foreach ($old_items AS &$item) {
- $item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
- }
+ return self::GetItemsUnpublished($release, StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES));
+ }
+ }
+
+ public static function GetItemsUnpublished($release, $base) {
+ $old_items = self::GetItems($base);
+ foreach ($old_items AS &$item) {
+ $item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
+ }
- $pending = StdlibPending::GetEntries($release);
+ $pending = StdlibPending::GetEntries($release);
- foreach ($pending AS &$entry) {
- switch ($entry['update']) {
- case UpdateType::REMOVE:
- $index = searchSubArray($old_items, array('id' => $entry['id']));
- if ($index === NULL)
- throw new HttpException(500);
- unset($old_items[$index]);
- break;
- case UpdateType::ADD:
- unset($entry['update']);
- $old_items[] = $entry;
- break;
- default:
- unset($entry['update']);
- $index = searchSubArray($old_items, array('name' => $entry['name']));
- if ($index === NULL)
- throw new HttpException(500);
- $old_items[$index] = $entry;
- break;
- }
+ foreach ($pending AS &$entry) {
+ switch ($entry['update']) {
+ case UpdateType::REMOVE:
+ $index = searchSubArray($old_items, array('id' => $entry['id']));
+ if ($index === NULL)
+ throw new HttpException(500);
+ unset($old_items[$index]);
+ break;
+ case UpdateType::ADD:
+ unset($entry['update']);
+ $old_items[] = $entry;
+ break;
+ default:
+ unset($entry['update']);
+ $index = searchSubArray($old_items, array('name' => $entry['name']));
+ if ($index === NULL)
+ throw new HttpException(500);
+ $old_items[$index] = $entry;
+ break;
}
-
- sort($old_items); # make array continuous
- return $old_items;
}
+
+ sort($old_items); # make array continuous
+ return $old_items;
}
public static function diff($old, $new) {
From 7ee6e702b97de0cca8084799ab8926c27ef18ad1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 14:47:11 +0100
Subject: [PATCH 088/241] add method for previous release to StdlibRelease
class
---
stdlib/releases/StdlibRelease.php | 14 ++++++++++++++
stdlib/releases/describe.php | 8 +++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 87e7b25..359e710 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -125,6 +125,20 @@ public static function update($release, $data)
}
}
+ public static function previousRelease($release, $published) {
+ $releases = self::ListReleases(self::PUBLISHED_BOTH);
+ usort($releases, array('StdlibRelease', 'semver_sort'));
+ $index = array_search($release, $releases);
+ if ($index !== FALSE) {
+ while ($index >= 1) {
+ $prev_release = $releases[--$index];
+ if (self::exists($prev_release, $published))
+ return $prev_release;
+ }
+ }
+ return NULL;
+ }
+
static function semver_sort($a, $b)
{
return semver_compare($a, $b);
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 9fb7198..eb3e435 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -33,11 +33,9 @@
# todo later: get frameworks in the release
if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
- $releases = StdlibRelease::ListReleases(StdlibRelease::PUBLISHED_YES);
- usort($releases, 'semver_sort');
- $index = array_search($release['release'], $releases) - 1;
- if ($index >= 0) {
- $changeset = Stdlib::diff($releases[$index], $release['release']);
+ $prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
+ if ($prev_release !== NULL) {
+ $changeset = Stdlib::diff($prev_release, $release['release']);
}
} else {
$changeset = StdlibPending::GetEntries($release['release']);
From 590b8c375ed11e8fadf364a6280cc5411721dbb8 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 15:08:53 +0100
Subject: [PATCH 089/241] fix StdlibPending::DeleteEntry() column name
---
stdlib/StdlibPending.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 44e2188..df01fad 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -88,7 +88,7 @@ public static function DeleteEntry($id)
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $db_query = 'DELETE * FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `id` = UNHEX('$id')";
+ $db_query = 'DELETE * FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `lib` = UNHEX('$id')";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
From 0c458dbb3185dfcac69c0f7e041cd38093b94da4 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 15:13:30 +0100
Subject: [PATCH 090/241] add a force_unpublished parameter to
StdlibRelease::update()
---
stdlib/releases/StdlibRelease.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 359e710..bc2916c 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -99,7 +99,7 @@ public static function delete($release)
}
}
- public static function update($release, $data)
+ public static function update($release, $data, $force_unpublished = false)
{
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
@@ -112,7 +112,7 @@ public static function update($release, $data)
array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))
)
)
- . " WHERE `release` = '$release' AND " . self::get_publish_cond(self::PUBLISHED_NO);
+ . " WHERE `release` = '$release'" . (($t = self::get_publish_cond($force_unpublished ? self::PUBLISHED_BOTH : self::PUBLISHED_NO)) ? ' AND ' . $t : '');;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
From b137114940f56f2dca7229d9382ee44f672cedd9 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 15:20:56 +0100
Subject: [PATCH 091/241] one more SQL fix to StdlibPending::DeleteEntry()
---
stdlib/StdlibPending.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index df01fad..fcc1360 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -88,7 +88,7 @@ public static function DeleteEntry($id)
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $db_query = 'DELETE * FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `lib` = UNHEX('$id')";
+ $db_query = 'DELETE FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `lib` = UNHEX('$id')";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
From 0bd61b0f5b1153fb9e592a9cb1b30a8645bbabc6 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 15:22:40 +0100
Subject: [PATCH 092/241] add new StdlibRelease::publish() method
---
stdlib/releases/StdlibRelease.php | 15 +++++++++++++++
stdlib/releases/publish.php | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index bc2916c..f54a43f 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -1,5 +1,7 @@
date('Y-m-d H:i:s')), true);
+ }
+ }
+
static function semver_sort($a, $b)
{
return semver_compare($a, $b);
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index ae343e9..58dd95b 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -20,7 +20,7 @@
if (StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_YES)) # check if already published
throw new HttpException(403, NULL, "Must not change published release!");
- StdlibRelease::update($_GET["version"], array("date" => date("c")));
+ StdlibRelease::publish($_GET["version"]);
header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
}
catch (HttpException $e)
From c42c796249b6b6998f5ef2be1b8778bab05328cd Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 15:58:57 +0100
Subject: [PATCH 093/241] workaround for releases with timed publication
If a release has set a publication date in advance,
the data has not yet been moved to the correct table.
Therefore, if a release has no items, try publishing
and re-reading items.
---
stdlib/Stdlib.php | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 80cae26..62a24e3 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -8,7 +8,7 @@
class Stdlib
{
- public static function GetItems($release)
+ public static function GetItems($release, $suppress_publish = false)
{
if (StdlibRelease::exists($release, StdlibRelease::PUBLISHED_YES)) { # check if published
$db_connection = db_ensure_connection();
@@ -21,7 +21,19 @@ public static function GetItems($release)
throw new HttpException(500);
}
- return sql2array($db_result);
+ $items = sql2array($db_result);
+ if (!$suppress_publish && count($items) == 0) {
+ try {
+ if ($retry = count(StdlibPending::GetEntries($release)) > 0)
+ StdlibRelease::publish($release);
+ } catch (HttpException $e) {
+ $retry = false;
+ }
+ if ($retry) {
+ return self::GetItems($release, true); # avoid never-ending loop
+ }
+ }
+ return $items;
} else {
return self::GetItemsUnpublished($release, StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES));
}
From 4a366668e4c1a2f877d4f9610bb0dd58d24c7720 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 16:17:34 +0100
Subject: [PATCH 094/241] rename privilege for stdlib
---
User.php | 2 +-
stdlib/releases/create.php | 2 +-
stdlib/releases/delete.php | 2 +-
stdlib/releases/describe.php | 2 +-
stdlib/releases/list.php | 2 +-
stdlib/releases/modify.php | 2 +-
stdlib/releases/publish.php | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/User.php b/User.php
index fd969cd..74c340e 100644
--- a/User.php
+++ b/User.php
@@ -8,7 +8,7 @@ class User
const PRIVILEGE_NONE = 0;
const PRIVILEGE_USER_MANAGE = 2;
const PRIVILEGE_REVIEW = 4;
- const PRIVILEGE_DEFAULT_INCLUDE = 8;
+ const PRIVILEGE_STDLIB = 8;
const PRIVILEGE_ADMIN = 16;
const PRIVILEGE_REGISTRATION = 32;
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index b82cf38..ae92619 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -31,7 +31,7 @@
}
user_basic_auth("Restricted API");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403);
# get latest release
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
index c16ce77..d9b2a02 100644
--- a/stdlib/releases/delete.php
+++ b/stdlib/releases/delete.php
@@ -11,7 +11,7 @@
Assert::GetParameters("version");
user_basic_auth("Restricted API");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403);
StdlibRelease::delete($_GET["version"]);
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index eb3e435..5bf8ad6 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -23,7 +23,7 @@
if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"]))
{
user_basic_auth("");
- if (User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
$publish_status = StdlibRelease::PUBLISHED_BOTH;
}
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 5deb5ea..5c60ede 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -20,7 +20,7 @@
if (in_array($published, array(-1, "no", "false"), true) || ($both = in_array($published, array(0, "both"), true))) {
user_basic_auth("Unpublished releases can only be viewed by members of the stdlib team!"); # check auth
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403);
$publish_status = $both ? StdlibRelease::PUBLISHED_BOTH : StdlibRelease::PUBLISHED_NO;
}
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index 1d846c4..c7adb66 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -12,7 +12,7 @@
Assert::GetParameters("version");
user_basic_auth("You must be part of the stdlib team!");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index 58dd95b..44fcc83 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -11,7 +11,7 @@
Assert::GetParameters("version");
user_basic_auth("You must be part of the stdlib team!");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_DEFAULT_INCLUDE))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
From 2477ebcd92a1530d8b8899e7337beda4dd0439c1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 20:03:26 +0100
Subject: [PATCH 095/241] move most of sorting logic to separate file
---
items/list.php | 16 ++--------------
sort_get_order_clause.php | 19 +++++++++++++++++++
2 files changed, 21 insertions(+), 14 deletions(-)
create mode 100644 sort_get_order_clause.php
diff --git a/items/list.php b/items/list.php
index f914b5b..a2aaf17 100644
--- a/items/list.php
+++ b/items/list.php
@@ -2,6 +2,7 @@
require_once("../modules/HttpException/HttpException.php");
require_once("../db.php");
require_once("../util.php");
+ require_once('../sort_get_order_clause.php');
require_once("../User.php");
require_once("../Assert.php");
require_once("../modules/semver/semver.php");
@@ -95,20 +96,7 @@
# retrieve sorting parameters
$sort_by_rating = false;
if (isset($_GET['sort'])) {
- $sort_keys = explode(' ', $_GET['sort']);
- $sort_dirs = array_map(function($item) { return substr($item, 0, 1) != '!'; }, $sort_keys);
- $sort_keys = array_map(function($item) { return substr($item, 0, 1) == '!' ? substr($item, 1, strlen($item) - 1 ) : $item; }, $sort_keys);
- $sorting = array_combine($sort_keys, $sort_dirs);
-
- # can sort by:
- $allowed_sorting = array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => 'SUM(`rating`)');
- foreach ($sorting AS $key => $dir) {
- if (array_key_exists($key, $allowed_sorting)) {
- $db_order .= ($db_order) ? ', ' : 'ORDER BY ';
- $db_order .= $allowed_sorting[$key] . ' ' . ($dir ? 'ASC' : 'DESC');
- $sort_by_rating = $sort_by_rating || $key == 'rating';
- }
- }
+ $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => 'SUM(`rating`)'));
}
# enable rating filters if necessary
diff --git a/sort_get_order_clause.php b/sort_get_order_clause.php
new file mode 100644
index 0000000..2e85014
--- /dev/null
+++ b/sort_get_order_clause.php
@@ -0,0 +1,19 @@
+ $dir) {
+ if (array_key_exists($key, $allowed)) {
+ $db_order .= ($db_order) ? ', ' : 'ORDER BY ';
+ $db_order .= $allowed[$key] . ' ' . ($dir ? 'ASC' : 'DESC');
+ }
+ }
+
+ return $db_order;
+}
+?>
\ No newline at end of file
From 2c2f1a375cd434b909cb7c7b51123c39624e5bf0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 20:04:11 +0100
Subject: [PATCH 096/241] support user sorting
Allowed sorting fields so far are 'name' and 'joined'.
---
users/list.php | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/users/list.php b/users/list.php
index 393ec7e..0933544 100644
--- a/users/list.php
+++ b/users/list.php
@@ -2,6 +2,7 @@
require_once("../modules/HttpException/HttpException.php");
require_once("../db.php");
require_once("../util.php");
+ require_once('../sort_get_order_clause.php');
require_once('../sql2array.php');
require_once("../Assert.php");
@@ -17,6 +18,8 @@
# retrieve data limits
$db_limit = "";
+ $db_order = '';
+
if (isset($_GET["count"]) && strtolower($_GET["count"]) != "all")
{
$db_limit = "LIMIT " . mysql_real_escape_string($_GET["count"], $db_connection);
@@ -30,8 +33,12 @@
$db_limit .= " OFFSET " . mysql_real_escape_string($_GET["start"], $db_connection);
}
+ if (isset($_GET['sort'])) {
+ $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'joined' => '`joined`'));
+ }
+
# query for data:
- $db_query = "SELECT name, HEX(id) AS id FROM " . DB_TABLE_USERS . " $db_limit";
+ $db_query = "SELECT name, HEX(id) AS id FROM " . DB_TABLE_USERS . " $db_order $db_limit";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
From a657a67f956e6505fc39bde83365ce2b7c769b2b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 22:26:27 +0100
Subject: [PATCH 097/241] fix regression: include rating if it is used for
sorting
---
items/list.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/items/list.php b/items/list.php
index a2aaf17..5afb669 100644
--- a/items/list.php
+++ b/items/list.php
@@ -97,6 +97,7 @@
$sort_by_rating = false;
if (isset($_GET['sort'])) {
$db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => 'SUM(`rating`)'));
+ $sort_by_rating = preg_match('/(^|\s)!?rating/', $_GET['sort']) == 1;
}
# enable rating filters if necessary
From a924a8b7f4e7434084ac42345de883275e76b5fd Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Feb 2013 22:32:49 +0100
Subject: [PATCH 098/241] fix sorting according to rating
Use the same complicate SQL query for sorting as for filtering.
Move it to a constant definition.
---
items/list.php | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/items/list.php b/items/list.php
index 5afb669..83ecf2d 100644
--- a/items/list.php
+++ b/items/list.php
@@ -9,6 +9,9 @@
require_once('ItemType.php');
require_once('../sql2array.php');
+ # this complicated query ensures items without any ratings are considered to be rated 0
+ define('SQL_QUERY_RATING', '(SELECT CASE WHEN ' . DB_TABLE_ITEMS . '.id IN (SELECT item FROM ratings) THEN (SELECT SUM(rating) FROM ratings WHERE ratings.item = ' . DB_TABLE_ITEMS . '.id) ELSE 0 END)');
+
try
{
Assert::RequestMethod(Assert::REQUEST_METHOD_GET); # only allow GET requests
@@ -96,7 +99,7 @@
# retrieve sorting parameters
$sort_by_rating = false;
if (isset($_GET['sort'])) {
- $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => 'SUM(`rating`)'));
+ $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => SQL_QUERY_RATING));
$sort_by_rating = preg_match('/(^|\s)!?rating/', $_GET['sort']) == 1;
}
@@ -104,19 +107,17 @@
if ($get_rating = isset($_GET['rating']) || isset($_GET['rating-min']) || isset($_GET['rating-max']) || $sort_by_rating) {
$db_join = 'LEFT JOIN ' . DB_TABLE_RATINGS . ' ON item = id';
- # this complicated query ensures items without any ratings are considered to be rated 0
- $sub_query = '(SELECT CASE WHEN ' . DB_TABLE_ITEMS . '.id IN (SELECT item FROM ratings) THEN (SELECT SUM(rating) FROM ratings WHERE ratings.item = ' . DB_TABLE_ITEMS . '.id) ELSE 0 END)';
if (isset($_GET['rating'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating'], $db_connection) . ' = ' . $sub_query;
+ $db_having .= mysql_real_escape_string($_GET['rating'], $db_connection) . ' = ' . SQL_QUERY_RATING;
} else {
if (isset($_GET['rating-min'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating-min'], $db_connection) . ' <= ' . $sub_query;
+ $db_having .= mysql_real_escape_string($_GET['rating-min'], $db_connection) . ' <= ' . SQL_QUERY_RATING;
}
if (isset($_GET['rating-max'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating-max'], $db_connection) . ' >= ' . $sub_query;
+ $db_having .= mysql_real_escape_string($_GET['rating-max'], $db_connection) . ' >= ' . SQL_QUERY_RATING;
}
}
}
From d24cc53b45c105423b670a7be781fadbfec907f7 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 27 Feb 2013 21:12:26 +0100
Subject: [PATCH 099/241] simplify publication code with a new DB field
For timed publications, the workarounds being used were quite ugly.
Do not use them anymore. Instead, add a new DB field to save whether
a release has been explicitly published to the DB table. Ensure this
before every API call.
More code cleanup, removal of debug code, syntax error fixes etc.
---
MySQL/DB_TABLE_STDLIB_RELEASES.sql | 3 +-
stdlib/Stdlib.php | 16 ++---------
stdlib/releases/StdlibRelease.php | 46 ++++++++++++++++++++++++------
stdlib/releases/create.php | 3 ++
stdlib/releases/delete.php | 3 ++
stdlib/releases/describe.php | 3 ++
stdlib/releases/list.php | 3 ++
stdlib/releases/modify.php | 3 ++
stdlib/releases/publish.php | 3 ++
9 files changed, 59 insertions(+), 24 deletions(-)
diff --git a/MySQL/DB_TABLE_STDLIB_RELEASES.sql b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
index ce87ba6..2224f37 100644
--- a/MySQL/DB_TABLE_STDLIB_RELEASES.sql
+++ b/MySQL/DB_TABLE_STDLIB_RELEASES.sql
@@ -10,7 +10,8 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_releases` (
`release` tinytext NOT NULL,
`date` timestamp NULL DEFAULT NULL,
- `description` text NOT NULL
+ `description` text NOT NULL,
+ `published` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 62a24e3..80cae26 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -8,7 +8,7 @@
class Stdlib
{
- public static function GetItems($release, $suppress_publish = false)
+ public static function GetItems($release)
{
if (StdlibRelease::exists($release, StdlibRelease::PUBLISHED_YES)) { # check if published
$db_connection = db_ensure_connection();
@@ -21,19 +21,7 @@ public static function GetItems($release, $suppress_publish = false)
throw new HttpException(500);
}
- $items = sql2array($db_result);
- if (!$suppress_publish && count($items) == 0) {
- try {
- if ($retry = count(StdlibPending::GetEntries($release)) > 0)
- StdlibRelease::publish($release);
- } catch (HttpException $e) {
- $retry = false;
- }
- if ($retry) {
- return self::GetItems($release, true); # avoid never-ending loop
- }
- }
- return $items;
+ return sql2array($db_result);
} else {
return self::GetItemsUnpublished($release, StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES));
}
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index f54a43f..5858f6a 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -34,7 +34,7 @@ public static function getVersion($special_version, $published)
if (in_array($special_version, array(self::SPECIAL_VERSION_LATEST, self::SPECIAL_VERSION_FIRST)))
{
$releases = self::ListReleases($published);
- if (count($releases > 0))
+ if (count($releases) > 0)
{
usort($releases, array("StdlibRelease", "semver_sort")); # sort following the semver rules
return $releases[$special_version == self::SPECIAL_VERSION_LATEST ? count($releases) - 1 : 0]; # latest / first release
@@ -89,7 +89,7 @@ public static function delete($release)
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
- $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND " . self::get_publish_cond(self::PUBLISHED_NO);
+ $db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND !`published`";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -101,8 +101,12 @@ public static function delete($release)
}
}
- public static function update($release, $data, $force_unpublished = false)
+ public static function update($release, $data)
{
+ if (self::exists($release, self::PUBLISHED_YES)) {
+ throw new HttpException(400, NULL, 'Cannot update already published release!');
+ }
+
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
@@ -114,7 +118,7 @@ public static function update($release, $data, $force_unpublished = false)
array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))
)
)
- . " WHERE `release` = '$release'" . (($t = self::get_publish_cond($force_unpublished ? self::PUBLISHED_BOTH : self::PUBLISHED_NO)) ? ' AND ' . $t : '');;
+ . " WHERE `release` = '$release' AND !`published`";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -141,17 +145,41 @@ public static function previousRelease($release, $published) {
return NULL;
}
- public static function publish($release) { # caller must ensure that $release is not published
+ public static function publishPending() {
+ $db_connection = db_ensure_connection();
+ $db_query = 'SELECT `release` FROM ' . DB_TABLE_STDLIB_RELEASES . ' WHERE !`published` AND `date` <= NOW()';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+
+ $releases = array();
+ while ($release = mysql_fetch_array($db_result)) { # sort by release
+ $releases[] = $release['release'];
+ }
+
+ usort($releases, array('StdlibRelease', 'semver_sort')); # sort following the semver rules
+ foreach ($releases AS $release) {
+ self::publish($release);
+ }
+ }
+
+ public static function publish($release) {
+ if (self::exists($release, self::PUBLISHED_YES)) {
+ throw new HttpException(400, NULL, 'Cannot publish already published release!');
+ }
+
$entries = Stdlib::GetItemsUnpublished($release, self::previousRelease($release, self::PUBLISHED_YES));
foreach ($entries AS $entry) {
Stdlib::writeEntry($release, $entry['id'], $entry['comment']);
StdlibPending::DeleteEntry($entry['id']);
}
- print_r($release_data = self::describe($release, self::PUBLISHED_BOTH));
+ $release_data = self::describe($release, self::PUBLISHED_BOTH);
if ($release_data['date'] === NULL) {
- self::update($release, array('date' => date('Y-m-d H:i:s')), true);
+ self::update($release, array('date' => date('Y-m-d H:i:s')));
}
+ self::update($release, array('published' => true));
}
static function semver_sort($a, $b)
@@ -186,9 +214,9 @@ static function get_publish_cond($published)
switch ($published)
{
case self::PUBLISHED_YES:
- return '(`date` IS NOT NULL AND `date` AND NOW() >= `date`)';
+ return '`published`';
case self::PUBLISHED_NO:
- return '(`date` IS NULL OR !`date` OR NOW() < `date`)';
+ return '!`published`';
case self::PUBLISHED_BOTH:
return NULL;
default:
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index ae92619..00490ce 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -34,6 +34,9 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403);
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
# get latest release
$prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $publish_status);
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
index d9b2a02..9a4fb34 100644
--- a/stdlib/releases/delete.php
+++ b/stdlib/releases/delete.php
@@ -14,6 +14,9 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403);
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
StdlibRelease::delete($_GET["version"]);
header("HTTP/1.1 204 " . HttpException::getStatusMessage(204));
}
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 5bf8ad6..222f5b1 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -27,6 +27,9 @@
$publish_status = StdlibRelease::PUBLISHED_BOTH;
}
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
$release = StdlibRelease::describe($_GET["version"], $publish_status);
$release['libs'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 5c60ede..f47ba6c 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -27,6 +27,9 @@
# else if (in_array($published, array(1, "+1", "true", "yes"))) # the default
}
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
$releases = StdlibRelease::ListReleases($publish_status);
if ($content_type == "application/json")
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index c7adb66..6371ebf 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -15,6 +15,9 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
throw new HttpException(404, NULL, "Release does not exist!");
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index 44fcc83..7d15143 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -14,6 +14,9 @@
if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
throw new HttpException(403, NULL, "You must be part of the stdlib team!");
+ # make sure all releases that should be published are published
+ StdlibRelease::publishPending();
+
if (!StdlibRelease::exists($_GET["version"], StdlibRelease::PUBLISHED_BOTH)) # check if release exists
throw new HttpException(404, NULL, "Release does not exist!");
From 944a25b7cba62d7ecf23c60751fe590885bfa89d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 16:19:25 +0100
Subject: [PATCH 100/241] delete pending removals on publish
---
stdlib/releases/StdlibRelease.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 5858f6a..fabc5c7 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -2,6 +2,7 @@
require_once(dirname(__FILE__) . "/../../db.php");
require_once(dirname(__FILE__) . "/../Stdlib.php");
require_once(dirname(__FILE__) . "/../StdlibPending.php");
+require_once(dirname(__FILE__) . '/../../UpdateType.php');
require_once(dirname(__FILE__) . "/../../modules/HttpException/HttpException.php");
require_once(dirname(__FILE__) . "/../../modules/semver/semver.php");
@@ -175,6 +176,14 @@ public static function publish($release) {
StdlibPending::DeleteEntry($entry['id']);
}
+ # removals are not covered by deletion above, so delete these entries here
+ $pending = StdlibPending::GetEntries($release);
+ foreach ($pending AS $entry) {
+ if ($entry['update'] == UpdateType::REMOVE) {
+ StdlibPending::DeleteEntry($entry['id']);
+ }
+ }
+
$release_data = self::describe($release, self::PUBLISHED_BOTH);
if ($release_data['date'] === NULL) {
self::update($release, array('date' => date('Y-m-d H:i:s')));
From 20adf6f33d90e9d684a3ce2eb36aaeac62daa802 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 16:40:08 +0100
Subject: [PATCH 101/241] delete unused table
---
MySQL/DB_TABLE_STDLIB_ACTIONS.sql | 19 -------------------
1 file changed, 19 deletions(-)
delete mode 100644 MySQL/DB_TABLE_STDLIB_ACTIONS.sql
diff --git a/MySQL/DB_TABLE_STDLIB_ACTIONS.sql b/MySQL/DB_TABLE_STDLIB_ACTIONS.sql
deleted file mode 100644
index b4cac4e..0000000
--- a/MySQL/DB_TABLE_STDLIB_ACTIONS.sql
+++ /dev/null
@@ -1,19 +0,0 @@
-SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-SET time_zone = "+00:00";
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-
-
-CREATE TABLE IF NOT EXISTS `stdlib_actions` (
- `type` int(11) NOT NULL,
- `item` binary(16) NOT NULL,
- `user` binary(16) NOT NULL,
- `accept` tinyint(1) NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
From 67646c609aa5f603aadb7467fddc1f363934fc52 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 16:44:13 +0100
Subject: [PATCH 102/241] add new privilege STDLIB_ADMIN
---
User.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/User.php b/User.php
index 74c340e..f3d4558 100644
--- a/User.php
+++ b/User.php
@@ -11,6 +11,7 @@ class User
const PRIVILEGE_STDLIB = 8;
const PRIVILEGE_ADMIN = 16;
const PRIVILEGE_REGISTRATION = 32;
+ const PRIVILEGE_STDLIB_ADMIN = 64;
public static function hasPrivilegeById($id, $privilege)
{
From 9ed1637aa72c743460746de66034d2d4ccec98aa Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 16:52:15 +0100
Subject: [PATCH 103/241] require STDLIB_ADMIN privilege for release
publication and deletion
For publications, also cover timed publications by setting a date.
---
stdlib/releases/create.php | 6 ++++++
stdlib/releases/delete.php | 2 +-
stdlib/releases/modify.php | 5 ++++-
stdlib/releases/publish.php | 4 ++--
4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 00490ce..077cfa7 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -95,6 +95,12 @@
$date = isset($_POST['date']) ? $_POST['date'] : NULL;
$description = isset($_POST['description']) ? $_POST['description'] : '';
+ if ($date !== NULL) {
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB_ADMIN)) {
+ throw new HttpException(403, NULL, 'Only stdlib admins can set the publication date for a release.');
+ }
+ }
+
StdlibRelease::create($release, $date, $description);
if ($content_type == "application/json")
diff --git a/stdlib/releases/delete.php b/stdlib/releases/delete.php
index 9a4fb34..c71a128 100644
--- a/stdlib/releases/delete.php
+++ b/stdlib/releases/delete.php
@@ -11,7 +11,7 @@
Assert::GetParameters("version");
user_basic_auth("Restricted API");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB) || !User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB_ADMIN))
throw new HttpException(403);
# make sure all releases that should be published are published
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index 6371ebf..ecd7071 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -46,7 +46,10 @@
# verify date
if (isset($data["date"]))
{
- # todo: check stdlib admin
+ # check stdlib admin
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB_ADMIN)) {
+ throw new HttpException(403, NULL, 'Only stdlib admins can set the publication date for a release.');
+ }
# check valid date
$date = array();
diff --git a/stdlib/releases/publish.php b/stdlib/releases/publish.php
index 7d15143..a5c1adc 100644
--- a/stdlib/releases/publish.php
+++ b/stdlib/releases/publish.php
@@ -11,8 +11,8 @@
Assert::GetParameters("version");
user_basic_auth("You must be part of the stdlib team!");
- if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB))
- throw new HttpException(403, NULL, "You must be part of the stdlib team!");
+ if (!User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB) || !User::hasPrivilege($_SERVER["PHP_AUTH_USER"], User::PRIVILEGE_STDLIB_ADMIN))
+ throw new HttpException(403, NULL, "You must be stdlib admin to publish a release!");
# make sure all releases that should be published are published
StdlibRelease::publishPending();
From fb9ae27f7cbdf037bb329193caefb294fcee7395 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 17:08:09 +0100
Subject: [PATCH 104/241] add DB tables for candidate handling
---
MySQL/DB_TABLE_CANDIDATES.sql | 21 +++++++++++++++++++++
MySQL/DB_TABLE_CANDIDATE_RATING.sql | 23 +++++++++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 MySQL/DB_TABLE_CANDIDATES.sql
create mode 100644 MySQL/DB_TABLE_CANDIDATE_RATING.sql
diff --git a/MySQL/DB_TABLE_CANDIDATES.sql b/MySQL/DB_TABLE_CANDIDATES.sql
new file mode 100644
index 0000000..2bd8be8
--- /dev/null
+++ b/MySQL/DB_TABLE_CANDIDATES.sql
@@ -0,0 +1,21 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `candidates` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `item` binary(16) NOT NULL,
+ `user` binary(16) NOT NULL,
+ `reason` text NOT NULL,
+ `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/MySQL/DB_TABLE_CANDIDATE_RATING.sql b/MySQL/DB_TABLE_CANDIDATE_RATING.sql
new file mode 100644
index 0000000..f680fd8
--- /dev/null
+++ b/MySQL/DB_TABLE_CANDIDATE_RATING.sql
@@ -0,0 +1,23 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `candidate-rating` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `candidate` int(11) NOT NULL,
+ `user` binary(16) NOT NULL,
+ `accept` tinyint(1) NOT NULL,
+ `final` tinyint(1) NOT NULL DEFAULT '0',
+ `reason` text NOT NULL,
+ `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
From bcd5a1e7c763b487480eab3989ffe8b0a3423d23 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 17:43:09 +0100
Subject: [PATCH 105/241] Add methods to check if an item is pending for or in
the stdlib
---
stdlib/Stdlib.php | 14 ++++++++++++++
stdlib/StdlibPending.php | 13 +++++++++++++
2 files changed, 27 insertions(+)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 80cae26..b462eac 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -105,5 +105,19 @@ public static function writeEntry($release, $lib, $comment) {
throw new HttpException(500);
}
}
+
+ public static function releaseHasItem($release, $id) {
+ $db_connection = db_ensure_connection();
+ $release = mysql_real_escape_string($release, $db_connection);
+ $id= mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $release . '" AND `lib` = UNHEX("' . $id . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ throw new HttpException(500);
+ }
+
+ return mysql_num_rows($db_result) > 0;
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index fcc1360..ab1612d 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -95,5 +95,18 @@ public static function DeleteEntry($id)
throw new HttpException(500);
}
}
+
+ public static function IsPending($id) {
+ $db_connection = db_ensure_connection();
+ $id = mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `lib` = UNHEX"' . $id . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ return mysql_num_rows($db_result) > 0;
+ }
}
?>
\ No newline at end of file
From 8fd7a72fabfa58218f895ece30c8d47f8ec77cf1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:02:58 +0100
Subject: [PATCH 106/241] delete config for deleted DB
---
config/database.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/config/database.php b/config/database.php
index 34bad70..99976cb 100644
--- a/config/database.php
+++ b/config/database.php
@@ -11,7 +11,6 @@
define('DB_TABLE_STDLIB', 'stdlib'); #
define('DB_TABLE_STDLIB_RELEASES', 'stdlib_releases'); #
define('DB_TABLE_STDLIB_PENDING', 'stdlib_pending'); #
- define('DB_TABLE_STDLIB_ACTIONS', 'stdlib_actions'); #
define('DB_TABLE_REGISTRATION', 'registration'); #
define('DB_TABLE_TYPES', 'types'); #
From 148598e56b7afb594c026b127e9fe2df4ace2246 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:05:18 +0100
Subject: [PATCH 107/241] add config for new DBs
---
config/database.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/config/database.php b/config/database.php
index 34bad70..96dc9fc 100644
--- a/config/database.php
+++ b/config/database.php
@@ -12,6 +12,10 @@
define('DB_TABLE_STDLIB_RELEASES', 'stdlib_releases'); #
define('DB_TABLE_STDLIB_PENDING', 'stdlib_pending'); #
define('DB_TABLE_STDLIB_ACTIONS', 'stdlib_actions'); #
+
+ define('DB_TABLE_CANDIDATES', 'candidates'); #
+ define('DB_TABLE_CANDIDATE_RATING', 'candidate_rating'); #
+
define('DB_TABLE_REGISTRATION', 'registration'); #
define('DB_TABLE_TYPES', 'types'); #
From 2ec56021d95fdea9401dda71ba522c1cf0a91003 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:14:46 +0100
Subject: [PATCH 108/241] begin a Candidate class for candidate handling
---
stdlib/candidates/Candidate.php | 38 +++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 stdlib/candidates/Candidate.php
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
new file mode 100644
index 0000000..a1062d6
--- /dev/null
+++ b/stdlib/candidates/Candidate.php
@@ -0,0 +1,38 @@
+ 0;
+ }
+
+ public static function accepted($item) {
+ # ... todo ...
+ }
+}
+?>
\ No newline at end of file
From b83f9196e3c222b1a50bdc8c4ff8acdd17982a03 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:15:01 +0100
Subject: [PATCH 109/241] add candidate creation API
---
stdlib/candidates/create.php | 66 ++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 stdlib/candidates/create.php
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
new file mode 100644
index 0000000..4fc4140
--- /dev/null
+++ b/stdlib/candidates/create.php
@@ -0,0 +1,66 @@
+ $candidate));
+ } else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
+ $content = '' . $candidate . '';
+ }
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-type: ' . $content_type);
+ echo $content;
+ exit;
+
+} catch (HttpException $e) {
+ handleHttpException($e);
+} catch (Exception $e) {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+}
+?>
\ No newline at end of file
From 14ba626ef85ee233b39e6c4d5994f246968147d3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:31:09 +0100
Subject: [PATCH 110/241] fix path
---
stdlib/candidates/Candidate.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index a1062d6..7d50ce9 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -1,6 +1,6 @@
Date: Thu, 28 Feb 2013 18:32:00 +0100
Subject: [PATCH 111/241] add .htaccess file for candidates
---
stdlib/candidates/.htaccess | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 stdlib/candidates/.htaccess
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
new file mode 100644
index 0000000..8fbe8f0
--- /dev/null
+++ b/stdlib/candidates/.htaccess
@@ -0,0 +1,9 @@
+Options -Multiviews
+
+RewriteEngine On
+
+RewriteRule ^list$ list.php [L]
+
+RewriteRule ^(rate|approve)/(\d+)$ $1.php?id=$2 [L]
+RewriteRule ^create/([0-9a-fA-F]{32})$ create.php?id=$1 [L]
+RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
\ No newline at end of file
From 4dffb143ad5d38d2c1571607ec9c3c7d98655b53 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:37:31 +0100
Subject: [PATCH 112/241] fix DB table constant name
---
stdlib/candidates/Candidate.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 7d50ce9..33c5b52 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -9,7 +9,7 @@ public static function create($item, $user, $reason) {
$user = mysql_real_escape_string($user, $db_connection);
$reason = mysql_real_escape_string($reason, $db_connection);
- $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATE . ' (`item`, `user`, `reason`) VALUES (UNHEX("' . $item . '"), UNHEX("' . $user . '"), "' . $reason . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATES . ' (`item`, `user`, `reason`) VALUES (UNHEX("' . $item . '"), UNHEX("' . $user . '"), "' . $reason . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
@@ -22,7 +22,7 @@ public static function exists($item) {
$db_connection = db_ensure_connection();
$item = mysql_real_escape_string($item, $db_connection);
- $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATE . ' WHERE `item` = UNHEX("' . $item . '")';
+ $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATES . ' WHERE `item` = UNHEX("' . $item . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
From 6d6ee6748cd3b5f6aded670e6bcb3f815b9d31b8 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:37:43 +0100
Subject: [PATCH 113/241] add listing function to Candidate class
---
stdlib/candidates/Candidate.php | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 33c5b52..3ee4e11 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -1,5 +1,6 @@
\ No newline at end of file
From 3fcaa58e693c5fda1fa4cc85471bad34260f6385 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 18:41:16 +0100
Subject: [PATCH 114/241] begin listing API for candidates
---
stdlib/candidates/list.php | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 stdlib/candidates/list.php
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
new file mode 100644
index 0000000..314f108
--- /dev/null
+++ b/stdlib/candidates/list.php
@@ -0,0 +1,33 @@
+';
+ foreach ($candidates AS $candidate) {
+ $content .= '';
+ }
+ $content .= '';
+ }
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-type: ' . $content_type);
+ echo $content;
+ exit;
+
+} catch (HttpException $e) {
+ handleHttpException($e);
+} catch (Exception $e) {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+}
+?>
\ No newline at end of file
From de89e5bed1b0c854fe22cdb38534970341224f5b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Feb 2013 20:36:57 +0100
Subject: [PATCH 115/241] begin rating of candidates
Begin the API method for accepting / rejecting an item.
Add a method to the candidate class to store a rating.
Adjust .htacces file.
---
stdlib/candidates/.htaccess | 3 ++-
stdlib/candidates/Candidate.php | 16 ++++++++++++++
stdlib/candidates/rating.php | 38 +++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+), 1 deletion(-)
create mode 100644 stdlib/candidates/rating.php
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
index 8fbe8f0..9a270ef 100644
--- a/stdlib/candidates/.htaccess
+++ b/stdlib/candidates/.htaccess
@@ -4,6 +4,7 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^(rate|approve)/(\d+)$ $1.php?id=$2 [L]
+RewriteRule ^(rating|approve)/(\d+)$ $1.php?id=$2 [L]
+RewriteRule ^(reject|accept)/(\d+)$ rating.php?id=$2&mode=$1 [L]
RewriteRule ^create/([0-9a-fA-F]{32})$ create.php?id=$1 [L]
RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 3ee4e11..cbbf331 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -46,5 +46,21 @@ public static function listCandidates() {
return sql2array($db_result);
}
+
+ public static function rate($candidate, $user, $accept, $reason, $final = false) {
+ $db_connection = db_ensure_connection();
+
+ $candidate = mysql_real_escape_string($candidate, $db_connection);
+ $user = mysql_real_escape_string($user, $db_connection);
+ $reason = mysql_real_escape_string($reason, $db_connection);
+ $accept = $accept ? 'TRUE' : 'FALSE';
+ $final = $final ? 'TRUE' : 'FALSE';
+
+ $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATE_RATING . ' (`candidate`, `user`, `accept`, `final`, `reason`) VALUES (' . $candidate . ', UNHEX("' . $user . '"), ' . $accept . ', ' . $final . ', "' . $reason . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/candidates/rating.php b/stdlib/candidates/rating.php
new file mode 100644
index 0000000..54dd5de
--- /dev/null
+++ b/stdlib/candidates/rating.php
@@ -0,0 +1,38 @@
+getMessage()));
+}
+?>
\ No newline at end of file
From f5856f5723bae5c4df716b15665f7d50db2fad54 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 15:05:18 +0100
Subject: [PATCH 116/241] retrieve the user who suggested a candidate
---
stdlib/candidates/Candidate.php | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index cbbf331..9505d15 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -36,6 +36,20 @@ public static function accepted($item) {
# ... todo ...
}
+ public static function getUser($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT HEX(`user`) AS user FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ $t = mysql_fetch_assoc($db_result);
+ return $t['user'];
+ }
+
public static function listCandidates() {
$db_connection = db_ensure_connection();
$db_query = 'SELECT `id`, HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES; # todo: include status + approval
From 7448c16407300593202c7ede566506d52d819953 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 15:07:08 +0100
Subject: [PATCH 117/241] retrieve item for candidate ID and vice versa
---
stdlib/candidates/Candidate.php | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 9505d15..7a3b0ae 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -36,6 +36,20 @@ public static function accepted($item) {
# ... todo ...
}
+ public static function getId($item) {
+ $db_connection = db_ensure_connection();
+ $item = mysql_real_escape_string($item, $db_connection);
+
+ $db_query = 'SELECT `id` FROM ' . DB_TABLE_CANDIDATES . ' WHERE `item` = UNHEX("' . $item . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ $t = mysql_fetch_assoc($db_result);
+ return $t['id'];
+ }
+
public static function getUser($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
@@ -50,6 +64,20 @@ public static function getUser($id) {
return $t['user'];
}
+ public static function getItem($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ $t = mysql_fetch_assoc($db_result);
+ return $t['item'];
+ }
+
public static function listCandidates() {
$db_connection = db_ensure_connection();
$db_query = 'SELECT `id`, HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES; # todo: include status + approval
From 7851fb4aa69a87dc484e488fe848eb0254ede1b2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 15:09:57 +0100
Subject: [PATCH 118/241] Rename + Add methods
Two methods for existence-checking: one by candidate ID,
one by item ID. Adjust create.php to use the one by item.
---
stdlib/candidates/Candidate.php | 15 ++++++++++++++-
stdlib/candidates/create.php | 5 +++--
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 7a3b0ae..e4a0862 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -19,7 +19,20 @@ public static function create($item, $user, $reason) {
return mysql_insert_id($db_connection);
}
- public static function exists($item) {
+ public static function exists($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ return mysql_num_rows($db_result) > 0;
+ }
+
+ public static function existsItem($item) {
$db_connection = db_ensure_connection();
$item = mysql_real_escape_string($item, $db_connection);
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
index 4fc4140..71942df 100644
--- a/stdlib/candidates/create.php
+++ b/stdlib/candidates/create.php
@@ -32,8 +32,9 @@
throw new HttpException(409, NULL, 'This item is already in the stdlib or pending for future inclusion.');
}
- if (Candidate::exists($item)) {
- $status = Candidate::accepted($item);
+ if (Candidate::existsItem($item)) {
+ $id = Candidate::getId($item);
+ $status = Candidate::accepted($id);
if ($status === FALSE) { # previously rejected
if (!User::hasPrivilege($_SERVER['PHP_AUTH_USER'], User::PRIVILEGE_STDLIB)) { # reject unless privilege stdlib
throw new HttpException(403, NULL, 'This item has been refused earlier. Only members of the stdlib team can make it a candidate again!');
From 75861cae2e869eea92ba9577c6c1fcad8461dc5a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 15:11:57 +0100
Subject: [PATCH 119/241] add checks in case a candidate is not found
---
stdlib/candidates/Candidate.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index e4a0862..d30a912 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -58,6 +58,9 @@ public static function getId($item) {
if ($db_result === FALSE) {
throw new HttpException(500);
}
+ if (mysql_num_rows($db_result) < 1) {
+ throw new HttpException(404);
+ }
$t = mysql_fetch_assoc($db_result);
return $t['id'];
@@ -72,6 +75,9 @@ public static function getUser($id) {
if ($db_result === FALSE) {
throw new HttpException(500);
}
+ if (mysql_num_rows($db_result) < 1) {
+ throw new HttpException(404);
+ }
$t = mysql_fetch_assoc($db_result);
return $t['user'];
@@ -86,6 +92,9 @@ public static function getItem($id) {
if ($db_result === FALSE) {
throw new HttpException(500);
}
+ if (mysql_num_rows($db_result) < 1) {
+ throw new HttpException(404);
+ }
$t = mysql_fetch_assoc($db_result);
return $t['item'];
From 5a921d5560f6bcaae8f2fb8ee207dd9c5d25165d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 15:13:16 +0100
Subject: [PATCH 120/241] Add DB column and method for approval
---
MySQL/DB_TABLE_CANDIDATES.sql | 1 +
stdlib/candidates/Candidate.php | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/MySQL/DB_TABLE_CANDIDATES.sql b/MySQL/DB_TABLE_CANDIDATES.sql
index 2bd8be8..8d53171 100644
--- a/MySQL/DB_TABLE_CANDIDATES.sql
+++ b/MySQL/DB_TABLE_CANDIDATES.sql
@@ -13,6 +13,7 @@ CREATE TABLE IF NOT EXISTS `candidates` (
`user` binary(16) NOT NULL,
`reason` text NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `approval` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index d30a912..212cada 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -66,6 +66,17 @@ public static function getId($item) {
return $t['id'];
}
+ public static function approve($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'UPDATE ' . DB_TABLE_CANDIDATES . ' SET `approval` = NOW() WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+ }
+
public static function getUser($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
From c188c85881796b376896ae4f2247ab21afb4d581 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 16:01:48 +0100
Subject: [PATCH 121/241] implement method for acception status retrieval
---
stdlib/candidates/Candidate.php | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 212cada..5c1f302 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -45,8 +45,31 @@ public static function existsItem($item) {
return mysql_num_rows($db_result) > 0;
}
- public static function accepted($item) {
- # ... todo ...
+ public static function accepted($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT COUNT(*) AS count, `final`, `accept` FROM ' . DB_TABLE_CANDIDATE_RATING . ' WHERE `candidate` = ' . $id . ' GROUP BY `final`, `accept`';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ $accept = array();
+ while ($row = mysql_fetch_assoc($db_result)) {
+ if ($row['final'])
+ return $row['accept']; # final decisions overwrite everything else (there must only be one of them)
+ $accept[$row['accept']] = $row['count'];
+ }
+ if (CANDIDATE_ALWAYS_REQUIRE_FINAL)
+ return NULL; # if there had been a final, it would already have exited the loop
+
+ if ($accept[true] >= CANDIDATE_MIN_ACCEPTS && $accept[false] == 0 && !CANDIDATE_ACCEPT_REQUIRE_FINAL)
+ return true; # accepted based on the current (non-final) accepts
+ else if ($accept[false] >= CANDIDATE_MIN_REJECTS && $accept[true] == 0 && !CANDIDATE_REJECT_REQUIRE_FINAL)
+ return false; # rejected based on the current (no-final) rejects
+
+ return NULL; # must still be open
}
public static function getId($item) {
From 8f39cf34cbeddc436b644cc108fc3496f2863541 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 16:16:19 +0100
Subject: [PATCH 122/241] add a method for checking if candidate has been
approved
---
stdlib/candidates/Candidate.php | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 5c1f302..3fc4060 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -100,6 +100,23 @@ public static function approve($id) {
}
}
+ public static function isApproved($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT (`approval` IS NOT NULL) AS approved FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) < 1) {
+ throw new HttpException(404);
+ }
+
+ $t = mysql_fetch_assoc($db_result);
+ return $t['approved'];
+ }
+
public static function getUser($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
From 513e9f438494a1d849293b25c7968db0ac3067f6 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 16:31:11 +0100
Subject: [PATCH 123/241] Add missing config file required for
Candidate::accepted()
---
config/stdlib.php | 22 ++++++++++++++++++++++
stdlib/candidates/Candidate.php | 1 +
2 files changed, 23 insertions(+)
create mode 100644 config/stdlib.php
diff --git a/config/stdlib.php b/config/stdlib.php
new file mode 100644
index 0000000..aa1fc45
--- /dev/null
+++ b/config/stdlib.php
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 3fc4060..fd3337b 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -1,6 +1,7 @@
Date: Fri, 1 Mar 2013 16:34:18 +0100
Subject: [PATCH 124/241] Begin API method for candidate approval
---
stdlib/candidates/approve.php | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 stdlib/candidates/approve.php
diff --git a/stdlib/candidates/approve.php b/stdlib/candidates/approve.php
new file mode 100644
index 0000000..a11ec10
--- /dev/null
+++ b/stdlib/candidates/approve.php
@@ -0,0 +1,29 @@
+getMessage()));
+}
+?>
\ No newline at end of file
From 3b9561e579a6b623df0ec4deb91e1245e50ca487 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 16:40:52 +0100
Subject: [PATCH 125/241] implement StdlibPending::AddEntry()
---
stdlib/StdlibPending.php | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index ab1612d..a233c9b 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -79,8 +79,17 @@ public static function GetEntries($release) {
return $libs;
}
- public static function AddEntry($id)
+ public static function AddEntry($id, $comment)
{
+ $db_connection = db_ensure_connection();
+ $id = mysql_real_escape_string($id, $db_connection);
+ $comment = mysql_real_escape_string($comment, $db_connection);
+
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_PENDING . ' (`lib`, `comment`) VALUES (UNHEX("' . $id . '"), "' . $comment . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
}
public static function DeleteEntry($id)
From d8f7fee14c61d8ba1b5f7c892bec1fa9bc499426 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 16:43:44 +0100
Subject: [PATCH 126/241] Use new StdlibPending method when a candidate is
accepted and approved
---
stdlib/candidates/approve.php | 3 ++-
stdlib/candidates/rating.php | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/stdlib/candidates/approve.php b/stdlib/candidates/approve.php
index a11ec10..20fba75 100644
--- a/stdlib/candidates/approve.php
+++ b/stdlib/candidates/approve.php
@@ -5,6 +5,7 @@
require_once('../../User.php');
require_once('../../Item.php');
require_once('Candidate.php');
+require_once('../StdlibPending.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
@@ -18,7 +19,7 @@
Candidate::approve($_GET['id']);
if (Candidate::accepted($_GET['id'])) {
- Candidate::makePending($_GET['id']);
+ StdlibPending::AddEntry(Candidate::getItem($_GET['id']), '');
}
} catch (HttpException $e) {
diff --git a/stdlib/candidates/rating.php b/stdlib/candidates/rating.php
index 54dd5de..9c1c194 100644
--- a/stdlib/candidates/rating.php
+++ b/stdlib/candidates/rating.php
@@ -4,6 +4,7 @@
require_once('../../Assert.php');
require_once('../../User.php');
require_once('Candidate.php');
+require_once('../StdlibPending.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_POST, Assert::REQUEST_METHOD_GET);
@@ -25,6 +26,10 @@
Candidate::rate($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']), $_GET['mode'] == 'accept', $_POST['reason'], $final);
+ if (Candidate::accepted($_GET['id']) && Candidate::isApproved($_GET['id'])) {
+ StdlibPending::AddEntry(Candidate::getItem($_GET['id']), '');
+ }
+
} else {
Assert::GetParameters('id');
# ...
From 1fc680b1aa0850629fc788906bdf5ea31b8b1b52 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 23:18:45 +0100
Subject: [PATCH 127/241] Some more restrictions on candidate rating
Do not allow rating of closed candidates.
Do not allow several ratings by the same user.
---
MySQL/DB_TABLE_CANDIDATE_RATING.sql | 5 +++--
stdlib/candidates/Candidate.php | 14 ++++++++++++++
stdlib/candidates/rating.php | 10 ++++++++++
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/MySQL/DB_TABLE_CANDIDATE_RATING.sql b/MySQL/DB_TABLE_CANDIDATE_RATING.sql
index f680fd8..da3f447 100644
--- a/MySQL/DB_TABLE_CANDIDATE_RATING.sql
+++ b/MySQL/DB_TABLE_CANDIDATE_RATING.sql
@@ -7,7 +7,7 @@ SET time_zone = "+00:00";
/*!40101 SET NAMES utf8 */;
-CREATE TABLE IF NOT EXISTS `candidate-rating` (
+CREATE TABLE IF NOT EXISTS `candidate_rating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`candidate` int(11) NOT NULL,
`user` binary(16) NOT NULL,
@@ -15,7 +15,8 @@ CREATE TABLE IF NOT EXISTS `candidate-rating` (
`final` tinyint(1) NOT NULL DEFAULT '0',
`reason` text NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`)
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `rating` (`candidate`,`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index fd3337b..ca75d30 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -178,5 +178,19 @@ public static function rate($candidate, $user, $accept, $reason, $final = false)
throw new HttpException(500);
}
}
+
+ public static function hasRated($id, $user) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+ $user = mysql_real_escape_string($user, $db_connection);
+
+ $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATE_RATING . ' WHERE `user` = UNHEX("' . $user . '") AND `candidate` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ return mysql_num_rows($db_result) > 0;
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/candidates/rating.php b/stdlib/candidates/rating.php
index 9c1c194..7831d84 100644
--- a/stdlib/candidates/rating.php
+++ b/stdlib/candidates/rating.php
@@ -24,6 +24,16 @@
throw new HttpException(403, NULL, 'Only stdlib admins can make a final decision.');
}
+ # reject if same user already rated
+ if (Candidate::hasRated($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']))) {
+ throw new HttpException(403, NULL, 'You cannot rate the same candidate twice.');
+ }
+
+ # reject if already closed
+ if (Candidate::accepted($_GET['id']) != NULL) {
+ throw new HttpException(403, NULL, 'Cannot rate a candidate that has already been accepted or rejected.');
+ }
+
Candidate::rate($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']), $_GET['mode'] == 'accept', $_POST['reason'], $final);
if (Candidate::accepted($_GET['id']) && Candidate::isApproved($_GET['id'])) {
From f28a8ccd788305298c5235178441328ae816ce16 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 23:27:18 +0100
Subject: [PATCH 128/241] Rename candidate "rating" to "voting"
---
...DIDATE_RATING.sql => DB_TABLE_CANDIDATE_VOTING.sql} | 4 ++--
config/database.php | 2 +-
stdlib/candidates/.htaccess | 4 ++--
stdlib/candidates/Candidate.php | 10 +++++-----
stdlib/candidates/{rating.php => voting.php} | 10 +++++-----
5 files changed, 15 insertions(+), 15 deletions(-)
rename MySQL/{DB_TABLE_CANDIDATE_RATING.sql => DB_TABLE_CANDIDATE_VOTING.sql} (90%)
rename stdlib/candidates/{rating.php => voting.php} (84%)
diff --git a/MySQL/DB_TABLE_CANDIDATE_RATING.sql b/MySQL/DB_TABLE_CANDIDATE_VOTING.sql
similarity index 90%
rename from MySQL/DB_TABLE_CANDIDATE_RATING.sql
rename to MySQL/DB_TABLE_CANDIDATE_VOTING.sql
index da3f447..67f43aa 100644
--- a/MySQL/DB_TABLE_CANDIDATE_RATING.sql
+++ b/MySQL/DB_TABLE_CANDIDATE_VOTING.sql
@@ -7,7 +7,7 @@ SET time_zone = "+00:00";
/*!40101 SET NAMES utf8 */;
-CREATE TABLE IF NOT EXISTS `candidate_rating` (
+CREATE TABLE IF NOT EXISTS `candidate_voting` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`candidate` int(11) NOT NULL,
`user` binary(16) NOT NULL,
@@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS `candidate_rating` (
`reason` text NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
- UNIQUE KEY `rating` (`candidate`,`user`)
+ UNIQUE KEY `voting` (`candidate`,`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/config/database.php b/config/database.php
index 96dc9fc..984f887 100644
--- a/config/database.php
+++ b/config/database.php
@@ -14,7 +14,7 @@
define('DB_TABLE_STDLIB_ACTIONS', 'stdlib_actions'); #
define('DB_TABLE_CANDIDATES', 'candidates'); #
- define('DB_TABLE_CANDIDATE_RATING', 'candidate_rating'); #
+ define('DB_TABLE_CANDIDATE_VOTING', 'candidate_voting'); #
define('DB_TABLE_REGISTRATION', 'registration'); #
define('DB_TABLE_TYPES', 'types'); #
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
index 9a270ef..a0c059b 100644
--- a/stdlib/candidates/.htaccess
+++ b/stdlib/candidates/.htaccess
@@ -4,7 +4,7 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^(rating|approve)/(\d+)$ $1.php?id=$2 [L]
-RewriteRule ^(reject|accept)/(\d+)$ rating.php?id=$2&mode=$1 [L]
+RewriteRule ^(voting|approve)/(\d+)$ $1.php?id=$2 [L]
+RewriteRule ^(reject|accept)/(\d+)$ voting.php?id=$2&mode=$1 [L]
RewriteRule ^create/([0-9a-fA-F]{32})$ create.php?id=$1 [L]
RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index ca75d30..308c717 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -50,7 +50,7 @@ public static function accepted($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
- $db_query = 'SELECT COUNT(*) AS count, `final`, `accept` FROM ' . DB_TABLE_CANDIDATE_RATING . ' WHERE `candidate` = ' . $id . ' GROUP BY `final`, `accept`';
+ $db_query = 'SELECT COUNT(*) AS count, `final`, `accept` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $id . ' GROUP BY `final`, `accept`';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
@@ -163,7 +163,7 @@ public static function listCandidates() {
return sql2array($db_result);
}
- public static function rate($candidate, $user, $accept, $reason, $final = false) {
+ public static function vote($candidate, $user, $accept, $reason, $final = false) {
$db_connection = db_ensure_connection();
$candidate = mysql_real_escape_string($candidate, $db_connection);
@@ -172,19 +172,19 @@ public static function rate($candidate, $user, $accept, $reason, $final = false)
$accept = $accept ? 'TRUE' : 'FALSE';
$final = $final ? 'TRUE' : 'FALSE';
- $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATE_RATING . ' (`candidate`, `user`, `accept`, `final`, `reason`) VALUES (' . $candidate . ', UNHEX("' . $user . '"), ' . $accept . ', ' . $final . ', "' . $reason . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATE_VOTING . ' (`candidate`, `user`, `accept`, `final`, `reason`) VALUES (' . $candidate . ', UNHEX("' . $user . '"), ' . $accept . ', ' . $final . ', "' . $reason . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
}
}
- public static function hasRated($id, $user) {
+ public static function hasVoted($id, $user) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
$user = mysql_real_escape_string($user, $db_connection);
- $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATE_RATING . ' WHERE `user` = UNHEX("' . $user . '") AND `candidate` = ' . $id;
+ $db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `user` = UNHEX("' . $user . '") AND `candidate` = ' . $id;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/rating.php b/stdlib/candidates/voting.php
similarity index 84%
rename from stdlib/candidates/rating.php
rename to stdlib/candidates/voting.php
index 7831d84..fb88af8 100644
--- a/stdlib/candidates/rating.php
+++ b/stdlib/candidates/voting.php
@@ -24,17 +24,17 @@
throw new HttpException(403, NULL, 'Only stdlib admins can make a final decision.');
}
- # reject if same user already rated
- if (Candidate::hasRated($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']))) {
- throw new HttpException(403, NULL, 'You cannot rate the same candidate twice.');
+ # reject if same user already voted
+ if (Candidate::hasVoted($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']))) {
+ throw new HttpException(403, NULL, 'You cannot vote the same candidate twice.');
}
# reject if already closed
if (Candidate::accepted($_GET['id']) != NULL) {
- throw new HttpException(403, NULL, 'Cannot rate a candidate that has already been accepted or rejected.');
+ throw new HttpException(403, NULL, 'Cannot vote a candidate that has already been accepted or rejected.');
}
- Candidate::rate($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']), $_GET['mode'] == 'accept', $_POST['reason'], $final);
+ Candidate::vote($_GET['id'], User::getId($_SERVER['PHP_AUTH_USER']), $_GET['mode'] == 'accept', $_POST['reason'], $final);
if (Candidate::accepted($_GET['id']) && Candidate::isApproved($_GET['id'])) {
StdlibPending::AddEntry(Candidate::getItem($_GET['id']), '');
From f08608a8e6ddfce9381bdc07c7d0ab536b42bbf1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 1 Mar 2013 23:40:07 +0100
Subject: [PATCH 129/241] implement retrieval of candidate votes
---
stdlib/candidates/Candidate.php | 13 +++++++++++++
stdlib/candidates/voting.php | 17 ++++++++++++++++-
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 308c717..d65c846 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -163,6 +163,19 @@ public static function listCandidates() {
return sql2array($db_result);
}
+ public static function listVotings($candidate) {
+ $db_connection = db_ensure_connection();
+ $candidate = (int)mysql_real_escape_string($candidate, $db_connection);
+
+ $db_query = 'SELECT `candidate`, HEX(`user`) AS user, `accept`, `final`, `reason`, `date` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $candidate;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+
+ return sql2array($db_result);
+ }
+
public static function vote($candidate, $user, $accept, $reason, $final = false) {
$db_connection = db_ensure_connection();
diff --git a/stdlib/candidates/voting.php b/stdlib/candidates/voting.php
index fb88af8..263aba9 100644
--- a/stdlib/candidates/voting.php
+++ b/stdlib/candidates/voting.php
@@ -42,7 +42,22 @@
} else {
Assert::GetParameters('id');
- # ...
+ $content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
+
+ $votings = Candidate::listVotings($_GET['id']);
+ if ($content_type == 'application/json') {
+ $content = json_encode($votings);
+ } else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
+ $content = '';
+ foreach ($votings AS $voting) {
+ $content .= '';
+ }
+ $content .= '';
+ }
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-type: ' . $content_type);
+ echo $content;
+ exit;
}
} catch (HttpException $e) {
From 891843f3431f3cb2e25cbf28cbc43022e2aacc8e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 2 Mar 2013 17:30:32 +0100
Subject: [PATCH 130/241] begin candidate description API
---
stdlib/candidates/.htaccess | 2 +-
stdlib/candidates/Candidate.php | 16 ++++++++++++++++
stdlib/candidates/describe.php | 32 ++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 1 deletion(-)
create mode 100644 stdlib/candidates/describe.php
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
index a0c059b..9d756c8 100644
--- a/stdlib/candidates/.htaccess
+++ b/stdlib/candidates/.htaccess
@@ -4,7 +4,7 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^(voting|approve)/(\d+)$ $1.php?id=$2 [L]
+RewriteRule ^(voting|approve|describe)/(\d+)$ $1.php?id=$2 [L]
RewriteRule ^(reject|accept)/(\d+)$ voting.php?id=$2&mode=$1 [L]
RewriteRule ^create/([0-9a-fA-F]{32})$ create.php?id=$1 [L]
RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
\ No newline at end of file
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index d65c846..2bc6195 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -20,6 +20,22 @@ public static function create($item, $user, $reason) {
return mysql_insert_id($db_connection);
}
+ public static function describe($id) {
+ $db_connection = db_ensure_connection();
+ $id = (int)mysql_real_escape_string($id, $db_connection);
+
+ $db_query = 'SELECT *, HEX(`item`) AS item, HEX(`user`) AS user FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500);
+ }
+ if (mysql_num_rows($db_result) < 1) {
+ throw new HttpException(404);
+ }
+
+ return mysql_fetch_assoc($db_result);
+ }
+
public static function exists($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
diff --git a/stdlib/candidates/describe.php b/stdlib/candidates/describe.php
new file mode 100644
index 0000000..e96e7a4
--- /dev/null
+++ b/stdlib/candidates/describe.php
@@ -0,0 +1,32 @@
+ $v) {
+ $content .= ' ald:' . $key . '="' . $v . '"';
+ }
+ $content .= '/>';
+ }
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-type: ' . $content_type);
+ echo $content;
+ exit;
+
+} catch (HttpException $e) {
+ handleHttpException($e);
+} catch (Exception $e) {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+}
+?>
\ No newline at end of file
From c6c27f2a71ace0bc3fbff36080e5925bdf65d63f Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 2 Mar 2013 22:59:13 +0100
Subject: [PATCH 131/241] begin supporting filters for candidate list
---
stdlib/candidates/Candidate.php | 30 ++++++++++++++++++++++++++++--
stdlib/candidates/list.php | 2 +-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 2bc6195..715c0d0 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -168,9 +168,35 @@ public static function getItem($id) {
return $t['item'];
}
- public static function listCandidates() {
+ public static function listCandidates($filters = array()) {
+ if (!is_array($filters)) {
+ throw new Exception('Must provide a valid array as candidate filter');
+ }
$db_connection = db_ensure_connection();
- $db_query = 'SELECT `id`, HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES; # todo: include status + approval
+ $db_cond = '';
+
+ foreach (array('item', 'user') AS $field) { # filter binary fields
+ if (isset($filters[$field])) {
+ $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`' . $field . '` = UNHEX("' . mysql_real_escape_string($filters[$field], $db_connection) . '")';
+ }
+ }
+
+ foreach (array('created' => '=', 'created-after' => '>', 'created-before' => '<') AS $field => $op) { # filter creation date
+ if (isset($filters[$field])) {
+ $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`date` ' . $op . ' "' . mysql_real_escape_string($filters[$field], $db_connection) . '"';
+ }
+ }
+
+ if (isset($filters['approved'])) {
+ if (in_array($filters['approved'], array(1, '+1', 'yes', 'true'))) {
+ $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`approval` IS NOT NULL';
+ } else if (in_array($filters['approved'], array(-1, 'no', 'false'))) {
+ $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`approval` IS NULL';
+ }
+ # else if (in_array($filters['approved'], array(0, 'both'))) - the default
+ }
+
+ $db_query = 'SELECT `id`, HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 314f108..6b37927 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -9,7 +9,7 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $candidates = Candidate::listCandidates();
+ $candidates = Candidate::listCandidates(array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved'))));
if ($content_type == 'application/json') {
$content = json_encode($candidates);
From 0ad75be5b2a7567b54c90c8f59d2d783da5806ca Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 13:54:36 +0100
Subject: [PATCH 132/241] fix incorrect error check (copy-paste error)
---
stdlib/Stdlib.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index b462eac..3afd9e1 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -113,7 +113,7 @@ public static function releaseHasItem($release, $id) {
$db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $release . '" AND `lib` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ if ($db_result === FALSE) {
throw new HttpException(500);
}
From 31e266d3cf492c5f88b11320fe25e181808caf69 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 13:55:00 +0100
Subject: [PATCH 133/241] fix StdlibPending SQL syntax error
---
stdlib/StdlibPending.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index a233c9b..e464ace 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -109,7 +109,7 @@ public static function IsPending($id) {
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `lib` = UNHEX"' . $id . '")';
+ $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `lib` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
From 09becc882dad2447a19352fae7c83a595178da39 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:08:46 +0100
Subject: [PATCH 134/241] fix missing content negotiation
---
stdlib/candidates/describe.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/stdlib/candidates/describe.php b/stdlib/candidates/describe.php
index e96e7a4..a48d127 100644
--- a/stdlib/candidates/describe.php
+++ b/stdlib/candidates/describe.php
@@ -8,6 +8,8 @@
Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
Assert::GetParameters('id');
+ $content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
+
$candidate = Candidate::describe($_GET['id']);
if ($content_type == 'application/json') {
From fc80300ab96096ef7bece80d22e838de1eeb7a22 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:09:55 +0100
Subject: [PATCH 135/241] fix incorrect variable name
---
stdlib/candidates/describe.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/candidates/describe.php b/stdlib/candidates/describe.php
index a48d127..7846f10 100644
--- a/stdlib/candidates/describe.php
+++ b/stdlib/candidates/describe.php
@@ -17,7 +17,7 @@
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
$content = ' $v) {
- $content .= ' ald:' . $key . '="' . $v . '"';
+ $content .= ' ald:' . $k . '="' . $v . '"';
}
$content .= '/>';
}
From 7f77003bfc4a3f10141727f9811c3fc7f5f259ca Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:16:34 +0100
Subject: [PATCH 136/241] methods without output: return status code 204
---
stdlib/candidates/approve.php | 3 +++
stdlib/candidates/voting.php | 3 +++
2 files changed, 6 insertions(+)
diff --git a/stdlib/candidates/approve.php b/stdlib/candidates/approve.php
index 20fba75..e30903c 100644
--- a/stdlib/candidates/approve.php
+++ b/stdlib/candidates/approve.php
@@ -22,6 +22,9 @@
StdlibPending::AddEntry(Candidate::getItem($_GET['id']), '');
}
+ header('HTTP/1.1 204 ' . HttpException::getStatusMessage(204));
+ exit;
+
} catch (HttpException $e) {
handleHttpException($e);
} catch (Exception $e) {
diff --git a/stdlib/candidates/voting.php b/stdlib/candidates/voting.php
index 263aba9..1e9e466 100644
--- a/stdlib/candidates/voting.php
+++ b/stdlib/candidates/voting.php
@@ -40,6 +40,9 @@
StdlibPending::AddEntry(Candidate::getItem($_GET['id']), '');
}
+ header('HTTP/1.1 204 ' . HttpException::getStatusMessage(204));
+ exit;
+
} else {
Assert::GetParameters('id');
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
From 5ed674d90ba99b4ba11920135334ae3e3c6cb03a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:27:00 +0100
Subject: [PATCH 137/241] valid XML - corresponds to 88f99ff71bd2
---
stdlib/releases/create.php | 2 +-
stdlib/releases/list.php | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 077cfa7..56e09c0 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -109,7 +109,7 @@
}
else if ($content_type == "text/xml" || $content_type == "application/xml")
{
- $content = "$release";
+ $content = "" . htmlspecialchars($release, ENT_QUOTES) . '';
}
header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
header("Content-type: $content_type");
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index f47ba6c..095bd1e 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -38,10 +38,10 @@
}
else if ($content_type == "text/xml" || $content_type == "application/xml")
{
- $content = "";
+ $content = "";
foreach ($releases AS $release)
{
- $content .= "";
+ $content .= '';
}
$content .= "";
}
From e5f0e96e1bc611f7687186ab82976ebf049b34a8 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:27:41 +0100
Subject: [PATCH 138/241] valid XML - corresponds to 88f99ff71bd2
---
stdlib/candidates/create.php | 2 +-
stdlib/candidates/describe.php | 4 ++--
stdlib/candidates/list.php | 4 ++--
stdlib/candidates/voting.php | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
index 71942df..f6723ad 100644
--- a/stdlib/candidates/create.php
+++ b/stdlib/candidates/create.php
@@ -52,7 +52,7 @@
if ($content_type == 'application/json') {
$content = json_encode(array('candidate' => $candidate));
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
- $content = '' . $candidate . '';
+ $content = '' . htmlspecialchars($candidate, ENT_QUOTES) . '';
}
header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
header('Content-type: ' . $content_type);
diff --git a/stdlib/candidates/describe.php b/stdlib/candidates/describe.php
index 7846f10..f9d6e4d 100644
--- a/stdlib/candidates/describe.php
+++ b/stdlib/candidates/describe.php
@@ -15,9 +15,9 @@
if ($content_type == 'application/json') {
$content = json_encode($candidate);
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
- $content = ' $v) {
- $content .= ' ald:' . $k . '="' . $v . '"';
+ $content .= ' ald:' . $k . '="' . htmlspecialchars($v, ENT_QUOTES) . '"';
}
$content .= '/>';
}
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 6b37927..8a3330d 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -14,9 +14,9 @@
if ($content_type == 'application/json') {
$content = json_encode($candidates);
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
- $content = '';
+ $content = '';
foreach ($candidates AS $candidate) {
- $content .= '';
+ $content .= '';
}
$content .= '';
}
diff --git a/stdlib/candidates/voting.php b/stdlib/candidates/voting.php
index 1e9e466..c474bf3 100644
--- a/stdlib/candidates/voting.php
+++ b/stdlib/candidates/voting.php
@@ -51,9 +51,9 @@
if ($content_type == 'application/json') {
$content = json_encode($votings);
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
- $content = '';
+ $content = '';
foreach ($votings AS $voting) {
- $content .= '';
+ $content .= '';
}
$content .= '';
}
From 19b92b37ba2524bd8daa9274a9c766569410cae0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:44:04 +0100
Subject: [PATCH 139/241] implement release description XML output
---
stdlib/releases/describe.php | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 222f5b1..0892b26 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -57,7 +57,19 @@
}
else if ($content_type == "text/xml" || $content_type == "application/xml")
{
- throw new HttpException(501);
+ $content = '';
+ foreach ($release['libs'] AS $lib) {
+ $content .= '';
+ }
+ $content .= '';
+ foreach ($release['changelog'] AS $item => $text) {
+ $content .= '';
+ }
+ $content .= '';
}
header("HTTP/1.1 200 " . HttpException::getStatusMessage(200));
From 604a2521cf4232159c5e3085961ec6f5ef0359c2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 14:50:37 +0100
Subject: [PATCH 140/241] minor bug fix: release "published" status is boolean,
not integer
---
stdlib/releases/StdlibRelease.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index fabc5c7..803bd88 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -68,7 +68,9 @@ public static function describe($release, $published)
{
throw new HttpException(404);
}
- return mysql_fetch_assoc($db_result);
+ $t = mysql_fetch_assoc($db_result);
+ $t['published'] = (bool)$t['published'];
+ return $t;
}
public static function create($release, $date = NULL, $description = '') {
From 21e575c941d6e26fe049c86147ae4d8748e3d65b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 15:04:00 +0100
Subject: [PATCH 141/241] candidate approval: reject if already approved
---
stdlib/candidates/Candidate.php | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 715c0d0..5784c6e 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -110,11 +110,14 @@ public static function approve($id) {
$db_connection = db_ensure_connection();
$id = (int)mysql_real_escape_string($id, $db_connection);
- $db_query = 'UPDATE ' . DB_TABLE_CANDIDATES . ' SET `approval` = NOW() WHERE `id` = ' . $id;
+ $db_query = 'UPDATE ' . DB_TABLE_CANDIDATES . ' SET `approval` = NOW() WHERE `approval` IS NULL AND `id` = ' . $id;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
}
+ if (mysql_affected_rows() < 1) {
+ throw new HttpException(400);
+ }
}
public static function isApproved($id) {
From 69d311e36d1dcdd5b26de4f3b16a367a1f627934 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 16:01:54 +0100
Subject: [PATCH 142/241] one more boolean fix: this time candidate voting list
---
stdlib/candidates/Candidate.php | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 5784c6e..32ea461 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -204,7 +204,6 @@ public static function listCandidates($filters = array()) {
if ($db_result === FALSE) {
throw new HttpException(500);
}
-
return sql2array($db_result);
}
@@ -218,7 +217,12 @@ public static function listVotings($candidate) {
throw new HttpException(500);
}
- return sql2array($db_result);
+ return sql2array($db_result, array('Candidate', '_cleanup_voting'));
+ }
+ static function _cleanup_voting($item, $key) {
+ $item['accept'] = (bool)$item['accept'];
+ $item['final'] = (bool)$item['final'];
+ return $item;
}
public static function vote($candidate, $user, $accept, $reason, $final = false) {
From fb7dd08f5e06150e93da7e5afaa9c6720186e696 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 16:36:51 +0100
Subject: [PATCH 143/241] implement planned candidate listing filters
Implement 'owner' filter as SQL condition,
the rest is done in PHP after the results are read.
---
stdlib/candidates/Candidate.php | 8 +++++-
stdlib/candidates/list.php | 47 ++++++++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 32ea461..39f9154 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -177,6 +177,7 @@ public static function listCandidates($filters = array()) {
}
$db_connection = db_ensure_connection();
$db_cond = '';
+ $db_join = '';
foreach (array('item', 'user') AS $field) { # filter binary fields
if (isset($filters[$field])) {
@@ -199,7 +200,12 @@ public static function listCandidates($filters = array()) {
# else if (in_array($filters['approved'], array(0, 'both'))) - the default
}
- $db_query = 'SELECT `id`, HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_cond;
+ if (isset($filters['owner'])) {
+ $db_join = ' LEFT JOIN ' . DB_TABLE_ITEMS . ' ON ' . DB_TABLE_CANDIDATES . '.`item` = ' . DB_TABLE_ITEMS . '.`id`';
+ $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . DB_TABLE_ITEMS . '.`user` = UNHEX("' . mysql_real_escape_string($filters['owner'], $db_connection) . '")';
+ }
+
+ $db_query = 'SELECT ' . DB_TABLE_CANDIDATES . '.`id`, HEX(' . DB_TABLE_CANDIDATES. '.`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_join . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 8a3330d..1ac5618 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -9,7 +9,52 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $candidates = Candidate::listCandidates(array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved'))));
+ $candidates = Candidate::listCandidates(array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner'))));
+
+ $filtered_candidates = array();
+ $status_map = array('accepted' => true, 'open' => NULL, 'rejected' => false);
+
+ foreach ($candidates AS $candidate) {
+ if (isset($_GET['status'])) {
+ if (!in_array($_GET['status'], array_keys($status_map))) {
+ throw new HttpException(400);
+ }
+
+ $status = Candidate::accepted($candidate['id']);
+ if ($status_map[$_GET['status']] !== $status) {
+ continue;
+ }
+ }
+
+ if (isset($_GET['accepted-by']) || isset($_GET['rejected-by'])) {
+ $user = isset($_GET['accepted-by']) ? $_GET['accepted-by'] : $_GET['rejected-by'];
+ if (!Candidate::hasVoted($candidate['id'], $user)) {
+ continue;
+ }
+
+ $votings = Candidate::listVotings($candidate['id']);
+ if (searchSubArray($votings, array('user' => $user, 'accept' => isset($_GET['accepted-by']))) === NULL) {
+ continue;
+ }
+ }
+
+ if (isset($_GET['accepted']) || isset($_GET['accepted-min']) || isset($_GET['accepted-max']) || isset($_GET['rejected']) || isset($_GET['rejected-min']) || isset($_GET['rejected-max'])) {
+ $votings = Candidate::listVotings($candidate['id']);
+ $count = count($votings);
+
+ if (isset($_GET['accepted']) && $count != (int)$_GET['accepted']
+ || isset($_GET['accepted-min']) && $count < (int)$_GET['accepted-min']
+ || isset($_GET['accepted-max']) && $count > (int)$_GET['accepted-max']
+ || isset($_GET['rejected']) && $count != (int)$_GET['rejected']
+ || isset($_GET['rejected-min']) && $count < (int)$_GET['rejected-min']
+ || isset($_GET['rejected-max']) && $count > (int)$_GET['rejected-max']) {
+ continue;
+ }
+ }
+
+ $filtered_candidates[] = $candidate;
+ }
+ $candidates = $filtered_candidates;
if ($content_type == 'application/json') {
$content = json_encode($candidates);
From c9583a5cdd55963c5b932daa366c2380b66952a6 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 17:23:53 +0100
Subject: [PATCH 144/241] Add API to list items in all releases
---
stdlib/items.php | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 stdlib/items.php
diff --git a/stdlib/items.php b/stdlib/items.php
new file mode 100644
index 0000000..1a405e2
--- /dev/null
+++ b/stdlib/items.php
@@ -0,0 +1,72 @@
+';
+ foreach ($items AS $name => $versions) {
+ $content .= '';
+ foreach ($versions AS $version) {
+ $content .= '';
+ foreach ($version['releases'] AS $release) {
+ $content .= '' . htmlspecialchars($release, ENT_QUOTES) . '';
+ }
+ $content .= '';
+ }
+ $content .= '';
+ }
+ $content .= '';
+ }
+
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-type: ' . $content_type);
+ echo $content;
+ exit;
+
+} catch (HttpException $e) {
+ handleHttpException($e);
+} catch (Exception $e) {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+}
+?>
\ No newline at end of file
From c0b18448322cc376d276089df95b7114b1c8fe3c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 17:35:40 +0100
Subject: [PATCH 145/241] candidate voting API: only redirect matching request
methods
---
stdlib/candidates/.htaccess | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
index 9d756c8..04cca09 100644
--- a/stdlib/candidates/.htaccess
+++ b/stdlib/candidates/.htaccess
@@ -4,7 +4,12 @@ RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^(voting|approve|describe)/(\d+)$ $1.php?id=$2 [L]
-RewriteRule ^(reject|accept)/(\d+)$ voting.php?id=$2&mode=$1 [L]
+RewriteRule ^(approve|describe)/(\d+)$ $1.php?id=$2 [L]
RewriteRule ^create/([0-9a-fA-F]{32})$ create.php?id=$1 [L]
-RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
\ No newline at end of file
+RewriteRule ^create/(.+)/(.+)$ create.php?name=$1&version=$2 [L]
+
+RewriteCond %{REQUEST_METHOD} =POST [NC]
+RewriteRule ^(reject|accept)/(\d+)$ voting.php?id=$2&mode=$1 [L]
+
+RewriteCond %{REQUEST_METHOD} =GET [NC]
+RewriteRule ^voting/(\d+)$ voting.php?id=$1 [L]
\ No newline at end of file
From 2356cad286d4c3171afa409c8c6ddeb1db0a5990 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 21:55:05 +0100
Subject: [PATCH 146/241] Add missing .htaccess for new stdlib API method
Should have gone into c9583a5cdd.
---
stdlib/.htaccess | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 stdlib/.htaccess
diff --git a/stdlib/.htaccess b/stdlib/.htaccess
new file mode 100644
index 0000000..2d02193
--- /dev/null
+++ b/stdlib/.htaccess
@@ -0,0 +1,2 @@
+RewriteEngine On
+RewriteRule ^items$ items.php [L]
\ No newline at end of file
From d890a1cec042041ad4b89447c6fbbdc91a0a0d00 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 9 Mar 2013 22:09:36 +0100
Subject: [PATCH 147/241] candidate creation: allow requests to remove an item
---
stdlib/candidates/Candidate.php | 5 +++--
stdlib/candidates/create.php | 14 +++++++++++---
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 39f9154..83d18d3 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -5,13 +5,14 @@
require_once(dirname(__FILE__) . '/../../modules/HttpException/HttpException.php');
class Candidate {
- public static function create($item, $user, $reason) {
+ public static function create($item, $user, $reason, $deletion = false) {
$db_connection = db_ensure_connection();
$item = mysql_real_escape_string($item, $db_connection);
$user = mysql_real_escape_string($user, $db_connection);
$reason = mysql_real_escape_string($reason, $db_connection);
+ $deletion = $deletion ? '0' : 'NULL';
- $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATES . ' (`item`, `user`, `reason`) VALUES (UNHEX("' . $item . '"), UNHEX("' . $user . '"), "' . $reason . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATES . ' (`item`, `user`, `reason`, `approval`) VALUES (UNHEX("' . $item . '"), UNHEX("' . $user . '"), "' . $reason . '", ' . $deletion . ')';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
index f6723ad..c1536aa 100644
--- a/stdlib/candidates/create.php
+++ b/stdlib/candidates/create.php
@@ -28,8 +28,16 @@
user_basic_auth('Restricted API');
# reject if pending or in latest published release (don't check for unpublished releases - equals pending)
- if (StdlibPending::IsPending($item) || Stdlib::releaseHasItem(StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES), $item)) {
- throw new HttpException(409, NULL, 'This item is already in the stdlib or pending for future inclusion.');
+ if (StdlibPending::IsPending($item)) {
+ throw new HttpException(409, NULL, 'This item is already pending for future inclusion.');
+ }
+
+ $deletion = false;
+ if (Stdlib::releaseHasItem(StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES), $item)) {
+ if (!isset($_POST['delete']) || !in_array($_POST['delete'], array('1', 'true', 'yes'))) {
+ throw new HttpException(409, NULL, 'This item is already in the stdlib.');
+ }
+ $deletion = true;
}
if (Candidate::existsItem($item)) {
@@ -46,7 +54,7 @@
}
# create DB entry
- $candidate = Candidate::create($item, User::getId($_SERVER['PHP_AUTH_USER']), $_POST['reason']);
+ $candidate = Candidate::create($item, User::getId($_SERVER['PHP_AUTH_USER']), $_POST['reason'], $deletion);
# return the ID
if ($content_type == 'application/json') {
From 27b402d04c8dc4cc801bfec450c8664280b9e661 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 10 Mar 2013 15:05:38 +0100
Subject: [PATCH 148/241] item list cleanup: remove misplaced output
Previously, the list included type and user information. Both of these
belongs into the item description, not the list. Now it's back to only
id, name and version.
---
items/list.php | 42 ++++++++++++++++--------------------------
1 file changed, 16 insertions(+), 26 deletions(-)
diff --git a/items/list.php b/items/list.php
index ae458c7..44906d7 100644
--- a/items/list.php
+++ b/items/list.php
@@ -26,30 +26,30 @@
if (isset($_GET["type"]))
{
- $db_cond = "AND type = '" . ItemType::getCode($_GET["type"]) . "'";
+ $db_cond = ($db_cond ? ' AND ' : 'WHERE '). "type = '" . ItemType::getCode($_GET["type"]) . "'";
}
if (isset($_GET["user"]))
{
- $db_cond .= " AND user = UNHEX('" . User::getID($_GET["user"]) . "')";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "user = UNHEX('" . User::getID($_GET["user"]) . "')";
}
if (isset($_GET["name"]))
{
- $db_cond .= " AND " . DB_TABLE_ITEMS . ".name = '" . mysql_real_escape_string($_GET["name"], $db_connection) . "'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE ') . DB_TABLE_ITEMS . ".name = '" . mysql_real_escape_string($_GET["name"], $db_connection) . "'";
}
if (isset($_GET["tags"]))
{
- $db_cond .= " AND tags REGEXP '(^|;)" . mysql_real_escape_string($_GET["tags"], $db_connection) . "($|;)'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "tags REGEXP '(^|;)" . mysql_real_escape_string($_GET["tags"], $db_connection) . "($|;)'";
}
# items in or not in the stdlib
# ================================ #
if (isset($_GET["stdlib"]) && in_array(strtolower($_GET["stdlib"]), array("no", "false", "-1")))
{
- $db_cond .= " AND default_include = '0'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "default_include = '0'";
}
else if (isset($_GET["stdlib"]) && in_array(strtolower($_GET["stdlib"]), array("yes", "true", "+1", "1")))
{
- $db_cond .= " AND default_include = '1'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "default_include = '1'";
}
/* else {} */ # default (use "both" or "0") - leave empty so both match
# ================================ #
@@ -58,27 +58,27 @@
# ================================ #
if (isset($_GET["reviewed"]) && in_array(strtolower($_GET["reviewed"]), array("no", "false", "-1")))
{
- $db_cond .= " AND reviewed = '0'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "reviewed = '0'";
}
else if (isset($_GET["reviewed"]) && in_array(strtolower($_GET["reviewed"]), array("both", "0")))
{
- $db_cond .= " AND (reviewed = '0' OR reviewed = '1')";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "(reviewed = '0' OR reviewed = '1')";
}
else # default (use "yes", "true", "+1" or "1")
{
- $db_cond .= " AND reviewed = '1'";
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). " reviewed = '1'";
}
# ================================ #
# filter for download count
if (isset($_GET['downloads'])) {
- $db_cond .= ' AND `downloads` = ' . (int)mysql_real_escape_string($_GET['downloads']);
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` = ' . (int)mysql_real_escape_string($_GET['downloads']);
} else {
if (isset($_GET['downloads-min'])) {
- $db_cond .= ' AND `downloads` >= ' . (int)mysql_real_escape_string($_GET['downloads-min']);
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` >= ' . (int)mysql_real_escape_string($_GET['downloads-min']);
}
if (isset($_GET['downloads-max'])) {
- $db_cond .= ' AND `downloads` <= ' . (int)mysql_real_escape_string($_GET['downloads-max']);
+ $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` <= ' . (int)mysql_real_escape_string($_GET['downloads-max']);
}
}
@@ -127,9 +127,9 @@
}
# query data
- $db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, type, HEX(" . DB_TABLE_ITEMS . ".id) AS id, version, HEX(" . DB_TABLE_ITEMS . ".user) AS userID, " . DB_TABLE_USERS . ".name AS userName"
- . " FROM " . DB_TABLE_ITEMS . ' ' . $db_join . ', ' . DB_TABLE_USERS
- . " WHERE " . DB_TABLE_ITEMS . ".user = " . DB_TABLE_USERS . ".id $db_cond $db_having $db_limit";
+ $db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, HEX(" . DB_TABLE_ITEMS . ".id) AS id, version"
+ . " FROM " . DB_TABLE_ITEMS . ' ' . $db_join
+ . " $db_cond $db_having $db_limit";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
@@ -138,7 +138,7 @@
}
# parse data to array
- $data = sql2array($db_result, 'cleanup_item');
+ $data = sql2array($db_result);
if (isset($version))
{
@@ -209,13 +209,3 @@
handleHttpException(new HttpException(500, NULL, $e->getMessage()));
}
?>
- $item["userName"], "id" => $item["userID"]);
- unset($item["userName"]);
- unset($item["userID"]);
-
- $item['type'] = ItemType::getName($item['type']);
- return $item;
-}
-?>
From 70a1218a7b8200b05156ad98360308957961a205 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 10 Mar 2013 16:17:28 +0100
Subject: [PATCH 149/241] adjust XML output to recent item list changes
---
items/list.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/items/list.php b/items/list.php
index 44906d7..9b79b42 100644
--- a/items/list.php
+++ b/items/list.php
@@ -190,7 +190,7 @@
$content = "";
foreach ($data AS $item)
{
- $content .= '';
+ $content .= '';
}
$content .= "";
}
From 76080d16a3da4294421ddb45cef0e09c64e3236c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 10 Mar 2013 20:07:28 +0100
Subject: [PATCH 150/241] add README
---
README.md | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..dcdb4f4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# ALD
+***ALD*** is short for ***A***utoHotkey ***L***ibrary ***D***istribution. It is a system for management, distribution and installation of libraries and applications written in AutoHotkey.
+This system consists of several parts. The most important part is the HTTP server API. Also, there can be a lot of different clients: websites, desktop apps and more.
+More information on the ALD system can be read up [in the wiki](https://github.com/maul-esel/ALD-API/wiki/The-ALD-model).
+
+## This repo
+The code in this repo is part of the ALD system. It's the HTTP API that is running on an ALD server to handle the libraries and applications stored on that server.
+
+### Get started
+To use the API, you only need to be able to issue standard HTTP requests. Read up the documentation on the API methods in the [wiki](https://github.com/maul-esel/ALD-API/wiki).
+
+Keep in mind that this is still in development, and breaking changes can occur at any time. At the moment, version `0.1.0` is live on `api.libba.net`. To test the current version from your client,
+just issue a `GET` request to `http://api.libba.net/version` (with the appropriate `Accept` header).
+
+Also note that the wiki documentation is slightly out of date and incomplete at the moment.
+
+### Development
+You can watch active development in this repo. For example check the open [issues](https://github.com/maul-esel/ALD-API/issues) and [pull requests](https://github.com/maul-esel/ALD-API/issues), and comment on them if you have something to say.
+If you wish further information, or want to get involved in development, be my guest. Just contact me, and if you want to contribute, fork the repo on github. I can then give you more information on planned features and tasks to complete.
+
+## ALD Clients
+There are several clients for this backend in development. Most importantly, there's [libba.net](http://libba.net), the official website, which presents the data stored in the backend in a user-friendly way.
\ No newline at end of file
From 4fe4297c8679f6e29e26b3e79d65a75328c1da1e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 11 Mar 2013 16:48:03 +0100
Subject: [PATCH 151/241] list pending entries (for all kinds of releases)
---
stdlib/pending/.htaccess | 3 +++
stdlib/pending/list.php | 33 +++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 stdlib/pending/.htaccess
create mode 100644 stdlib/pending/list.php
diff --git a/stdlib/pending/.htaccess b/stdlib/pending/.htaccess
new file mode 100644
index 0000000..6a3cc26
--- /dev/null
+++ b/stdlib/pending/.htaccess
@@ -0,0 +1,3 @@
+RewriteEngine On
+
+RewriteRule ^list$ list.php [L]
\ No newline at end of file
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
new file mode 100644
index 0000000..55e30e3
--- /dev/null
+++ b/stdlib/pending/list.php
@@ -0,0 +1,33 @@
+';
+ foreach ($data AS $entry) {
+ $content .= '';
+ }
+ $content .= '';
+ }
+
+ header('HTTP/1.1 200 ' . HttpException::getStatusMessage(200));
+ header('Content-Type: ' . $content_type);
+ echo $content;
+ exit;
+
+} catch (HttpException $e) {
+ handleHttpException($e);
+} catch (Exception $e) {
+ handleHttpException(new HttpException(500, NULL, $e->getMessage()));
+}
+?>
\ No newline at end of file
From 080582c03151725ec4c1c703ac323c0c793449c6 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 11 Mar 2013 18:19:00 +0100
Subject: [PATCH 152/241] 2 fixes to StdlibPending::GetEntries()
First, explictly require semver. Second, do not delete downgrade
entries, as they may be allowed by config. To do so, also require
stdlib configuration.
---
stdlib/StdlibPending.php | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index e464ace..7dd5ec8 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -1,11 +1,13 @@
new), delete the entry
- self::DeleteEntry($lib['id']);
- unset($libs[$i]);
+ if (!STDLIB_RELEASES_ALLOW_DOWNGRADE) {
+ throw new HttpException(500);
+ }
+ $update_type = UpdateType::getUpdate($lib['version'], $old_items[$old]['version']);
} else { # actually an update
$update_type = UpdateType::getUpdate($old_items[$old]['version'], $lib['version']); # retrieve update type
}
From 1ec02cf2507e74fc4b773feccb16aebd5598b23c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 11 Mar 2013 18:22:28 +0100
Subject: [PATCH 153/241] change StdlibPending::GetEntries()
Instead of a fixed release version, just pass the
release update type as argument. Adjust all calls
to the method accordingly.
---
stdlib/Stdlib.php | 2 +-
stdlib/StdlibPending.php | 3 +--
stdlib/releases/StdlibRelease.php | 5 +++--
stdlib/releases/describe.php | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 3afd9e1..f1cc68d 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -33,7 +33,7 @@ public static function GetItemsUnpublished($release, $base) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
- $pending = StdlibPending::GetEntries($release);
+ $pending = StdlibPending::GetEntries(UpdateType::getUpdate($base, $release));
foreach ($pending AS &$entry) {
switch ($entry['update']) {
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 7dd5ec8..79bc62f 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -24,9 +24,8 @@ public static function GetAllEntries()
return sql2array($db_result);
}
- public static function GetEntries($release) {
+ public static function GetEntries($release_update) {
$base = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
- $release_update = UpdateType::getUpdate($base, $release); # get release update type
$old_items = Stdlib::GetItems($base); # get items in base
foreach ($old_items AS &$item) {
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 803bd88..e8573c2 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -172,14 +172,15 @@ public static function publish($release) {
throw new HttpException(400, NULL, 'Cannot publish already published release!');
}
- $entries = Stdlib::GetItemsUnpublished($release, self::previousRelease($release, self::PUBLISHED_YES));
+ $previous_release = self::previousRelease($release, self::PUBLISHED_YES);
+ $entries = Stdlib::GetItemsUnpublished($release, $previous_release);
foreach ($entries AS $entry) {
Stdlib::writeEntry($release, $entry['id'], $entry['comment']);
StdlibPending::DeleteEntry($entry['id']);
}
# removals are not covered by deletion above, so delete these entries here
- $pending = StdlibPending::GetEntries($release);
+ $pending = StdlibPending::GetEntries(UpdateType::getUpdate($previous_release, $release));
foreach ($pending AS $entry) {
if ($entry['update'] == UpdateType::REMOVE) {
StdlibPending::DeleteEntry($entry['id']);
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 0892b26..b820fc4 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -35,13 +35,13 @@
# todo later: get frameworks in the release
+ $prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
- $prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
if ($prev_release !== NULL) {
$changeset = Stdlib::diff($prev_release, $release['release']);
}
} else {
- $changeset = StdlibPending::GetEntries($release['release']);
+ $changeset = StdlibPending::GetEntries(UpdateType::getUpdate($prev_release, $release['release']));
}
$release['changelog'] = array();
From 5c8eec8eb048bdfffbf461040968e4748284fdfa Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 11 Mar 2013 18:50:26 +0100
Subject: [PATCH 154/241] add 2 filters to pending list
Can now filter by the item update type
and the release update type which the
pending change can go in.
---
stdlib/pending/list.php | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
index 55e30e3..c791e23 100644
--- a/stdlib/pending/list.php
+++ b/stdlib/pending/list.php
@@ -2,13 +2,30 @@
require_once('../../modules/HttpException/HttpException.php');
require_once('../../util.php');
require_once('../../Assert.php');
+require_once('../../UpdateType.php');
require_once('../StdlibPending.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $data = StdlibPending::GetAllEntries();
+ if (isset($_GET['action'])) {
+ $action = UpdateType::getCode($_GET['action'], UpdateType::USAGE_STDLIB);
+ }
+
+ $release_update = UpdateType::MAJOR; # the default because any change can go into major
+ if (isset($_GET['release-type'])) {
+ $release_update = UpdateType::getCode($_GET['release-type'], UpdateType::USAGE_STDLIB_RELEASES);
+ }
+
+ $data = StdlibPending::GetEntries($release_update);
+ foreach ($data AS $i => &$entry) {
+ if (isset($action) && $entry['update'] != $action) {
+ unset($data[$i]);
+ }
+ $entry['update'] = UpdateType::getName($entry['update'], UpdateType::USAGE_STDLIB);
+ }
+ sort($data); # make array continous
if ($content_type == 'application/json') {
$content = json_encode($data);
From 4f2fa67b757f869eb5d497b3ff12d4552e63bbf4 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 15 Mar 2013 14:35:15 +0100
Subject: [PATCH 155/241] implement editing the pending item's changelog
comment
---
stdlib/StdlibPending.php | 12 ++++++++++++
stdlib/pending/.htaccess | 3 ++-
stdlib/pending/edit.php | 31 +++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 1 deletion(-)
create mode 100644 stdlib/pending/edit.php
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 79bc62f..48d0e04 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -120,5 +120,17 @@ public static function IsPending($id) {
return mysql_num_rows($db_result) > 0;
}
+
+ public static function SetComment($id, $comment) {
+ $db_connection = db_ensure_connection();
+ $id = mysql_real_escape_string($id, $db_connection);
+ $comment = mysql_real_escape_string($comment, $db_connection);
+
+ $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `comment` = "' . $comment . '" WHERE `lib` = UNHEX("' . $id . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ throw new HttpException(500);
+ }
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/pending/.htaccess b/stdlib/pending/.htaccess
index 6a3cc26..5d8465c 100644
--- a/stdlib/pending/.htaccess
+++ b/stdlib/pending/.htaccess
@@ -1,3 +1,4 @@
RewriteEngine On
-RewriteRule ^list$ list.php [L]
\ No newline at end of file
+RewriteRule ^list$ list.php [L]
+RewriteRule ^edit/([0-9a-fA-F]{32})$ edit.php?id=$1 [L]
diff --git a/stdlib/pending/edit.php b/stdlib/pending/edit.php
new file mode 100644
index 0000000..d0eb356
--- /dev/null
+++ b/stdlib/pending/edit.php
@@ -0,0 +1,31 @@
+getMessage()));
+}
+?>
\ No newline at end of file
From 80fdd3bd3fe52bd32660666592e94f728d814d77 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 13:49:09 +0100
Subject: [PATCH 156/241] add method to bump a semver version
---
UpdateType.php | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/UpdateType.php b/UpdateType.php
index e69b689..b8ac1d9 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -95,5 +95,35 @@ public static function getUpdate($old, $new) {
throw new HttpException(500);
}
+
+ public static function bumpVersion($base, $type) {
+ $parts = array();
+ if (!semver_parts($base, $parts)) { # split into parts
+ throw new HttpException(500);
+ }
+
+ $reset = array('minor' => 0, 'patch' => 0, 'prerelease' => NULL, 'build' => NULL);
+ switch ($type) {
+ case self::MAJOR: $field = 'major';
+ break;
+ case self::MINOR: $field = 'minor';
+ unset($reset['minor']); # must not reset minor field
+ break;
+ case self::PATCH: $field = 'patch';
+ unset($reset['minor']); # must not reset minor field
+ unset($reset['patch']); # must not reset patch field
+ break;
+ default:
+ throw new HttpException(500); # bumping other parts is not supported
+ break;
+ }
+
+ $parts[$field] = ((int)$parts[$field]) + 1; # increase bumped version part
+ foreach ($reset AS $field => $value) { # reset lower parts to default value
+ $parts[$field] = $value;
+ }
+
+ return semver_string($parts);
+ }
}
?>
\ No newline at end of file
From 8ddbaf186e7315fc48881bfe0ac68b091a56060e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 13:54:01 +0100
Subject: [PATCH 157/241] Revert "change StdlibPending::GetEntries()"
This reverts commit 1ec02cf2507e74fc4b773feccb16aebd5598b23c.
---
stdlib/Stdlib.php | 2 +-
stdlib/StdlibPending.php | 3 ++-
stdlib/releases/StdlibRelease.php | 5 ++---
stdlib/releases/describe.php | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index f1cc68d..3afd9e1 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -33,7 +33,7 @@ public static function GetItemsUnpublished($release, $base) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
- $pending = StdlibPending::GetEntries(UpdateType::getUpdate($base, $release));
+ $pending = StdlibPending::GetEntries($release);
foreach ($pending AS &$entry) {
switch ($entry['update']) {
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 48d0e04..723b55d 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -24,8 +24,9 @@ public static function GetAllEntries()
return sql2array($db_result);
}
- public static function GetEntries($release_update) {
+ public static function GetEntries($release) {
$base = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ $release_update = UpdateType::getUpdate($base, $release); # get release update type
$old_items = Stdlib::GetItems($base); # get items in base
foreach ($old_items AS &$item) {
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index e8573c2..803bd88 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -172,15 +172,14 @@ public static function publish($release) {
throw new HttpException(400, NULL, 'Cannot publish already published release!');
}
- $previous_release = self::previousRelease($release, self::PUBLISHED_YES);
- $entries = Stdlib::GetItemsUnpublished($release, $previous_release);
+ $entries = Stdlib::GetItemsUnpublished($release, self::previousRelease($release, self::PUBLISHED_YES));
foreach ($entries AS $entry) {
Stdlib::writeEntry($release, $entry['id'], $entry['comment']);
StdlibPending::DeleteEntry($entry['id']);
}
# removals are not covered by deletion above, so delete these entries here
- $pending = StdlibPending::GetEntries(UpdateType::getUpdate($previous_release, $release));
+ $pending = StdlibPending::GetEntries($release);
foreach ($pending AS $entry) {
if ($entry['update'] == UpdateType::REMOVE) {
StdlibPending::DeleteEntry($entry['id']);
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index b820fc4..0892b26 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -35,13 +35,13 @@
# todo later: get frameworks in the release
- $prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
+ $prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
if ($prev_release !== NULL) {
$changeset = Stdlib::diff($prev_release, $release['release']);
}
} else {
- $changeset = StdlibPending::GetEntries(UpdateType::getUpdate($prev_release, $release['release']));
+ $changeset = StdlibPending::GetEntries($release['release']);
}
$release['changelog'] = array();
From b0351f66a9758cbfb123516729bc2e8302e85be0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 14:02:55 +0100
Subject: [PATCH 158/241] Adjust list of pending items to commit 8ddbaf186e
The mentioned commit changed StdlibPending::GetEntries() back to
accepting a release instead of a UpdateType constant as argument.
To get the matching release version for a given update type, use
the new UpdateType::bumpVersion() introduced in commit 80fdd3bd3f.
---
UpdateType.php | 2 +-
stdlib/pending/list.php | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index b8ac1d9..3a5821c 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -25,7 +25,7 @@ class UpdateType
private static $usage = array(self::USAGE_ITEMS => array(self::MAJOR, self::MINOR, self::PATCH, self::BUILD_INCREASE, self::PRERELEASE_INCREASE, self::ADD),
self::USAGE_STDLIB => array(self::MAJOR, self::MINOR, self::PATCH, self::ADD, self::REMOVE),
- self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH));
+ self::USAGE_STDLIB_RELEASES => array(self::MAJOR, self::MINOR, self::PATCH)); # stdlib/pending/list relies on this not to be changed
public static function getCode($str, $usage)
{
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
index c791e23..4655fd8 100644
--- a/stdlib/pending/list.php
+++ b/stdlib/pending/list.php
@@ -4,6 +4,7 @@
require_once('../../Assert.php');
require_once('../../UpdateType.php');
require_once('../StdlibPending.php');
+require_once('../releases/StdlibRelease.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
@@ -18,7 +19,9 @@
$release_update = UpdateType::getCode($_GET['release-type'], UpdateType::USAGE_STDLIB_RELEASES);
}
- $data = StdlibPending::GetEntries($release_update);
+ $latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ $data = StdlibPending::GetEntries(UpdateType::bumpVersion($latest_release, $release_update));
+
foreach ($data AS $i => &$entry) {
if (isset($action) && $entry['update'] != $action) {
unset($data[$i]);
From 573442f82d00f6e73bfba72426b86777b7a7c75c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 14:22:51 +0100
Subject: [PATCH 159/241] implement delay handling
Add a new DB attribute 'delay'. It can be set via
StdlibPending::SetDelay(). Also obey the delay in
StdlibPending::GetEntries($release) and output it
in StdlibPending::GetAllEntries();
---
MySQL/DB_TABLE_STDLIB_PENDING.sql | 1 +
stdlib/StdlibPending.php | 23 ++++++++++++++++++-----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/MySQL/DB_TABLE_STDLIB_PENDING.sql b/MySQL/DB_TABLE_STDLIB_PENDING.sql
index 746dfe0..589fc11 100644
--- a/MySQL/DB_TABLE_STDLIB_PENDING.sql
+++ b/MySQL/DB_TABLE_STDLIB_PENDING.sql
@@ -10,6 +10,7 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_pending` (
`lib` binary(16) NOT NULL,
`comment` text NOT NULL,
+ `delay` tinytext,
PRIMARY KEY (`lib`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 723b55d..40e44b7 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -14,7 +14,7 @@ class StdlibPending
public static function GetAllEntries()
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT HEX(`lib`) AS id, comment FROM ' . DB_TABLE_STDLIB_PENDING;
+ $db_query = 'SELECT HEX(`lib`) AS id, comment, delay FROM ' . DB_TABLE_STDLIB_PENDING;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -24,7 +24,7 @@ public static function GetAllEntries()
return sql2array($db_result);
}
- public static function GetEntries($release) {
+ public static function GetEntries($release) { # $release is not required to exist!
$base = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
$release_update = UpdateType::getUpdate($base, $release); # get release update type
@@ -61,13 +61,14 @@ public static function GetEntries($release) {
# filter according to release update type
#################################################
+ $delayed = $lib['delay'] !== NULL && semver_compare($release, $lib['delay']) < 0;
$include = false;
switch ($release_update) {
- case UpdateType::MAJOR: $include = true; # everything can go in a major release
+ case UpdateType::MAJOR: $include = !$delayed; # everything can go in a major release, just exclude delayed items
break;
- case UpdateType::MINOR: $include = $update_type == UpdateType::MINOR || $update_type == UpdateType::PATCH;
+ case UpdateType::MINOR: $include = !$delayed && ($update_type == UpdateType::MINOR || $update_type == UpdateType::PATCH);
break;
- case UpdateType::PATCH: $include = $update_type == UpdateType::PATCH;
+ case UpdateType::PATCH: $include = !$delayed && ($update_type == UpdateType::PATCH);
break;
}
@@ -133,5 +134,17 @@ public static function SetComment($id, $comment) {
throw new HttpException(500);
}
}
+
+ public static function SetDelay($id, $delay = NULL) {
+ $db_connection = db_ensure_connection();
+ $id = mysql_real_escape_string($id, $db_connection);
+ $delay = ($delay !== NULL) ? '"' . mysql_real_escape_string($delay, $db_connection) . '"' : 'NULL';
+
+ $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `delay` = ' . $delay . ' WHERE `lib` = UNHEX("' . $id . '")';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ throw new HttpException(500);
+ }
+ }
}
?>
\ No newline at end of file
From ed3c2a1239ad2f46e7c9341bc803ed029816d830 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 14:28:44 +0100
Subject: [PATCH 160/241] Add new 'release' filter to pending list
Commit b0351f66a9 made it possible to specify a specific release
instead of just an update type. This makes it possible to enlist
delayed items even if they are delayed for several major version
steps from the current version.
---
stdlib/pending/list.php | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
index 4655fd8..3e2403b 100644
--- a/stdlib/pending/list.php
+++ b/stdlib/pending/list.php
@@ -20,7 +20,13 @@
}
$latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
- $data = StdlibPending::GetEntries(UpdateType::bumpVersion($latest_release, $release_update));
+ $version = UpdateType::bumpVersion($latest_release, $release_update);
+
+ if (isset($_GET['release'])) {
+ $version = $_GET['release'];
+ }
+
+ $data = StdlibPending::GetEntries($version);
foreach ($data AS $i => &$entry) {
if (isset($action) && $entry['update'] != $action) {
From e09fd59076714308cc3768db84563f29b2ee901d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 14:39:26 +0100
Subject: [PATCH 161/241] add API for delaying a pending item
---
stdlib/pending/.htaccess | 2 +-
stdlib/pending/delay.php | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
create mode 100644 stdlib/pending/delay.php
diff --git a/stdlib/pending/.htaccess b/stdlib/pending/.htaccess
index 5d8465c..e2c0ea7 100644
--- a/stdlib/pending/.htaccess
+++ b/stdlib/pending/.htaccess
@@ -1,4 +1,4 @@
RewriteEngine On
RewriteRule ^list$ list.php [L]
-RewriteRule ^edit/([0-9a-fA-F]{32})$ edit.php?id=$1 [L]
+RewriteRule ^(edit|delay)/([0-9a-fA-F]{32})$ $1.php?id=$2 [L]
diff --git a/stdlib/pending/delay.php b/stdlib/pending/delay.php
new file mode 100644
index 0000000..b44944b
--- /dev/null
+++ b/stdlib/pending/delay.php
@@ -0,0 +1,37 @@
+getMessage()));
+}
+?>
\ No newline at end of file
From cb7868e1f27b3afbde98dda98d664533f2d84760 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 20:41:31 +0100
Subject: [PATCH 162/241] rename DB columns to fit variable item types
---
MySQL/DB_TABLE_STDLIB.sql | 2 +-
MySQL/DB_TABLE_STDLIB_PENDING.sql | 4 ++--
stdlib/Stdlib.php | 6 +++---
stdlib/StdlibPending.php | 12 ++++++------
stdlib/items.php | 2 +-
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/MySQL/DB_TABLE_STDLIB.sql b/MySQL/DB_TABLE_STDLIB.sql
index f33e1db..4ab4323 100644
--- a/MySQL/DB_TABLE_STDLIB.sql
+++ b/MySQL/DB_TABLE_STDLIB.sql
@@ -9,7 +9,7 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib` (
`release` tinytext NOT NULL,
- `lib` binary(16) NOT NULL,
+ `item` binary(16) NOT NULL,
`comment` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/MySQL/DB_TABLE_STDLIB_PENDING.sql b/MySQL/DB_TABLE_STDLIB_PENDING.sql
index 589fc11..8c51892 100644
--- a/MySQL/DB_TABLE_STDLIB_PENDING.sql
+++ b/MySQL/DB_TABLE_STDLIB_PENDING.sql
@@ -8,10 +8,10 @@ SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `stdlib_pending` (
- `lib` binary(16) NOT NULL,
+ `item` binary(16) NOT NULL,
`comment` text NOT NULL,
`delay` tinytext,
- PRIMARY KEY (`lib`)
+ PRIMARY KEY (`item`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 3afd9e1..7d7f0e4 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -14,7 +14,7 @@ public static function GetItems($release)
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
- $db_query = 'SELECT HEX(`lib`) AS id, comment FROM ' . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
+ $db_query = 'SELECT HEX(`item`) AS id, comment FROM ' . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -99,7 +99,7 @@ public static function writeEntry($release, $lib, $comment) {
$lib = mysql_real_escape_string($lib, $db_connection);
$comment = mysql_real_escape_string($comment, $db_connection);
- $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `lib`, `comment`) VALUES ("' . $release . '", UNHEX("' . $lib . '"), "' . $comment . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `item`, `comment`) VALUES ("' . $release . '", UNHEX("' . $lib . '"), "' . $comment . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE || mysql_affected_rows() < 1) {
throw new HttpException(500);
@@ -111,7 +111,7 @@ public static function releaseHasItem($release, $id) {
$release = mysql_real_escape_string($release, $db_connection);
$id= mysql_real_escape_string($id, $db_connection);
- $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $release . '" AND `lib` = UNHEX("' . $id . '")';
+ $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $release . '" AND `item` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 40e44b7..7c0eadd 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -14,7 +14,7 @@ class StdlibPending
public static function GetAllEntries()
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT HEX(`lib`) AS id, comment, delay FROM ' . DB_TABLE_STDLIB_PENDING;
+ $db_query = 'SELECT HEX(`item`) AS id, comment, delay FROM ' . DB_TABLE_STDLIB_PENDING;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -90,7 +90,7 @@ public static function AddEntry($id, $comment)
$id = mysql_real_escape_string($id, $db_connection);
$comment = mysql_real_escape_string($comment, $db_connection);
- $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_PENDING . ' (`lib`, `comment`) VALUES (UNHEX("' . $id . '"), "' . $comment . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_PENDING . ' (`item`, `comment`) VALUES (UNHEX("' . $id . '"), "' . $comment . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
@@ -102,7 +102,7 @@ public static function DeleteEntry($id)
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $db_query = 'DELETE FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `lib` = UNHEX('$id')";
+ $db_query = 'DELETE FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `item` = UNHEX('$id')";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
@@ -114,7 +114,7 @@ public static function IsPending($id) {
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `lib` = UNHEX("' . $id . '")';
+ $db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `item` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
@@ -128,7 +128,7 @@ public static function SetComment($id, $comment) {
$id = mysql_real_escape_string($id, $db_connection);
$comment = mysql_real_escape_string($comment, $db_connection);
- $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `comment` = "' . $comment . '" WHERE `lib` = UNHEX("' . $id . '")';
+ $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `comment` = "' . $comment . '" WHERE `item` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE || mysql_affected_rows() < 1) {
throw new HttpException(500);
@@ -140,7 +140,7 @@ public static function SetDelay($id, $delay = NULL) {
$id = mysql_real_escape_string($id, $db_connection);
$delay = ($delay !== NULL) ? '"' . mysql_real_escape_string($delay, $db_connection) . '"' : 'NULL';
- $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `delay` = ' . $delay . ' WHERE `lib` = UNHEX("' . $id . '")';
+ $db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `delay` = ' . $delay . ' WHERE `item` = UNHEX("' . $id . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE || mysql_affected_rows() < 1) {
throw new HttpException(500);
diff --git a/stdlib/items.php b/stdlib/items.php
index 1a405e2..2fb7233 100644
--- a/stdlib/items.php
+++ b/stdlib/items.php
@@ -22,7 +22,7 @@
$db_cond .= 'AND id = UNHEX("' . mysql_real_escape_string($_GET['id'], $db_connection) . '")';
}
- $db_query = 'SELECT name, version, HEX(`id`) AS id, GROUP_CONCAT(DISTINCT `release` SEPARATOR "\0") AS releases FROM ' . DB_TABLE_STDLIB . ', ' . DB_TABLE_ITEMS . ' WHERE lib = id ' . $db_cond . ' GROUP BY name, version';
+ $db_query = 'SELECT name, version, HEX(`id`) AS id, GROUP_CONCAT(DISTINCT `release` SEPARATOR "\0") AS releases FROM ' . DB_TABLE_STDLIB . ', ' . DB_TABLE_ITEMS . ' WHERE item = id ' . $db_cond . ' GROUP BY name, version';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500, NULL, mysql_error());
From ca4dbf2382340fd716a843a90716ed216fcbbfa9 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 20:42:39 +0100
Subject: [PATCH 163/241] rename param
---
stdlib/Stdlib.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 7d7f0e4..6b57bcb 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -93,13 +93,13 @@ public static function diff($old, $new) {
return $diff;
}
- public static function writeEntry($release, $lib, $comment) {
+ public static function writeEntry($release, $id, $comment) {
$db_connection = db_ensure_connection();
$release = mysql_real_escape_string($release, $db_connection);
- $lib = mysql_real_escape_string($lib, $db_connection);
+ $id = mysql_real_escape_string($id, $db_connection);
$comment = mysql_real_escape_string($comment, $db_connection);
- $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `item`, `comment`) VALUES ("' . $release . '", UNHEX("' . $lib . '"), "' . $comment . '")';
+ $db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `item`, `comment`) VALUES ("' . $release . '", UNHEX("' . $id . '"), "' . $comment . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE || mysql_affected_rows() < 1) {
throw new HttpException(500);
From 75f4ca0dc758df0922228d52f0d33825a16c26c5 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:07:08 +0100
Subject: [PATCH 164/241] add new config: item types allowed in the stdlib
Check item type on candidate creation.
---
config/stdlib.php | 3 +++
stdlib/candidates/create.php | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/config/stdlib.php b/config/stdlib.php
index aa1fc45..7ea12ba 100644
--- a/config/stdlib.php
+++ b/config/stdlib.php
@@ -2,6 +2,9 @@
# Whether or not downgrading a lib in the stdlib to a previous version (in a new stdlib release) is allowed
define('STDLIB_RELEASES_ALLOW_DOWNGRADE', true);
+ # The item types allowed in the stdlib, separated by \0
+ define('STDLIB_ALLOWED_TYPES', 'lib');
+
# The minimum number of accepts a candidate needs to be accepted
define('CANDIDATE_MIN_ACCEPTS', 3);
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
index c1536aa..4bd0cc5 100644
--- a/stdlib/candidates/create.php
+++ b/stdlib/candidates/create.php
@@ -4,10 +4,12 @@
require_once('../../Assert.php');
require_once('../../User.php');
require_once('../../Item.php');
+require_once('../../items/ItemType.php');
require_once('../StdlibPending.php');
require_once('../Stdlib.php');
require_once('../releases/StdlibRelease.php');
require_once('Candidate.php');
+require_once('../../config/stdlib.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_POST);
@@ -27,6 +29,12 @@
user_basic_auth('Restricted API');
+ $allowed_types = explode("\0", STDLIB_ALLOWED_TYPES);
+ $t = Item::get($item, array('type'));
+ if (!in_array(ItemType::getName($t['type']), $allowed_types)) {
+ throw new HttpException(403, NULL, 'This type of item can not be part of the stdlib.');
+ }
+
# reject if pending or in latest published release (don't check for unpublished releases - equals pending)
if (StdlibPending::IsPending($item)) {
throw new HttpException(409, NULL, 'This item is already pending for future inclusion.');
From 05c2dbb8a67a30086cada4e15e06516d5a13c9ad Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:13:01 +0100
Subject: [PATCH 165/241] adjust release description to variable item types
---
stdlib/releases/describe.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 0892b26..77c9642 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -31,7 +31,7 @@
StdlibRelease::publishPending();
$release = StdlibRelease::describe($_GET["version"], $publish_status);
- $release['libs'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
+ $release['items'] = array_map(create_function('$item', 'return $item[\'id\'];'), Stdlib::GetItems($release['release']));
# todo later: get frameworks in the release
@@ -62,8 +62,8 @@
$content .= ' ald:' . $key . '="' . htmlspecialchars(is_bool($release[$key]) ? ($release[$key] ? 'true' : 'false') : $release[$key], ENT_QUOTES) . '"';
}
$content .= '>' . htmlspecialchars($release['description'], ENT_QUOTES) . '';
- foreach ($release['libs'] AS $lib) {
- $content .= '';
+ foreach ($release['items'] AS $item) {
+ $content .= '';
}
$content .= '';
foreach ($release['changelog'] AS $item => $text) {
From 1f2d14a0e8440120d56a21ce99ff4372b97bd736 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:17:11 +0100
Subject: [PATCH 166/241] small fix: use UpdateType constant instead of literal
---
stdlib/releases/create.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 56e09c0..49b40a9 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -58,7 +58,7 @@
$release = $_POST["version"];
} else {
- $type = UpdateType::getCode($_GET["type"], "stdlib_releases");
+ $type = UpdateType::getCode($_GET["type"], UpdateType::USAGE_STDLIB_RELEASES);
# bump version number according to $type
$release = array();
From b5f4f970cb0c7b04838cf7c1587a13eb5cd6534a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:23:54 +0100
Subject: [PATCH 167/241] shorten release creation code, minor code shortening
for UpdateType
---
UpdateType.php | 2 +-
stdlib/releases/create.php | 25 +------------------------
2 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/UpdateType.php b/UpdateType.php
index 3a5821c..1c75039 100644
--- a/UpdateType.php
+++ b/UpdateType.php
@@ -118,7 +118,7 @@ public static function bumpVersion($base, $type) {
break;
}
- $parts[$field] = ((int)$parts[$field]) + 1; # increase bumped version part
+ $parts[$field]++;
foreach ($reset AS $field => $value) { # reset lower parts to default value
$parts[$field] = $value;
}
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 49b40a9..6d33589 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -59,30 +59,7 @@
$release = $_POST["version"];
} else {
$type = UpdateType::getCode($_GET["type"], UpdateType::USAGE_STDLIB_RELEASES);
-
- # bump version number according to $type
- $release = array();
- semver_parts($prev_release, $release);
-
- if ($type == UpdateType::PATCH || $type == UpdateType::MINOR || $type == UpdateType::MAJOR)
- {
- unset($release["prerelease"]);
- unset($release["build"]);
- $release["patch"]++;
-
- if ($type == UpdateType::MINOR || $type == UpdateType::MAJOR)
- {
- $release["patch"] = 0;
- $release["minor"]++;
-
- if ($type == UpdateType::MAJOR)
- {
- $release["minor"] = 0;
- $release["major"]++;
- }
- }
- }
- $release = semver_string($release);
+ $release = UpdateType::bumpVersion($prev_release, $type); # bump version number according to $type
# check if (unpublished) release already exists (unpublished because the latest published is always >= the base for $release)
# only check for PUBLISHED_YES as otherwise, $release must be based on the latest release anyway.
From 6c710e83bd2a472da7234b5ebccfa67a23d1c269 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:27:22 +0100
Subject: [PATCH 168/241] pending items list: add 'name' filter
---
stdlib/pending/list.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
index 3e2403b..a396449 100644
--- a/stdlib/pending/list.php
+++ b/stdlib/pending/list.php
@@ -32,6 +32,9 @@
if (isset($action) && $entry['update'] != $action) {
unset($data[$i]);
}
+ if (isset($_GET['name']) && $_GET['name'] != $entry['name']) {
+ unset($data[$i]);
+ }
$entry['update'] = UpdateType::getName($entry['update'], UpdateType::USAGE_STDLIB);
}
sort($data); # make array continous
From 9ce47c978a08dd7fc686bd67a090f20cb700bc22 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 21:46:35 +0100
Subject: [PATCH 169/241] rename config setting to be less misunderstandable
---
config/stdlib.php | 2 +-
stdlib/StdlibPending.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/config/stdlib.php b/config/stdlib.php
index 7ea12ba..f15027a 100644
--- a/config/stdlib.php
+++ b/config/stdlib.php
@@ -1,6 +1,6 @@
new), delete the entry
- if (!STDLIB_RELEASES_ALLOW_DOWNGRADE) {
+ if (!STDLIB_ALLOW_DOWNGRADE) {
throw new HttpException(500);
}
$update_type = UpdateType::getUpdate($lib['version'], $old_items[$old]['version']);
From 8d0eb22e72f2d10df526f4f77f81ce99916e007a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 16 Mar 2013 22:23:22 +0100
Subject: [PATCH 170/241] add some DB hygiene cleanup code
Add new methods to the classes Stdlib, StdlibPending
and StdlibRelease that detect problems in the DB and
remove them. Make sure they are called by adding the
respective calls in the respective files.
---
stdlib/Stdlib.php | 21 +++++++++++++++++++++
stdlib/StdlibPending.php | 29 +++++++++++++++++++++++++++++
stdlib/releases/StdlibRelease.php | 17 +++++++++++++++++
3 files changed, 67 insertions(+)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 6b57bcb..e7d1e44 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -6,6 +6,8 @@
require_once(dirname(__FILE__) . '/releases/StdlibRelease.php');
require_once(dirname(__FILE__) . '/../modules/HttpException/HttpException.php');
+Stdlib::cleanup();
+
class Stdlib
{
public static function GetItems($release)
@@ -119,5 +121,24 @@ public static function releaseHasItem($release, $id) {
return mysql_num_rows($db_result) > 0;
}
+
+ public static function cleanup() {
+ $db_connection = db_ensure_connection();
+
+ # ensure not 2x stdlib with same item and release
+ $db_query = 'SELECT `release`, `item` FROM ' . DB_TABLE_STDLIB . ' GROUP BY `release`, `item` HAVING COUNT(*) > 1';
+ $db_result = mysql_query($db_query, $db_connection);
+ if ($db_result === FALSE) {
+ throw new HttpException(500, NULL, mysql_error());
+ }
+
+ while ($dup = mysql_fetch_assoc($db_result)) {
+ $db_query = 'DELETE FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $dup['release'] . '" AND `item` = "' . $dup['item'] . '" LIMIT 1';
+ $db_result2 = mysql_query($db_query, $db_connection);
+ if ($db_result2 === FALSE) {
+ throw new HttpException(500);
+ }
+ }
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index bfbf5e5..27e5f3d 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -9,6 +9,8 @@
require_once(dirname(__FILE__) . '/releases/StdlibRelease.php');
require_once(dirname(__FILE__) . '/../config/stdlib.php');
+StdlibPending::cleanup();
+
class StdlibPending
{
public static function GetAllEntries()
@@ -146,5 +148,32 @@ public static function SetDelay($id, $delay = NULL) {
throw new HttpException(500);
}
}
+
+ public static function cleanup() {
+ $latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ $live_items = array_map(array('StdlibPending', 'sanitize_items'), Stdlib::GetItems($latest_release));
+ $pending = array_map(array('StdlibPending', 'sanitize_items'), self::GetAllEntries());
+
+ # ensure there are no pending entries < live entries if downgrades not allowed
+ if (!STDLIB_ALLOW_DOWNGRADE) {
+ $pending_copy = $pending;
+
+ foreach ($live_items AS $item) {
+ while (($i = searchSubArray($pending_copy, array('name' => $item['name']))) !== NULL) {
+ if (semver_compare($item['version'], $pending_copy[$i]['version']) > 0) { # if the live version is > the pending (and no downgrades allowed, see above)
+ self::DeleteEntry($pending_copy[$i]['id']); # delete the pending downgrade
+ }
+ unset($pending_copy[$i]);
+ }
+ }
+ }
+
+ # todo: ensure not removal + addition of the same item pending >> delete both
+ # todo: ensure not removal + addition of different versions of the same item pending >> make upgrade
+ }
+
+ static function sanitize_items($item) {
+ return array_merge($item, Item::get($item['id'], array('name', 'version')));
+ }
}
?>
\ No newline at end of file
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 803bd88..d8f3f94 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -6,6 +6,8 @@
require_once(dirname(__FILE__) . "/../../modules/HttpException/HttpException.php");
require_once(dirname(__FILE__) . "/../../modules/semver/semver.php");
+StdlibRelease::cleanup();
+
class StdlibRelease
{
const RELEASE_BASE_ALL = "all";
@@ -216,6 +218,21 @@ public static function ListReleases($published)
return sql2array($db_result, create_function('$release', 'return $release[\'release\'];'));
}
+ public static function cleanup() {
+ $latest_release = self::getVersion(self::SPECIAL_VERSION_LATEST, self::PUBLISHED_YES);
+
+ # ensure everything that should be published is published
+ self::publishPending();
+
+ # ensure there are no downgrade releases
+ $releases = self::ListReleases(self::PUBLISHED_NO);
+ foreach ($releases AS $release) {
+ if (semver_compare($latest_release, $release) > -1) {
+ self::delete($release);
+ }
+ }
+ }
+
const PUBLISHED_YES = 1;
const PUBLISHED_NO = 2;
const PUBLISHED_BOTH = 3; # self::PUBLISHED_YES | self::PUBLISHED_NO
From e3f89e93a24414d0cf46ad6f34c80b73979f1203 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 15:59:49 +0100
Subject: [PATCH 171/241] add minimal .travis.yml file for travis testing
---
.travis.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 .travis.yml
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..9c276be
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,11 @@
+language: php
+php:
+ - "5.4"
+ - "5.3"
+ - "5.2"
+
+before_install:
+ - git submodule update --init --recursive
+
+services:
+ - mysql
From 2b0e9e3abd6fef000a81d5f9ee9cfec24597991c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 16:37:15 +0100
Subject: [PATCH 172/241] add mysql setup script
---
.travis.yml | 3 +++
tests/setup/db-mysql.sh | 10 ++++++++++
2 files changed, 13 insertions(+)
create mode 100755 tests/setup/db-mysql.sh
diff --git a/.travis.yml b/.travis.yml
index 9c276be..28b829d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,3 +9,6 @@ before_install:
services:
- mysql
+
+before_script:
+ - tests/setup/db-mysql.sh
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
new file mode 100755
index 0000000..fcb39e8
--- /dev/null
+++ b/tests/setup/db-mysql.sh
@@ -0,0 +1,10 @@
+#! /usr/bin/env sh
+
+# create the database
+mysql -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
+
+# import the individual tables
+for file in MySQL/*.sql;
+do
+ mysql -u root travis-test < "$file"
+done
From e5416aa1c69da2c12fb91e11839a0e996510f149 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 16:43:11 +0100
Subject: [PATCH 173/241] add config copy for travis
---
config/README.md | 6 ++
config/profiles/travis/database.php | 28 +++++++++
config/profiles/travis/rating.php | 10 ++++
config/profiles/travis/registration.php | 79 +++++++++++++++++++++++++
config/profiles/travis/stdlib.php | 25 ++++++++
config/profiles/travis/suspensions.php | 21 +++++++
config/profiles/travis/upload.php | 21 +++++++
7 files changed, 190 insertions(+)
create mode 100644 config/README.md
create mode 100644 config/profiles/travis/database.php
create mode 100644 config/profiles/travis/rating.php
create mode 100644 config/profiles/travis/registration.php
create mode 100644 config/profiles/travis/stdlib.php
create mode 100644 config/profiles/travis/suspensions.php
create mode 100644 config/profiles/travis/upload.php
diff --git a/config/README.md b/config/README.md
new file mode 100644
index 0000000..a242335
--- /dev/null
+++ b/config/README.md
@@ -0,0 +1,6 @@
+# Configuration
+Almost all configuration options available for ALD can be changed in the files in this folder.
+They should be self-explaining or, in most cases, documented.
+
+## Profiles
+The `profiles/` folder contains usage-ready configuration sets, which are used for example for unit testing on travis-ci.org.
\ No newline at end of file
diff --git a/config/profiles/travis/database.php b/config/profiles/travis/database.php
new file mode 100644
index 0000000..2b8d784
--- /dev/null
+++ b/config/profiles/travis/database.php
@@ -0,0 +1,28 @@
+
\ No newline at end of file
diff --git a/config/profiles/travis/rating.php b/config/profiles/travis/rating.php
new file mode 100644
index 0000000..2028d33
--- /dev/null
+++ b/config/profiles/travis/rating.php
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/config/profiles/travis/registration.php b/config/profiles/travis/registration.php
new file mode 100644
index 0000000..10d210f
--- /dev/null
+++ b/config/profiles/travis/registration.php
@@ -0,0 +1,79 @@
+]{2,25}$/i');
+ # If a user name does not fit this RegEx, the request to initiate a registration is ans-
+ # wered with a '403 - Forbidden' status code.
+ #
+ # Notes:
+ # + When the maximum length is increased, the database fields must be adjusted accordingly.
+ # This affects the 'DB_TABLE_USERS' database table and the 'DB_TABLE_REGISTRATION' table.
+
+ # a list of user names which must not be registered
+ define('FORBIDDEN_USER_NAMES', "");
+ # This is a list of user names which fit the USER_NAME_REGEX, but must still not be registered.
+ # Separate the names by NUL bytes ('\0').
+ #
+ # Notes:
+ # + remember that the '\0' escape sequence requires double quotes
+
+ # a list of user names which can not be registered by the public
+ define('RESERVED_USER_NAMES', "");
+ # The only difference between this and FORBIDDEN_USER_NAMES is that the names
+ # in this list may be registered by users which have the PRIVILEGE_REGISTRATION
+ # but not by anyone else.
+ #
+ # Notes:
+ # + as above, separate the names by '\0' and use double quotes
+
+ # defines whether registration is open to public or not
+ define('PUBLIC_REGISTRATION', true);
+ # If this is set to `true`, any internet user can register himself to the site.
+ # Otherwise, only users who are already registered and have the PRIVILEGE_REGISTRATION
+ # privilege can start a registration. In this case, such a user initiates a registration
+ # with some name, mail and password. The user to be registered receives the mail and can
+ # then complete the registration.
+ #
+ # Notes:
+ # + the password should in this case be included in the mail
+ # + the REGISTRATION_TIMEOUT should be configured in a way which allows cooperation e.g. between different timezones.
+
+ # the subject for the mail sent to the registering user
+ define('REGISTRATION_MAIL_SUBJECT', 'Confirm your registration');
+
+ # the template for the mail to be sent to the registering user
+ define('REGISTRATION_MAIL_TEMPLATE', 'Hi {$NAME},
+
+Welcome to the libba.net!
+You have requested registration with the following data:
+
+ Name: {$NAME}
+ Mail: {$MAIL}
+ (Password not included for security)
+
+To complete your registration, go to libba.net/register/{$ID} and follow the steps described there.
+If you do not follow this step, your registration will expire after some time. You can then start a new registration.
+
+If you did not request registration, you may safely ignore this mail.');
+ # When registering, a mail is sent to the new user to validate he's a human and he owns the specified email address.
+ # This template can contain the following variables:
+ # * {$NAME} - the name to be registered
+ # * {$MAIL} - the mail address the mail is sent to
+ # * {$PASSWORD} - the password specified
+ # * {$ID} - the ID of the registration session, required to complete the registration
+
+ # the sender mail address to send registration verification mails from
+ define('REGISTRATION_MAIL_SENDER', '');
+?>
\ No newline at end of file
diff --git a/config/profiles/travis/stdlib.php b/config/profiles/travis/stdlib.php
new file mode 100644
index 0000000..f15027a
--- /dev/null
+++ b/config/profiles/travis/stdlib.php
@@ -0,0 +1,25 @@
+
\ No newline at end of file
diff --git a/config/profiles/travis/suspensions.php b/config/profiles/travis/suspensions.php
new file mode 100644
index 0000000..8250834
--- /dev/null
+++ b/config/profiles/travis/suspensions.php
@@ -0,0 +1,21 @@
+this page.');
+ # The following variables are available:
+ # * {$USER} - the user's name
+ # * {$ID} - the user's ID
+ # * {$MAIL} - the new mail address
+ # * {$SUSPENSION} - the ID of the created suspension
+?>
\ No newline at end of file
diff --git a/config/profiles/travis/upload.php b/config/profiles/travis/upload.php
new file mode 100644
index 0000000..b1c2289
--- /dev/null
+++ b/config/profiles/travis/upload.php
@@ -0,0 +1,21 @@
+
\ No newline at end of file
From 52d3cdeb5303c1d08349885c95d17df1c55fe56e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 17:13:22 +0100
Subject: [PATCH 174/241] add profile config script
---
.travis.yml | 3 ++-
tests/setup/profile.sh | 10 ++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100755 tests/setup/profile.sh
diff --git a/.travis.yml b/.travis.yml
index 28b829d..f327250 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,4 +11,5 @@ services:
- mysql
before_script:
- - tests/setup/db-mysql.sh
+ - ./tests/setup/db-mysql.sh
+ - ./tests/setup/profile.sh travis
diff --git a/tests/setup/profile.sh b/tests/setup/profile.sh
new file mode 100755
index 0000000..e5e2718
--- /dev/null
+++ b/tests/setup/profile.sh
@@ -0,0 +1,10 @@
+#! /usr/bin/env sh
+
+# check if the specified profile is valid
+if [ ! -d "config/profiles/$1" ]; then
+ echo "$1 is not a valid config profile!"
+ exit 1
+fi
+
+# overwrite config with all profile-specific config files
+mmv -c -o -- "config/profiles/$1/*.php" "config/#1.php"
\ No newline at end of file
From 7337774de2c27110c6c6da399080c898eec5a630 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 17:43:06 +0100
Subject: [PATCH 175/241] fix profile script (broken due to unsupported
command)
---
tests/setup/profile.sh | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tests/setup/profile.sh b/tests/setup/profile.sh
index e5e2718..25a2ebc 100755
--- a/tests/setup/profile.sh
+++ b/tests/setup/profile.sh
@@ -6,5 +6,12 @@ if [ ! -d "config/profiles/$1" ]; then
exit 1
fi
+echo "Using config profile \"$1\"..."
+
# overwrite config with all profile-specific config files
-mmv -c -o -- "config/profiles/$1/*.php" "config/#1.php"
\ No newline at end of file
+for file in config/profiles/$1/*.php;
+do
+ base=${file##*/}
+ cp -v -f $file config/$base
+done
+echo "\n\n"
\ No newline at end of file
From 60ec0e44a2a2de596f4cbe22fc3601215d6480f7 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 19:47:43 +0100
Subject: [PATCH 176/241] fix User class for privilege renamings and additions
---
User.php | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/User.php b/User.php
index 0debe65..8bd2f9b 100644
--- a/User.php
+++ b/User.php
@@ -25,9 +25,12 @@ public static function privilegeToArray($privilege) {
if (($privilege & self::PRIVILEGE_REVIEW) == self::PRIVILEGE_REVIEW) {
$arr[] = 'review';
}
- if (($privilege & self::PRIVILEGE_DEFAULT_INCLUDE) == self::PRIVILEGE_DEFAULT_INCLUDE) {
+ if (($privilege & self::PRIVILEGE_STDLIB) == self::PRIVILEGE_STDLIB) {
$arr[] = 'stdlib';
}
+ if (($privilege & self::PRIVILEGE_STDLIB_ADMIN) == self::PRIVILEGE_STDLIB_ADMIN) {
+ $arr[] = 'stdlib-admin';
+ }
if (($privilege & self::PRIVILEGE_ADMIN) == self::PRIVILEGE_ADMIN) {
$arr[] = 'admin';
}
@@ -52,7 +55,9 @@ public static function privilegeFromArray($arr) {
break;
case 'review': $privilege |= self::PRIVILEGE_REVIEW;
break;
- case 'stdlib': $privilege |= self::PRIVILEGE_DEFAULT_INCLUDE;
+ case 'stdlib': $privilege |= self::PRIVILEGE_STDLIB;
+ break;
+ case 'stdlib-admin': $privilege |= self::PRIVILEGE_STDLIB_ADMIN;
break;
case 'admin': $privilege |= self::PRIVILEGE_ADMIN;
break;
From cb16e25c0a11b1b0c0d374ca93816064ef692fea Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 20:04:36 +0100
Subject: [PATCH 177/241] specify tests directory for phpunit
---
.travis.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index f327250..f0ced61 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,3 +13,5 @@ services:
before_script:
- ./tests/setup/db-mysql.sh
- ./tests/setup/profile.sh travis
+
+script: phpunit tests
From 93b94cf4b5a0c335787ad4a63099c47300621542 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 20:07:06 +0100
Subject: [PATCH 178/241] add first test class UserTest
---
tests/UserTest.php | 72 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 tests/UserTest.php
diff --git a/tests/UserTest.php b/tests/UserTest.php
new file mode 100644
index 0000000..f2383f3
--- /dev/null
+++ b/tests/UserTest.php
@@ -0,0 +1,72 @@
+
\ No newline at end of file
From 0250690fdd9f7438b62ca50551c0640ed817585c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 20:47:46 +0100
Subject: [PATCH 179/241] enable coloured output
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index f0ced61..6deebea 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,4 +14,4 @@ before_script:
- ./tests/setup/db-mysql.sh
- ./tests/setup/profile.sh travis
-script: phpunit tests
+script: phpunit --colors tests
From f12bbcb6d472edf6b3ea286c4ea4d0d6ada91b60 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 21 Mar 2013 20:48:00 +0100
Subject: [PATCH 180/241] add more debug info on failing test
---
User.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/User.php b/User.php
index 8bd2f9b..9cd657e 100644
--- a/User.php
+++ b/User.php
@@ -231,7 +231,7 @@ public static function create($name, $mail, $pw) {
$db_query = 'INSERT INTO ' . DB_TABLE_USERS . ' (`id`, `name`, `mail`, `pw`) VALUES (UNHEX(REPLACE(UUID(), "-", "")), "' . $name . '", "' . $mail . '", "' . $pw . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
- throw new HttpException(500);
+ throw new HttpException(500, NULL, mysql_error());
}
}
}
From 15f55836761bade2e16a7fb99eac838c07ea8ffc Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 12:53:01 +0100
Subject: [PATCH 181/241] remove git submodule cloning (done by travis)
---
.travis.yml | 3 ---
1 file changed, 3 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 6deebea..02fc4d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,9 +4,6 @@ php:
- "5.3"
- "5.2"
-before_install:
- - git submodule update --init --recursive
-
services:
- mysql
From 8b616e0e35cb98bca6efd23f6ad1c658a3a2d486 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 15:03:42 +0100
Subject: [PATCH 182/241] move common sorting code to new SortHelper class
---
SortHelper.php | 34 ++++++++++++++++++++++++++++++++++
items/list.php | 7 ++++---
sort_get_order_clause.php | 19 -------------------
users/list.php | 4 ++--
4 files changed, 40 insertions(+), 24 deletions(-)
create mode 100644 SortHelper.php
delete mode 100644 sort_get_order_clause.php
diff --git a/SortHelper.php b/SortHelper.php
new file mode 100644
index 0000000..3cacaf9
--- /dev/null
+++ b/SortHelper.php
@@ -0,0 +1,34 @@
+ $dir) {
+ if (array_key_exists($key, $allowed)) {
+ $db_order .= ($db_order) ? ', ' : 'ORDER BY ';
+ $db_order .= $allowed[$key] . ' ' . ($dir ? 'ASC' : 'DESC');
+ }
+ # TODO: throw an error here?
+ }
+
+ return $db_order;
+ }
+
+ public static function getListFromParam($param) {
+ $parts = explode(' ', $param);
+
+ $keys = array_map(array('SortHelper', '_cleanupSortKey'), $parts);
+ $dirs = array_map(array('SortHelper', '_getSortDir'), $parts);
+
+ return array_combine($keys, $dirs);
+ }
+
+ static function _cleanupSortKey($k) {
+ return ltrim($k, '!');
+ }
+
+ static function _getSortDir($k) {
+ return substr($k, 0, 1) != '!';
+ }
+}
+?>
\ No newline at end of file
diff --git a/items/list.php b/items/list.php
index 9c81e96..d3730a3 100644
--- a/items/list.php
+++ b/items/list.php
@@ -2,7 +2,7 @@
require_once("../modules/HttpException/HttpException.php");
require_once("../db.php");
require_once("../util.php");
- require_once('../sort_get_order_clause.php');
+ require_once('../SortHelper.php');
require_once("../User.php");
require_once("../Assert.php");
require_once("../modules/semver/semver.php");
@@ -86,8 +86,9 @@
# retrieve sorting parameters
$sort_by_rating = false;
if (isset($_GET['sort'])) {
- $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => SQL_QUERY_RATING));
- $sort_by_rating = preg_match('/(^|\s)!?rating/', $_GET['sort']) == 1;
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ $db_order = SortHelper::getOrderClause($sort_list, array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => SQL_QUERY_RATING));
+ $sort_by_rating = array_key_exists('rating', $sort_list);
}
# enable rating filters if necessary
diff --git a/sort_get_order_clause.php b/sort_get_order_clause.php
deleted file mode 100644
index 2e85014..0000000
--- a/sort_get_order_clause.php
+++ /dev/null
@@ -1,19 +0,0 @@
- $dir) {
- if (array_key_exists($key, $allowed)) {
- $db_order .= ($db_order) ? ', ' : 'ORDER BY ';
- $db_order .= $allowed[$key] . ' ' . ($dir ? 'ASC' : 'DESC');
- }
- }
-
- return $db_order;
-}
-?>
\ No newline at end of file
diff --git a/users/list.php b/users/list.php
index 5b335b1..86a71b4 100644
--- a/users/list.php
+++ b/users/list.php
@@ -2,7 +2,7 @@
require_once("../modules/HttpException/HttpException.php");
require_once("../db.php");
require_once("../util.php");
- require_once('../sort_get_order_clause.php');
+ require_once('../SortHelper.php');
require_once('../sql2array.php');
require_once("../Assert.php");
require_once("../User.php");
@@ -36,7 +36,7 @@
}
if (isset($_GET['sort'])) {
- $db_order = sort_get_order_clause($_GET['sort'], array('name' => '`name`', 'joined' => '`joined`'));
+ $db_order = SortHelper::getOrderClause(SortHelper::getListFromParam($_GET['sort']), array('name' => '`name`', 'joined' => '`joined`'));
}
# retrieve filters
From 7c91da1aa75a7bf9af8ca5f53833abd1f3ad7afc Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 15:49:25 +0100
Subject: [PATCH 183/241] fix item retrieval for unpublished stdlib releases
Do not use the latest published, but the previous published release
as base release. Technically, this should always be the same as un-
published releases < latest published are deleted on cleanup. But it
enables us to make Stdlib::GetItemsUnpublished() private and reduce
code size
---
stdlib/Stdlib.php | 4 ++--
stdlib/releases/StdlibRelease.php | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index e7d1e44..c1dd32b 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -25,11 +25,11 @@ public static function GetItems($release)
return sql2array($db_result);
} else {
- return self::GetItemsUnpublished($release, StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES));
+ return self::GetItemsUnpublished($release, StdlibRelease::previousRelease($release, StdlibRelease::PUBLISHED_YES));
}
}
- public static function GetItemsUnpublished($release, $base) {
+ private static function GetItemsUnpublished($release, $base) {
$old_items = self::GetItems($base);
foreach ($old_items AS &$item) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index d8f3f94..69fc288 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -174,7 +174,7 @@ public static function publish($release) {
throw new HttpException(400, NULL, 'Cannot publish already published release!');
}
- $entries = Stdlib::GetItemsUnpublished($release, self::previousRelease($release, self::PUBLISHED_YES));
+ $entries = Stdlib::GetItems($release);
foreach ($entries AS $entry) {
Stdlib::writeEntry($release, $entry['id'], $entry['comment']);
StdlibPending::DeleteEntry($entry['id']);
From d5898054baf64c958646732e6ad92985c6d0a506 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 15:59:08 +0100
Subject: [PATCH 184/241] return NULL from StdlibRelease::getVersion()
This has more semantic meaning than the previous FALSE. But
more importantly, add NULL checks wherever this function is
used to prevent errors before the first release is published.
---
stdlib/Stdlib.php | 3 ++-
stdlib/StdlibPending.php | 14 ++++++++++++--
stdlib/candidates/create.php | 3 ++-
stdlib/pending/list.php | 3 +++
stdlib/releases/StdlibRelease.php | 2 +-
stdlib/releases/create.php | 3 +++
stdlib/releases/modify.php | 3 ++-
7 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index c1dd32b..de64a2c 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -30,7 +30,8 @@ public static function GetItems($release)
}
private static function GetItemsUnpublished($release, $base) {
- $old_items = self::GetItems($base);
+ $old_items = ($base !== NULL) ? self::GetItems($base) : array(); # catch $base = NULL in case there's no previous release
+
foreach ($old_items AS &$item) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index 27e5f3d..d47c971 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -28,9 +28,15 @@ public static function GetAllEntries()
public static function GetEntries($release) { # $release is not required to exist!
$base = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
- $release_update = UpdateType::getUpdate($base, $release); # get release update type
- $old_items = Stdlib::GetItems($base); # get items in base
+ if ($base !== NULL) {
+ $release_update = UpdateType::getUpdate($base, $release); # get release update type
+ $old_items = Stdlib::GetItems($base); # get items in base
+ } else { # in case there's no previous release
+ $release_update = UpdateType::PATCH; # this way, the first release can hold any suggested change (though there should only be ADD changes)
+ $old_items = array(); # no release => no previous items
+ }
+
foreach ($old_items AS &$item) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
@@ -151,6 +157,10 @@ public static function SetDelay($id, $delay = NULL) {
public static function cleanup() {
$latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ if ($latest_release === NULL) {
+ return; # we can't do any cleanup right now. When the TODOs below are implemented, they can be executed regardless of this.
+ }
+
$live_items = array_map(array('StdlibPending', 'sanitize_items'), Stdlib::GetItems($latest_release));
$pending = array_map(array('StdlibPending', 'sanitize_items'), self::GetAllEntries());
diff --git a/stdlib/candidates/create.php b/stdlib/candidates/create.php
index 4bd0cc5..20a9f7b 100644
--- a/stdlib/candidates/create.php
+++ b/stdlib/candidates/create.php
@@ -41,7 +41,8 @@
}
$deletion = false;
- if (Stdlib::releaseHasItem(StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES), $item)) {
+ $latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ if ($latest_release !== NULL && Stdlib::releaseHasItem($latest_release, $item)) {
if (!isset($_POST['delete']) || !in_array($_POST['delete'], array('1', 'true', 'yes'))) {
throw new HttpException(409, NULL, 'This item is already in the stdlib.');
}
diff --git a/stdlib/pending/list.php b/stdlib/pending/list.php
index a396449..028113a 100644
--- a/stdlib/pending/list.php
+++ b/stdlib/pending/list.php
@@ -20,6 +20,9 @@
}
$latest_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
+ if ($latest_release === NULL) {
+ $latest_release = '0.0.0';
+ }
$version = UpdateType::bumpVersion($latest_release, $release_update);
if (isset($_GET['release'])) {
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 69fc288..defd573 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -44,7 +44,7 @@ public static function getVersion($special_version, $published)
}
}
- return FALSE;
+ return NULL;
}
public static function describe($release, $published)
diff --git a/stdlib/releases/create.php b/stdlib/releases/create.php
index 6d33589..45bdbfc 100644
--- a/stdlib/releases/create.php
+++ b/stdlib/releases/create.php
@@ -39,6 +39,9 @@
# get latest release
$prev_release = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, $publish_status);
+ if ($prev_release === NULL) {
+ $prev_release = '0.0.0';
+ }
if (isset($_POST["version"]))
{
diff --git a/stdlib/releases/modify.php b/stdlib/releases/modify.php
index ecd7071..fde751d 100644
--- a/stdlib/releases/modify.php
+++ b/stdlib/releases/modify.php
@@ -38,8 +38,9 @@
throw new HttpException(400, NULL, "Incorrect release version!");
if (!StdlibRelease::exists($data["release"], StdlibRelease::PUBLISHED_BOTH)) # check if not already existing
throw new HttpException(409, NULL, "Release '$data[release]' already exists!");
+
$latest = StdlibRelease::getVersion(StdlibRelease::SPECIAL_VERSION_LATEST, StdlibRelease::PUBLISHED_YES);
- if (semver_compare($latest, $data['release']) != -1) # check if not below latest published release
+ if ($latest !== NULL && semver_compare($latest, $data['release']) != -1) # check if not below latest published release
throw new HttpException(400, NULL, "Can't modify release version: Newer release $latest already published!");
}
From ec7ac80154f3104026f2302e72a2bdf223731dcf Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 16:30:31 +0100
Subject: [PATCH 185/241] implement sorting for suspension list
Allow sorting by "created" and "expires". As the list is retrieved
by the Suspension class and not in users/suspensions/list directly,
this implementation slightly differs from the previous ones.
---
users/Suspension.php | 9 ++++++---
users/suspensions/list.php | 8 +++++++-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index 342c47a..a7e5aeb 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -1,6 +1,7 @@
'`created`', 'expires' => '`expires`'));
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `user` = UNHEX("' . $id . '")'
. ($active === NULL ? '' : ($active
? ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'
- : ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))'));
+ : ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))'))
+ . $sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/users/suspensions/list.php b/users/suspensions/list.php
index ea76854..60aa958 100644
--- a/users/suspensions/list.php
+++ b/users/suspensions/list.php
@@ -2,6 +2,7 @@
require_once('../../Assert.php');
require_once('../../modules/HttpException/HttpException.php');
require_once('../../util.php');
+require_once('../../SortHelper.php');
require_once('../../User.php');
require_once('../Suspension.php');
@@ -36,7 +37,12 @@
}
}
- $suspensions = Suspension::getSuspensionsById($id, $active);
+ $sort_list = array();
+ if (isset($_GET['sort'])) {
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ }
+
+ $suspensions = Suspension::getSuspensionsById($id, $active, $sort_list);
# cleanup the suspension entries
foreach ($suspensions AS $suspension) {
$suspension->created = $suspension->created->format(TIMESTAMP_FORMAT);
From dcd1c5258c945904092f13cfd62bebbe04d78349 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 16:44:02 +0100
Subject: [PATCH 186/241] configure travis to only build the testing branch
This is temporary and must be undone / adjusted when testing is merged.
[ci skip]
---
.travis.yml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index 02fc4d9..452fe2e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,3 +12,7 @@ before_script:
- ./tests/setup/profile.sh travis
script: phpunit --colors tests
+
+branches:
+ only:
+ - testing
From 1d28988879fc3efaa2abf91fd2a11f9d7dc9d4c4 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 16:56:31 +0100
Subject: [PATCH 187/241] testing: try changing character set to make tests
pass
---
tests/setup/db-mysql.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index fcb39e8..194e892 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -1,10 +1,10 @@
#! /usr/bin/env sh
# create the database
-mysql -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
+mysql --default-character-set=latin1 -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
# import the individual tables
for file in MySQL/*.sql;
do
- mysql -u root travis-test < "$file"
+ mysql --default-character-set=latin1 -u root travis-test < "$file"
done
From 0cdb6b8f5842bce4c428163a6b4df8c82ffd6e83 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:03:25 +0100
Subject: [PATCH 188/241] indent test setup output [ci skip]
---
tests/setup/profile.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/setup/profile.sh b/tests/setup/profile.sh
index 25a2ebc..1b5fca3 100755
--- a/tests/setup/profile.sh
+++ b/tests/setup/profile.sh
@@ -12,6 +12,6 @@ echo "Using config profile \"$1\"..."
for file in config/profiles/$1/*.php;
do
base=${file##*/}
- cp -v -f $file config/$base
+ cp -v -f $file config/$base | sed 's/^/ /'
done
echo "\n\n"
\ No newline at end of file
From 91ec3f8aa7aa5fde695fce174938f184416c93a6 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:19:35 +0100
Subject: [PATCH 189/241] To be sure, output MySQL encoding during test setup
---
tests/setup/db-mysql.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index 194e892..eb75956 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -8,3 +8,5 @@ for file in MySQL/*.sql;
do
mysql --default-character-set=latin1 -u root travis-test < "$file"
done
+
+php -r '$conn = mysql_connect("localhost", "root", ""); echo "MySQL client encoding: ", mysql_client_encoding($conn), "\n\n";'
\ No newline at end of file
From a3e2c6c92be4983f4cb4b3127c8c53dcafe3bc03 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:32:55 +0100
Subject: [PATCH 190/241] improve output for MySQL setup [ci skip]
---
tests/setup/db-mysql.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index eb75956..5a6c389 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -1,12 +1,17 @@
#! /usr/bin/env sh
+echo "Setting up MySQL for the tests..."
+
# create the database
+echo " Creating the database..."
mysql --default-character-set=latin1 -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
# import the individual tables
+echo " Importing the DB tables..."
for file in MySQL/*.sql;
do
+ echo " $file"
mysql --default-character-set=latin1 -u root travis-test < "$file"
done
-php -r '$conn = mysql_connect("localhost", "root", ""); echo "MySQL client encoding: ", mysql_client_encoding($conn), "\n\n";'
\ No newline at end of file
+php -r '$conn = mysql_connect("localhost", "root", ""); echo " MySQL client encoding: ", mysql_client_encoding($conn), "\n\n";'
\ No newline at end of file
From 467ae9d6200f1141f8c3f1957e085a2af6030efb Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:33:29 +0100
Subject: [PATCH 191/241] Adjust mysql encoding to travis
---
tests/setup/db-mysql.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index 5a6c389..85fbf03 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -4,14 +4,14 @@ echo "Setting up MySQL for the tests..."
# create the database
echo " Creating the database..."
-mysql --default-character-set=latin1 -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
+mysql --default-character-set=utf8 -u root -e 'CREATE DATABASE IF NOT EXISTS `travis-test`;'
# import the individual tables
echo " Importing the DB tables..."
for file in MySQL/*.sql;
do
echo " $file"
- mysql --default-character-set=latin1 -u root travis-test < "$file"
+ mysql --default-character-set=utf8 -u root travis-test < "$file"
done
php -r '$conn = mysql_connect("localhost", "root", ""); echo " MySQL client encoding: ", mysql_client_encoding($conn), "\n\n";'
\ No newline at end of file
From 7bd5e696ba81c1c484ad0ef403e93cdab02ea32d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:42:32 +0100
Subject: [PATCH 192/241] try fixing travis builds: set charset to latin1
---
db.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/db.php b/db.php
index a373016..6c674e3 100644
--- a/db.php
+++ b/db.php
@@ -17,6 +17,7 @@ function db_ensure_connection()
{
throw new HttpException(500);
}
+ mysql_set_charset('latin1', $connection);
}
return $connection;
}
From 94dbe5c58d56be8667fafa99c5316f155e2c6c3e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 17:48:48 +0100
Subject: [PATCH 193/241] changing the character set worked [ci skip]
---
tests/setup/db-mysql.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index 85fbf03..044fbdc 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -14,4 +14,4 @@ do
mysql --default-character-set=utf8 -u root travis-test < "$file"
done
-php -r '$conn = mysql_connect("localhost", "root", ""); echo " MySQL client encoding: ", mysql_client_encoding($conn), "\n\n";'
\ No newline at end of file
+php -r '$conn = mysql_connect("localhost", "root", ""); echo " MySQL client encoding: ", mysql_client_encoding($conn), " (will be changed to latin1)\n\n";'
\ No newline at end of file
From a190dc598d014b3931a2866ba6cadcfb129a81a9 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 22 Mar 2013 21:54:17 +0100
Subject: [PATCH 194/241] include status images in README
[ci skip]
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index dcdb4f4..bfe2d8a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
# ALD
+[](http://travis-ci.org/maul-esel/ALD-API)
+[](http://travis-ci.org/maul-esel/ALD-API)
+
***ALD*** is short for ***A***utoHotkey ***L***ibrary ***D***istribution. It is a system for management, distribution and installation of libraries and applications written in AutoHotkey.
This system consists of several parts. The most important part is the HTTP server API. Also, there can be a lot of different clients: websites, desktop apps and more.
More information on the ALD system can be read up [in the wiki](https://github.com/maul-esel/ALD-API/wiki/The-ALD-model).
From 9edb5abce90a0ed93e2b57fc09b465cfd1c47966 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Mar 2013 12:38:10 +0100
Subject: [PATCH 195/241] fix item list version sorting to obey semver
As MySQL does not allow custom comparison functions, this is a
little complicated:
- Add 3 stored MySQL functions / procedures that collect all compare
and sort the required semver data.
- Then add a method to SortHelper that collects the necessary data
beforehand and stores it in a temporary MySQL table.
- Last, fix items/list.php to allow multiple table joins and use one
to sort by version.
---
MySQL/code/semver_compare.sql | 39 +++++++++++++++++++++++++++++++++++
MySQL/code/semver_parts.sql | 21 +++++++++++++++++++
MySQL/code/semver_sort.sql | 36 ++++++++++++++++++++++++++++++++
SortHelper.php | 30 +++++++++++++++++++++++++++
items/list.php | 17 +++++++++++----
5 files changed, 139 insertions(+), 4 deletions(-)
create mode 100644 MySQL/code/semver_compare.sql
create mode 100644 MySQL/code/semver_parts.sql
create mode 100644 MySQL/code/semver_sort.sql
diff --git a/MySQL/code/semver_compare.sql b/MySQL/code/semver_compare.sql
new file mode 100644
index 0000000..fc0a6c5
--- /dev/null
+++ b/MySQL/code/semver_compare.sql
@@ -0,0 +1,39 @@
+DROP FUNCTION IF EXISTS semver_compare;
+
+DELIMITER //
+
+CREATE FUNCTION semver_compare(version1 varchar(50), version2 varchar(50))
+ RETURNS INT(1)
+ LANGUAGE SQL
+ DETERMINISTIC
+ BEGIN
+ CALL semver_parts(version1, @maj1, @min1, @pat1, @pre1, @build1);
+ CALL semver_parts(version2, @maj2, @min2, @pat2, @pre2, @build2);
+
+ SET @maj1 = CAST(@maj1 AS UNSIGNED), @maj2 = CAST(@maj2 AS UNSIGNED);
+ IF (@maj1 != @maj2) THEN
+ RETURN IF(@maj1 < @maj2, -1, 1);
+ END IF;
+
+ SET @min1 = CAST(@min1 AS UNSIGNED), @min2 = CAST(@min2 AS UNSIGNED);
+ IF (@min1 != @min2) THEN
+ RETURN IF(@min1 < @min2, -1, 1);
+ END IF;
+
+ SET @pat1 = CAST(@pat1 AS UNSIGNED), @pat2 = CAST(@pat2 AS UNSIGNED);
+ IF (@pat1 != @pat2) THEN
+ RETURN IF(@pat1 < @pat2, -1, 1);
+ END IF;
+
+ IF (@pre1 IS NULL AND @pre2 IS NOT NULL) THEN
+ RETURN 1;
+ ELSEIF (@pre1 IS NOT NULL AND @pre2 IS NULL) THEN
+ RETURN -1;
+ END IF;
+
+ -- TODO: no full prerelease / build support so far
+ RETURN 0;
+ END
+ //
+
+DELIMITER ;
\ No newline at end of file
diff --git a/MySQL/code/semver_parts.sql b/MySQL/code/semver_parts.sql
new file mode 100644
index 0000000..06f7daa
--- /dev/null
+++ b/MySQL/code/semver_parts.sql
@@ -0,0 +1,21 @@
+DROP PROCEDURE IF EXISTS semver_parts;
+
+DELIMITER //
+
+CREATE PROCEDURE semver_parts(IN version VARCHAR(50), OUT major VARCHAR(50), OUT minor VARCHAR(50), OUT patch VARCHAR(50), OUT prerelease VARCHAR(50), OUT build VARCHAR(50))
+ LANGUAGE SQL
+ DETERMINISTIC
+ BEGIN
+ SET @pre_start = INSTR(version, '-'), @build_start = INSTR(version, '+');
+ SET @end_patch = LEAST(IF(@pre_start = 0, LENGTH(version), @pre_start - 1), IF(@build_start = 0, LENGTH(version), @build_start - 1));
+
+ SELECT SUBSTRING_INDEX(version, '.', 1) INTO major;
+ SELECT TRIM(LEADING CONCAT(major, '.') FROM SUBSTRING_INDEX(version, '.', 2)) INTO minor;
+ SELECT SUBSTRING(version, LOCATE('.', version, @t := LENGTH(CONCAT(major, '.', minor, '.'))) + 1, @end_patch - @t) INTO patch;
+
+ SELECT (CASE @pre_start WHEN 0 THEN NULL ELSE SUBSTRING(version, @pre_start + 1, IF(@build_start = 0, LENGTH(version), @build_start - @pre_start - 1)) END) INTO prerelease;
+ SELECT (CASE @build_start WHEN 0 THEN NULL ELSE SUBSTRING(version, @build_start + 1, LENGTH(version)) END) INTO build;
+ END;
+ //
+
+DELIMITER ;
\ No newline at end of file
diff --git a/MySQL/code/semver_sort.sql b/MySQL/code/semver_sort.sql
new file mode 100644
index 0000000..ce860dd
--- /dev/null
+++ b/MySQL/code/semver_sort.sql
@@ -0,0 +1,36 @@
+DROP PROCEDURE IF EXISTS semver_sort;
+
+DELIMITER //
+
+CREATE PROCEDURE semver_sort()
+ LANGUAGE SQL
+ NOT DETERMINISTIC
+ MODIFIES SQL DATA
+ BEGIN
+ SELECT COUNT(*) INTO @length FROM `semver_index`;
+ SET @gap := @length, @swapped = FALSE;
+
+ WHILE (@gap > 1 || @swapped) DO -- an implementation of the comb sort algorithm (see )
+ IF @gap > 1 THEN
+ SET @gap := FLOOR(@gap / 1.3);
+ END IF;
+
+ SET @i := 1, @swapped := FALSE;
+ WHILE ((@j := @i + @gap) <= @length) DO
+ SELECT `version` INTO @a FROM `semver_index` WHERE `position` = @i; -- read the entries for comparison
+ SELECT `version` INTO @b FROM `semver_index` WHERE `position` = @j;
+
+ IF (semver_compare(@a, @b) > 0) THEN
+ UPDATE `semver_index` SET `position` = -1 WHERE `position` = @i; -- temp item
+ UPDATE `semver_index` SET `position` = @i WHERE `position` = @j;
+ UPDATE `semver_index` SET `position` = @j WHERE `position` = -1;
+
+ SET @swapped := TRUE;
+ END IF;
+ SET @i := @i + 1;
+ END WHILE;
+ END WHILE;
+ END;
+ //
+
+DELIMITER ;
\ No newline at end of file
diff --git a/SortHelper.php b/SortHelper.php
index 3cacaf9..fa29530 100644
--- a/SortHelper.php
+++ b/SortHelper.php
@@ -1,4 +1,7 @@
\ No newline at end of file
diff --git a/items/list.php b/items/list.php
index d3730a3..ea143bc 100644
--- a/items/list.php
+++ b/items/list.php
@@ -26,6 +26,7 @@
$db_cond = "";
$db_having = '';
$db_join = '';
+ $db_join_on = '';
$db_limit = "";
$db_order = '';
@@ -87,13 +88,19 @@
$sort_by_rating = false;
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
- $db_order = SortHelper::getOrderClause($sort_list, array('name' => '`name`', 'version' => '`version`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => SQL_QUERY_RATING));
+ $db_order = SortHelper::getOrderClause($sort_list, array('name' => '`name`', 'version' => '`position`', 'uploaded' => '`uploaded`', 'downloads' => '`downloads`', 'rating' => SQL_QUERY_RATING));
$sort_by_rating = array_key_exists('rating', $sort_list);
+ if (array_key_exists('version', $sort_list)) {
+ SortHelper::PrepareSemverSorting(DB_TABLE_ITEMS, 'version', $db_cond);
+ $db_join .= ($db_join ? ', ' : 'LEFT JOIN (') . '`semver_index`';
+ $db_join_on .= ($db_join_on ? ' AND ' : ' ON (') . '`data`.`version` = `semver_index`.`version`';
+ }
}
# enable rating filters if necessary
if ($get_rating = isset($_GET['rating']) || isset($_GET['rating-min']) || isset($_GET['rating-max']) || $sort_by_rating) {
- $db_join = 'LEFT JOIN ' . DB_TABLE_RATINGS . ' ON item = id';
+ $db_join .= ($db_join ? ', ' : 'LEFT JOIN (') . DB_TABLE_RATINGS;
+ $db_join_on .= ($db_join_on ? ' AND ' : ' ON (') . 'item = id';
if (isset($_GET['rating'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
@@ -124,9 +131,11 @@
$db_limit .= " OFFSET " . mysql_real_escape_string($_GET["start"], $db_connection);
}
+ $db_join_on .= $db_join_on ? ')' : ''; # clause braces if necessary
+ $db_join .= $db_join ? ')' : ''; # clause braces if necessary
# query data
- $db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, HEX(" . DB_TABLE_ITEMS . ".id) AS id, version"
- . " FROM " . DB_TABLE_ITEMS . ' ' . $db_join
+ $db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, HEX(" . DB_TABLE_ITEMS . ".id) AS id, " . DB_TABLE_ITEMS . '.version'
+ . " FROM " . DB_TABLE_ITEMS . ' ' . $db_join . $db_join_on
. " $db_cond $db_having $db_order $db_limit";
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
From 29f213d184c4145a027cfb0a22230cdd3ec26e8b Mon Sep 17 00:00:00 2001
From: maul-esel
Date: Sat, 23 Mar 2013 12:49:33 +0100
Subject: [PATCH 196/241] Update README.md
Change build image links to HTTPS
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index bfe2d8a..a7f018d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# ALD
-[](http://travis-ci.org/maul-esel/ALD-API)
-[](http://travis-ci.org/maul-esel/ALD-API)
+[](http://travis-ci.org/maul-esel/ALD-API)
+[](http://travis-ci.org/maul-esel/ALD-API)
***ALD*** is short for ***A***utoHotkey ***L***ibrary ***D***istribution. It is a system for management, distribution and installation of libraries and applications written in AutoHotkey.
This system consists of several parts. The most important part is the HTTP server API. Also, there can be a lot of different clients: websites, desktop apps and more.
@@ -22,4 +22,4 @@ You can watch active development in this repo. For example check the open [issue
If you wish further information, or want to get involved in development, be my guest. Just contact me, and if you want to contribute, fork the repo on github. I can then give you more information on planned features and tasks to complete.
## ALD Clients
-There are several clients for this backend in development. Most importantly, there's [libba.net](http://libba.net), the official website, which presents the data stored in the backend in a user-friendly way.
\ No newline at end of file
+There are several clients for this backend in development. Most importantly, there's [libba.net](http://libba.net), the official website, which presents the data stored in the backend in a user-friendly way.
From c30e9317f9b8065b046052f2b5e1819d8af6427e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Mar 2013 22:53:22 +0100
Subject: [PATCH 197/241] one more fix for getVersion() returning NULL
(d5898054ba)
Add a missing check in StdlibRelease::cleanup() which led to
a semver exception.
---
stdlib/releases/StdlibRelease.php | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index defd573..a2f8edf 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -219,16 +219,18 @@ public static function ListReleases($published)
}
public static function cleanup() {
- $latest_release = self::getVersion(self::SPECIAL_VERSION_LATEST, self::PUBLISHED_YES);
-
# ensure everything that should be published is published
self::publishPending();
- # ensure there are no downgrade releases
- $releases = self::ListReleases(self::PUBLISHED_NO);
- foreach ($releases AS $release) {
- if (semver_compare($latest_release, $release) > -1) {
- self::delete($release);
+ $latest_release = self::getVersion(self::SPECIAL_VERSION_LATEST, self::PUBLISHED_YES);
+
+ if ($latest_release !== NULL) {
+ # ensure there are no downgrade releases (only if there's actually a published release)
+ $releases = self::ListReleases(self::PUBLISHED_NO);
+ foreach ($releases AS $release) {
+ if (semver_compare($latest_release, $release) > -1) {
+ self::delete($release);
+ }
}
}
}
From 2bbf699540b62a1c29ab78ab78411e254e72fcf4 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Mar 2013 23:09:27 +0100
Subject: [PATCH 198/241] item list sorting: remove literal DB table name
---
items/list.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/items/list.php b/items/list.php
index ea143bc..64ff26f 100644
--- a/items/list.php
+++ b/items/list.php
@@ -93,7 +93,7 @@
if (array_key_exists('version', $sort_list)) {
SortHelper::PrepareSemverSorting(DB_TABLE_ITEMS, 'version', $db_cond);
$db_join .= ($db_join ? ', ' : 'LEFT JOIN (') . '`semver_index`';
- $db_join_on .= ($db_join_on ? ' AND ' : ' ON (') . '`data`.`version` = `semver_index`.`version`';
+ $db_join_on .= ($db_join_on ? ' AND ' : ' ON (') . '`' . DB_TABLE_ITEMS . '`.`version` = `semver_index`.`version`';
}
}
From cdf20342a24629c40799347e157f901799d14a0e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Mar 2013 23:31:01 +0100
Subject: [PATCH 199/241] Fix SortHelper for columns with different names
MySQLs 'CREATE TABLE ... SELECT' uses the source column names in
the destination table. To make the column names of the temporary
table independent from the source, use 'AS' to change the name.
---
SortHelper.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SortHelper.php b/SortHelper.php
index fa29530..5e7777c 100644
--- a/SortHelper.php
+++ b/SortHelper.php
@@ -48,7 +48,7 @@ public static function PrepareSemverSorting($table, $column, $db_cond = '') {
$db_query = 'CREATE TEMPORARY TABLE `semver_index` ('
. '`position` int NOT NULL AUTO_INCREMENT PRIMARY KEY,'
. '`version` varchar(50) NOT NULL'
- . ') SELECT DISTINCT `' . $column . '` FROM `' . $table . '` ' . $db_cond;
+ . ') SELECT DISTINCT `' . $column . '` AS version FROM `' . $table . '` ' . $db_cond;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
From 4447c0778c6ea30706da62f4bf8f06b7d7b60a11 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sat, 23 Mar 2013 23:32:59 +0100
Subject: [PATCH 200/241] add sorting support for stdlib release listing
Just as with suspension sorting, the logic is split between
stdlib/releases/list and the StdlibRelease class. Also take
semver into account when sorting by release version.
---
stdlib/releases/StdlibRelease.php | 13 +++++++++++--
stdlib/releases/list.php | 9 ++++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index a2f8edf..4858504 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -1,5 +1,6 @@
'`date`', 'release' => '`position`'));
+ if (array_key_exists('release', $sort)) { # sorting with semver needs special setup
+ SortHelper::PrepareSemverSorting(DB_TABLE_STDLIB_RELEASES, 'release', $db_cond);
+ $db_join = ' LEFT JOIN (`semver_index`) ON (`' . DB_TABLE_STDLIB_RELEASES . '`.`release` = `semver_index`.`version`) ';
+ }
+
# get all releases from DB
- $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_cond;
+ $db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_join . $db_cond . $db_sort;
$db_result = mysql_query($db_query, $db_connection);
if (!$db_result)
{
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index 095bd1e..c8bc35c 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -2,6 +2,7 @@
require_once("../../modules/HttpException/HttpException.php");
require_once("../../util.php");
require_once("../../User.php");
+ require_once('../../SortHelper.php');
require_once("../../Assert.php");
require_once("StdlibRelease.php");
@@ -27,10 +28,16 @@
# else if (in_array($published, array(1, "+1", "true", "yes"))) # the default
}
+ # add sort support
+ $sort_list = array();
+ if (isset($_GET['sort'])) {
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ }
+
# make sure all releases that should be published are published
StdlibRelease::publishPending();
- $releases = StdlibRelease::ListReleases($publish_status);
+ $releases = StdlibRelease::ListReleases($publish_status, $sort_list);
if ($content_type == "application/json")
{
From 81d18d7d311b8e4e3211b75043ab481e981fff7c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 13:46:39 +0100
Subject: [PATCH 201/241] support sorting by creation and approval date for
candidates
---
stdlib/candidates/Candidate.php | 9 +++++++--
stdlib/candidates/list.php | 7 ++++++-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 83d18d3..8099399 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -1,5 +1,6 @@
'`date`', 'approval' => '`approval`'));
foreach (array('item', 'user') AS $field) { # filter binary fields
if (isset($filters[$field])) {
@@ -206,7 +211,7 @@ public static function listCandidates($filters = array()) {
$db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . DB_TABLE_ITEMS . '.`user` = UNHEX("' . mysql_real_escape_string($filters['owner'], $db_connection) . '")';
}
- $db_query = 'SELECT ' . DB_TABLE_CANDIDATES . '.`id`, HEX(' . DB_TABLE_CANDIDATES. '.`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_join . $db_cond;
+ $db_query = 'SELECT ' . DB_TABLE_CANDIDATES . '.`id`, HEX(' . DB_TABLE_CANDIDATES. '.`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_join . $db_cond . ' ' . $db_sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 1ac5618..5d98a29 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -2,6 +2,7 @@
require_once('../../modules/HttpException/HttpException.php');
require_once('../../util.php');
require_once('../../Assert.php');
+require_once('../../SortHelper.php');
require_once('Candidate.php');
try {
@@ -9,7 +10,11 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $candidates = Candidate::listCandidates(array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner'))));
+ $filters = array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner')));
+ if (isset($_GET['sort'])) {
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ }
+ $candidates = Candidate::listCandidates($filters, isset($sort_list) ? $sort_list : array());
$filtered_candidates = array();
$status_map = array('accepted' => true, 'open' => NULL, 'rejected' => false);
From 1404928605fbaacaac9eb3f511b32b5b8c3bd4e2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 13:47:24 +0100
Subject: [PATCH 202/241] enable sorting support for candidate voting output
---
stdlib/candidates/.htaccess | 2 +-
stdlib/candidates/Candidate.php | 5 +++--
stdlib/candidates/voting.php | 6 +++++-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/stdlib/candidates/.htaccess b/stdlib/candidates/.htaccess
index 04cca09..bf32070 100644
--- a/stdlib/candidates/.htaccess
+++ b/stdlib/candidates/.htaccess
@@ -12,4 +12,4 @@ RewriteCond %{REQUEST_METHOD} =POST [NC]
RewriteRule ^(reject|accept)/(\d+)$ voting.php?id=$2&mode=$1 [L]
RewriteCond %{REQUEST_METHOD} =GET [NC]
-RewriteRule ^voting/(\d+)$ voting.php?id=$1 [L]
\ No newline at end of file
+RewriteRule ^voting/(\d+)$ voting.php?id=$1 [L,QSA]
\ No newline at end of file
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 8099399..2e7e5fe 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -219,11 +219,12 @@ public static function listCandidates($filters = array(), $sort = array()) {
return sql2array($db_result);
}
- public static function listVotings($candidate) {
+ public static function listVotings($candidate, $sort = array()) {
$db_connection = db_ensure_connection();
$candidate = (int)mysql_real_escape_string($candidate, $db_connection);
+ $db_sort = SortHelper::getOrderClause($sort, array('date' => '`date`'));
- $db_query = 'SELECT `candidate`, HEX(`user`) AS user, `accept`, `final`, `reason`, `date` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $candidate;
+ $db_query = 'SELECT `candidate`, HEX(`user`) AS user, `accept`, `final`, `reason`, `date` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $candidate . ' ' . $db_sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
diff --git a/stdlib/candidates/voting.php b/stdlib/candidates/voting.php
index c474bf3..0a866e7 100644
--- a/stdlib/candidates/voting.php
+++ b/stdlib/candidates/voting.php
@@ -2,6 +2,7 @@
require_once('../../modules/HttpException/HttpException.php');
require_once('../../util.php');
require_once('../../Assert.php');
+require_once('../../SortHelper.php');
require_once('../../User.php');
require_once('Candidate.php');
require_once('../StdlibPending.php');
@@ -47,7 +48,10 @@
Assert::GetParameters('id');
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $votings = Candidate::listVotings($_GET['id']);
+ if (isset($_GET['sort'])) {
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ }
+ $votings = Candidate::listVotings($_GET['id'], isset($sort_list) ? $sort_list : array());
if ($content_type == 'application/json') {
$content = json_encode($votings);
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
From 0cc701b54fc1e90fe65bc933130cbe80011d415c Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 13:57:50 +0100
Subject: [PATCH 203/241] fix Candidate::accepted() to return a bool
---
stdlib/candidates/Candidate.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 83d18d3..4cd35a8 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -76,7 +76,7 @@ public static function accepted($id) {
$accept = array();
while ($row = mysql_fetch_assoc($db_result)) {
if ($row['final'])
- return $row['accept']; # final decisions overwrite everything else (there must only be one of them)
+ return (bool)$row['accept']; # final decisions overwrite everything else (there must only be one of them)
$accept[$row['accept']] = $row['count'];
}
if (CANDIDATE_ALWAYS_REQUIRE_FINAL)
From 042bc9dc3d38483fcc5253d22dbd38d68b613d21 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 14:01:58 +0100
Subject: [PATCH 204/241] fix StdlibPending: MAJOR release can hold anything,
not PATCH
---
stdlib/StdlibPending.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index d47c971..b2e2599 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -33,7 +33,7 @@ public static function GetEntries($release) { # $release is not required to exis
$release_update = UpdateType::getUpdate($base, $release); # get release update type
$old_items = Stdlib::GetItems($base); # get items in base
} else { # in case there's no previous release
- $release_update = UpdateType::PATCH; # this way, the first release can hold any suggested change (though there should only be ADD changes)
+ $release_update = UpdateType::MAJOR; # this way, the first release can hold any suggested change (though there should only be ADD changes)
$old_items = array(); # no release => no previous items
}
From 6386bf530ea513670320995d813a6934c8318d3f Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 14:13:04 +0100
Subject: [PATCH 205/241] fix stdlib release description for first release
If there's no previous release still fetch a changelog.
Just assume an empty array for the old release's items.
---
stdlib/Stdlib.php | 2 +-
stdlib/releases/describe.php | 10 +++-------
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index de64a2c..44a5304 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -65,7 +65,7 @@ private static function GetItemsUnpublished($release, $base) {
}
public static function diff($old, $new) {
- $old_items = self::GetItems($old);
+ $old_items = $old !== NULL ? self::GetItems($old) : array();
foreach ($old_items AS &$item) {
$item = array_merge($item, Item::get($item['id'], array('name', 'version'))); # get name + version
}
diff --git a/stdlib/releases/describe.php b/stdlib/releases/describe.php
index 77c9642..25a41bf 100644
--- a/stdlib/releases/describe.php
+++ b/stdlib/releases/describe.php
@@ -37,18 +37,14 @@
if (StdlibRelease::exists($release['release'], StdlibRelease::PUBLISHED_YES)) {
$prev_release = StdlibRelease::previousRelease($release['release'], StdlibRelease::PUBLISHED_YES);
- if ($prev_release !== NULL) {
- $changeset = Stdlib::diff($prev_release, $release['release']);
- }
+ $changeset = Stdlib::diff($prev_release, $release['release']); # Stdlib::diff() can handle NULL as old release
} else {
$changeset = StdlibPending::GetEntries($release['release']);
}
$release['changelog'] = array();
- if (isset($changeset)) {
- foreach ($changeset AS $entry) {
- $release['changelog'][$entry['name']] = $entry['comment'];
- }
+ foreach ($changeset AS $entry) {
+ $release['changelog'][$entry['name']] = $entry['comment'];
}
if ($content_type == "application/json")
From b650f6ee2e927a40a73cb2a74f80187cc7f7c8ed Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 14:21:56 +0100
Subject: [PATCH 206/241] Add sort support for stdlib/items
Can now sort by name and version.
---
stdlib/items.php | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/stdlib/items.php b/stdlib/items.php
index 2fb7233..dffaf77 100644
--- a/stdlib/items.php
+++ b/stdlib/items.php
@@ -4,6 +4,7 @@
require_once('../sql2array.php');
require_once('../db.php');
require_once('../Assert.php');
+require_once('../SortHelper.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
@@ -11,6 +12,8 @@
$db_connection = db_ensure_connection();
$db_cond = '';
+ $db_sort = '';
+ $db_join = '';
if (isset($_GET['name'])) {
$db_cond .= 'AND name = "' . mysql_real_escape_string($_GET['name'], $db_connection) . '"';
@@ -22,7 +25,16 @@
$db_cond .= 'AND id = UNHEX("' . mysql_real_escape_string($_GET['id'], $db_connection) . '")';
}
- $db_query = 'SELECT name, version, HEX(`id`) AS id, GROUP_CONCAT(DISTINCT `release` SEPARATOR "\0") AS releases FROM ' . DB_TABLE_STDLIB . ', ' . DB_TABLE_ITEMS . ' WHERE item = id ' . $db_cond . ' GROUP BY name, version';
+ if (isset($_GET['sort'])) {
+ $sort_list = SortHelper::getListFromParam($_GET['sort']);
+ $db_sort = SortHelper::getOrderClause($sort_list, array('name' => '`name`', 'version' => '`position`'));
+ if (array_key_exists('version', $sort_list)) {
+ SortHelper::PrepareSemverSorting(DB_TABLE_ITEMS, 'version', $db_cond);
+ $db_join = ' LEFT JOIN `semver_index` ON (`' . DB_TABLE_ITEMS . '`.`version` = `semver_index`.`version`) ';
+ }
+ }
+
+ $db_query = 'SELECT name, `' . DB_TABLE_ITEMS . '`.`version`, HEX(`id`) AS id, GROUP_CONCAT(DISTINCT `release` SEPARATOR "\0") AS releases FROM ' . DB_TABLE_STDLIB . ', ' . DB_TABLE_ITEMS . $db_join . ' WHERE item = id ' . $db_cond . ' GROUP BY name, `' . DB_TABLE_ITEMS . '`.`version` ' . $db_sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500, NULL, mysql_error());
From 4a5fec911a19ff882c167bb80376252176d86ca3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 16:02:45 +0100
Subject: [PATCH 207/241] support prerelease and build parts when comparing
semver
---
MySQL/code/semver_compare.sql | 67 +++++++++++++++++++++++++++++++++--
1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/MySQL/code/semver_compare.sql b/MySQL/code/semver_compare.sql
index fc0a6c5..8eea44f 100644
--- a/MySQL/code/semver_compare.sql
+++ b/MySQL/code/semver_compare.sql
@@ -26,12 +26,75 @@ CREATE FUNCTION semver_compare(version1 varchar(50), version2 varchar(50))
END IF;
IF (@pre1 IS NULL AND @pre2 IS NOT NULL) THEN
- RETURN 1;
+ RETURN +1;
ELSEIF (@pre1 IS NOT NULL AND @pre2 IS NULL) THEN
RETURN -1;
+ ELSEIF (@pre1 IS NOT NULL AND @pre2 IS NOT NULL) THEN
+ -- compare each prerelease part
+ SELECT (LENGTH(@pre1) - LENGTH(REPLACE(@pre1, '.', ''))) / LENGTH('.') + 1 INTO @pre_parts1; -- count the number of parts
+ SELECT (LENGTH(@pre2) - LENGTH(REPLACE(@pre2, '.', ''))) / LENGTH('.') + 1 INTO @pre_parts2;
+ SET @m = 1;
+
+ WHILE (@m <= LEAST(@pre_parts1, @pre_parts2)) DO
+ SET @part1 = TRIM(LEADING CONCAT(SUBSTRING_INDEX(@pre1, '.', @m - 1), '.') FROM SUBSTRING_INDEX(@pre1, '.', @m));
+ SET @part2 = TRIM(LEADING CONCAT(SUBSTRING_INDEX(@pre2, '.', @m - 1), '.') FROM SUBSTRING_INDEX(@pre2, '.', @m));
+
+ IF (@part1 RLIKE '^[[:digit:]]+$' AND @part2 RLIKE '^[[:digit:]]+$') THEN
+ SET @part1 = CAST(@part1 AS SIGNED), @part2 = CAST(@part2 AS SIGNED);
+ IF (@part1 < @part2) THEN
+ RETURN -1;
+ ELSEIF (@part1 > @part2) THEN
+ RETURN +1;
+ END IF;
+ ELSEIF ((@cmp := STRCMP(@part1, @part2)) != 0) THEN
+ RETURN @cmp;
+ END IF;
+
+ SET @m = @m + 1;
+ END WHILE;
+
+ IF (@pre_parts1 < @pre_parts2) THEN -- the longer one wins
+ RETURN -1;
+ ELSEIF (@pre_parts2 > @pre_parts1) THEN
+ RETURN +1;
+ END IF;
+ END IF;
+
+ IF (@build1 IS NULL AND @build2 IS NOT NULL) THEN
+ RETURN -1;
+ ELSEIF (@build1 IS NOT NULL AND @build2 IS NULL) THEN
+ RETURN 1;
+ ELSEIF (@build1 IS NOT NULL AND @build2 IS NOT NULL) THEN
+ -- compare each build part
+ SELECT (LENGTH(@build1) - LENGTH(REPLACE(@build1, '.', ''))) / LENGTH('.') + 1 INTO @build_parts1; -- count the number of parts
+ SELECT (LENGTH(@build2) - LENGTH(REPLACE(@build2, '.', ''))) / LENGTH('.') + 1 INTO @build_parts2;
+ SET @m = 1;
+
+ WHILE (@m <= LEAST(@build_parts1, @build_parts2)) DO
+ SET @part1 = TRIM(LEADING CONCAT(SUBSTRING_INDEX(@build1, '.', @m - 1), '.') FROM SUBSTRING_INDEX(@build1, '.', @m));
+ SET @part2 = TRIM(LEADING CONCAT(SUBSTRING_INDEX(@build2, '.', @m - 1), '.') FROM SUBSTRING_INDEX(@build2, '.', @m));
+
+ IF (@part1 RLIKE '^[[:digit:]]+$' AND @part2 RLIKE '^[[:digit:]]+$') THEN
+ SET @part1 = CAST(@part1 AS SIGNED), @part2 = CAST(@part2 AS SIGNED);
+ IF (@part1 < @part2) THEN
+ RETURN -1;
+ ELSEIF (@part1 > @part2) THEN
+ RETURN +1;
+ END IF;
+ ELSEIF ((@cmp := STRCMP(@part1, @part2)) != 0) THEN
+ RETURN @cmp;
+ END IF;
+
+ SET @m = @m + 1;
+ END WHILE;
+
+ IF (@build_parts1 < @build_parts2) THEN -- the longer one wins
+ RETURN -1;
+ ELSEIF (@build_parts1 > @build_parts2) THEN
+ RETURN +1;
+ END IF;
END IF;
- -- TODO: no full prerelease / build support so far
RETURN 0;
END
//
From 1d690a918fbeae9101c0d0120121306d60ee29a0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 19:26:33 +0100
Subject: [PATCH 208/241] minor code shortening in Suspensions class
---
users/Suspension.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index a7e5aeb..b016daa 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -47,7 +47,7 @@ public static function clear() {
}
public static function isSuspended($user) {
- return self::isSuspendedById(User::getID($user));
+ return self::getSuspensions($user);
}
public static function isSuspendedById($id) {
From bab8c1de4215129302f1c535a54cfb5ce2674578 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 19:27:03 +0100
Subject: [PATCH 209/241] fix Suspension::getSuspensions() to pass on sorting
array
---
users/Suspension.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index b016daa..f2769a4 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -55,7 +55,7 @@ public static function isSuspendedById($id) {
}
public static function getSuspensions($user, $active = true, $sort = array()) {
- return self::getSuspensionsById(User::getID($user), $active);
+ return self::getSuspensionsById(User::getID($user), $active, $sort);
}
public static function getSuspensionsById($id, $active = true, $sort = array()) {
From ae78166f0ef97dbb359631de978eecff4618cdfd Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 20:01:58 +0100
Subject: [PATCH 210/241] add a lot of new filters to suspension listing
Move filter logic into the Suspension class. Add filters for
created, expires, infinite and restricted.
---
users/Suspension.php | 52 +++++++++++++++++++++++++++++++++-----
users/suspensions/list.php | 12 ++-------
2 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index f2769a4..419d78a 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -54,19 +54,57 @@ public static function isSuspendedById($id) {
return count(self::getSuspensionsById($id)) != 0;
}
- public static function getSuspensions($user, $active = true, $sort = array()) {
- return self::getSuspensionsById(User::getID($user), $active, $sort);
+ public static function getSuspensions($user, $filters = array(), $sort = array()) {
+ return self::getSuspensionsById(User::getID($user), $filters, $sort);
}
- public static function getSuspensionsById($id, $active = true, $sort = array()) {
+ public static function getSuspensionsById($id, $filters = array(), $sort = array()) {
$db_connection = db_ensure_connection();
$id = mysql_real_escape_string($id, $db_connection);
- $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'));
+
+ if (!is_array($filters)) {
+ throw new HttpException(500, NULL, 'Must pass a valid array as suspension filter!');
+ }
+
+ $db_cond = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
+ if (isset($filters['active'])) {
+ if (in_array($filters['active'], array('no', 'false', -1))) {
+ $db_cond = ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))';
+ } else if (in_array($filters['active'], array('both', 0))) {
+ $db_cond = ''; # empty to override the default
+ }
+ }
+
+ foreach (array('expires' => '`expires`', 'created' => '`created`') AS $property => $db_field) { # filter by creation and expiration date
+ foreach (array($property => '=', $property . '-after' => '>', $property . '-before' => '<') AS $field => $op) {
+ if (isset($filters[$field])) {
+ $db_cond .= ' AND ' . $db_field . ' ' . $op . ' "' . mysql_real_escape_string($filters[$field], $db_connection) . '"';
+ }
+ }
+ }
+
+ if (isset($filters['infinite'])) {
+ if (in_array($filters['infinite'], array('yes', 'true', '+1', 1))) {
+ $db_cond .= ' AND `expires` IS NULL';
+ } else if (in_array($filters['infinite'], array('no', 'false', -1))) {
+ $db_cond .= ' AND `expires` IS NOT NULL';
+ }
+ # default: both, 0
+ }
+
+ if (isset($filters['restricted'])) {
+ if (in_array($filters['restricted'], array('yes', 'true', '+1', 1))) {
+ $db_cond .= ' AND `restricted`';
+ } else if (in_array($filters['restricted'], array('no', 'false', -1))) {
+ $db_cond .= ' AND NOT `restricted`';
+ }
+ # default: both, 0
+ }
+
+ $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), ' WHERE TRUE AND ' . $db_cond); # must prefix here as long as $db_cond does not include WHERE itself
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `user` = UNHEX("' . $id . '")'
- . ($active === NULL ? '' : ($active
- ? ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'
- : ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))'))
+ . $db_cond
. $sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
diff --git a/users/suspensions/list.php b/users/suspensions/list.php
index 60aa958..73d112a 100644
--- a/users/suspensions/list.php
+++ b/users/suspensions/list.php
@@ -28,21 +28,13 @@
# validate accept header of request
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml', 'application/x-ald-package'), 'application/json');
- $active = true;
- if (isset($_GET['active'])) {
- if (in_array($_GET['active'], array('no', -1, 'false'))) {
- $active = false;
- } else if (in_array($_GET['active'], array('both', '0'))) {
- $active = NULL;
- }
- }
-
+ $filters = array_intersect_key($_GET, array_flip(array('active', 'created', 'created-after', 'created-before', 'expires', 'expires-after', 'expires-before', 'infinite', 'restricted')));
$sort_list = array();
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
}
- $suspensions = Suspension::getSuspensionsById($id, $active, $sort_list);
+ $suspensions = Suspension::getSuspensionsById($id, $filters, $sort_list);
# cleanup the suspension entries
foreach ($suspensions AS $suspension) {
$suspension->created = $suspension->created->format(TIMESTAMP_FORMAT);
From 90a3ff3574265eb7fde1894deb929c8dac5d4a07 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:29:19 +0100
Subject: [PATCH 211/241] begin a helper class for filtering
This should help shortening code and making it more readable. The
code filtering DB results defines its possible filters using this
class. Later on, it passes the actual filter data to it and recei-
ves the ready-to-use MySQL condition as result.
---
FilterHelper.php | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
create mode 100644 FilterHelper.php
diff --git a/FilterHelper.php b/FilterHelper.php
new file mode 100644
index 0000000..9e28b1e
--- /dev/null
+++ b/FilterHelper.php
@@ -0,0 +1,94 @@
+filters[] = $data; #array('name' => $name, 'db-name' => $db_name, $method => 'GET', 'operator' => $op, 'default' => $default, 'force-value' => $force);
+ }
+
+ public function evaluate($source, $prefix = ' WHERE ') { # support no|false|-1 vs true|yes|1|+1 vs both|0
+ $db_cond = '';
+
+ foreach ($this->filters AS $filter) {
+ unset($value);
+ $ignore = false;
+
+ # Get the value for comparison
+ if (isset($filter['value'])) { # a value has explicitly been specified
+ $value = $filter['value'];
+ } else if (isset($filter['name'])) { # a name to look for in the parameters (GET or POST) has been specified
+ if (isset($source[$filter['name']])) {
+ $value = $source[$filter['name']];
+ } else if (isset($filter['default'])) { # it is not specified in parameters, but a default was provided
+ $value = $filter['default'];
+ }
+ } else { # neither name nor value specified => error
+ throw new HttpException(500, NULL, 'Must specify "name" or "value" for filter');
+ }
+
+ if (!isset($filter['name']) && !isset($filter['db-name'])) {
+ throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
+ }
+ $key = isset($filter['db-name']) ? $filter['db-name'] : '`' . $filter['name'] . '`'; # the name is also used as column name if no other is specified
+
+ $null_check = isset($filter['null']) ? $filter['null'] : NULL;
+
+ if (!isset($value)) {
+ continue;
+ }
+
+ $value_type = $null_check !== NULL ? 'switch' : (isset($filter['type']) ? $filter['type'] : 'string');
+ switch ($value_type) {
+ case 'string':
+ $value = '"' . $value . '"';
+ break;
+ case 'int':
+ break;
+ case 'bool':
+ $value = is_bool($value) ? ($value ? 'TRUE' : 'FALSE') : $value;
+ break;
+ case 'binary':
+ $value = 'UNHEX("' . $value . '")';
+ break;
+ case 'switch':
+ if (in_array($value, array('yes', 'true', 1, '+1'))) {
+ $value = 'TRUE';
+ } else if (in_array($value, array('no', 'false', -1))) {
+ $value = 'FALSE';
+ } else if (in_array($value, array('both', '0'))) {
+ $ignore = true;
+ } else {
+ throw new HttpException(400, NULL, 'Invalid value "' . $value . '" for switch specified!');
+ }
+ break;
+ default:
+ throw new HttpException(500, NULL, 'Unsupported filter type "' . $value_type . '"');
+ }
+
+ if ($ignore) {
+ continue;
+ }
+
+ $db_cond .= ($db_cond ? ' AND ' : '') . $key;
+ if ($null_check === NULL) {
+ $operator = isset($filter['operator']) ? $filter['operator'] : '=';
+ $db_cond .= ' ' . $operator . ' ' . $value;
+ } else {
+ $db_cond .= ' IS ' . ((!$null_check xor $value == 'TRUE') ? 'NOT ' : '') . 'NULL';
+ }
+ }
+
+ return $db_cond ? $prefix . $db_cond : '';
+ }
+
+ public static function FromParams($filters, $source = NULL) {
+ $source = $source !== NULL ? $source : $_GET;
+ if (!is_array($source)) {
+ throw new HttpException(500, NULL, 'Must provide valid array as filter source');
+ }
+ return array_intersect_key($source, array_flip($filters));
+ }
+}
+?>
\ No newline at end of file
From 63dc4ff71ea071ca257762980a0487a4a78e332d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:33:07 +0100
Subject: [PATCH 212/241] Use new FilterHelper class for suspension filters
One last filter is still done using the old method as
FilterHelper is not yet ready to handle such complicated
conditions.
---
users/Suspension.php | 51 ++++++++++++++++----------------------
users/suspensions/list.php | 4 ++-
2 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index 419d78a..e776c44 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -2,6 +2,7 @@
require_once(dirname(__FILE__) . '/../db.php');
require_once(dirname(__FILE__) . '/../User.php');
require_once(dirname(__FILE__) . '/../SortHelper.php');
+require_once(dirname(__FILE__) . '/../FilterHelper.php');
require_once(dirname(__FILE__) . '/../sql2array.php');
require_once(dirname(__FILE__) . '/../modules/HttpException/HttpException.php');
require_once(dirname(__FILE__) . '/../config/suspensions.php');
@@ -66,40 +67,32 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
throw new HttpException(500, NULL, 'Must pass a valid array as suspension filter!');
}
- $db_cond = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
- if (isset($filters['active'])) {
- if (in_array($filters['active'], array('no', 'false', -1))) {
- $db_cond = ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))';
- } else if (in_array($filters['active'], array('both', 0))) {
- $db_cond = ''; # empty to override the default
- }
- }
+ $filter = new FilterHelper();
- foreach (array('expires' => '`expires`', 'created' => '`created`') AS $property => $db_field) { # filter by creation and expiration date
- foreach (array($property => '=', $property . '-after' => '>', $property . '-before' => '<') AS $field => $op) {
- if (isset($filters[$field])) {
- $db_cond .= ' AND ' . $db_field . ' ' . $op . ' "' . mysql_real_escape_string($filters[$field], $db_connection) . '"';
- }
- }
- }
+ $filter->add(array('db-name' => 'user', 'value' => $id, 'type' => 'binary'));
- if (isset($filters['infinite'])) {
- if (in_array($filters['infinite'], array('yes', 'true', '+1', 1))) {
- $db_cond .= ' AND `expires` IS NULL';
- } else if (in_array($filters['infinite'], array('no', 'false', -1))) {
- $db_cond .= ' AND `expires` IS NOT NULL';
- }
- # default: both, 0
- }
+ $filter->add(array('name' => 'expires'));
+ $filter->add(array('name' => 'expires-before', 'db-name' => 'expires', 'operator' => '<'));
+ $filter->add(array('name' => 'expires-after', 'db-name' => 'expires', 'operator' => '>'));
+
+ $filter->add(array('name' => 'created'));
+ $filter->add(array('name' => 'created-before', 'db-name' => 'created', 'operator' => '<'));
+ $filter->add(array('name' => 'created-after', 'db-name' => 'created', 'operator' => '>'));
+
+ $filter->add(array('name' => 'infinite', 'db-name' => '`expires`', 'null' => false));
+ $filter->add(array('name' => 'restricted', 'type' => 'switch'));
+
+ $db_cond = $filter->evaluate($filters, ' AND ');
- if (isset($filters['restricted'])) {
- if (in_array($filters['restricted'], array('yes', 'true', '+1', 1))) {
- $db_cond .= ' AND `restricted`';
- } else if (in_array($filters['restricted'], array('no', 'false', -1))) {
- $db_cond .= ' AND NOT `restricted`';
+ $db_cond_ = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
+ if (isset($filters['active'])) {
+ if (in_array($filters['active'], array('no', 'false', -1))) {
+ $db_cond_ = ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))';
+ } else if (in_array($filters['active'], array('both', 0))) {
+ $db_cond_ = ''; # empty to override the default
}
- # default: both, 0
}
+ $db_cond .= $db_cond_;
$sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), ' WHERE TRUE AND ' . $db_cond); # must prefix here as long as $db_cond does not include WHERE itself
diff --git a/users/suspensions/list.php b/users/suspensions/list.php
index 73d112a..728ed9e 100644
--- a/users/suspensions/list.php
+++ b/users/suspensions/list.php
@@ -3,6 +3,7 @@
require_once('../../modules/HttpException/HttpException.php');
require_once('../../util.php');
require_once('../../SortHelper.php');
+require_once('../../FilterHelper.php');
require_once('../../User.php');
require_once('../Suspension.php');
@@ -28,7 +29,8 @@
# validate accept header of request
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml', 'application/x-ald-package'), 'application/json');
- $filters = array_intersect_key($_GET, array_flip(array('active', 'created', 'created-after', 'created-before', 'expires', 'expires-after', 'expires-before', 'infinite', 'restricted')));
+ $filters = FilterHelper::FromParams(array('active', 'created', 'created-after', 'created-before', 'expires', 'expires-after', 'expires-before', 'infinite', 'restricted'));
+
$sort_list = array();
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
From 9103bfd50eedabb96b2f6321bd54f424cfe4a695 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:44:34 +0100
Subject: [PATCH 213/241] fix FilterHelper value conversion
Always escape strings for security, therefore pass
a connection ID. Also fix int and bool conversion.
Remove outdated comment.
---
FilterHelper.php | 9 +++++----
users/Suspension.php | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 9e28b1e..963c1b8 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -8,7 +8,7 @@ public function add($data) { #$name, $db_name = NULL, $method = 'GET', $op = '='
$this->filters[] = $data; #array('name' => $name, 'db-name' => $db_name, $method => 'GET', 'operator' => $op, 'default' => $default, 'force-value' => $force);
}
- public function evaluate($source, $prefix = ' WHERE ') { # support no|false|-1 vs true|yes|1|+1 vs both|0
+ public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
$db_cond = '';
foreach ($this->filters AS $filter) {
@@ -42,15 +42,16 @@ public function evaluate($source, $prefix = ' WHERE ') { # support no|false|-1 v
$value_type = $null_check !== NULL ? 'switch' : (isset($filter['type']) ? $filter['type'] : 'string');
switch ($value_type) {
case 'string':
- $value = '"' . $value . '"';
+ $value = '"' . mysql_real_escape_string($value, $db_connection) . '"';
break;
case 'int':
+ $value = (int)$value;
break;
case 'bool':
- $value = is_bool($value) ? ($value ? 'TRUE' : 'FALSE') : $value;
+ $value = $value ? 'TRUE' : 'FALSE';
break;
case 'binary':
- $value = 'UNHEX("' . $value . '")';
+ $value = 'UNHEX("' . mysql_real_escape_string($value, $db_connection) . '")';
break;
case 'switch':
if (in_array($value, array('yes', 'true', 1, '+1'))) {
diff --git a/users/Suspension.php b/users/Suspension.php
index e776c44..3fe0e08 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -82,7 +82,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$filter->add(array('name' => 'infinite', 'db-name' => '`expires`', 'null' => false));
$filter->add(array('name' => 'restricted', 'type' => 'switch'));
- $db_cond = $filter->evaluate($filters, ' AND ');
+ $db_cond = $filter->evaluate($filters, $db_connection, ' AND ');
$db_cond_ = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
if (isset($filters['active'])) {
From a167ee3fd3791a277215887fba87076e6e4c9fbd Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:57:18 +0100
Subject: [PATCH 214/241] FilterHelper: escape column names always
---
FilterHelper.php | 2 +-
users/Suspension.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 963c1b8..3281549 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -31,7 +31,7 @@ public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
if (!isset($filter['name']) && !isset($filter['db-name'])) {
throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
}
- $key = isset($filter['db-name']) ? $filter['db-name'] : '`' . $filter['name'] . '`'; # the name is also used as column name if no other is specified
+ $key = '`' . (isset($filter['db-name']) ? $filter['db-name'] : $filter['name']) . '`'; # the name is also used as column name if no other is specified
$null_check = isset($filter['null']) ? $filter['null'] : NULL;
diff --git a/users/Suspension.php b/users/Suspension.php
index 3fe0e08..7fe4f00 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -79,7 +79,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$filter->add(array('name' => 'created-before', 'db-name' => 'created', 'operator' => '<'));
$filter->add(array('name' => 'created-after', 'db-name' => 'created', 'operator' => '>'));
- $filter->add(array('name' => 'infinite', 'db-name' => '`expires`', 'null' => false));
+ $filter->add(array('name' => 'infinite', 'db-name' => 'expires', 'null' => false));
$filter->add(array('name' => 'restricted', 'type' => 'switch'));
$db_cond = $filter->evaluate($filters, $db_connection, ' AND ');
From 7caa599852a401892a9d5089e73fad3ed5eb3898 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:58:04 +0100
Subject: [PATCH 215/241] fix null-check handling: was inversed
---
FilterHelper.php | 2 +-
users/Suspension.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 3281549..7508818 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -77,7 +77,7 @@ public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
$operator = isset($filter['operator']) ? $filter['operator'] : '=';
$db_cond .= ' ' . $operator . ' ' . $value;
} else {
- $db_cond .= ' IS ' . ((!$null_check xor $value == 'TRUE') ? 'NOT ' : '') . 'NULL';
+ $db_cond .= ' IS ' . (($null_check xor $value == 'TRUE') ? 'NOT ' : '') . 'NULL';
}
}
diff --git a/users/Suspension.php b/users/Suspension.php
index 7fe4f00..c8a68eb 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -79,7 +79,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$filter->add(array('name' => 'created-before', 'db-name' => 'created', 'operator' => '<'));
$filter->add(array('name' => 'created-after', 'db-name' => 'created', 'operator' => '>'));
- $filter->add(array('name' => 'infinite', 'db-name' => 'expires', 'null' => false));
+ $filter->add(array('name' => 'infinite', 'db-name' => 'expires', 'null' => true));
$filter->add(array('name' => 'restricted', 'type' => 'switch'));
$db_cond = $filter->evaluate($filters, $db_connection, ' AND ');
From 36d7ad9fb6eb4d22ba9914a05f64fe4b29ae90a0 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Sun, 24 Mar 2013 23:59:57 +0100
Subject: [PATCH 216/241] Suspension filters: remove duplication
Filtering for user has been redefined with the new class, so
remove its literal inclusion in the query. Thus, the special
prefix is no longer needed.
---
users/Suspension.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index c8a68eb..3843249 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -82,7 +82,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$filter->add(array('name' => 'infinite', 'db-name' => 'expires', 'null' => true));
$filter->add(array('name' => 'restricted', 'type' => 'switch'));
- $db_cond = $filter->evaluate($filters, $db_connection, ' AND ');
+ $db_cond = $filter->evaluate($filters, $db_connection);
$db_cond_ = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
if (isset($filters['active'])) {
@@ -96,9 +96,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), ' WHERE TRUE AND ' . $db_cond); # must prefix here as long as $db_cond does not include WHERE itself
- $db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `user` = UNHEX("' . $id . '")'
- . $db_cond
- . $sort;
+ $db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . $db_cond . $sort;
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
throw new HttpException(500);
From adbd1cb85da0c163ee9973e1837816988ddd1c94 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 00:04:00 +0100
Subject: [PATCH 217/241] Rewrite candidate list filters with new class
Again, one condition is still implemented in the old way
as FilterHelper can not yet handle table joins.
---
stdlib/candidates/Candidate.php | 30 +++++++++++-------------------
stdlib/candidates/list.php | 3 ++-
2 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 848f714..d8403b3 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -1,6 +1,7 @@
'`date`', 'approval' => '`approval`'));
- foreach (array('item', 'user') AS $field) { # filter binary fields
- if (isset($filters[$field])) {
- $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`' . $field . '` = UNHEX("' . mysql_real_escape_string($filters[$field], $db_connection) . '")';
- }
- }
+ $filter = new FilterHelper();
- foreach (array('created' => '=', 'created-after' => '>', 'created-before' => '<') AS $field => $op) { # filter creation date
- if (isset($filters[$field])) {
- $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`date` ' . $op . ' "' . mysql_real_escape_string($filters[$field], $db_connection) . '"';
- }
- }
+ $filter->add(array('name' => 'item', 'type' => 'binary'));
+ $filter->add(array('name' => 'user', 'type' => 'binary'));
- if (isset($filters['approved'])) {
- if (in_array($filters['approved'], array(1, '+1', 'yes', 'true'))) {
- $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`approval` IS NOT NULL';
- } else if (in_array($filters['approved'], array(-1, 'no', 'false'))) {
- $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . '`approval` IS NULL';
- }
- # else if (in_array($filters['approved'], array(0, 'both'))) - the default
- }
+ $filter->add(array('name' => 'created', 'db-name' => 'date'));
+ $filter->add(array('name' => 'created-before', 'db-name' => 'date', 'operator' => '<'));
+ $filter->add(array('name' => 'created-after', 'db-name' => 'date', 'operator' => '>'));
+
+ $filter->add(array('name' => 'approved', 'db-name' => 'approval', 'null' => false));
+
+ $db_cond = $filter->evaluate($filters, $db_connection);
if (isset($filters['owner'])) {
$db_join = ' LEFT JOIN ' . DB_TABLE_ITEMS . ' ON ' . DB_TABLE_CANDIDATES . '.`item` = ' . DB_TABLE_ITEMS . '.`id`';
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 5d98a29..4117bde 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -3,6 +3,7 @@
require_once('../../util.php');
require_once('../../Assert.php');
require_once('../../SortHelper.php');
+require_once('../../FilterHelper.php');
require_once('Candidate.php');
try {
@@ -10,7 +11,7 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- $filters = array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner')));
+ $filters = FilterHelper::FromParams(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner'));
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
}
From e4069359114a35f61669d530929d09a72b1b5b0a Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 00:12:54 +0100
Subject: [PATCH 218/241] undo meaningless whitespace change
---
users/suspensions/list.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/users/suspensions/list.php b/users/suspensions/list.php
index 728ed9e..c80737e 100644
--- a/users/suspensions/list.php
+++ b/users/suspensions/list.php
@@ -30,7 +30,6 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml', 'application/x-ald-package'), 'application/json');
$filters = FilterHelper::FromParams(array('active', 'created', 'created-after', 'created-before', 'expires', 'expires-after', 'expires-before', 'infinite', 'restricted'));
-
$sort_list = array();
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
From 7edb1d7539b6c0a1521b8ca4cc200e303e29c48b Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 00:20:06 +0100
Subject: [PATCH 219/241] some code shortening when retrieving sort data
---
stdlib/candidates/list.php | 6 ++----
stdlib/candidates/voting.php | 6 ++----
stdlib/releases/list.php | 5 +----
users/suspensions/list.php | 5 +----
4 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/stdlib/candidates/list.php b/stdlib/candidates/list.php
index 5d98a29..0532322 100644
--- a/stdlib/candidates/list.php
+++ b/stdlib/candidates/list.php
@@ -11,10 +11,8 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
$filters = array_intersect_key($_GET, array_flip(array('user', 'item', 'created', 'created-after', 'created-before', 'approved', 'owner')));
- if (isset($_GET['sort'])) {
- $sort_list = SortHelper::getListFromParam($_GET['sort']);
- }
- $candidates = Candidate::listCandidates($filters, isset($sort_list) ? $sort_list : array());
+ $sort_list = SortHelper::getListFromParam(isset($_GET['sort']) ? $_GET['sort'] : '');
+ $candidates = Candidate::listCandidates($filters, $sort_list);
$filtered_candidates = array();
$status_map = array('accepted' => true, 'open' => NULL, 'rejected' => false);
diff --git a/stdlib/candidates/voting.php b/stdlib/candidates/voting.php
index 0a866e7..7dc2f6b 100644
--- a/stdlib/candidates/voting.php
+++ b/stdlib/candidates/voting.php
@@ -48,10 +48,8 @@
Assert::GetParameters('id');
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
- if (isset($_GET['sort'])) {
- $sort_list = SortHelper::getListFromParam($_GET['sort']);
- }
- $votings = Candidate::listVotings($_GET['id'], isset($sort_list) ? $sort_list : array());
+ $sort_list = SortHelper::getListFromParam(isset($_GET['sort']) ? $_GET['sort'] : '');
+ $votings = Candidate::listVotings($_GET['id'], $sort_list);
if ($content_type == 'application/json') {
$content = json_encode($votings);
} else if ($content_type == 'text/xml' || $content_type == 'application/xml') {
diff --git a/stdlib/releases/list.php b/stdlib/releases/list.php
index c8bc35c..d8fe118 100644
--- a/stdlib/releases/list.php
+++ b/stdlib/releases/list.php
@@ -29,10 +29,7 @@
}
# add sort support
- $sort_list = array();
- if (isset($_GET['sort'])) {
- $sort_list = SortHelper::getListFromParam($_GET['sort']);
- }
+ $sort_list = SortHelper::getListFromParam(isset($_GET['sort']) ? $_GET['sort'] : '');
# make sure all releases that should be published are published
StdlibRelease::publishPending();
diff --git a/users/suspensions/list.php b/users/suspensions/list.php
index 73d112a..e441002 100644
--- a/users/suspensions/list.php
+++ b/users/suspensions/list.php
@@ -29,10 +29,7 @@
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml', 'application/x-ald-package'), 'application/json');
$filters = array_intersect_key($_GET, array_flip(array('active', 'created', 'created-after', 'created-before', 'expires', 'expires-after', 'expires-before', 'infinite', 'restricted')));
- $sort_list = array();
- if (isset($_GET['sort'])) {
- $sort_list = SortHelper::getListFromParam($_GET['sort']);
- }
+ $sort_list = SortHelper::getListFromParam(isset($_GET['sort']) ? $_GET['sort'] : '');
$suspensions = Suspension::getSuspensionsById($id, $filters, $sort_list);
# cleanup the suspension entries
From 99c808b354453e8b36d148c9ca160bafc571ae74 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 12:29:24 +0100
Subject: [PATCH 220/241] cleanup FilterHelper code by breaking it into several
methods
---
FilterHelper.php | 99 +++++++++++++++++++++++++-----------------------
1 file changed, 52 insertions(+), 47 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 7508818..50cd302 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -12,63 +12,20 @@ public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
$db_cond = '';
foreach ($this->filters AS $filter) {
- unset($value);
- $ignore = false;
-
- # Get the value for comparison
- if (isset($filter['value'])) { # a value has explicitly been specified
- $value = $filter['value'];
- } else if (isset($filter['name'])) { # a name to look for in the parameters (GET or POST) has been specified
- if (isset($source[$filter['name']])) {
- $value = $source[$filter['name']];
- } else if (isset($filter['default'])) { # it is not specified in parameters, but a default was provided
- $value = $filter['default'];
- }
- } else { # neither name nor value specified => error
- throw new HttpException(500, NULL, 'Must specify "name" or "value" for filter');
- }
-
if (!isset($filter['name']) && !isset($filter['db-name'])) {
throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
}
$key = '`' . (isset($filter['db-name']) ? $filter['db-name'] : $filter['name']) . '`'; # the name is also used as column name if no other is specified
- $null_check = isset($filter['null']) ? $filter['null'] : NULL;
-
- if (!isset($value)) {
+ # Get the value for comparison
+ if (!self::extractValue($filter, $value)) {
continue;
}
+ $null_check = isset($filter['null']) ? $filter['null'] : NULL;
$value_type = $null_check !== NULL ? 'switch' : (isset($filter['type']) ? $filter['type'] : 'string');
- switch ($value_type) {
- case 'string':
- $value = '"' . mysql_real_escape_string($value, $db_connection) . '"';
- break;
- case 'int':
- $value = (int)$value;
- break;
- case 'bool':
- $value = $value ? 'TRUE' : 'FALSE';
- break;
- case 'binary':
- $value = 'UNHEX("' . mysql_real_escape_string($value, $db_connection) . '")';
- break;
- case 'switch':
- if (in_array($value, array('yes', 'true', 1, '+1'))) {
- $value = 'TRUE';
- } else if (in_array($value, array('no', 'false', -1))) {
- $value = 'FALSE';
- } else if (in_array($value, array('both', '0'))) {
- $ignore = true;
- } else {
- throw new HttpException(400, NULL, 'Invalid value "' . $value . '" for switch specified!');
- }
- break;
- default:
- throw new HttpException(500, NULL, 'Unsupported filter type "' . $value_type . '"');
- }
- if ($ignore) {
+ if (self::coerceValue($value, $value_type, $db_connection)) {
continue;
}
@@ -84,6 +41,54 @@ public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
return $db_cond ? $prefix . $db_cond : '';
}
+ private static function extractValue($filter, &$value) {
+ if (isset($filter['value'])) { # a value has explicitly been specified
+ $value = $filter['value'];
+ } else if (isset($filter['name'])) { # a name to look for in the parameters (GET or POST) has been specified
+ if (isset($source[$filter['name']])) {
+ $value = $source[$filter['name']];
+ } else if (isset($filter['default'])) { # it is not specified in parameters, but a default was provided
+ $value = $filter['default'];
+ } else {
+ return false;
+ }
+ } else { # neither name nor value specified => error
+ throw new HttpException(500, NULL, 'Must specify "name" or "value" for filter');
+ }
+
+ return true;
+ }
+
+ private static function coerceValue(&$value, $type, $db_connection) {
+ $ignore = false;
+
+ switch ($type) {
+ case 'string': $value = '"' . mysql_real_escape_string($value, $db_connection) . '"';
+ break;
+ case 'int': $value = (int)$value;
+ break;
+ case 'bool': $value = $value ? 'TRUE' : 'FALSE';
+ break;
+ case 'binary': $value = 'UNHEX("' . mysql_real_escape_string($value, $db_connection) . '")';
+ break;
+ case 'switch':
+ if (in_array($value, array('yes', 'true', 1, '+1'))) {
+ $value = 'TRUE';
+ } else if (in_array($value, array('no', 'false', -1))) {
+ $value = 'FALSE';
+ } else if (in_array($value, array('both', '0'))) {
+ $ignore = true;
+ } else {
+ throw new HttpException(400, NULL, 'Invalid value "' . $value . '" for switch specified!');
+ }
+ break;
+ default:
+ throw new HttpException(500, NULL, 'Unsupported filter type "' . $type . '"');
+ }
+
+ return $ignore;
+ }
+
public static function FromParams($filters, $source = NULL) {
$source = $source !== NULL ? $source : $_GET;
if (!is_array($source)) {
From 6e19a401210344ebfa3bc34f8f29651607cdcb0d Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 12:30:47 +0100
Subject: [PATCH 221/241] simplify suspension listing by removing duplication
(@36d7ad9fb6)
---
users/Suspension.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index 3843249..d1bea19 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -94,7 +94,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
}
$db_cond .= $db_cond_;
- $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), ' WHERE TRUE AND ' . $db_cond); # must prefix here as long as $db_cond does not include WHERE itself
+ $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), $db_cond);
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . $db_cond . $sort;
$db_result = mysql_query($db_query, $db_connection);
From 53a034d9ed38193dbe1174fa60c09a2d56f442e2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 20:11:52 +0100
Subject: [PATCH 222/241] massive changes to FilterHelper to support more
complex conditions
Pass the DB connection to the constructor. Split up into further
methods. For filters of type 'switch', allow a set of conditions
to be met. Validate comparison parameters. Add a new 'expr' type
and some structuring comments.
Use the modified FilterHelper class to re-implement the last pa-
rameter of the Suspension class. Adjust the filter code for can-
didate listing.
---
FilterHelper.php | 182 +++++++++++++++++++++++++++-----
stdlib/candidates/Candidate.php | 4 +-
users/Suspension.php | 27 +++--
3 files changed, 170 insertions(+), 43 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 50cd302..e84b865 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -4,49 +4,173 @@
class FilterHelper {
private $filters = array();
+ /*
+ * Public class instance interface
+ */
+ public function __construct($db_connection) {
+ $this->connection = $db_connection;
+ }
+
public function add($data) { #$name, $db_name = NULL, $method = 'GET', $op = '=', $default = NULL, $force = NULL) {
$this->filters[] = $data; #array('name' => $name, 'db-name' => $db_name, $method => 'GET', 'operator' => $op, 'default' => $default, 'force-value' => $force);
}
- public function evaluate($source, $db_connection, $prefix = ' WHERE ') {
+ public function evaluate($source, $prefix = ' WHERE ') {
$db_cond = '';
+ $this->source = $source;
foreach ($this->filters AS $filter) {
- if (!isset($filter['name']) && !isset($filter['db-name'])) {
- throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
- }
- $key = '`' . (isset($filter['db-name']) ? $filter['db-name'] : $filter['name']) . '`'; # the name is also used as column name if no other is specified
- # Get the value for comparison
- if (!self::extractValue($filter, $value)) {
- continue;
+ if (isset($filter['conditions'])) {
+ if ($filter['type'] != 'switch') {
+ throw new HttpException(500, NULL, 'Only filters of type "switch" can have conditions');
+ }
+ $conditions = $filter['conditions'];
+ } else {
+ $conditions = array($filter);
}
- $null_check = isset($filter['null']) ? $filter['null'] : NULL;
- $value_type = $null_check !== NULL ? 'switch' : (isset($filter['type']) ? $filter['type'] : 'string');
+ # if the filter is a switch and it is disabled: skip the entire thing
+ if (self::extractType($filter, $null) == 'switch') {
+ if ($this->extractValue($filter, $value)) {
+ if (!$this->coerceValue($value, 'switch')) { # returns false for disabled filters
+ continue;
+ }
+ }
+ }
- if (self::coerceValue($value, $value_type, $db_connection)) {
- continue;
+ $cond = $this->evaluateConditions($conditions, $filter);
+ if ($cond) {
+ $db_cond .= ($db_cond ? ' AND ' : '') . $cond;
}
+ }
+ return $db_cond ? $prefix . $db_cond : '';
+ }
+
+ /*
+ * Main conversion method
+ */
+ private function evaluateConditions($conditions, $filter) {
+ $logic = self::extractLogic($conditions);
+
+ $db_cond = '';
+ foreach ($conditions AS $condition) {
+ if (array_key_exists(0, $condition)) { # another array of sub-conditions
+ # obey the value of the switch containing this condition set by reversing it if the switch was turned off
+ if ($this->should_reverse_logic($filter, $filter_value)) {
+ $operator = self::reverseOperator($operator);
+ $logic = self::reverseLogic($logic);
+ }
+
+ $cond = $this->evaluateConditions($condition, $filter);
+ if ($cond) {
+ $db_cond .= ($db_cond ? ' ' . $logic . ' ' : '') . $cond;
+ }
- $db_cond .= ($db_cond ? ' AND ' : '') . $key;
- if ($null_check === NULL) {
- $operator = isset($filter['operator']) ? $filter['operator'] : '=';
- $db_cond .= ' ' . $operator . ' ' . $value;
} else {
- $db_cond .= ' IS ' . (($null_check xor $value == 'TRUE') ? 'NOT ' : '') . 'NULL';
+ $data = array_merge(self::FromParams(array('db-name', 'name', 'type', 'default'), $filter), $condition); # collect data
+
+ if (!isset($data['name']) && !isset($data['db-name'])) {
+ throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
+ }
+ $key = '`' . (isset($data['db-name']) ? $data['db-name'] : $data['name']) . '`'; # the name is also used as column name if no other is specified
+
+ # Get the value for comparison
+ if (!$this->extractValue($data, $value)) {
+ continue;
+ }
+
+ $value_type = self::extractType($data, $null_check);
+ if (!$this->coerceValue($value, $value_type)) {
+ continue;
+ }
+
+ if ($null_check === NULL) {
+ $operator = isset($data['operator']) ? $data['operator'] : '=';
+ self::validateOperator($operator);
+
+ # obey the value of the switch containing this condition by reversing it if the switch was turned off
+ if ($this->should_reverse_logic($filter, $filter_value) && $filter_value != $value) {
+ $operator = self::reverseOperator($operator);
+ $logic = self::reverseLogic($logic);
+ }
+
+ $db_cond .= ($db_cond ? ' ' . $logic . ' ' : '') . $key . ' ' . $operator . ' ' . $value;
+ } else {
+ $db_cond .= ($db_cond ? ' ' . $logic . ' ' : '') . $key . ' IS ' . (($null_check xor $value == 'TRUE') ? 'NOT ' : '') . 'NULL';
+ }
}
}
+ return $db_cond ? '(' . $db_cond . ')' : $db_cond;
+ }
- return $db_cond ? $prefix . $db_cond : '';
+ private function should_reverse_logic($filter, &$filter_value) {
+ if ($this->extractValue($filter, $filter_value)) {
+ $filter_value_type = self::extractType($filter, $filter_null);
+ if ($this->coerceValue($filter_value, $filter_value_type)) {
+ if ($filter_value_type == 'switch' && $filter_value == 'FALSE') {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Logic handling code
+ */
+ private static $logic_map = array('AND' => 'OR', 'OR' => 'AND');
+
+ private static function extractLogic(&$conditions) {
+ $logic = isset($conditions['logic']) ? strtoupper($conditions['logic']) : 'AND'; # default is 'AND'
+ self::validateLogic($logic);
+ unset($conditions['logic']); # avoid iterating through it below
+
+ return $logic;
+ }
+
+ private static function validateLogic($logic) {
+ if (!in_array($logic, array_keys(self::$logic_map))) {
+ throw new HttpException(500, NULL, 'Unsupported filter logic "' . $logic . '"');
+ }
+ }
+
+ private static function reverseLogic($logic) {
+ return self::$logic_map[$logic];
+ }
+
+ /*
+ * Type handling code
+ */
+ private static function extractType($filter, &$null_check) {
+ $null_check = isset($filter['null']) ? $filter['null'] : NULL;
+ return $null_check !== NULL ? 'switch' : (isset($filter['type']) ? $filter['type'] : 'string');
+ }
+
+ /*
+ * Operator handling code
+ */
+ private static $operator_map = array('>' => '<=', '<=' => '>', '<' => '>=', '>=' => '<', '=' => '!=', '!=' => '=');
+
+ private static function reverseOperator($operator) {
+ return self::$operator_map[$operator];
+ }
+
+ private static function validateOperator($operator) {
+ if (!in_array($operator, array_keys(self::$operator_map))) {
+ throw new HttpException(500, NULL, 'Unsupported filter operator "' . $operator . '"');
+ }
}
- private static function extractValue($filter, &$value) {
+ /*
+ * Value handling code
+ */
+ private function extractValue($filter, &$value) {
if (isset($filter['value'])) { # a value has explicitly been specified
$value = $filter['value'];
} else if (isset($filter['name'])) { # a name to look for in the parameters (GET or POST) has been specified
- if (isset($source[$filter['name']])) {
- $value = $source[$filter['name']];
+ if (isset($this->source[$filter['name']])) {
+ $value = $this->source[$filter['name']];
} else if (isset($filter['default'])) { # it is not specified in parameters, but a default was provided
$value = $filter['default'];
} else {
@@ -59,25 +183,26 @@ private static function extractValue($filter, &$value) {
return true;
}
- private static function coerceValue(&$value, $type, $db_connection) {
- $ignore = false;
+ private function coerceValue(&$value, $type) {
+ $success = true;
switch ($type) {
- case 'string': $value = '"' . mysql_real_escape_string($value, $db_connection) . '"';
+ case 'string': $value = '"' . mysql_real_escape_string($value, $this->connection) . '"';
break;
case 'int': $value = (int)$value;
break;
case 'bool': $value = $value ? 'TRUE' : 'FALSE';
break;
- case 'binary': $value = 'UNHEX("' . mysql_real_escape_string($value, $db_connection) . '")';
+ case 'binary': $value = 'UNHEX("' . mysql_real_escape_string($value, $this->connection) . '")';
break;
+ case 'expr': break;
case 'switch':
if (in_array($value, array('yes', 'true', 1, '+1'))) {
$value = 'TRUE';
} else if (in_array($value, array('no', 'false', -1))) {
$value = 'FALSE';
} else if (in_array($value, array('both', '0'))) {
- $ignore = true;
+ $success = false;
} else {
throw new HttpException(400, NULL, 'Invalid value "' . $value . '" for switch specified!');
}
@@ -86,9 +211,12 @@ private static function coerceValue(&$value, $type, $db_connection) {
throw new HttpException(500, NULL, 'Unsupported filter type "' . $type . '"');
}
- return $ignore;
+ return $success;
}
+ /*
+ * Public function for filtering HTTP params for supported filters
+ */
public static function FromParams($filters, $source = NULL) {
$source = $source !== NULL ? $source : $_GET;
if (!is_array($source)) {
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index d8403b3..a78a71b 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -185,7 +185,7 @@ public static function listCandidates($filters = array(), $sort = array()) {
$db_join = '';
$db_sort = SortHelper::getOrderClause($sort, array('date' => '`date`', 'approval' => '`approval`'));
- $filter = new FilterHelper();
+ $filter = new FilterHelper($db_connection);
$filter->add(array('name' => 'item', 'type' => 'binary'));
$filter->add(array('name' => 'user', 'type' => 'binary'));
@@ -196,7 +196,7 @@ public static function listCandidates($filters = array(), $sort = array()) {
$filter->add(array('name' => 'approved', 'db-name' => 'approval', 'null' => false));
- $db_cond = $filter->evaluate($filters, $db_connection);
+ $db_cond = $filter->evaluate($filters);
if (isset($filters['owner'])) {
$db_join = ' LEFT JOIN ' . DB_TABLE_ITEMS . ' ON ' . DB_TABLE_CANDIDATES . '.`item` = ' . DB_TABLE_ITEMS . '.`id`';
diff --git a/users/Suspension.php b/users/Suspension.php
index d1bea19..fe7dab2 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -61,13 +61,12 @@ public static function getSuspensions($user, $filters = array(), $sort = array()
public static function getSuspensionsById($id, $filters = array(), $sort = array()) {
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
if (!is_array($filters)) {
throw new HttpException(500, NULL, 'Must pass a valid array as suspension filter!');
}
- $filter = new FilterHelper();
+ $filter = new FilterHelper($db_connection);
$filter->add(array('db-name' => 'user', 'value' => $id, 'type' => 'binary'));
@@ -82,18 +81,18 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$filter->add(array('name' => 'infinite', 'db-name' => 'expires', 'null' => true));
$filter->add(array('name' => 'restricted', 'type' => 'switch'));
- $db_cond = $filter->evaluate($filters, $db_connection);
-
- $db_cond_ = ' AND (`active` AND (`expires` IS NULL OR `expires` > NOW()))'; # if no 'active' filter is specified, assume active = true
- if (isset($filters['active'])) {
- if (in_array($filters['active'], array('no', 'false', -1))) {
- $db_cond_ = ' AND (NOT `active` OR (`expires` IS NOT NULL AND `expires` <= NOW()))';
- } else if (in_array($filters['active'], array('both', 0))) {
- $db_cond_ = ''; # empty to override the default
- }
- }
- $db_cond .= $db_cond_;
-
+ $filter->add(array('name' => 'active', 'type' => 'switch', 'default' => 'true',
+ 'conditions' => array( # an array of conditions to be satisified
+ array('db-name' => 'active'), # the `active` field must be TRUE (see 'default' value of filter)
+ array( # a set of sub-conditions, to be combined using 'OR'
+ 'logic' => 'OR',
+ array('db-name' => 'expires', 'null' => true), # [if the filter is set,] 'expires' must either be NULL ...
+ array('db-name' => 'expires', 'operator' => '>', 'value' => 'NOW()', 'type' => 'expr') # ... or it must be > NOW()
+ )
+ )
+ ));
+
+ $db_cond = $filter->evaluate($filters);
$sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), $db_cond);
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . $db_cond . $sort;
From eadc5bfc86639d1a0bc2be143f5ebdc29a6da0c1 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 22:56:27 +0100
Subject: [PATCH 223/241] extend FilterHelper to handle table joins
Implement the last candidate filter with FilterHelper.
Adjust all calls as necessary.
---
FilterHelper.php | 42 ++++++++++++++++++++++++++++++---
stdlib/candidates/Candidate.php | 11 ++++-----
users/Suspension.php | 2 +-
3 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index e84b865..493aad2 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -7,8 +7,9 @@ class FilterHelper {
/*
* Public class instance interface
*/
- public function __construct($db_connection) {
+ public function __construct($db_connection, $table) {
$this->connection = $db_connection;
+ $this->table = $table;
}
public function add($data) { #$name, $db_name = NULL, $method = 'GET', $op = '=', $default = NULL, $force = NULL) {
@@ -47,6 +48,41 @@ public function evaluate($source, $prefix = ' WHERE ') {
return $db_cond ? $prefix . $db_cond : '';
}
+ public function evaluateJoins() {
+ $table_list = array();
+
+ foreach ($this->filters AS $filter) { # joins are only supported on filter-level
+ if (isset($filter['db-table']) && $filter['db-table'] != $this->table) {
+ if (!isset($filter['join-ref']) || !isset($filter['join-key'])) {
+ throw new HttpException(500, NULL, 'Must specify JOIN key and reference for filters');
+ }
+
+ if (!isset($table_list[$filter['db-table']])) {
+ $table_list[$filter['db-table']][$filter['join-ref']] = $filter['join-key'];
+ } else {
+ $table_list[$filter['db-table']] = array($filter['join-ref'] => $filter['join-key']);
+ }
+ }
+ }
+
+ if (count($table_list) > 0) {
+ array_walk($table_list, array($this, 'extractJoinCondition'));
+ return ' LEFT JOIN ' . implode(' AND ', array_keys($table_list)) . ' ON (' . implode(' AND ', $table_list) . ')';
+ }
+ return '';
+ }
+
+ /*
+ * Table join condition evaluation
+ */
+ function extractJoinCondition(&$arr, $tbl) {
+ $join = '';
+ foreach ($arr AS $ref => $key) {
+ $join .= ($join ? ' AND ' : '') . '`' . $this->table . '`.`' . $ref . '` = `' . $tbl . '`.`' . $key . '`';
+ }
+ $arr = $join;
+ }
+
/*
* Main conversion method
*/
@@ -68,12 +104,12 @@ private function evaluateConditions($conditions, $filter) {
}
} else {
- $data = array_merge(self::FromParams(array('db-name', 'name', 'type', 'default'), $filter), $condition); # collect data
+ $data = array_merge(self::FromParams(array('db-name', 'name', 'type', 'default', 'db-table', 'join-key', 'join-on'), $filter), $condition); # collect data
if (!isset($data['name']) && !isset($data['db-name'])) {
throw new HttpException(500, NULL, 'Must specify "name" or "db-name" for filter');
}
- $key = '`' . (isset($data['db-name']) ? $data['db-name'] : $data['name']) . '`'; # the name is also used as column name if no other is specified
+ $key = '`' . (isset($data['db-table']) ? $data['db-table'] : $this->table) . '`.`' . (isset($data['db-name']) ? $data['db-name'] : $data['name']) . '`'; # the name is also used as column name if no other is specified
# Get the value for comparison
if (!$this->extractValue($data, $value)) {
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index a78a71b..46fef8f 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -182,10 +182,9 @@ public static function listCandidates($filters = array(), $sort = array()) {
throw new Exception('Must provide a valid array for candidate sorting');
}
$db_connection = db_ensure_connection();
- $db_join = '';
$db_sort = SortHelper::getOrderClause($sort, array('date' => '`date`', 'approval' => '`approval`'));
- $filter = new FilterHelper($db_connection);
+ $filter = new FilterHelper($db_connection, DB_TABLE_CANDIDATES);
$filter->add(array('name' => 'item', 'type' => 'binary'));
$filter->add(array('name' => 'user', 'type' => 'binary'));
@@ -196,12 +195,10 @@ public static function listCandidates($filters = array(), $sort = array()) {
$filter->add(array('name' => 'approved', 'db-name' => 'approval', 'null' => false));
- $db_cond = $filter->evaluate($filters);
+ $filter->add(array('name' => 'owner', 'db-name' => 'user', 'type' => 'binary', 'db-table' => DB_TABLE_ITEMS, 'join-ref' => 'item', 'join-key' => 'id'));
- if (isset($filters['owner'])) {
- $db_join = ' LEFT JOIN ' . DB_TABLE_ITEMS . ' ON ' . DB_TABLE_CANDIDATES . '.`item` = ' . DB_TABLE_ITEMS . '.`id`';
- $db_cond .= ($db_cond ? ' AND ' : ' WHERE ') . DB_TABLE_ITEMS . '.`user` = UNHEX("' . mysql_real_escape_string($filters['owner'], $db_connection) . '")';
- }
+ $db_cond = $filter->evaluate($filters);
+ $db_join = $filter->evaluateJoins();
$db_query = 'SELECT ' . DB_TABLE_CANDIDATES . '.`id`, HEX(' . DB_TABLE_CANDIDATES. '.`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_join . $db_cond . ' ' . $db_sort;
$db_result = mysql_query($db_query, $db_connection);
diff --git a/users/Suspension.php b/users/Suspension.php
index fe7dab2..e8a4df8 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -66,7 +66,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
throw new HttpException(500, NULL, 'Must pass a valid array as suspension filter!');
}
- $filter = new FilterHelper($db_connection);
+ $filter = new FilterHelper($db_connection, DB_TABLE_SUSPENSIONS);
$filter->add(array('db-name' => 'user', 'value' => $id, 'type' => 'binary'));
From 571eb973b96141dd8a6695857ded5c18e3c3e206 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 23:00:54 +0100
Subject: [PATCH 224/241] remove undefined parameter from suspension sorting
Was added in ae78166f0e.
---
users/Suspension.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index 419d78a..22fc2f5 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -101,7 +101,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
# default: both, 0
}
- $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'), ' WHERE TRUE AND ' . $db_cond); # must prefix here as long as $db_cond does not include WHERE itself
+ $sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'));
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `user` = UNHEX("' . $id . '")'
. $db_cond
From 8105a4c86012ad56a544ee4dfc26cd449ad970c3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 23:39:41 +0100
Subject: [PATCH 225/241] minor code shortening for FilterHelper
---
FilterHelper.php | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 493aad2..4054a13 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -219,9 +219,8 @@ private function extractValue($filter, &$value) {
return true;
}
- private function coerceValue(&$value, $type) {
- $success = true;
+ private function coerceValue(&$value, $type) {
switch ($type) {
case 'string': $value = '"' . mysql_real_escape_string($value, $this->connection) . '"';
break;
@@ -238,7 +237,7 @@ private function coerceValue(&$value, $type) {
} else if (in_array($value, array('no', 'false', -1))) {
$value = 'FALSE';
} else if (in_array($value, array('both', '0'))) {
- $success = false;
+ return false;
} else {
throw new HttpException(400, NULL, 'Invalid value "' . $value . '" for switch specified!');
}
@@ -246,8 +245,7 @@ private function coerceValue(&$value, $type) {
default:
throw new HttpException(500, NULL, 'Unsupported filter type "' . $type . '"');
}
-
- return $success;
+ return true;
}
/*
From 635edd5796bd892d6f1bbc5f75894cae1e07e2bc Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 23:44:14 +0100
Subject: [PATCH 226/241] Shorten FilterHelper with new getValue() method
---
FilterHelper.php | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 4054a13..d283686 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -112,12 +112,7 @@ private function evaluateConditions($conditions, $filter) {
$key = '`' . (isset($data['db-table']) ? $data['db-table'] : $this->table) . '`.`' . (isset($data['db-name']) ? $data['db-name'] : $data['name']) . '`'; # the name is also used as column name if no other is specified
# Get the value for comparison
- if (!$this->extractValue($data, $value)) {
- continue;
- }
-
- $value_type = self::extractType($data, $null_check);
- if (!$this->coerceValue($value, $value_type)) {
+ if (!$this->getValue($data, $value, $null_check)) {
continue;
}
@@ -141,15 +136,10 @@ private function evaluateConditions($conditions, $filter) {
}
private function should_reverse_logic($filter, &$filter_value) {
- if ($this->extractValue($filter, $filter_value)) {
- $filter_value_type = self::extractType($filter, $filter_null);
- if ($this->coerceValue($filter_value, $filter_value_type)) {
- if ($filter_value_type == 'switch' && $filter_value == 'FALSE') {
- return true;
- }
- }
- }
- return false;
+ return $this->getValue($filter, $filter_value, $filter_null)
+ && $this->extractType($filter, $filter_null) == 'switch'
+ && !$filter_null
+ && $filter_value == 'FALSE';
}
/*
@@ -219,6 +209,10 @@ private function extractValue($filter, &$value) {
return true;
}
+ private function getValue($filter, &$value, &$null_check) {
+ $type = $this->extractType($filter, $null_check);
+ return $this->extractValue($filter, $value) AND $this->coerceValue($value, $type);
+ }
private function coerceValue(&$value, $type) {
switch ($type) {
From 4b52dd1ecd50c84c67d70c63a153637929c32c55 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 23:58:07 +0100
Subject: [PATCH 227/241] support values of type "custom" for filters
A coerce callback must be specified.
---
FilterHelper.php | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index d283686..42da266 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -34,7 +34,7 @@ public function evaluate($source, $prefix = ' WHERE ') {
# if the filter is a switch and it is disabled: skip the entire thing
if (self::extractType($filter, $null) == 'switch') {
if ($this->extractValue($filter, $value)) {
- if (!$this->coerceValue($value, 'switch')) { # returns false for disabled filters
+ if (!$this->coerceValue($value, 'switch', $filter)) { # returns false for disabled filters
continue;
}
}
@@ -211,10 +211,10 @@ private function extractValue($filter, &$value) {
private function getValue($filter, &$value, &$null_check) {
$type = $this->extractType($filter, $null_check);
- return $this->extractValue($filter, $value) AND $this->coerceValue($value, $type);
+ return $this->extractValue($filter, $value) AND $this->coerceValue($value, $type, $filter);
}
- private function coerceValue(&$value, $type) {
+ private function coerceValue(&$value, $type, $filter) {
switch ($type) {
case 'string': $value = '"' . mysql_real_escape_string($value, $this->connection) . '"';
break;
@@ -225,6 +225,12 @@ private function coerceValue(&$value, $type) {
case 'binary': $value = 'UNHEX("' . mysql_real_escape_string($value, $this->connection) . '")';
break;
case 'expr': break;
+ case 'custom':
+ if (!isset($filter['coerce']) || !is_callable($filter['coerce'])) {
+ throw new HttpException(500, NULL, 'None or invalid callback for filter value coerce');
+ }
+ $value = call_user_func($filter['coerce'], $value, $this->connection);
+ break;
case 'switch':
if (in_array($value, array('yes', 'true', 1, '+1'))) {
$value = 'TRUE';
From 3f93641403403723abb0a634e79f8bdfc17c47f3 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Mon, 25 Mar 2013 23:58:24 +0100
Subject: [PATCH 228/241] support REGEXP operator for filters
---
FilterHelper.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 42da266..294b043 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -176,7 +176,7 @@ private static function extractType($filter, &$null_check) {
/*
* Operator handling code
*/
- private static $operator_map = array('>' => '<=', '<=' => '>', '<' => '>=', '>=' => '<', '=' => '!=', '!=' => '=');
+ private static $operator_map = array('>' => '<=', '<=' => '>', '<' => '>=', '>=' => '<', '=' => '!=', '!=' => '=', 'REGEXP' => 'NOT REGEXP', 'NOT REGEXP' => 'REGEXP');
private static function reverseOperator($operator) {
return self::$operator_map[$operator];
From 62c4e00213366632755b21259c67b27edfb6b72e Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Tue, 26 Mar 2013 00:08:53 +0100
Subject: [PATCH 229/241] Convert item list filters to FilterHelper class
WARNING: This changes the outdated behaviour that the 'user'
filter took user names instead of IDs.
---
items/list.php | 62 +++++++++++++++-----------------------------------
1 file changed, 18 insertions(+), 44 deletions(-)
diff --git a/items/list.php b/items/list.php
index 64ff26f..406a5fd 100644
--- a/items/list.php
+++ b/items/list.php
@@ -3,6 +3,7 @@
require_once("../db.php");
require_once("../util.php");
require_once('../SortHelper.php');
+ require_once('../FilterHelper.php');
require_once("../User.php");
require_once("../Assert.php");
require_once("../modules/semver/semver.php");
@@ -23,58 +24,31 @@
$db_connection = db_ensure_connection();
# retrieve conditions for returned data from GET parameters
- $db_cond = "";
$db_having = '';
$db_join = '';
$db_join_on = '';
$db_limit = "";
$db_order = '';
- if (isset($_GET["type"]))
- {
- $db_cond = ($db_cond ? ' AND ' : 'WHERE '). "type = '" . ItemType::getCode($_GET["type"]) . "'";
- }
- if (isset($_GET["user"]))
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "user = UNHEX('" . User::getID($_GET["user"]) . "')";
- }
- if (isset($_GET["name"]))
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE ') . DB_TABLE_ITEMS . ".name = '" . mysql_real_escape_string($_GET["name"], $db_connection) . "'";
- }
- if (isset($_GET["tags"]))
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "tags REGEXP '(^|;)" . mysql_real_escape_string($_GET["tags"], $db_connection) . "($|;)'";
- }
+ $filter = new FilterHelper($db_connection, DB_TABLE_ITEMS);
- # reviewed and unreviewed items
- # ================================ #
- if (isset($_GET["reviewed"]) && in_array(strtolower($_GET["reviewed"]), array("no", "false", "-1")))
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "reviewed = '0'";
- }
- else if (isset($_GET["reviewed"]) && in_array(strtolower($_GET["reviewed"]), array("both", "0")))
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). "(reviewed = '0' OR reviewed = '1')";
- }
- else # default (use "yes", "true", "+1" or "1")
- {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). " reviewed = '1'";
- }
- # ================================ #
-
- # filter for download count
- if (isset($_GET['downloads'])) {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` = ' . (int)mysql_real_escape_string($_GET['downloads']);
- } else {
- if (isset($_GET['downloads-min'])) {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` >= ' . (int)mysql_real_escape_string($_GET['downloads-min']);
- }
- if (isset($_GET['downloads-max'])) {
- $db_cond .= ($db_cond ? ' AND ' : 'WHERE '). '`downloads` <= ' . (int)mysql_real_escape_string($_GET['downloads-max']);
- }
+ $filter->add(array('name' => 'type', 'type' => 'custom', 'coerce' => array('ItemType', 'getCode')));
+ $filter->add(array('name' => 'user', 'type' => 'binary')); # WARN: changes parameter to receive ID instead of name
+ $filter->add(array('name' => 'name'));
+ $filter->add(array('name' => 'reviewed', 'type' => 'switch')); # reviewed and unreviewed items
+
+ $filter->add(array('name' => 'downloads', 'type' => 'int')); # filter for download count
+ $filter->add(array('name' => 'downloads-min', 'db-name' => 'downloads', 'type' => 'int', 'operator' => '>='));
+ $filter->add(array('name' => 'downloads-max', 'db-name' => 'downloads', 'type' => 'int', 'operator' => '<='));
+
+ $filter->add(array('name' => 'tags', 'operator' => 'REGEXP', 'type' => 'custom', 'coerce' => 'coerce_regex'));
+ function coerce_regex($value, $db_connection) {
+ return '"(^|;)' . mysql_real_escape_string($value, $db_connection) . '($|;)"';
}
+ $db_cond = $filter->evaluate($_GET);
+
+ # special filtering (post-MySQL), thus not handled by FilterHelper
if (isset($_GET["version"]))
{
$version = strtolower($_GET["version"]);
@@ -97,7 +71,7 @@
}
}
- # enable rating filters if necessary
+ # enable rating filters if necessary (filter with HAVING instead of WHERE, not currently supported by FilterHelper)
if ($get_rating = isset($_GET['rating']) || isset($_GET['rating-min']) || isset($_GET['rating-max']) || $sort_by_rating) {
$db_join .= ($db_join ? ', ' : 'LEFT JOIN (') . DB_TABLE_RATINGS;
$db_join_on .= ($db_join_on ? ' AND ' : ' ON (') . 'item = id';
From 832dad531c38a10fe74ddc971ed71db5f1bb825f Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Tue, 26 Mar 2013 00:09:08 +0100
Subject: [PATCH 230/241] convert stdlib items filtering to FilterHelper class
---
stdlib/items.php | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/stdlib/items.php b/stdlib/items.php
index dffaf77..70ed5e1 100644
--- a/stdlib/items.php
+++ b/stdlib/items.php
@@ -5,25 +5,23 @@
require_once('../db.php');
require_once('../Assert.php');
require_once('../SortHelper.php');
+require_once('../FilterHelper.php');
try {
Assert::RequestMethod(Assert::REQUEST_METHOD_GET);
$content_type = get_preferred_mimetype(array('application/json', 'text/xml', 'application/xml'), 'application/json');
$db_connection = db_ensure_connection();
- $db_cond = '';
$db_sort = '';
$db_join = '';
- if (isset($_GET['name'])) {
- $db_cond .= 'AND name = "' . mysql_real_escape_string($_GET['name'], $db_connection) . '"';
- }
- if (isset($_GET['user'])) {
- $db_cond .= 'AND user = UNHEX("' . mysql_real_escape_string($_GET['user'], $db_connection) . '")';
- }
- if (isset($_GET['id'])) {
- $db_cond .= 'AND id = UNHEX("' . mysql_real_escape_string($_GET['id'], $db_connection) . '")';
- }
+ $filter = new FilterHelper($db_connection, DB_TABLE_STDLIB);
+
+ $filter->add(array('name' => 'name', 'db-table' => DB_TABLE_ITEMS));
+ $filter->add(array('name' => 'user', 'type' => 'binary', 'db-table' => DB_TABLE_ITEMS));
+ $filter->add(array('name' => 'id', 'type' => 'binary', 'db-table' => DB_TABLE_ITEMS));
+
+ $db_cond = $filter->evaluate($_GET, ' AND ');
if (isset($_GET['sort'])) {
$sort_list = SortHelper::getListFromParam($_GET['sort']);
From e3bff67b1b48bf22de89747a5298ce0376199835 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 27 Mar 2013 22:23:13 +0100
Subject: [PATCH 231/241] also test on PHP 5.5
---
.travis.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.travis.yml b/.travis.yml
index 452fe2e..e75765b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,6 @@
language: php
php:
+ - "5.5"
- "5.4"
- "5.3"
- "5.2"
From bac017cad5b73b128511f49c262b3fdfe64955a2 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Wed, 27 Mar 2013 22:24:22 +0100
Subject: [PATCH 232/241] undo whitespace and debugging changes
---
README.md | 2 +-
User.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index a7f018d..e776004 100644
--- a/README.md
+++ b/README.md
@@ -22,4 +22,4 @@ You can watch active development in this repo. For example check the open [issue
If you wish further information, or want to get involved in development, be my guest. Just contact me, and if you want to contribute, fork the repo on github. I can then give you more information on planned features and tasks to complete.
## ALD Clients
-There are several clients for this backend in development. Most importantly, there's [libba.net](http://libba.net), the official website, which presents the data stored in the backend in a user-friendly way.
+There are several clients for this backend in development. Most importantly, there's [libba.net](http://libba.net), the official website, which presents the data stored in the backend in a user-friendly way.
\ No newline at end of file
diff --git a/User.php b/User.php
index 9cd657e..8bd2f9b 100644
--- a/User.php
+++ b/User.php
@@ -231,7 +231,7 @@ public static function create($name, $mail, $pw) {
$db_query = 'INSERT INTO ' . DB_TABLE_USERS . ' (`id`, `name`, `mail`, `pw`) VALUES (UNHEX(REPLACE(UUID(), "-", "")), "' . $name . '", "' . $mail . '", "' . $pw . '")';
$db_result = mysql_query($db_query, $db_connection);
if ($db_result === FALSE) {
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500);
}
}
}
From 497197127d564466e2033d5bb179b56ba653847f Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 19:29:15 +0100
Subject: [PATCH 233/241] remove unused function
---
db.php | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/db.php b/db.php
index a373016..588702f 100644
--- a/db.php
+++ b/db.php
@@ -20,18 +20,4 @@ function db_ensure_connection()
}
return $connection;
}
-
- function db_get_enum_column_values($table, $column, &$values)
- {
- $db_connection = db_ensure_connection();
- $db_query = "SHOW COLUMNS IN $table WHERE Field = '" . mysql_real_escape_String($column) . "'";
- $db_result = mysql_query($db_query, $db_connection);
- if (!$db_result)
- {
- return false;
- }
- $data = mysql_fetch_assoc($db_result);
- $values = explode("','",substr($data["Type"],6,-2));
- return true;
- }
?>
\ No newline at end of file
From c46140ecbbd370307142637f0d7795421d8290cb Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 21:07:38 +0100
Subject: [PATCH 234/241] switch from MySQL extension to MySQLI
The old MySQL extension is deprecated and causes warnings in newer
PHP versions. Thus, switch to the new recommended mysqli extension.
---
FilterHelper.php | 4 +-
Item.php | 46 +++++++-------
SortHelper.php | 10 +--
User.php | 60 +++++++++---------
db.php | 8 +--
items/ItemType.php | 22 +++----
items/add.php | 10 +--
items/describe.php | 10 +--
items/list.php | 14 ++---
items/modify.php | 12 ++--
items/rating.php | 12 ++--
items/tags.php | 4 +-
sql2array.php | 2 +-
stdlib/Stdlib.php | 30 ++++-----
stdlib/StdlibPending.php | 34 +++++-----
stdlib/candidates/Candidate.php | 96 ++++++++++++++---------------
stdlib/items.php | 4 +-
stdlib/releases/StdlibRelease.php | 56 ++++++++---------
users/Suspension.php | 28 ++++-----
users/describe.php | 8 +--
users/list.php | 6 +-
users/modify.php | 18 +++---
users/registration/Registration.php | 30 ++++-----
23 files changed, 260 insertions(+), 264 deletions(-)
diff --git a/FilterHelper.php b/FilterHelper.php
index 294b043..8780664 100644
--- a/FilterHelper.php
+++ b/FilterHelper.php
@@ -216,13 +216,13 @@ private function getValue($filter, &$value, &$null_check) {
private function coerceValue(&$value, $type, $filter) {
switch ($type) {
- case 'string': $value = '"' . mysql_real_escape_string($value, $this->connection) . '"';
+ case 'string': $value = '"' . $this->connection->real_escape_string($value) . '"';
break;
case 'int': $value = (int)$value;
break;
case 'bool': $value = $value ? 'TRUE' : 'FALSE';
break;
- case 'binary': $value = 'UNHEX("' . mysql_real_escape_string($value, $this->connection) . '")';
+ case 'binary': $value = 'UNHEX("' . $this->connection->real_escape_string($value) . '")';
break;
case 'expr': break;
case 'custom':
diff --git a/Item.php b/Item.php
index 2bba61d..951852f 100644
--- a/Item.php
+++ b/Item.php
@@ -9,8 +9,8 @@ class Item
public static function getId($name, $version)
{
$db_connection = db_ensure_connection();
- $name = mysql_real_escape_string($name, $db_connection);
- $version = mysql_real_escape_string($version, $db_connection);
+ $name = $db_connection->real_escape_string($name);
+ $version = $db_connection->real_escape_string($version);
$db_cond = "name = '$name'";
if (!$special_version = in_array($version, array("latest", "first")))
@@ -19,19 +19,19 @@ public static function getId($name, $version)
}
$db_query = 'SELECT HEX(id) AS id, version FROM ' . DB_TABLE_ITEMS . ' WHERE ' . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- if (mysql_num_rows($db_result) < 1)
+ if ($db_result->num_rows < 1)
{
throw new HttpException(404);
}
if (!$special_version)
{
- $db_entry = mysql_fetch_assoc($db_result);
+ $db_entry = $db_result->fetch_assoc();
}
else
{
@@ -46,38 +46,38 @@ public static function getId($name, $version)
public static function get($id, array $cols)
{
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
+ $id = $db_connection->real_escape_string($id);
$db_query = 'SELECT ' . implode(', ', $c = array_map('EnwrapColName', $cols)) . ' FROM ' . DB_TABLE_ITEMS . " WHERE `id` = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- return mysql_fetch_assoc($db_result);
+ return $db_result->fetch_assoc();
}
public static function existsId($id)
{
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
+ $id = $db_connection->real_escape_string($id);
$db_query = "SELECT COUNT(*) FROM " . DB_TABLE_ITEMS . " WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- $db_entry = mysql_fetch_assoc($db_result);
+ $db_entry = $db_result->fetch_assoc();
return $db_entry["COUNT(*)"] > 0;
}
public static function exists($name, $version = NULL)
{
$db_connection = db_ensure_connection();
- $name = mysql_real_escape_string($name, $db_connection);
- $version = $version == NULL ? NULL : mysql_real_escape_string($version);
+ $name = $db_connection->real_escape_string($name);
+ $version = $version == NULL ? NULL : $db_connection->real_escape_string($version);
$db_cond = "name = '$name'";
if ($version != NULL)
@@ -86,13 +86,13 @@ public static function exists($name, $version = NULL)
}
$db_query = "SELECT COUNT(*) FROM " . DB_TABLE_ITEMS . " WHERE $db_cond";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- $db_entry = mysql_fetch_assoc($db_result);
+ $db_entry = $db_result->fetch_assoc();
return $db_entry["COUNT(*)"] > 0;
}
@@ -104,16 +104,16 @@ public static function getUser($name, $version)
public static function getUserForId($id)
{
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
+ $id = $db_connection->real_escape_string($id);
$db_query = "SELECT HEX(user) AS user FROM " . DB_TABLE_ITEMS . " WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- $db_entry = mysql_fetch_assoc($db_result);
+ $db_entry = $db_result->fetch_assoc();
return $db_entry["user"];
}
diff --git a/SortHelper.php b/SortHelper.php
index 5e7777c..fd5a931 100644
--- a/SortHelper.php
+++ b/SortHelper.php
@@ -36,11 +36,11 @@ static function _getSortDir($k) {
public static function PrepareSemverSorting($table, $column, $db_cond = '') {
$db_connection = db_ensure_connection();
- $table = mysql_real_escape_string($table, $db_connection);
- $column = mysql_real_escape_string($column, $db_connection);
+ $table = $db_connection->real_escape_string($table);
+ $column = $db_connection->real_escape_string($column);
$db_query = 'DROP TEMPORARY TABLE IF EXISTS `semver_index`';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -49,13 +49,13 @@ public static function PrepareSemverSorting($table, $column, $db_cond = '') {
. '`position` int NOT NULL AUTO_INCREMENT PRIMARY KEY,'
. '`version` varchar(50) NOT NULL'
. ') SELECT DISTINCT `' . $column . '` AS version FROM `' . $table . '` ' . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
$db_query = 'CALL semver_sort()';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
diff --git a/User.php b/User.php
index 8bd2f9b..101d1ae 100644
--- a/User.php
+++ b/User.php
@@ -75,19 +75,19 @@ public static function hasPrivilegeById($id, $privilege)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . mysql_real_escape_string($id, $db_connection) . "')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . $db_connection->real_escape_string($id) . "')";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1)
+ if ($db_result->num_rows != 1)
{
throw new HttpException(404, NULL, "User not found");
}
- $data = mysql_fetch_object($db_result);
+ $data = $db_result->fetch_object();
return (((int)$data->privileges) & $privilege) == $privilege;
}
@@ -95,19 +95,19 @@ public static function hasPrivilege($name, $privilege)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE name = '" . mysql_real_escape_string($name, $db_connection) . "'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE name = '" . $db_connection->real_escape_string($name) . "'";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1)
+ if ($db_result->num_rows != 1)
{
throw new HttpException(404, NULL, "User not found");
}
- $data = mysql_fetch_object($db_result);
+ $data = $db_result->fetch_object();
return (((int)$data->privileges) & $privilege) == $privilege;
}
@@ -115,26 +115,26 @@ public static function existsName($name)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT id FROM " . DB_TABLE_USERS . " WHERE name = '" . mysql_real_escape_string($name, $db_connection) . "'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT id FROM " . DB_TABLE_USERS . " WHERE name = '" . $db_connection->real_escape_string($name) . "'";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- return mysql_num_rows($db_result) == 1;
+ return $db_result->num_rows == 1;
}
public static function existsMail($mail)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT id FROM " . DB_TABLE_USERS . " WHERE mail = '" . mysql_real_escape_string($mail, $db_connection) . "'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT id FROM " . DB_TABLE_USERS . " WHERE mail = '" . $db_connection->real_escape_string($mail) . "'";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- return mysql_num_rows($db_result) == 1;
+ return $db_result->num_rows == 1;
}
public static function validateLogin($user, $pw)
@@ -142,21 +142,21 @@ public static function validateLogin($user, $pw)
$db_connection = db_ensure_connection();
$pw = hash("sha256", $pw);
- $escaped_user = mysql_real_escape_string($user, $db_connection);
+ $escaped_user = $db_connection->real_escape_string($user);
$db_query = "SELECT pw FROM " . DB_TABLE_USERS . " WHERE name = '$escaped_user'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1)
+ if ($db_result->num_rows != 1)
{
throw new HttpException(403, NULL, "User not found");
}
- $data = mysql_fetch_object($db_result);
+ $data = $db_result->fetch_object();
if ($data->pw != $pw)
{
throw new HttpException(403, NULL, "Invalid credentials were specified.");
@@ -172,14 +172,14 @@ public static function getName($id)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT name FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . mysql_real_escape_string($id, $db_connection) . "')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT name FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . $db_connection->real_escape_string($id) . "')";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- while ($data = mysql_fetch_object($db_result))
+ while ($data = $db_result->fetch_object())
{
return $data->name;
}
@@ -190,14 +190,14 @@ public static function getID($name)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT HEX(id) AS id FROM " . DB_TABLE_USERS . " WHERE name = '" . mysql_real_escape_string($name, $db_connection) . "'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT HEX(id) AS id FROM " . DB_TABLE_USERS . " WHERE name = '" . $db_connection->real_escape_string($name) . "'";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- while ($data = mysql_fetch_assoc($db_result))
+ while ($data = $db_result->fetch_assoc())
{
return $data["id"];
}
@@ -208,14 +208,14 @@ public static function getPrivileges($id)
{
$db_connection = db_ensure_connection();
- $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . mysql_real_escape_string($id, $db_connection) . "')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT privileges FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('" . $db_connection->real_escape_string($id) . "')";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- while ($data = mysql_fetch_assoc($db_result))
+ while ($data = $db_result->fetch_assoc())
{
return $data["privileges"];
}
@@ -224,12 +224,12 @@ public static function getPrivileges($id)
public static function create($name, $mail, $pw) {
$db_connection = db_ensure_connection();
- $name = mysql_real_escape_string($name, $db_connection);
- $mail = mysql_real_escape_string($mail, $db_connection);
+ $name = $db_connection->real_escape_string($name);
+ $mail = $db_connection->real_escape_string($mail);
$pw = hash('sha256', $pw);
$db_query = 'INSERT INTO ' . DB_TABLE_USERS . ' (`id`, `name`, `mail`, `pw`) VALUES (UNHEX(REPLACE(UUID(), "-", "")), "' . $name . '", "' . $mail . '", "' . $pw . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
diff --git a/db.php b/db.php
index 588702f..c7cb520 100644
--- a/db.php
+++ b/db.php
@@ -8,12 +8,8 @@ function db_ensure_connection()
if (!$connection)
{
- $connection = mysql_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD);
- if (!$connection)
- {
- throw new HttpException(500);
- }
- if (!mysql_select_db(DB_NAME, $connection))
+ $connection = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
+ if ($connection->connect_error || mysqli_connect_error() || $connection->error)
{
throw new HttpException(500);
}
diff --git a/items/ItemType.php b/items/ItemType.php
index 88070bd..a593812 100644
--- a/items/ItemType.php
+++ b/items/ItemType.php
@@ -8,36 +8,36 @@ class ItemType
public static function getCode($name)
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT code FROM ' . DB_TABLE_TYPES . ' WHERE name = \'' . mysql_real_escape_string($name, $db_connection) . '\'';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = 'SELECT code FROM ' . DB_TABLE_TYPES . ' WHERE name = \'' . $db_connection->real_escape_string($name) . '\'';
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, 'Could not read item type code: ' . mysql_error());
+ throw new HttpException(500, NULL, 'Could not read item type code: ' . $db_connection->error);
}
- if (mysql_num_rows($db_result) < 1)
+ if ($db_result->num_rows < 1)
{
throw new HttpException(400, NULL, "Item type '$name' is not supported!");
}
- $row = mysql_fetch_array($db_result);
+ $row = $db_result->fetch_array();
return $row['code'];
}
public static function getName($code)
{
$db_connection = db_ensure_connection();
- $db_query = 'SELECT name FROM ' . DB_TABLE_TYPES . ' WHERE code = \'' . mysql_real_escape_string($code, $db_connection) . '\'';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = 'SELECT name FROM ' . DB_TABLE_TYPES . ' WHERE code = \'' . $db_connection->real_escape_string($code) . '\'';
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, 'Could not read item type name: ' . mysql_error());
+ throw new HttpException(500, NULL, 'Could not read item type name: ' . $db_connection->error);
}
- if (mysql_num_rows($db_result) < 1)
+ if ($db_result->num_rows < 1)
{
throw new HttpException(500, NULL, "Item type '$code' is unknown!");
}
- $row = mysql_fetch_array($db_result);
+ $row = $db_result->fetch_array();
return $row['name'];
}
@@ -45,7 +45,7 @@ public static function getAllNames()
{
$db_connection = db_ensure_connection();
$db_query = 'SELECT name FROM ' . DB_TABLE_TYPES;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE)
{
throw new HttpException(500, NULL, 'Could not read supported item types!');
diff --git a/items/add.php b/items/add.php
index b754c4b..c8d6da7 100644
--- a/items/add.php
+++ b/items/add.php
@@ -56,10 +56,10 @@
###########################################################
# escape data to prevent SQL injection
- $escaped_name = mysql_real_escape_string($pack_name, $db_connection);
- $escaped_version = mysql_real_escape_string($pack_version, $db_connection);
- $escaped_description = mysql_real_escape_string($pack_description, $db_connection);
- $escaped_tags = mysql_real_escape_string($pack_tags, $db_connection);
+ $escaped_name = $db_connection->real_escape_string($pack_name);
+ $escaped_version = $db_connection->real_escape_string($pack_version);
+ $escaped_description = $db_connection->real_escape_string($pack_description);
+ $escaped_tags = $db_connection->real_escape_string($pack_tags);
# check if item type is supported and read the code
$escaped_type = ItemType::getCode($pack_type); # unsupported types throw an exception
@@ -93,7 +93,7 @@
# add the database entry
$db_query = "INSERT INTO " . DB_TABLE_ITEMS . " (id, name, type, version, user, description, tags)
VALUES (UNHEX('$pack_id'), '$escaped_name', '$escaped_type', '$escaped_version', UNHEX('" . User::getID($user) . "'), '$escaped_description', '$escaped_tags')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
unlink(UPLOAD_FOLDER . $pack_id . '.zip');
diff --git a/items/describe.php b/items/describe.php
index 41796fc..e56c549 100644
--- a/items/describe.php
+++ b/items/describe.php
@@ -26,7 +26,7 @@
}
else
{
- $id = mysql_real_escape_string($_GET["id"], $db_connection);
+ $id = $db_connection->real_escape_string($_GET["id"], $db_connection);
}
$file = UPLOAD_FOLDER . $id . '.zip';
@@ -37,7 +37,7 @@
}
$db_query = "UPDATE " . DB_TABLE_ITEMS . " Set downloads = downloads + 1 WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
@@ -57,16 +57,16 @@
. " WHERE `" . DB_TABLE_ITEMS . "`.`user` = `" . DB_TABLE_USERS . "`.`id` AND `" . DB_TABLE_RATINGS . "`.`item` = `" . DB_TABLE_ITEMS . "`.`id`" # table combination
. " AND `" . DB_TABLE_ITEMS . "`.`id` = UNHEX('$id') AND `reviewed` != '-1'"; # extra criteria
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1)
+ if ($db_result->num_rows != 1)
{
throw new HttpException(404);
}
- $db_entry = mysql_fetch_assoc($db_result);
+ $db_entry = $db_result->fetch_assoc();
$data = read_package($file);
diff --git a/items/list.php b/items/list.php
index 13eb7ac..3791036 100644
--- a/items/list.php
+++ b/items/list.php
@@ -43,7 +43,7 @@
$filter->add(array('name' => 'tags', 'operator' => 'REGEXP', 'type' => 'custom', 'coerce' => 'coerce_regex'));
function coerce_regex($value, $db_connection) {
- return '"(^|;)' . mysql_real_escape_string($value, $db_connection) . '($|;)"';
+ return '"(^|;)' . $db_connection->real_escape_string($value) . '($|;)"';
}
$db_cond = $filter->evaluate($_GET);
@@ -78,15 +78,15 @@ function coerce_regex($value, $db_connection) {
if (isset($_GET['rating'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating'], $db_connection) . ' = ' . SQL_QUERY_RATING;
+ $db_having .= $db_connection->real_escape_string($_GET['rating']) . ' = ' . SQL_QUERY_RATING;
} else {
if (isset($_GET['rating-min'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating-min'], $db_connection) . ' <= ' . SQL_QUERY_RATING;
+ $db_having .= $db_connection->real_escape_string($_GET['rating-min']) . ' <= ' . SQL_QUERY_RATING;
}
if (isset($_GET['rating-max'])) {
$db_having .= ($db_having) ? ' AND ' : 'HAVING ';
- $db_having .= mysql_real_escape_string($_GET['rating-max'], $db_connection) . ' >= ' . SQL_QUERY_RATING;
+ $db_having .= $db_connection->real_escape_string($_GET['rating-max']) . ' >= ' . SQL_QUERY_RATING;
}
}
}
@@ -94,7 +94,7 @@ function coerce_regex($value, $db_connection) {
# retrieve data limits
if (isset($_GET["count"]) && strtolower($_GET["count"]) != "all" && !isset($version)) # if version ("latest" or "first") is set, the data is shortened after being filtered
{
- $db_limit = "LIMIT " . mysql_real_escape_string($_GET["count"], $db_connection);
+ $db_limit = "LIMIT " . $db_connection->real_escape_string($_GET["count"]);
}
if (isset($_GET["start"]) && !isset($version)) # if version ("latest" or "first") is set, the data is shortened after being filtered
{
@@ -102,7 +102,7 @@ function coerce_regex($value, $db_connection) {
{
$db_limit = "LIMIT 18446744073709551615"; # Source: http://dev.mysql.com/doc/refman/5.5/en/select.html
}
- $db_limit .= " OFFSET " . mysql_real_escape_string($_GET["start"], $db_connection);
+ $db_limit .= " OFFSET " . $db_connection->real_escape_string($_GET["start"]);
}
$db_join_on .= $db_join_on ? ')' : ''; # clause braces if necessary
@@ -111,7 +111,7 @@ function coerce_regex($value, $db_connection) {
$db_query = "SELECT DISTINCT " . DB_TABLE_ITEMS . ".name, HEX(" . DB_TABLE_ITEMS . ".id) AS id, " . DB_TABLE_ITEMS . '.version'
. " FROM " . DB_TABLE_ITEMS . ' ' . $db_join . $db_join_on
. " $db_cond $db_having $db_order $db_limit";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
diff --git a/items/modify.php b/items/modify.php
index e30f2c0..2637774 100644
--- a/items/modify.php
+++ b/items/modify.php
@@ -21,7 +21,7 @@
}
else
{
- $id = mysql_real_escape_string($_GET["id"], $db_connection);
+ $id = $db_connection->real_escape_string($_GET["id"]);
}
if (!empty($_POST["user"]))
@@ -38,11 +38,11 @@
}
$db_query = "UPDATE " . DB_TABLE_ITEMS . " Set user = UNHEX('" . User::getID($_POST["user"]) . "') WHERE id = UNHEX('$id')";
- if (!mysql_query($db_query, $db_connection))
+ if (!$db_connection->query($db_query))
{
throw new HttpException(500);
}
- if (mysql_affected_rows() != 1)
+ if ($db_connection->affected_rows != 1)
{
throw new HttpException(404);
}
@@ -58,12 +58,12 @@
throw new HttpException(400);
}
- $db_query = "UPDATE " . DB_TABLE_ITEMS . " Set reviewed = '" . mysql_real_escape_string($_POST["reviewed"]) . "' WHERE id = UNHEX('$id')";
- if (!mysql_query($db_query, $db_connection))
+ $db_query = "UPDATE " . DB_TABLE_ITEMS . " Set reviewed = '" . $db_connection->real_escape_string($_POST["reviewed"]) . "' WHERE id = UNHEX('$id')";
+ if (!$db_connection->query($db_query))
{
throw new HttpException(500);
}
- if (mysql_affected_rows() != 1)
+ if ($db_connection->affected_rows != 1)
{
throw new HttpException(404);
}
diff --git a/items/rating.php b/items/rating.php
index dbbc0c0..bb463e5 100644
--- a/items/rating.php
+++ b/items/rating.php
@@ -23,7 +23,7 @@
}
else
{
- $id = mysql_real_escape_string($_GET["id"], $db_connection);
+ $id = $db_connection->real_escape_string($_GET["id"]);
}
$request_method = strtoupper($_SERVER['REQUEST_METHOD']);
@@ -31,7 +31,7 @@
Assert::PostParameters("rating");
user_basic_auth("Only registered users can rate items");
- $rating = (int)mysql_real_escape_string($_POST["rating"], $db_connection);
+ $rating = (int)$db_connection->real_escape_string($_POST["rating"]);
if ($rating < 0 || $rating > MAX_RATING)
{
throw new HttpException(400);
@@ -40,13 +40,13 @@
# check if user already voted
$user_id = User::getID($_SERVER["PHP_AUTH_USER"]);
$db_query = "SELECT * FROM " . DB_TABLE_RATINGS . " WHERE user = UNHEX('$user_id') AND item = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) > 0)
+ if ($db_result->num_rows > 0)
{
if (!CAN_UPDATE_RATING) {
throw new HttpException(409, NULL, 'The specified user already rated this item!');
@@ -58,7 +58,7 @@
$db_query = "INSERT INTO " . DB_TABLE_RATINGS . " (user, item, rating) VALUES (UNHEX('$user_id'), UNHEX('$id'), '$rating')"; # insert
}
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
@@ -71,7 +71,7 @@
$content_type = get_preferred_mimetype(array("application/json", "text/xml", "application/xml", "application/x-ald-package"), "application/json");
$db_query = 'SELECT name AS user, rating FROM ' . DB_TABLE_RATINGS . ', ' . DB_TABLE_USERS . ' WHERE item = UNHEX("' . $id . '") AND `user` = `id`';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result) {
throw new HttpException(500);
}
diff --git a/items/tags.php b/items/tags.php
index f48d8c5..2e9f335 100644
--- a/items/tags.php
+++ b/items/tags.php
@@ -14,13 +14,13 @@
$db_connection = db_ensure_connection();
$db_query = 'SELECT DISTINCT tags FROM ' . DB_TABLE_ITEMS;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result) {
throw new HttpException(500);
}
$tags = array();
- while ($row = mysql_fetch_array($db_result)) {
+ while ($row = $db_result->fetch_array()) {
$new_tags = explode(';', $row['tags']);
foreach ($new_tags AS $tag) {
$tags[$tag] = true; # keep tags as keys for simplicity, value is meaningless
diff --git a/sql2array.php b/sql2array.php
index 1aa6b77..08b3239 100644
--- a/sql2array.php
+++ b/sql2array.php
@@ -2,7 +2,7 @@
function sql2array($db_result, $item_handler = NULL) {
$arr = array();
$i = 0;
- while ($db_row = mysql_fetch_assoc($db_result)) {
+ while ($db_row = $db_result->fetch_assoc()) {
$key = $i;
$arr[$key] = $item_handler !== NULL ? (is_array($item_handler) ? call_user_func($item_handler, $db_row, $key) : $item_handler($db_row, $key)) : $db_row;
$i++;
diff --git a/stdlib/Stdlib.php b/stdlib/Stdlib.php
index 44a5304..7fe10e6 100644
--- a/stdlib/Stdlib.php
+++ b/stdlib/Stdlib.php
@@ -14,10 +14,10 @@ public static function GetItems($release)
{
if (StdlibRelease::exists($release, StdlibRelease::PUBLISHED_YES)) { # check if published
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
+ $release = $db_connection->real_escape_string($release);
$db_query = 'SELECT HEX(`item`) AS id, comment FROM ' . DB_TABLE_STDLIB . " WHERE `release` = '$release'";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
@@ -98,29 +98,29 @@ public static function diff($old, $new) {
public static function writeEntry($release, $id, $comment) {
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
- $id = mysql_real_escape_string($id, $db_connection);
- $comment = mysql_real_escape_string($comment, $db_connection);
+ $release = $db_connection->real_escape_string($release);
+ $id = $db_connection->real_escape_string($id);
+ $comment = $db_connection->real_escape_string($comment);
$db_query = 'INSERT INTO ' . DB_TABLE_STDLIB . ' (`release`, `item`, `comment`) VALUES ("' . $release . '", UNHEX("' . $id . '"), "' . $comment . '")';
- $db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ $db_result = $db_connection->query($db_query);
+ if ($db_result === FALSE || $db_connection->affected_rows < 1) {
throw new HttpException(500);
}
}
public static function releaseHasItem($release, $id) {
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
- $id= mysql_real_escape_string($id, $db_connection);
+ $release = $db_connection->real_escape_string($release);
+ $id = $db_connection->real_escape_string($id);
$db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $release . '" AND `item` = UNHEX("' . $id . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
public static function cleanup() {
@@ -128,14 +128,14 @@ public static function cleanup() {
# ensure not 2x stdlib with same item and release
$db_query = 'SELECT `release`, `item` FROM ' . DB_TABLE_STDLIB . ' GROUP BY `release`, `item` HAVING COUNT(*) > 1';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- while ($dup = mysql_fetch_assoc($db_result)) {
+ while ($dup = $db_result->fetch_assoc()) {
$db_query = 'DELETE FROM ' . DB_TABLE_STDLIB . ' WHERE `release` = "' . $dup['release'] . '" AND `item` = "' . $dup['item'] . '" LIMIT 1';
- $db_result2 = mysql_query($db_query, $db_connection);
+ $db_result2 = $db_connection->query($db_query);
if ($db_result2 === FALSE) {
throw new HttpException(500);
}
diff --git a/stdlib/StdlibPending.php b/stdlib/StdlibPending.php
index b2e2599..3b2ecb3 100644
--- a/stdlib/StdlibPending.php
+++ b/stdlib/StdlibPending.php
@@ -17,7 +17,7 @@ public static function GetAllEntries()
{
$db_connection = db_ensure_connection();
$db_query = 'SELECT HEX(`item`) AS id, comment, delay FROM ' . DB_TABLE_STDLIB_PENDING;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
@@ -95,11 +95,11 @@ public static function GetEntries($release) { # $release is not required to exis
public static function AddEntry($id, $comment)
{
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
- $comment = mysql_real_escape_string($comment, $db_connection);
+ $id = $db_connection->real_escape_string($id);
+ $comment = $db_connection->real_escape_string($comment);
$db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_PENDING . ' (`item`, `comment`) VALUES (UNHEX("' . $id . '"), "' . $comment . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -108,10 +108,10 @@ public static function AddEntry($id, $comment)
public static function DeleteEntry($id)
{
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
+ $id = $db_connection->real_escape_string($id);
$db_query = 'DELETE FROM ' . DB_TABLE_STDLIB_PENDING . " WHERE `item` = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
@@ -120,37 +120,37 @@ public static function DeleteEntry($id)
public static function IsPending($id) {
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
+ $id = $db_connection->real_escape_string($id);
$db_query = 'SELECT * FROM ' . DB_TABLE_STDLIB_PENDING . ' WHERE `item` = UNHEX("' . $id . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
public static function SetComment($id, $comment) {
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
- $comment = mysql_real_escape_string($comment, $db_connection);
+ $id = $db_connection->real_escape_string($id);
+ $comment = $db_connection->real_escape_string($comment);
$db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `comment` = "' . $comment . '" WHERE `item` = UNHEX("' . $id . '")';
- $db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ $db_result = $db_connection->query($db_query);
+ if ($db_result === FALSE || $db_connection->affected_rows < 1) {
throw new HttpException(500);
}
}
public static function SetDelay($id, $delay = NULL) {
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($id, $db_connection);
- $delay = ($delay !== NULL) ? '"' . mysql_real_escape_string($delay, $db_connection) . '"' : 'NULL';
+ $id = $db_connection->real_escape_string($id);
+ $delay = ($delay !== NULL) ? '"' . $db_connection->real_escape_string($delay) . '"' : 'NULL';
$db_query = 'UPDATE ' . DB_TABLE_STDLIB_PENDING . ' SET `delay` = ' . $delay . ' WHERE `item` = UNHEX("' . $id . '")';
- $db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ $db_result = $db_connection->query($db_query);
+ if ($db_result === FALSE || $db_connection->affected_rows < 1) {
throw new HttpException(500);
}
}
diff --git a/stdlib/candidates/Candidate.php b/stdlib/candidates/Candidate.php
index 46fef8f..b758a19 100644
--- a/stdlib/candidates/Candidate.php
+++ b/stdlib/candidates/Candidate.php
@@ -9,74 +9,74 @@
class Candidate {
public static function create($item, $user, $reason, $deletion = false) {
$db_connection = db_ensure_connection();
- $item = mysql_real_escape_string($item, $db_connection);
- $user = mysql_real_escape_string($user, $db_connection);
- $reason = mysql_real_escape_string($reason, $db_connection);
+ $item = $db_connection->real_escape_string($item);
+ $user = $db_connection->real_escape_string($user);
+ $reason = $db_connection->real_escape_string($reason);
$deletion = $deletion ? '0' : 'NULL';
$db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATES . ' (`item`, `user`, `reason`, `approval`) VALUES (UNHEX("' . $item . '"), UNHEX("' . $user . '"), "' . $reason . '", ' . $deletion . ')';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_insert_id($db_connection);
+ return $db_connection->insert_id;
}
public static function describe($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT *, HEX(`item`) AS item, HEX(`user`) AS user FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- return mysql_fetch_assoc($db_result);
+ return $db_result->fetch_assoc();
}
public static function exists($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
public static function existsItem($item) {
$db_connection = db_ensure_connection();
- $item = mysql_real_escape_string($item, $db_connection);
+ $item = $db_connection->real_escape_string($item);
$db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATES . ' WHERE `item` = UNHEX("' . $item . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
public static function accepted($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT COUNT(*) AS count, `final`, `accept` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $id . ' GROUP BY `final`, `accept`';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
$accept = array();
- while ($row = mysql_fetch_assoc($db_result)) {
+ while ($row = $db_result->fetch_assoc()) {
if ($row['final'])
return (bool)$row['accept']; # final decisions overwrite everything else (there must only be one of them)
$accept[$row['accept']] = $row['count'];
@@ -94,83 +94,83 @@ public static function accepted($id) {
public static function getId($item) {
$db_connection = db_ensure_connection();
- $item = mysql_real_escape_string($item, $db_connection);
+ $item = $db_connection->real_escape_string($item);
$db_query = 'SELECT `id` FROM ' . DB_TABLE_CANDIDATES . ' WHERE `item` = UNHEX("' . $item . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- $t = mysql_fetch_assoc($db_result);
+ $t = $db_result->fetch_assoc();
return $t['id'];
}
public static function approve($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'UPDATE ' . DB_TABLE_CANDIDATES . ' SET `approval` = NOW() WHERE `approval` IS NULL AND `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_affected_rows() < 1) {
+ if ($db_connection->affected_rows < 1) {
throw new HttpException(400);
}
}
public static function isApproved($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT (`approval` IS NOT NULL) AS approved FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- $t = mysql_fetch_assoc($db_result);
+ $t = $db_result->fetch_assoc();
return $t['approved'];
}
public static function getUser($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT HEX(`user`) AS user FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- $t = mysql_fetch_assoc($db_result);
+ $t = $db_result->fetch_assoc();
return $t['user'];
}
public static function getItem($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT HEX(`item`) AS item FROM ' . DB_TABLE_CANDIDATES . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- $t = mysql_fetch_assoc($db_result);
+ $t = $db_result->fetch_assoc();
return $t['item'];
}
@@ -201,7 +201,7 @@ public static function listCandidates($filters = array(), $sort = array()) {
$db_join = $filter->evaluateJoins();
$db_query = 'SELECT ' . DB_TABLE_CANDIDATES . '.`id`, HEX(' . DB_TABLE_CANDIDATES. '.`item`) AS item FROM ' . DB_TABLE_CANDIDATES . $db_join . $db_cond . ' ' . $db_sort;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -210,11 +210,11 @@ public static function listCandidates($filters = array(), $sort = array()) {
public static function listVotings($candidate, $sort = array()) {
$db_connection = db_ensure_connection();
- $candidate = (int)mysql_real_escape_string($candidate, $db_connection);
+ $candidate = (int)$db_connection->real_escape_string($candidate);
$db_sort = SortHelper::getOrderClause($sort, array('date' => '`date`'));
$db_query = 'SELECT `candidate`, HEX(`user`) AS user, `accept`, `final`, `reason`, `date` FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `candidate` = ' . $candidate . ' ' . $db_sort;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -230,14 +230,14 @@ static function _cleanup_voting($item, $key) {
public static function vote($candidate, $user, $accept, $reason, $final = false) {
$db_connection = db_ensure_connection();
- $candidate = mysql_real_escape_string($candidate, $db_connection);
- $user = mysql_real_escape_string($user, $db_connection);
- $reason = mysql_real_escape_string($reason, $db_connection);
+ $candidate = $db_connection->real_escape_string($candidate);
+ $user = $db_connection->real_escape_string($user);
+ $reason = $db_connection->real_escape_string($reason);
$accept = $accept ? 'TRUE' : 'FALSE';
$final = $final ? 'TRUE' : 'FALSE';
$db_query = 'INSERT INTO ' . DB_TABLE_CANDIDATE_VOTING . ' (`candidate`, `user`, `accept`, `final`, `reason`) VALUES (' . $candidate . ', UNHEX("' . $user . '"), ' . $accept . ', ' . $final . ', "' . $reason . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -245,16 +245,16 @@ public static function vote($candidate, $user, $accept, $reason, $final = false)
public static function hasVoted($id, $user) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
- $user = mysql_real_escape_string($user, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
+ $user = $db_connection->real_escape_string($user);
$db_query = 'SELECT * FROM ' . DB_TABLE_CANDIDATE_VOTING . ' WHERE `user` = UNHEX("' . $user . '") AND `candidate` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
}
?>
\ No newline at end of file
diff --git a/stdlib/items.php b/stdlib/items.php
index 70ed5e1..ad082f6 100644
--- a/stdlib/items.php
+++ b/stdlib/items.php
@@ -33,9 +33,9 @@
}
$db_query = 'SELECT name, `' . DB_TABLE_ITEMS . '`.`version`, HEX(`id`) AS id, GROUP_CONCAT(DISTINCT `release` SEPARATOR "\0") AS releases FROM ' . DB_TABLE_STDLIB . ', ' . DB_TABLE_ITEMS . $db_join . ' WHERE item = id ' . $db_cond . ' GROUP BY name, `' . DB_TABLE_ITEMS . '`.`version` ' . $db_sort;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
$data = sql2array($db_result, create_function('$item', '$item["releases"] = explode("\0", $item["releases"]); return $item;'));
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 4858504..146900a 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -19,13 +19,13 @@ public static function exists($release, $published)
$db_cond = ($t = self::get_publish_cond($published)) == NULL ? '' : " AND $t";
$db_connection = db_ensure_connection();
- $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . $db_connection->real_escape_string($release) . "'" . $db_cond;
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
const SPECIAL_VERSION_LATEST = "latest";
@@ -61,17 +61,17 @@ public static function describe($release, $published)
$db_cond = ($t = self::get_publish_cond($published)) == NULL ? '' : " AND $t";
$db_connection = db_ensure_connection();
- $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . mysql_real_escape_string($release) . "'" . $db_cond;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "SELECT * FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '" . $db_connection->real_escape_string($release) . "'" . $db_cond;
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1)
+ if ($db_result->num_rows != 1)
{
throw new HttpException(404);
}
- $t = mysql_fetch_assoc($db_result);
+ $t = $db_result->fetch_assoc();
$t['published'] = (bool)$t['published'];
return $t;
}
@@ -79,29 +79,29 @@ public static function describe($release, $published)
public static function create($release, $date = NULL, $description = '') {
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
- $description = mysql_real_escape_string($description, $db_connection);
- $date = $date !== NULL ? '"' . mysql_real_escape_string($date, $db_connection) . '"' : 'NULL';
+ $release = $db_connection->real_escape_string($release);
+ $description = $db_connection->real_escape_string($description);
+ $date = $date !== NULL ? '"' . $db_connection->real_escape_string($date) . '"' : 'NULL';
$db_query = 'INSERT INTO ' . DB_TABLE_STDLIB_RELEASES . ' (`release`, `description`, `date`) VALUES ("' . $release . '", "' . $description . '", ' . $date . ')';
- $db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() != 1) {
- throw new HttpException(500, NULL, mysql_error());
+ $db_result = $db_connection->query($db_query);
+ if ($db_result === FALSE || $db_connection->affected_rows != 1) {
+ throw new HttpException(500, NULL, $db_connection->error);
}
}
public static function delete($release)
{
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
+ $release = $db_connection->real_escape_string($release);
$db_query = "DELETE FROM " . DB_TABLE_STDLIB_RELEASES . " WHERE `release` = '$release' AND !`published`";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- else if (mysql_affected_rows($db_connection) < 1)
+ else if ($db_connection->affected_rows < 1)
{
throw new HttpException(400, NULL, "Release doesn't exist or is already published.");
}
@@ -114,24 +114,24 @@ public static function update($release, $data)
}
$db_connection = db_ensure_connection();
- $release = mysql_real_escape_string($release, $db_connection);
+ $release = $db_connection->real_escape_string($release);
$db_query = "UPDATE " . DB_TABLE_STDLIB_RELEASES . " Set "
. implode(", ",
array_map(
create_function('$col, $val', 'return "`$col` = \'$val\'";'),
array_keys($data),
- array_map('mysql_real_escape_string', array_values($data), array_fill(0, count($data), $db_connection))
+ array_map(array($db_connection, 'real_escape_string'), array_values($data))
)
)
. " WHERE `release` = '$release' AND !`published`";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
- else if (mysql_affected_rows($db_connection) != 1)
+ else if ($db_connection->affected_rows != 1)
{
throw new HttpException(400, NULL, "Release '$release' doesn't exist or is already published.");
}
@@ -154,13 +154,13 @@ public static function previousRelease($release, $published) {
public static function publishPending() {
$db_connection = db_ensure_connection();
$db_query = 'SELECT `release` FROM ' . DB_TABLE_STDLIB_RELEASES . ' WHERE !`published` AND `date` <= NOW()';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
$releases = array();
- while ($release = mysql_fetch_array($db_result)) { # sort by release
+ while ($release = $db_result->fetch_array()) { # sort by release
$releases[] = $release['release'];
}
@@ -217,10 +217,10 @@ public static function ListReleases($published, $sort = array())
# get all releases from DB
$db_query = "SELECT `release` FROM " . DB_TABLE_STDLIB_RELEASES . $db_join . $db_cond . $db_sort;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
- throw new HttpException(500, NULL, mysql_error());
+ throw new HttpException(500, NULL, $db_connection->error);
}
# fetch releases in array
diff --git a/users/Suspension.php b/users/Suspension.php
index 0b60ccf..554181d 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -15,20 +15,20 @@ public static function create($user, $reason, $expires = NULL, $restricted = tru
public static function createForId($user, $reason, $expires = NULL, $restricted = true) {
$db_connection = db_ensure_connection();
- $user = mysql_real_escape_string($user, $db_connection);
+ $user = $db_connection->real_escape_string($user);
if ($expires !== NULL) {
- $expires = mysql_real_escape_string($expires, $db_connection);
+ $expires = $db_connection->real_escape_string($expires);
}
$restricted = $restricted ? '1' : '0';
- $reason = mysql_real_escape_string($reason, $db_connection);
+ $reason = $db_connection->real_escape_string($reason);
$db_query = 'INSERT INTO ' . DB_TABLE_SUSPENSIONS . ' (`user`, `expires`, `restricted`, `reason`) VALUES (UNHEX("' . $user . '"), ' . ($expires !== NULL ? '"' . $expires . '"' : 'NULL') . ', ' . $restricted . ', "' . $reason . '")';
- $db_result = mysql_query($db_query, $db_connection);
- if ($db_result === FALSE || mysql_affected_rows() < 1) {
+ $db_result = $db_connection->query($db_query);
+ if ($db_result === FALSE || $db_connection->affected_rows < 1) {
throw new HttpException(500);
}
- return mysql_insert_id($db_connection);
+ return $db_connection->insert_id;
}
public static function clear() {
@@ -41,7 +41,7 @@ public static function clear() {
$db_query = 'UPDATE ' . DB_TABLE_SUSPENSIONS . ' SET `active` = FALSE WHERE `active` AND' . $cond;
}
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -96,7 +96,7 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
$sort = SortHelper::getOrderClause($sort, array('created' => '`created`', 'expires' => '`expires`'));
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . $db_cond . $sort;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -106,19 +106,19 @@ public static function getSuspensionsById($id, $filters = array(), $sort = array
public static function getSuspension($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT *, HEX(`user`) AS user FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `id` =' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) != 1) {
+ if ($db_result->num_rows != 1) {
throw new HttpException(404);
}
- return self::_create_inst_(mysql_fetch_assoc($db_result));
+ return self::_create_inst_($db_result->fetch_assoc());
}
public static function _create_inst_($arr) {
@@ -142,10 +142,10 @@ private function __construct($id, $user, $created, $expires, $restricted, $reaso
public function delete() {
$db_connection = db_ensure_connection();
- $id = mysql_real_escape_string($this->id, $db_connection);
+ $id = $db_connection->real_escape_string($this->id);
$db_query = 'UPDATE ' . DB_TABLE_SUSPENSIONS . ' SET `active` = FALSE WHERE `id` = "' . $id . '"';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
diff --git a/users/describe.php b/users/describe.php
index 3fb9c4c..950aedb 100644
--- a/users/describe.php
+++ b/users/describe.php
@@ -24,19 +24,19 @@
}
else
{
- $id = mysql_real_escape_string($_GET["id"], $db_connection);
+ $id = $db_connection->real_escape_string($_GET["id"]);
}
$db_query = "SELECT name, mail, privileges, joined FROM " . DB_TABLE_USERS . " WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) == 1)
+ if ($db_result->num_rows == 1)
{
- $user = mysql_fetch_assoc($db_result);
+ $user = $db_result->fetch_assoc();
$trusted_user = false;
if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"])) {
diff --git a/users/list.php b/users/list.php
index 86a71b4..5c1b4da 100644
--- a/users/list.php
+++ b/users/list.php
@@ -24,7 +24,7 @@
if (isset($_GET["count"]) && strtolower($_GET["count"]) != "all")
{
- $db_limit = "LIMIT " . mysql_real_escape_string($_GET["count"], $db_connection);
+ $db_limit = "LIMIT " . $db_connection->real_escape_string($_GET["count"]);
}
if (isset($_GET["start"]))
{
@@ -32,7 +32,7 @@
{
$db_limit = "LIMIT 18446744073709551615"; # Source: http://dev.mysql.com/doc/refman/5.5/en/select.html
}
- $db_limit .= " OFFSET " . mysql_real_escape_string($_GET["start"], $db_connection);
+ $db_limit .= " OFFSET " . $db_connection->real_escape_string($_GET["start"]);
}
if (isset($_GET['sort'])) {
@@ -51,7 +51,7 @@
# query for data:
$db_query = "SELECT name, HEX(id) AS id FROM " . DB_TABLE_USERS . " $db_cond $db_order $db_limit";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500);
diff --git a/users/modify.php b/users/modify.php
index 0f530f5..b159680 100644
--- a/users/modify.php
+++ b/users/modify.php
@@ -22,7 +22,7 @@
}
else
{
- $id = mysql_real_escape_string($_GET["id"], $db_connection);
+ $id = $db_connection->real_escape_string($_GET["id"]);
}
if ($id != User::getID($_SERVER["PHP_AUTH_USER"]))
@@ -37,13 +37,13 @@
throw new HttpException(409, NULL, "User name already taken");
}
- $db_query = "UPDATE " . DB_TABLE_USERS . " Set name = '" . mysql_real_escape_string($_POST["name"], $db_connection) . "' WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_query = "UPDATE " . DB_TABLE_USERS . " Set name = '" . $db_connection->real_escape_string($_POST["name"]) . "' WHERE id = UNHEX('$id')";
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500, NULL, "Failed to set user name.");
}
- if (mysql_affected_rows($db_connection) != 1)
+ if ($db_connection->affected_rows != 1)
{
throw new HttpException(404, NULL, "User with this ID was not found.");
}
@@ -55,7 +55,7 @@
throw new HttpException(409, NULL, "Mail address already taken");
}
- $mail = mysql_real_escape_string($_POST["mail"], $db_connection);
+ $mail = $db_connection->real_escape_string($_POST["mail"]);
$suspension = Suspension::createForId($id, 'Suspended for validation of modified email address', NULL, false);
$mail_text = str_replace(array('{$USER}', '{$ID}', '{$MAIL}', '{$SUSPENSION}'), array(User::getName($id), $id, $mail, $suspension), MAIL_CHANGE_TEMPLATE);
@@ -68,12 +68,12 @@
}
$db_query = "UPDATE " . DB_TABLE_USERS . " Set mail = '$mail' WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500, NULL, "Failed to set user mail address.");
}
- if (mysql_affected_rows($db_connection) != 1)
+ if ($db_connection->affected_rows != 1)
{
throw new HttpException(404, NULL, "User with this ID was not found.");
}
@@ -83,12 +83,12 @@
$pw = hash("sha256", $_POST["password"]);
$db_query = "UPDATE " . DB_TABLE_USERS . " Set pw = '$pw' WHERE id = UNHEX('$id')";
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if (!$db_result)
{
throw new HttpException(500, NULL, "Failed to set user password.");
}
- if (mysql_affected_rows($db_connection) != 1)
+ if ($db_connection->affected_rows != 1)
{
throw new HttpException(404, NULL, "User with this ID was not found.");
}
diff --git a/users/registration/Registration.php b/users/registration/Registration.php
index 6658d3d..5af2364 100644
--- a/users/registration/Registration.php
+++ b/users/registration/Registration.php
@@ -11,15 +11,15 @@ public static function create($name, $mail, $password) {
$db_connection = db_ensure_connection();
- $name = mysql_real_escape_string($name, $db_connection);
- $mail = mysql_real_escape_string($mail, $db_connection);
- $password = mysql_real_escape_string($password, $db_connection);
+ $name = $db_connection->real_escape_string($name);
+ $mail = $db_connection->real_escape_string($mail);
+ $password = $db_connection->real_escape_string($password);
$id = mt_rand();
$token = self::createToken();
$db_query = 'INSERT INTO ' . DB_TABLE_REGISTRATION . ' (`id`, `token`, `name`, `mail`, `password`) VALUES ("' . $id . '", "' . $token . '", "' . $name . '", "' . $mail . '", "' . $password . '")';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -31,7 +31,7 @@ public static function clear() {
$db_connection = db_ensure_connection();
$db_query = 'DELETE FROM ' . DB_TABLE_REGISTRATION . ' WHERE `created` + INTERVAL ' . REGISTRATION_TIMEOUT . ' <= NOW()';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
@@ -39,40 +39,40 @@ public static function clear() {
public static function existsPending($name, $mail) {
$db_connection = db_ensure_connection();
- $name = mysql_real_escape_string($name, $db_connection);
- $mail = mysql_real_escape_string($mail, $db_connection);
+ $name = $db_connection->real_escape_string($name);
+ $mail = $db_connection->real_escape_string($mail);
$db_query = 'SELECT * FROM ' . DB_TABLE_REGISTRATION . ' WHERE `name` = "' . $name . '" OR `mail` = "' . $mail . '"';
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- return mysql_num_rows($db_result) > 0;
+ return $db_result->num_rows > 0;
}
public static function get($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'SELECT * FROM ' . DB_TABLE_REGISTRATION . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
- if (mysql_num_rows($db_result) < 1) {
+ if ($db_result->num_rows < 1) {
throw new HttpException(404);
}
- return mysql_fetch_assoc($db_result);
+ return $db_result->fetch_assoc();
}
public static function delete($id) {
$db_connection = db_ensure_connection();
- $id = (int)mysql_real_escape_string($id, $db_connection);
+ $id = (int)$db_connection->real_escape_string($id);
$db_query = 'DELETE FROM ' . DB_TABLE_REGISTRATION . ' WHERE `id` = ' . $id;
- $db_result = mysql_query($db_query, $db_connection);
+ $db_result = $db_connection->query($db_query);
if ($db_result === FALSE) {
throw new HttpException(500);
}
From 7bd4f8abaee92a0ab59f2b33b9791fbac23ac942 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 21:12:14 +0100
Subject: [PATCH 235/241] When retrieving a MySQL row, always use fetch_assoc()
---
User.php | 16 ++++++++--------
items/ItemType.php | 4 ++--
items/tags.php | 2 +-
stdlib/releases/StdlibRelease.php | 2 +-
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/User.php b/User.php
index 101d1ae..e08bf52 100644
--- a/User.php
+++ b/User.php
@@ -87,8 +87,8 @@ public static function hasPrivilegeById($id, $privilege)
throw new HttpException(404, NULL, "User not found");
}
- $data = $db_result->fetch_object();
- return (((int)$data->privileges) & $privilege) == $privilege;
+ $data = $db_result->fetch_assoc();
+ return (((int)$data['privileges']) & $privilege) == $privilege;
}
public static function hasPrivilege($name, $privilege)
@@ -107,8 +107,8 @@ public static function hasPrivilege($name, $privilege)
throw new HttpException(404, NULL, "User not found");
}
- $data = $db_result->fetch_object();
- return (((int)$data->privileges) & $privilege) == $privilege;
+ $data = $db_result->fetch_assoc();
+ return (((int)$data['privileges']) & $privilege) == $privilege;
}
public static function existsName($name)
@@ -156,8 +156,8 @@ public static function validateLogin($user, $pw)
throw new HttpException(403, NULL, "User not found");
}
- $data = $db_result->fetch_object();
- if ($data->pw != $pw)
+ $data = $db_result->fetch_assoc();
+ if ($data['pw'] != $pw)
{
throw new HttpException(403, NULL, "Invalid credentials were specified.");
}
@@ -179,9 +179,9 @@ public static function getName($id)
throw new HttpException(500);
}
- while ($data = $db_result->fetch_object())
+ while ($data = $db_result->fetch_assoc())
{
- return $data->name;
+ return $data['name'];
}
throw new HttpException(404, NULL, "User not found");
}
diff --git a/items/ItemType.php b/items/ItemType.php
index a593812..00bd1fb 100644
--- a/items/ItemType.php
+++ b/items/ItemType.php
@@ -19,7 +19,7 @@ public static function getCode($name)
{
throw new HttpException(400, NULL, "Item type '$name' is not supported!");
}
- $row = $db_result->fetch_array();
+ $row = $db_result->fetch_assoc();
return $row['code'];
}
@@ -37,7 +37,7 @@ public static function getName($code)
{
throw new HttpException(500, NULL, "Item type '$code' is unknown!");
}
- $row = $db_result->fetch_array();
+ $row = $db_result->fetch_assoc();
return $row['name'];
}
diff --git a/items/tags.php b/items/tags.php
index 2e9f335..ec48f09 100644
--- a/items/tags.php
+++ b/items/tags.php
@@ -20,7 +20,7 @@
}
$tags = array();
- while ($row = $db_result->fetch_array()) {
+ while ($row = $db_result->fetch_assoc()) {
$new_tags = explode(';', $row['tags']);
foreach ($new_tags AS $tag) {
$tags[$tag] = true; # keep tags as keys for simplicity, value is meaningless
diff --git a/stdlib/releases/StdlibRelease.php b/stdlib/releases/StdlibRelease.php
index 146900a..7271151 100644
--- a/stdlib/releases/StdlibRelease.php
+++ b/stdlib/releases/StdlibRelease.php
@@ -160,7 +160,7 @@ public static function publishPending() {
}
$releases = array();
- while ($release = $db_result->fetch_array()) { # sort by release
+ while ($release = $db_result->fetch_assoc()) { # sort by release
$releases[] = $release['release'];
}
From f3ba7c8e08bbe6ce5c6fe34251dd0bb09611c711 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 21:27:35 +0100
Subject: [PATCH 236/241] bump travis-ci build
From 7683d37b5633e0e4b70bcfa088ca29068d8eebde Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 21:52:50 +0100
Subject: [PATCH 237/241] adjust tests to MySQL changes
---
db.php | 2 +-
tests/UserTest.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/db.php b/db.php
index 4b97263..3b8b9f7 100644
--- a/db.php
+++ b/db.php
@@ -13,7 +13,7 @@ function db_ensure_connection()
{
throw new HttpException(500);
}
- mysql_set_charset('latin1', $connection);
+ $connection->set_charset('latin1');
}
return $connection;
}
diff --git a/tests/UserTest.php b/tests/UserTest.php
index f2383f3..4550f98 100644
--- a/tests/UserTest.php
+++ b/tests/UserTest.php
@@ -44,7 +44,7 @@ public static function testDelete() {
public static function tearDownAfterClass() { # HACK: can be removed once testDelete() is done
$db_connection = db_ensure_connection();
$db_query = 'DELETE FROM ' . DB_TABLE_USERS . ' WHERE `mail` = "bob@example.com"';
- mysql_query($db_query, $db_connection);
+ $db_connection->query($db_query);
}
public static function testPrivilegeArray() {
From b8d60b73366386b63c18412589f5dc9be10b4f50 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Thu, 28 Mar 2013 21:58:47 +0100
Subject: [PATCH 238/241] remove useless output of client encoding
---
tests/setup/db-mysql.sh | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/setup/db-mysql.sh b/tests/setup/db-mysql.sh
index 044fbdc..83f096c 100755
--- a/tests/setup/db-mysql.sh
+++ b/tests/setup/db-mysql.sh
@@ -13,5 +13,3 @@ do
echo " $file"
mysql --default-character-set=utf8 -u root travis-test < "$file"
done
-
-php -r '$conn = mysql_connect("localhost", "root", ""); echo " MySQL client encoding: ", mysql_client_encoding($conn), " (will be changed to latin1)\n\n";'
\ No newline at end of file
From c03cfc8283dfe221832dedeeb4d832c84a00d780 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 29 Mar 2013 00:22:41 +0100
Subject: [PATCH 239/241] Revert "minor code shortening in Suspensions class"
This reverts commit 1d690a918f as it breaks
the Suspension::isSuspended() method.
---
users/Suspension.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/users/Suspension.php b/users/Suspension.php
index 554181d..65cdc19 100644
--- a/users/Suspension.php
+++ b/users/Suspension.php
@@ -48,7 +48,7 @@ public static function clear() {
}
public static function isSuspended($user) {
- return self::getSuspensions($user);
+ return self::isSuspendedById(User::getID($user));
}
public static function isSuspendedById($id) {
From d133faa82b34f438154772886174210b43f1ba34 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 29 Mar 2013 01:13:34 +0100
Subject: [PATCH 240/241] improve User tests
---
tests/UserTest.php | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/tests/UserTest.php b/tests/UserTest.php
index 4550f98..4fd40b1 100644
--- a/tests/UserTest.php
+++ b/tests/UserTest.php
@@ -3,15 +3,33 @@
require_once('PHPUnit/Framework/Assert/Functions.php'); # should not be required (?)
require_once(dirname(__FILE__) . '/../User.php');
+require_once(dirname(__FILE__) . '/../db.php');
-class UserTest extends PHPUnit_Framework_TestCase
-{
+class UserTest extends PHPUnit_Framework_TestCase {
public static function testCreate() {
User::create('Bob', 'bob@example.com', 'secret1234');
assertTrue(User::existsName('Bob'), 'Failed to create user "Bob" (no user with this name found)');
assertTrue(User::existsMail('bob@example.com'), 'Failed to create user "Bob" (no user with this mail address found)');
}
+ /**
+ * @depends testCreate
+ * @expectedException HttpException
+ * @expectedExceptionCode 500
+ */
+ public static function testCreateDuplicateName() {
+ User::create('Bob', 'bob2@example.com', 'some-pw');
+ }
+
+ /**
+ * @depends testCreate
+ * @expectedException HttpException
+ * @expectedExceptionCode 500
+ */
+ public static function testCreateDuplicateMail() {
+ User::create('Paul', 'bob@example.com', 'some-pw');
+ }
+
/**
* @depends testCreate
*/
@@ -20,6 +38,14 @@ public static function testID() {
assertRegExp('/[0-9a-fA-F]{32}/', $id, 'Invalid user ID for "Bob": "' . $id . '"');
}
+ /**
+ * @depends testID
+ */
+ public static function testName() {
+ $id = User::getID('Bob');
+ assertEquals(User::getName($id), 'Bob', 'Could not retrieve the user name for a given ID of "' . $id . '"');
+ }
+
/**
* @depends testCreate
*/
@@ -28,10 +54,10 @@ public static function testLogin() {
}
/**
- * @depends testCreate
+ * @depends testID
*/
- public static function testPrivilege() {
- # not implemented yet
+ public static function testPrivilegeBefore() {
+ assertEquals(User::getPrivileges(User::getID('Bob')), User::PRIVILEGE_NONE, 'User "Bob" should have zero privileges in the beginning.');
}
/**
@@ -53,6 +79,7 @@ public static function testPrivilegeArray() {
$arr = User::privilegeToArray(User::PRIVILEGE_ADMIN|User::PRIVILEGE_STDLIB_ADMIN|User::PRIVILEGE_REGISTRATION);
assertInternalType('array', $arr, 'Privilege conversion did not return an array');
+ assertCount(3, $arr, 'Invalid element count in privilege array');
assertContains('admin', $arr, 'Failed to convert privilege PRIVILEGE_ADMIN|PRIVILEGE_STDLIB_ADMIN|PRIVILEGE_REGISTRATION to array');
assertContains('stdlib-admin', $arr, 'Failed to convert privilege PRIVILEGE_ADMIN|PRIVILEGE_STDLIB_ADMIN|PRIVILEGE_REGISTRATION to array');
assertContains('registration', $arr, 'Failed to convert privilege PRIVILEGE_ADMIN|PRIVILEGE_STDLIB_ADMIN|PRIVILEGE_REGISTRATION to array');
From e81f004f9fbb8ba689035bec9d7ac59042cd1272 Mon Sep 17 00:00:00 2001
From: "maul.esel"
Date: Fri, 29 Mar 2013 01:13:45 +0100
Subject: [PATCH 241/241] add some tests for suspensions
---
tests/users/SuspensionTest.php | 101 +++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
create mode 100644 tests/users/SuspensionTest.php
diff --git a/tests/users/SuspensionTest.php b/tests/users/SuspensionTest.php
new file mode 100644
index 0000000..f4c2f48
--- /dev/null
+++ b/tests/users/SuspensionTest.php
@@ -0,0 +1,101 @@
+query($db_query);
+
+ $db_query = 'DELETE FROM ' . DB_TABLE_SUSPENSIONS . ' WHERE `user` = UNHEX("' . self::$id . '")';
+ $db_connection->query($db_query);
+ }
+
+ public static function testBeforeSuspension() {
+ assertFalse(Suspension::isSuspended(self::USER_NAME));
+ assertFalse(Suspension::isSuspendedById(self::$id));
+ }
+
+ /**
+ * @depends testBeforeSuspension
+ */
+ public static function testCreate() {
+ self::$s1 = Suspension::create(self::USER_NAME, 'Suspended for no particular reason');
+ assertInternalType('int', self::$s1, 'Suspension creation did not return an integer');
+ assertTrue(Suspension::isSuspended(self::USER_NAME));
+ }
+
+ /**
+ * @depends testBeforeSuspension
+ */
+ public static function testCreateForId() {
+ self::$s2 = Suspension::createForId(self::$id, 'For testing reasons', self::EXPIRATION_DATE);
+ assertInternalType('int', self::$s2, 'Suspension creation (for ID) did not return an integer');
+ assertTrue(Suspension::isSuspendedById(self::$id));
+ }
+
+ /**
+ * @depends testCreate
+ * @depends testCreateForId
+ */
+ public static function testRetrieveList() {
+ $s = Suspension::getSuspensions(self::USER_NAME);
+
+ assertInternalType('array', $s, 'Suspension retrieval did not return an array');
+ assertCount(2, $s, 'Incorrect number of suspensions: ' . count($s));
+
+ assertEquals($s[0], Suspension::getSuspension($s[0]->id), 'Should equal individually retrieved suspension');
+ }
+
+ /**
+ * @depends testCreate
+ */
+ public static function testFirstSuspension() {
+ $s = Suspension::getSuspension(self::$s1);
+
+ assertTrue($s->restricted, 'Suspension should be restricted but is not.');
+ assertTrue($s->infinite, 'Suspension should be infinite but is not.');
+ assertEquals($s->expires, NULL, 'Expiration date should be NULL');
+ }
+
+ /**
+ * @depends testCreateForId
+ */
+ public static function testSecondSuspension() {
+ $s = Suspension::getSuspension(self::$s2);
+
+ assertTrue($s->restricted, 'Suspension should be restricted but is not.');
+ assertFalse($s->infinite, 'Suspension should be infinite but is not.');
+ assertEquals($s->expires, new DateTime(self::EXPIRATION_DATE), 'Expiration date not set properly');
+ }
+
+ /**
+ * @depends testRetrieveList
+ */
+ public static function testDelete() {
+ foreach (Suspension::getSuspensionsById(self::$id) AS $s) {
+ $s->delete();
+ }
+ assertFalse(Suspension::isSuspendedById(self::$id));
+ }
+}
+?>
\ No newline at end of file