diff --git a/bin/monitor.php b/bin/monitor.php
index 4133d24a0..6a1c45582 100644
--- a/bin/monitor.php
+++ b/bin/monitor.php
@@ -8,7 +8,7 @@ require_once(dirname(__FILE__) . "/../lib/showsleep.php");
require_once(dirname(__FILE__) . "/../lib/functions.php");
-$version = "0.4r2004";
+$version = "0.4r2011";
$db = new DB();
$functions = new Functions();
@@ -49,10 +49,10 @@ $proc = "SELECT
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE categoryID BETWEEN 2000 AND 2999 AND imdbID IS NULL ) AS movies,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE categoryID BETWEEN 3000 AND 3999 AND musicinfoID IS NULL) AS audio,
( SELECT COUNT(*) FROM releases r USE INDEX(ix_releases_status), category c WHERE c.ID = r.categoryID AND c.parentID = 6000 AND r.passwordstatus = -1 AND r.haspreview = -1 AND c.disablepreview = 0) AS xxx,
-( SELECT COUNT(*) FROM releases r USE INDEX(ix_releases_status) INNER JOIN category c on c.ID = r.categoryID WHERE (r.passwordstatus = -1) OR (r.haspreview = -1 and c.disablepreview = 0)) AS pc,
+( SELECT COUNT(*) FROM releases r INNER JOIN category c ON c.ID = r.categoryID WHERE r.nzbstatus = 1 AND ((r.categoryID BETWEEN 4000 AND 4999 AND r.passwordstatus BETWEEN -6 AND -1 AND r.haspreview = -1 AND c.disablepreview = 0) OR (r.categoryID = 4050 AND r.gamesinfo_id IS NULL))) AS pc,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE categoryID BETWEEN 5000 AND 5999 AND rageID = -1) AS tv,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE categoryID = 7020 AND bookinfoID IS NULL ) AS book,
-( SELECT COUNT(*) FROM releases r USE INDEX(ix_releases_status), category c WHERE c.ID = r.categoryID AND r.passwordstatus = -1 AND r.haspreview = -1 AND c.disablepreview = 0) AS work,
+( SELECT COUNT(*) FROM releases r INNER JOIN category c ON c.ID = r.categoryID WHERE r.nzbstatus = 1 AND ((r.passwordstatus BETWEEN -6 AND -1 AND r.haspreview = -1 AND c.disablepreview = 0) OR (r.categoryID = 4050 AND r.gamesinfo_id IS NULL))) AS work,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status)) AS releases,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE releasenfoID = 0 AND nfostatus BETWEEN -6 AND -1) AS nforemains,
( SELECT COUNT(*) FROM releases USE INDEX(ix_releases_status) WHERE nfostatus = 1 AND releasenfoID = 1) AS nfo,
@@ -1657,12 +1657,12 @@ while ($i > 0) {
shell_exec("tmux respawnp -t${tmux_session}:2.4 'echo \"\033[38;5;${color}m\n${panes2[4]} has been disabled/terminated by Postprocess Anime\"'");
}
- //Process Console releases in pane 2.5 once if needed then exits
- if (($maxload >= get_load()) && ($post_amazon == 1) && ($console_releases_proc > 0)) {
+ //Process Games in pane 2.5 once if needed then exits
+ if (($maxload >= get_load()) && ($post_amazon == 1) && (($console_releases_proc > 0) || ($pc_releases_proc > 0))) {
$color = get_color($colors_start, $colors_end, $colors_exc);
$log = writelog($panes2[5]);
- shell_exec("tmux respawnp -t${tmux_session}:2.5 'echo \"\033[38;5;\"$color\"m\" && cd $_bin && $_php postprocess_new.php games 2>&1 $log && $_sleep $post_timer_amazon && echo \" \033[1;0;33m\"' 2>&1 1> /dev/null");
- } else if (($maxload >= get_load()) && ($post_amazon == 1) && ($console_releases_proc == 0)) {
+ shell_exec("tmux respawnp -t${tmux_session}:2.5 'echo \"\033[38;5;\"$color\"m\" && cd $_bin && $_php postprocess_new.php console 2>&1 $log && $_php postprocess_new.php games 2>&1 $log && $_sleep $post_timer_amazon && echo \" \033[1;0;33m\"' 2>&1 1> /dev/null");
+ } else if (($maxload >= get_load()) && ($post_amazon == 1) && (($console_releases_proc == 0) || ($pc_releases_proc > 0))) {
$color = get_color($colors_start, $colors_end, $colors_exc);
shell_exec("tmux respawnp -t${tmux_session}:2.5 'echo \"\033[38;5;\"$color\"m\n$panes2[5] has been disabled/terminated by No Games to process\"'");
} else if ($maxload <= get_load()) {
diff --git a/bin/postprocess_new.php b/bin/postprocess_new.php
index 7f1c371d2..eb5be7611 100644
--- a/bin/postprocess_new.php
+++ b/bin/postprocess_new.php
@@ -51,6 +51,8 @@ if (isset($argv[1]) && $argv[1] === "additional") {
$thetvdb->processReleases();
} else if (isset($argv[1]) && $argv[1] === "games") {
$pprocess->processGames();
+} else if (isset($argv[1]) && $argv[1] === "console") {
+ $pprocess->processConsoleGames();
} else if (isset($argv[1]) && $argv[1] === "ebook") {
$postprocess->processBooks();
} else if (isset($argv[1]) && $argv[1] === "music") {
diff --git a/lib/DB/db.sql b/lib/DB/db.sql
index d0c794fe3..ab8608169 100644
--- a/lib/DB/db.sql
+++ b/lib/DB/db.sql
@@ -17,6 +17,7 @@ ADD `proc_pp` TINYINT(1) NOT NULL DEFAULT 0,
ADD `proc_par2` BIT NOT NULL DEFAULT 0,
ADD `proc_nfo` BIT NOT NULL DEFAULT 0,
ADD `proc_files` BIT NOT NULL DEFAULT 0,
+ADD `gamesinfo_id` INT AFTER consoleinfoID,
ADD `nzbstatus` TINYINT(1) NOT NULL DEFAULT 1;
CREATE INDEX `ix_releases_nfostatus` ON `releases` (`nfostatus` ASC) USING HASH;
CREATE INDEX `ix_releases_reqidstatus` ON `releases` (`reqidstatus` ASC) USING HASH;
@@ -26,8 +27,11 @@ CREATE INDEX `ix_releases_dehashstatus` ON `releases` (`dehashstatus`);
CREATE INDEX `ix_releases_haspreview` ON `releases` (`haspreview` ASC) USING HASH;
CREATE INDEX `ix_releases_postdate_name` ON `releases` (`postdate`, `name`);
CREATE INDEX `ix_releases_prehashid_searchname` ON `releases` (`prehashID`, `searchname`);
+CREATE INDEX `ix_releases_gamesinfo_id` ON `releases` (`gamesinfo_id`);
CREATE INDEX `ix_releases_status` ON `releases` (`nzbstatus`, `iscategorized`, `isrenamed`, `nfostatus`, `ishashed`, `passwordstatus`, `dehashstatus`, `releasenfoID`, `musicinfoID`, `consoleinfoID`, `bookinfoID`, `haspreview`, `categoryID`, `imdbID`, `rageID`);
+ALTER TABLE users ADD COLUMN gameview INT AFTER consoleview;
+
DROP TABLE IF EXISTS prehash;
CREATE TABLE prehash (
ID INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -203,7 +207,7 @@ INSERT INTO tmux (setting, value) VALUES ('defrag_cache', '900'),
('ffmpeg_duration', '5'),
('ffmpeg_image_time', '5'),
('processvideos', '0'),
- ('sqlpatch', '50');
+ ('sqlpatch', '55');
DROP TABLE IF EXISTS releasesearch;
CREATE TABLE releasesearch (
@@ -476,6 +480,29 @@ INSERT INTO country (code, name) VALUES ('AF', 'Afghanistan'),
('ZM', 'Zambia'),
('ZW', 'Zimbabwe');
+DROP TABLE IF EXISTS gamesinfo;
+CREATE TABLE gamesinfo (
+ id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ title VARCHAR(255) NOT NULL,
+ asin VARCHAR(128) DEFAULT NULL,
+ url VARCHAR(1000) DEFAULT NULL,
+ platform VARCHAR(255) DEFAULT NULL,
+ publisher VARCHAR(255) DEFAULT NULL,
+ genreid INT(10) NULL DEFAULT NULL,
+ esrb VARCHAR(255) NULL DEFAULT NULL,
+ releasedate DATETIME DEFAULT NULL,
+ review VARCHAR(3000) DEFAULT NULL,
+ cover TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+ createddate DATETIME NOT NULL,
+ updateddate DATETIME NOT NULL,
+ PRIMARY KEY (id),
+ UNIQUE INDEX ix_gamesinfo_asin (asin)
+)
+ ENGINE = InnoDB
+ DEFAULT CHARSET = utf8
+ COLLATE = utf8_unicode_ci
+ AUTO_INCREMENT = 1;
+
DROP TABLE IF EXISTS shortgroups;
CREATE TABLE shortgroups (
ID INT(11) NOT NULL AUTO_INCREMENT,
@@ -701,6 +728,11 @@ INSERT INTO menu (href, title, tooltip, role, ordinal)
VALUES ('prehash', 'Prehash',
'Prehash', 1, 68);
+INSERT INTO `site` (`setting`, `value`) VALUES
+ ('categorizeforeign', '1'),
+ ('catwebdl', '0'),
+ ('giantbombkey', '');
+
DROP TRIGGER IF EXISTS check_insert;
DROP TRIGGER IF EXISTS check_update;
@@ -745,10 +777,4 @@ CREATE TRIGGER delete_search AFTER DELETE ON releases FOR EACH ROW BEGIN DELETE
WHERE releaseID = OLD.ID;
END;
$$
-DELIMITER ;
-
-
-
-
-
-
+DELIMITER ;
\ No newline at end of file
diff --git a/lib/DB/patches/0052~gamesinfo.sql b/lib/DB/patches/0052~gamesinfo.sql
new file mode 100644
index 000000000..1c51df787
--- /dev/null
+++ b/lib/DB/patches/0052~gamesinfo.sql
@@ -0,0 +1,24 @@
+DROP TABLE IF EXISTS gamesinfo;
+CREATE TABLE gamesinfo (
+ id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ title VARCHAR(255) NOT NULL,
+ asin VARCHAR(128) DEFAULT NULL,
+ url VARCHAR(1000) DEFAULT NULL,
+ platform VARCHAR(255) DEFAULT NULL,
+ publisher VARCHAR(255) DEFAULT NULL,
+ genreid INT(10) NULL DEFAULT NULL,
+ esrb VARCHAR(255) NULL DEFAULT NULL,
+ releasedate DATETIME DEFAULT NULL,
+ review VARCHAR(3000) DEFAULT NULL,
+ cover TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
+ createddate DATETIME NOT NULL,
+ updateddate DATETIME NOT NULL,
+ PRIMARY KEY (id),
+ UNIQUE INDEX ix_gamesinfo_asin (asin)
+)
+ ENGINE = InnoDB
+ DEFAULT CHARSET = utf8
+ COLLATE = utf8_unicode_ci
+ AUTO_INCREMENT = 1;
+
+ UPDATE `tmux` SET `value` = '52' WHERE `setting` = 'sqlpatch';
\ No newline at end of file
diff --git a/lib/DB/patches/0053~site.sql b/lib/DB/patches/0053~site.sql
new file mode 100644
index 000000000..eb03054de
--- /dev/null
+++ b/lib/DB/patches/0053~site.sql
@@ -0,0 +1,4 @@
+INSERT INTO `site`
+ (`setting`, `value`)
+ VALUES ('giantbombkey', '');
+UPDATE `tmux` SET `value` = '53' WHERE `setting` = 'sqlpatch';
\ No newline at end of file
diff --git a/lib/DB/patches/0054~releases.sql b/lib/DB/patches/0054~releases.sql
new file mode 100644
index 000000000..3e59e2db5
--- /dev/null
+++ b/lib/DB/patches/0054~releases.sql
@@ -0,0 +1,3 @@
+ALTER TABLE releases ADD COLUMN gamesinfo_id INT AFTER consoleinfoID;
+CREATE INDEX ix_releases_gamesinfo_id ON releases (gamesinfo_id);
+UPDATE `tmux` SET `value` = '54' WHERE `setting` = 'sqlpatch';
\ No newline at end of file
diff --git a/lib/DB/patches/0055~users.sql b/lib/DB/patches/0055~users.sql
new file mode 100644
index 000000000..3856ff3b1
--- /dev/null
+++ b/lib/DB/patches/0055~users.sql
@@ -0,0 +1,2 @@
+ALTER TABLE users ADD COLUMN gameview INT AFTER consoleview;
+UPDATE `tmux` SET `value` = '55' WHERE `setting` = 'sqlpatch';
\ No newline at end of file
diff --git a/lib/Pprocess.php b/lib/Pprocess.php
index 5a08d5426..8e98b44e6 100644
--- a/lib/Pprocess.php
+++ b/lib/Pprocess.php
@@ -16,6 +16,7 @@ require_once(WWW_DIR . "/lib/amazon.php");
require_once(WWW_DIR . "/lib/genres.php");
require_once(WWW_DIR . "/lib/anidb.php");
require_once(WWW_DIR . "/lib/book.php");
+require_once(WWW_DIR . "/lib/Games.php");
require_once("consoletools.php");
require_once("ColorCLI.php");
require_once("nzbcontents.php");
@@ -131,6 +132,7 @@ class PProcess
$this->processSharing($nntp);
$this->processMovies();
$this->processMusic();
+ $this->processConsoleGames();
$this->processGames();
$this->processAnime();
$this->processTv();
@@ -164,6 +166,19 @@ class PProcess
}
}
+ /**
+ * Lookup console games if enabled.
+ *
+ * @return void
+ */
+ public function processConsoleGames()
+ {
+ if ($this->site->lookupgames !== '0') {
+ $console = new Konsole($this->echooutput);
+ $console->processConsoleReleases();
+ }
+ }
+
/**
* Lookup games if enabled.
*
@@ -171,9 +186,9 @@ class PProcess
*/
public function processGames()
{
- if ($this->site->lookupgames !== '0') {
- $console = new Konsole($this->echooutput);
- $console->processConsoleReleases();
+ if ($this->site->lookupgames !== 0) {
+ $games = new Games($this->echooutput);
+ $games->processGamesReleases();
}
}
diff --git a/lib/copy_this/www/admin/user-edit.php b/lib/copy_this/www/admin/user-edit.php
new file mode 100644
index 000000000..bff4d5e6c
--- /dev/null
+++ b/lib/copy_this/www/admin/user-edit.php
@@ -0,0 +1,121 @@
+getRoles();
+$roles = array();
+$defaultrole = Users::ROLE_USER;
+$defaultinvites = Users::DEFAULT_INVITES;
+foreach ($userroles as $r) {
+ $roles[$r['ID']] = $r['name'];
+ if ($r['isdefault'] == 1)
+ {
+ $defaultrole = $r['ID'];
+ $defaultinvites = $r['defaultinvites'];
+ }
+}
+
+switch($action)
+{
+ case 'add':
+ $user = array();
+ $user["role"] = $defaultrole;
+ $user["notes"] = "";
+ $user["invites"] = $defaultinvites;
+ $user["movieview"] = "1";
+ $user["musicview"] = "1";
+ $user["gameview"] = "1";
+ $user["consoleview"] = "1";
+ $user["bookview"] = "1";
+ $page->smarty->assign('user', $user);
+ break;
+ case 'submit':
+
+ if ($_POST["id"] == "")
+ {
+ $invites = $defaultinvites;
+ foreach($userroles as $role) {
+ if ($role['ID'] == $_POST['role'])
+ $invites = $role['defaultinvites'];
+ }
+ $ret = $users->signup($_POST["username"], $_POST["password"], $_POST["email"], '', $_POST["role"], $_POST["notes"], $invites, "", true, false, false, true);
+ }
+ else
+ {
+ $ret = $users->update($_POST["id"], $_POST["username"], $_POST["email"], $_POST["grabs"], $_POST["role"], $_POST["notes"], $_POST["invites"], (isset($_POST['movieview']) ? "1" : "0"), (isset($_POST['musicview']) ? "1" : "0"), (isset($_POST['gameview']) ? "1" : "0"), (isset($_POST['consoleview']) ? "1" : "0"), (isset($_POST['bookview']) ? "1" : "0"));
+ if ($_POST['password'] != "")
+ $users->updatePassword($_POST["id"], $_POST['password']);
+ }
+
+ if ($ret >= 0)
+ header("Location:".WWW_TOP."/user-list.php");
+ else
+ {
+ switch ($ret)
+ {
+ case Users::ERR_SIGNUP_BADUNAME:
+ $page->smarty->assign('error', "Bad username. Try a better one.");
+ break;
+ case Users::ERR_SIGNUP_BADPASS:
+ $page->smarty->assign('error', "Bad password. Try a longer one.");
+ break;
+ case Users::ERR_SIGNUP_BADEMAIL:
+ $page->smarty->assign('error', "Bad email.");
+ break;
+ case Users::ERR_SIGNUP_UNAMEINUSE:
+ $page->smarty->assign('error', "Username in use.");
+ break;
+ case Users::ERR_SIGNUP_EMAILINUSE:
+ $page->smarty->assign('error', "Email in use.");
+ break;
+ default:
+ $page->smarty->assign('error', "Unknown save error.");
+ break;
+ }
+ $user = array();
+ $user["ID"] = $_POST["id"];
+ $user["username"] = $_POST["username"];
+ $user["email"] = $_POST["email"];
+ $user["grabs"] = (isset($_POST["grabs"]) ? $_POST["grabs"] : "0");
+ $user["role"] = $_POST["role"];
+ $user["notes"] = $_POST["notes"];
+ $user["invites"] = (isset($_POST["invites"]) ? $_POST["invites"] : "0");
+ $user["movieview"] = $_POST["movieview"];
+ $user["bookview"] = $_POST["bookview"];
+ $page->smarty->assign('user', $user);
+ }
+ break;
+ case 'view':
+ default:
+
+ if (isset($_GET["id"]))
+ {
+ $page->title = "User Edit";
+ $id = $_GET["id"];
+ $user = $users->getByID($id);
+
+ $page->smarty->assign('user', $user);
+ }
+
+ break;
+}
+
+$page->smarty->assign('yesno_ids', array(1,0));
+$page->smarty->assign('yesno_names', array( 'Yes', 'No'));
+
+$page->smarty->assign('role_ids', array_keys($roles));
+$page->smarty->assign('role_names', $roles);
+
+$page->content = $page->smarty->fetch('user-edit.tpl');
+$page->render();
+
diff --git a/lib/copy_this/www/lib/Games.php b/lib/copy_this/www/lib/Games.php
new file mode 100644
index 000000000..f727a826f
--- /dev/null
+++ b/lib/copy_this/www/lib/Games.php
@@ -0,0 +1,889 @@
+echooutput = $echooutput;
+
+ $this->pdo = new DB();
+ $s = new Sites();
+ $this->site = $s->get();
+ $t = new Tmux();
+ $this->tmux = $t->get();
+ $this->pubkey = $this->site->giantbombkey;
+ $this->gameqty = ($this->tmux->maxgamesprocessed != '') ? $this->tmux->maxgamesprocessed : 150;
+ $this->sleeptime = ($this->tmux->amazonsleep != '') ? $this->tmux->amazonsleep : 1000;
+ $this->imgSavePath = WWW_DIR . 'covers/games' . '/';
+ $this->renamed = '';
+ if ($this->site->lookupgames == 2) {
+ $this->renamed = 'AND isrenamed = 1';
+ }
+ //$this->cleangames = ($this->pdo->getSetting('lookupgames') == 2) ? 'AND isrenamed = 1' : '';
+ $this->c = new ColorCLI();
+ }
+
+ /**
+ * @param $id
+ *
+ * @return array|bool
+ */
+ public function getgamesinfo($id)
+ {
+ return $this->pdo->queryOneRow(
+ sprintf("
+ SELECT gamesinfo.*, genres.title AS genres
+ FROM gamesinfo
+ LEFT OUTER JOIN genres ON genres.ID = gamesinfo.genreid
+ WHERE gamesinfo.id = %d",
+ $id
+ )
+ );
+ }
+
+ /**
+ * @param $title
+ * @param $platform
+ *
+ * @return array|bool
+ */
+ public function getgamesinfoByName($title, $platform)
+ {
+ return $this->pdo->queryOneRow(
+ sprintf("
+ SELECT *
+ FROM gamesinfo
+ WHERE title LIKE %s
+ AND platform LIKE %s",
+ $this->pdo->escapeString("%" . $title . "%"),
+ $this->pdo->escapeString("%" . $platform . "%")
+ )
+ );
+ }
+
+ /**
+ * @param $start
+ * @param $num
+ *
+ * @return array
+ */
+ public function getRange($start, $num)
+ {
+ return $this->pdo->query(
+ sprintf(
+ "SELECT * FROM gamesinfo ORDER BY createddate DESC %s",
+ ($start === false ? '' : 'LIMIT ' . $num . ' OFFSET ' . $start)
+ )
+ );
+ }
+
+ /**
+ * @return int
+ */
+ public function getCount()
+ {
+ $res = $this->pdo->queryOneRow("SELECT COUNT(id) AS num FROM gamesinfo");
+ return ($res === false ? 0 : $res["num"]);
+ }
+
+ /**
+ * @param $cat
+ * @param $maxage
+ * @param array $excludedcats
+ *
+ * @return int
+ */
+ public function getgamesCount($cat, $maxage = -1, $excludedcats = array())
+ {
+ $catsrch = "";
+ if (count($cat) > 0 && $cat[0] != -1) {
+ $catsrch = " (";
+ $categ = new Category();
+ foreach ($cat as $category) {
+ if ($category != -1) {
+ if ($categ->isParent($category)) {
+ $children = $categ->getChildren($category);
+ $chlist = "-99";
+ foreach ($children as $child) {
+ $chlist .= ", " . $child["ID"];
+ }
+
+ if ($chlist != "-99") {
+ $catsrch .= " r.categoryID IN (" . $chlist . ") OR ";
+ }
+ } else {
+ $catsrch .= sprintf(" r.categoryID = %d OR ", $category);
+ }
+ }
+ }
+ $catsrch .= "1=2 )";
+ }
+
+ $res = $this->pdo->queryOneRow(
+ sprintf("
+ SELECT COUNT(DISTINCT r.gamesinfo_id) AS num
+ FROM releases r
+ INNER JOIN gamesinfo gam ON gam.id = r.gamesinfo_id
+ WHERE r.nzbstatus = 1
+ AND gam.title != ''
+ AND gam.cover = 1
+ AND r.passwordstatus <= (SELECT value FROM site WHERE setting='showpasswordedrelease')
+ AND %s %s %s %s",
+ $this->getBrowseBy(),
+ $catsrch,
+ ($maxage > 0 ? sprintf(' AND r.postdate > NOW() - INTERVAL %d DAY ', $maxage) : ''),
+ (count($excludedcats) > 0 ? " AND r.categoryID NOT IN (" . implode(",", $excludedcats) . ")" : '')
+ )
+ );
+
+ return ($res === false ? 0 : $res["num"]);
+ }
+
+ /**
+ * @param $cat
+ * @param $start
+ * @param $num
+ * @param $orderby
+ * @param $maxage
+ * @param array $excludedcats
+ *
+ * @return array
+ */
+ public function getgamesRange($cat, $start, $num, $orderby, $maxage = -1, $excludedcats = array())
+ {
+ $browseby = $this->getBrowseBy();
+
+ if ($start === false) {
+ $limit = "";
+ } else {
+ $limit = " LIMIT " . $num . " OFFSET " . $start;
+ }
+ $catsrch = "";
+ if (count($cat) > 0 && $cat[0] != -1) {
+ $catsrch = " (";
+ $categ = new Category();
+ foreach ($cat as $category) {
+ if ($category != -1) {
+ if ($categ->isParent($category)) {
+ $children = $categ->getChildren($category);
+ $chlist = "-99";
+ foreach ($children as $child) {
+ $chlist .= ", " . $child["id"];
+ }
+
+ if ($chlist != "-99") {
+ $catsrch .= " r.categoryID IN (" . $chlist . ") OR ";
+ }
+ } else {
+ $catsrch .= sprintf(" r.categoryID = %d OR ", $category);
+ }
+ }
+ }
+ $catsrch .= "1=2 )";
+ }
+
+ if ($maxage > 0) {
+ $maxage = sprintf(' AND r.postdate > NOW() - INTERVAL %d DAY ', $maxage);
+ } else {
+ $maxage = '';
+ }
+
+ $exccatlist = "";
+ if (count($excludedcats) > 0) {
+ $exccatlist = " AND r.categoryID NOT IN (" . implode(",", $excludedcats) . ")";
+ }
+
+ $order = $this->getgamesOrder($orderby);
+
+ return $this->pdo->query(
+ sprintf(
+ "SELECT GROUP_CONCAT(r.ID ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_id, "
+ . "GROUP_CONCAT(r.rarinnerfilecount ORDER BY r.postdate DESC SEPARATOR ',') as grp_rarinnerfilecount, "
+ . "GROUP_CONCAT(r.haspreview ORDER BY r.postdate DESC SEPARATOR ',') AS grp_haspreview, "
+ . "GROUP_CONCAT(r.passwordstatus ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_password, "
+ . "GROUP_CONCAT(r.guid ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_guid, "
+ . "GROUP_CONCAT(rn.ID ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_nfoid, "
+ . "GROUP_CONCAT(groups.name ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_grpname, "
+ . "GROUP_CONCAT(r.searchname ORDER BY r.postdate DESC SEPARATOR '#') AS grp_release_name, "
+ . "GROUP_CONCAT(r.postdate ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_postdate, "
+ . "GROUP_CONCAT(r.size ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_size, "
+ . "GROUP_CONCAT(r.totalpart ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_totalparts, "
+ . "GROUP_CONCAT(r.comments ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_comments, "
+ . "GROUP_CONCAT(r.grabs ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_grabs, "
+ . "gam.*, r.gamesinfo_id, groups.name AS group_name, rn.ID as nfoid FROM releases r "
+ . "LEFT OUTER JOIN groups ON groups.ID = r.groupID "
+ . "LEFT OUTER JOIN releasenfo rn ON rn.releaseID = r.ID "
+ . "INNER JOIN gamesinfo gam ON gam.id = r.gamesinfo_id "
+ . "WHERE r.nzbstatus = 1 AND gam.cover = 1 AND gam.title != '' AND "
+ . "r.passwordstatus <= (SELECT value FROM site WHERE setting='showpasswordedrelease') AND %s %s %s %s "
+ . "GROUP BY gam.id ORDER BY %s %s" . $limit,
+ $browseby,
+ $catsrch,
+ $maxage,
+ $exccatlist,
+ $order[0],
+ $order[1]
+ )
+ );
+ }
+
+ /**
+ * @param $orderby
+ *
+ * @return array
+ */
+ public function getgamesOrder($orderby)
+ {
+ $order = ($orderby == '') ? 'r.postdate' : $orderby;
+ $orderArr = explode("_", $order);
+ switch ($orderArr[0]) {
+ case 'title':
+ $orderfield = 'gam.title';
+ break;
+ case 'platform':
+ $orderfield = 'gam.platform';
+ break;
+ case 'releasedate':
+ $orderfield = 'gam.releasedate';
+ break;
+ case 'genre':
+ $orderfield = 'gam.genreID';
+ break;
+ case 'size':
+ $orderfield = 'r.size';
+ break;
+ case 'files':
+ $orderfield = 'r.totalpart';
+ break;
+ case 'stats':
+ $orderfield = 'r.grabs';
+ break;
+ case 'posted':
+ default:
+ $orderfield = 'r.postdate';
+ break;
+ }
+ $ordersort = (isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1])) ? $orderArr[1] : 'desc';
+
+ return array($orderfield, $ordersort);
+ }
+
+ /**
+ * @return array
+ */
+ public function getgamesOrdering()
+ {
+ return array(
+ 'title_asc', 'title_desc', 'posted_asc', 'posted_desc', 'size_asc', 'size_desc',
+ 'files_asc', 'files_desc', 'stats_asc', 'stats_desc', 'platform_asc', 'platform_desc',
+ 'releasedate_asc', 'releasedate_desc', 'genre_asc', 'genre_desc'
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function getBrowseByOptions()
+ {
+ return array('platform' => 'platform', 'title' => 'title', 'genre' => 'genreID');
+ }
+
+ /**
+ * @return string
+ */
+ public function getBrowseBy()
+ {
+ $browseby = ' ';
+ $browsebyArr = $this->getBrowseByOptions();
+ $like = 'LIKE';
+
+ foreach ($browsebyArr as $bbk => $bbv) {
+ if (isset($_REQUEST[$bbk]) && !empty($_REQUEST[$bbk])) {
+ $bbs = stripslashes($_REQUEST[$bbk]);
+ $browseby .= 'gam.' . $bbv . ' ' . $like . ' (' . $this->pdo->escapeString('%' . $bbs . '%') . ') AND ';
+ }
+ }
+
+ return $browseby;
+ }
+
+ /**
+ * @param $data
+ * @param $field
+ *
+ * @return string
+ */
+ public function makeFieldLinks($data, $field)
+ {
+ $tmpArr = explode(', ', $data[$field]);
+ $newArr = array();
+ $i = 0;
+ foreach ($tmpArr as $ta) {
+ // Only use first 6.
+ if ($i > 5) {
+ break;
+ }
+ $newArr[] =
+ '' . $ta . ' ';
+ $i++;
+ }
+
+ return implode(', ', $newArr);
+ }
+
+ /**
+ * @param $id
+ * @param $title
+ * @param $asin
+ * @param $url
+ * @param $salesrank
+ * @param $platform
+ * @param $publisher
+ * @param $releasedate
+ * @param $esrb
+ * @param $cover
+ * @param $genreID
+ */
+ public function update($id, $title, $asin, $url, $salesrank, $platform, $publisher, $releasedate, $esrb, $cover, $genreID)
+ {
+
+ $this->pdo->exec(
+ sprintf("
+ UPDATE gamesinfo
+ SET
+ title = %s, asin = %s, url = %s, salesrank = %s, platform = %s, publisher = %s,
+ releasedate= %s,esrb = %s, cover = %d, genreid = %d, updateddate = NOW()
+ WHERE id = %d",
+ $this->pdo->escapeString($title),
+ $this->pdo->escapeString($asin),
+ $this->pdo->escapeString($url),
+ $salesrank,
+ $this->pdo->escapeString($platform),
+ $this->pdo->escapeString($publisher),
+ $this->pdo->escapeString($releasedate),
+ $this->pdo->escapeString($esrb),
+ $cover,
+ $genreID,
+ $id
+ )
+ );
+ }
+
+ /**
+ * Process each game, updating game information from Giantbomb
+ *
+ * @param $gameInfo
+ *
+ * @return bool
+ */
+ public function updategamesinfo($gameInfo)
+ {
+ $gen = new Genres();
+ $ri = new ReleaseImage();
+
+ $con = array();
+ $ggameid = $this->fetchgiantbombgameid($gameInfo['title']);
+ $gb = $this->fetchGiantBombArray($ggameid);
+ $gb = $gb['results'];
+ if (!is_array($gb)) {
+ return false;
+ }
+
+ // Load genres.
+ $defaultGenres = $gen->getGenres(Genres::GAME_TYPE);
+ $genreassoc = array();
+ foreach ($defaultGenres as $dg) {
+ $genreassoc[$dg['ID']] = strtolower($dg['title']);
+ }
+
+ // Get game properties.
+ $con['coverurl'] = (string)$gb['image']['super_url'];
+ if ($con['coverurl'] != "") {
+ $con['cover'] = 1;
+ } else {
+ $con['cover'] = 0;
+ }
+
+ $con['title'] = (string)$gb['name'];
+ if (empty($con['title'])) {
+ $con['title'] = $gameInfo['title'];
+ }
+ if (is_array($gb['platforms'])) {
+ while (list($key) = each($gb['platforms'])) {
+ if ($gb['platforms'][$key]['id'] == $gameInfo['node']) {
+ $con['platform'] = (string)$gb['platforms'][$key]['name'];
+ }
+ }
+ }
+
+ if (empty($con['platform'])) {
+ $con['platform'] = $gameInfo['platform'];
+ }
+
+ // Beginning of Recheck Code.
+ // This is to verify the result back from amazon was at least somewhat related to what was intended.
+ // Some of the platforms don't match Amazon's exactly. This code is needed to facilitate rechecking.
+ if (preg_match('/^Pc$/i', $gameInfo['platform'])) {
+ $gameInfo['platform'] = str_replace('Pc', 'PC', $gameInfo['platform']);
+ } // baseline single quote
+ if (preg_match('/^Mac$/i', $gameInfo['platform'])) {
+ $gameInfo['platform'] = str_replace('Mac', 'MAC', $gameInfo['platform']);
+ } // baseline single quote
+
+ // Remove Online Game Code So Titles Match Properly.
+ if (preg_match('/\[Online Game Code\]/i', $con['title'])) {
+ $con['title'] = str_replace(' [Online Game Code]', '', $con['title']);
+ } // baseline single quote
+ // Basically the XBLA names contain crap, this is to reduce the title down far enough to be usable.
+
+ // This actual compares the two strings and outputs a percentage value.
+ $titlepercent = $platformpercent = '';
+ similar_text(strtolower($gameInfo['title']), strtolower($con['title']), $titlepercent);
+ similar_text(strtolower($gameInfo['platform']),
+ strtolower($con['platform']),
+ $platformpercent);
+
+ // If the release is DLC matching sucks, so assume anything over 50% is legit.
+ if (isset($gameInfo['dlc']) && $gameInfo['dlc'] == 1) {
+ if ($titlepercent >= 50) {
+ $titlepercent = 100;
+ $platformpercent = 100;
+ }
+ }
+
+ /*
+ echo("Matched: Title Percentage: $titlepercent% between " . strtolower($gameInfo['title']) . " and " . strtolower($con['title']) . ".\n");
+ echo("Matched: Platform Percentage: $platformpercent% \n");
+ */
+
+ // If the Title is less than 80% Platform must be 100% unless it is XBLA.
+ if ($titlepercent < 60) {
+ if ($platformpercent != 100) {
+ return false;
+ }
+ }
+
+ // If title is less than 80% then its most likely not a match.
+ if ($titlepercent < 60) {
+ similar_text(strtolower($gameInfo['title'] . ' - ' . $gameInfo['platform']),
+ strtolower($con['title']),
+ $titlewithplatpercent);
+ if ($titlewithplatpercent < 70) {
+ return false;
+ }
+ }
+
+ // Platform must equal 100%.
+ if ($platformpercent != 100) {
+ return false;
+ }
+
+ $con['asin'] = $ggameid;
+
+ $con['url'] = (string)$gb['site_detail_url'];
+ $con['url'] = str_replace("%26tag%3Dws", "%26tag%3Dopensourceins%2D21", $con['url']);
+
+ /*$con['salesrank'] = (string)$amaz->Items->Item->SalesRank;
+ if ($con['salesrank'] == "") {
+ $con['salesrank'] = 'null';
+ }
+ */
+ if (is_array($gb['publishers'])) {
+ while (list($key) = each($gb['publishers'])) {
+ if ($key == 0) {
+ $con['publisher'] = (string)$gb['publishers'][$key]['name'];
+ }
+ }
+ } else {
+ $con['publisher'] = "Unknown";
+ }
+
+ if (is_array($gb['original_game_rating'])) {
+ $con['esrb'] = (string)$gb['original_game_rating'][0]['name'];
+ } else {
+ $con['esrb'] = (string)$gb['original_game_rating']['name'];
+ }
+ $con['releasedate'] = $this->pdo->escapeString((string)$gb['original_release_date']);
+ if ($con['releasedate'] == "''") {
+ $con['releasedate'] = 'null';
+ }
+
+ $con['review'] = "";
+ if (isset($gb['decription'])) {
+ $con['review'] = trim(strip_tags((string)$gb['description']));
+ }
+
+ $genreKey = -1;
+ $genreName = '';
+
+ if (empty($genreName) && isset($gb['genres'][0]['name'])) {
+ $a = (string)$gb['genres'][0]['name'];
+ $b = str_replace('-', ' ', $a);
+ $tmpGenre = explode(',', $b);
+ foreach ($tmpGenre as $tg) {
+ $genreMatch = $this->matchBrowseNode(ucwords($tg));
+ if ($genreMatch !== false) {
+ $genreName = $genreMatch;
+ break;
+ }
+ }
+ }
+
+ if (empty($genreName)) {
+ $genreName = 'Unknown';
+ }
+ if (in_array(strtolower($genreName), $genreassoc)) {
+ $genreKey = array_search(strtolower($genreName), $genreassoc);
+ } else {
+ $genreKey = $this->pdo->queryInsert(
+ sprintf("
+ INSERT INTO genres (title, type)
+ VALUES (%s, %d)",
+ $this->pdo->escapeString($genreName),
+ Genres::GAME_TYPE
+ )
+ );
+ }
+
+ $con['gamesgenre'] = $genreName;
+ $con['gamesgenreID'] = $genreKey;
+
+ $check = $this->pdo->queryOneRow(
+ sprintf('
+ SELECT id
+ FROM gamesinfo
+ WHERE title = %s
+ AND asin = %s',
+ $this->pdo->escapeString($con['title']),
+ $this->pdo->escapeString($con['asin'])
+ )
+ );
+ if ($check === false) {
+ $gamesId = $this->pdo->queryInsert(
+ sprintf("
+ INSERT INTO gamesinfo
+ (title, asin, url, platform, publisher, genreid, esrb, releasedate, review, cover, createddate, updateddate)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %d, NOW(), NOW())",
+ $this->pdo->escapeString($con['title']),
+ $this->pdo->escapeString($con['asin']),
+ $this->pdo->escapeString($con['url']),
+ $this->pdo->escapeString($con['platform']),
+ $this->pdo->escapeString($con['publisher']),
+ ($con['gamesgenreID'] == -1 ? "null" : $con['gamesgenreID']),
+ $this->pdo->escapeString($con['esrb']),
+ $con['releasedate'],
+ $this->pdo->escapeString(substr($con['review'], 0, 3000)),
+ $con['cover']
+ )
+ );
+ } else {
+ $gamesId = $check['id'];
+ $this->pdo->exec(
+ sprintf('
+ UPDATE gamesinfo
+ SET
+ title = %s, asin = %s, url = %s, platform = %s, publisher = %s, genreid = %s,
+ esrb = %s, releasedate = %s, review = %s, cover = %s, updateddate = NOW()
+ WHERE id = %d',
+ $this->pdo->escapeString($con['title']),
+ $this->pdo->escapeString($con['asin']),
+ $this->pdo->escapeString($con['url']),
+ $this->pdo->escapeString($con['platform']),
+ $this->pdo->escapeString($con['publisher']),
+ ($con['gamesgenreID'] == -1 ? "null" : $con['gamesgenreID']),
+ $this->pdo->escapeString($con['esrb']),
+ $con['releasedate'],
+ $this->pdo->escapeString(substr($con['review'], 0, 3000)),
+ $con['cover'],
+ $gamesId
+ )
+ );
+ }
+
+ if ($gamesId) {
+ if ($this->echooutput) {
+ $this->c->doEcho(
+ $this->c->header("Added/updated game: ") .
+ $this->c->alternateOver(" Title: ") .
+ $this->c->primary($con['title']) .
+ $this->c->alternateOver(" Platform: ") .
+ $this->c->primary($con['platform'])
+ );
+ }
+ $con['cover'] = $ri->saveImage($gamesId, $con['coverurl'], $this->imgSavePath, 250, 250);
+ } else {
+ if ($this->echooutput) {
+ $this->c->doEcho(
+ $this->c->headerOver("Nothing to update: ") .
+ $this->c->primary($con['title'] . " (" . $con['platform'] . ')' )
+ );
+ }
+ }
+
+ return $gamesId;
+ }
+
+ /**
+ * Get Giantbomb search results
+ *
+ * @param $gameid
+ *
+ * @return bool|mixed Json Array if no result False
+ */
+
+ public function fetchGiantBombArray($gameid)
+ {
+ $obj = new GiantBomb($this->pubkey);
+ try {
+ $fields = array(
+ "deck", "description", "original_game_rating", "api_detail_url", "image", "genres",
+ "name", "platforms", "publishers", "original_release_date", "reviews",
+ "site_detail_url"
+ );
+ $result = json_decode(json_encode($obj->game($gameid, $fields)), true);
+ } catch (Exception $e) {
+ $result = false;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Retrieve Giantbomb game ID for api requests
+ *
+ * @param $title
+ *
+ * @return bool|mixed - Json Array if game was found false if nothing
+ */
+ public function fetchgiantbombgameid($title)
+ {
+ $obj = new GiantBomb($this->pubkey);
+ try {
+ $result = json_decode(json_encode($obj->search($title, '', 1)), true);
+ if (!is_array($result['results']) || (int) $result['number_of_total_results'] === 0) {
+ $result = false;
+ } else {
+ $result = $result['results'][0]['id'];
+ }
+ } catch (Exception $e) {
+ $result = false;
+ }
+
+ return $result;
+ }
+
+ /**
+ *
+ */
+ public function processGamesReleases()
+ {
+ $res = $this->pdo->queryDirect(
+ sprintf('
+ SELECT searchname, ID
+ FROM releases
+ WHERE nzbstatus = 1 %s
+ AND gamesinfo_id IS NULL
+ AND categoryID = 4050
+ ORDER BY postdate DESC
+ LIMIT %d',
+ $this->renamed,
+ $this->gameqty
+ )
+ );
+
+ if ($res !== false && $res->rowCount() > 0) {
+ if ($this->echooutput) {
+ $this->c->doEcho($this->c->header("Processing " . $res->rowCount() . ' games release(s).'));
+ }
+
+ foreach ($res as $arr) {
+ $startTime = microtime(true);
+ $usedgb = false;
+ $gameInfo = $this->parseTitle($arr['searchname']);
+ if ($gameInfo !== false) {
+
+ if ($this->echooutput) {
+ $this->c->doEcho(
+ $this->c->headerOver('Looking up: ') .
+ $this->c->primary($gameInfo['title'] . ' (' . $gameInfo['platform'] . ')' )
+ );
+ }
+
+ // Check for existing games entry.
+ $gameCheck = $this->getgamesinfoByName($gameInfo['title'], $gameInfo['platform']);
+
+ if ($gameCheck === false) {
+ $gameId = $this->updategamesinfo($gameInfo);
+ $usedgb = true;
+ if ($gameId === false) {
+ $gameId = -2;
+ }
+ } else {
+ $gameId = $gameCheck['id'];
+ }
+ //$gameId = null;
+ // Update release.
+ $this->pdo->exec(sprintf('UPDATE releases SET gamesinfo_id = %d WHERE ID = %d', $gameId, $arr['ID']));
+ } else {
+ // Could not parse release title.
+ $this->pdo->exec(sprintf('UPDATE releases SET gamesinfo_id = %d WHERE ID = %d', -2, $arr['ID']));
+
+ if ($this->echooutput) {
+ echo '.';
+ }
+ }
+
+ // Sleep to not flood amazon.
+ $diff = floor((microtime(true) - $startTime) * 1000000);
+ if ($this->sleeptime * 1000 - $diff > 0 && $usedgb === true) {
+ usleep($this->sleeptime * 1000 - $diff);
+ }
+ }
+ } else {
+ if ($this->echooutput) {
+ $this->c->doEcho($this->c->header('No games releases to process.'));
+ }
+ }
+ }
+
+ /**
+ * Parse the game release title
+ *
+ * @param string $releasename
+ *
+ * @return array|bool
+ */
+ public function parseTitle($releasename)
+ {
+ // Get name of the game from name of release.
+ if (preg_match(
+ '/^(.+((EFNet|EFNet\sFULL|FULL\sabgxEFNet|abgx\sFULL|abgxbox360EFNet)\s|illuminatenboard\sorg|' .
+ 'Place2(hom|us)e.net|united-forums? co uk|\(\d+\)))?(?P
.*?)[\.\-_ \:](v\.?\d\.\d|RIP|ADDON|' .
+ 'EUR|USA|JP|ASIA|JAP|JPN|AUS|MULTI(\.?\d{1,2})?|PATCHED|FULLDVD|DVD5|DVD9|DVDRIP|\(GAMES\)\s*\(C\)|PROPER|REPACK|RETAIL|' .
+ 'DEMO|DISTRIBUTION|BETA|REGIONFREE|READ\.?NFO|NFOFIX|Update|' .
+ // Group names, like Reloaded, CPY, Razor1911, etc
+ '[a-z0-9]{2,}$)/i',
+ preg_replace('/\sMulti\d?\s/i', '', $releasename),
+ $matches)
+ ) {
+ // Replace dots, underscores, or brackets with spaces.
+ $result['title'] = str_replace(' RF ', ' ', preg_replace('/(\.|_|\%20|\[|\])/', ' ', $matches['title']));
+ // Needed to add code to handle DLC Properly.
+ if (stripos($result['title'], 'dlc') !== false) {
+ $result['dlc'] = '1';
+ if (stripos($result['title'], 'Rock Band Network') !== false) {
+ $result['title'] = 'Rock Band';
+ } else if (stripos($result['title'], '-') !== false) {
+ $dlc = explode("-", $result['title']);
+ $result['title'] = $dlc[0];
+ } else if (preg_match('/(.*? .*?) /i', $result['title'], $dlc)) {
+ $result['title'] = $dlc[0];
+ }
+ }
+
+ //get the platform of the release
+ if (preg_match('/[\.\-_ ](?PMAC|MACOSX)/i', $releasename, $matches)) {
+ $platform = $matches['platform'];
+ if (preg_match('/^MAC$/i', $platform)) {
+ $platform = 'MAC';
+ } else {
+ $platform = 'MACOSX';
+ }
+ } else {
+ $platform = "PC";
+ }
+
+ $browseNode = $this->getBrowseNode($platform);
+ $result['platform'] = $platform;
+ $result['node'] = $browseNode;
+ $result['release'] = $releasename;
+
+ // Other option is to pass the $release->categoryID here if we don't find a platform but that would require an
+ // extra lookup to determine the name. In either case we should have a title at the minimum.
+ return array_map("trim", $result);
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the Giantbomb Category ID #
+ *
+ * @param $platform
+ *
+ * @return string
+ */
+ protected function getBrowseNode($platform)
+ {
+ switch ($platform) {
+ case 'PC':
+ $nodeId = '94';
+ break;
+ case 'MAC':
+ $nodeId = '17';
+ break;
+ default:
+ $nodeId = '94';
+ break;
+ }
+
+ return $nodeId;
+ }
+
+ /**
+ * Not in use for future additions.
+ *
+ * @param $nodeName
+ *
+ * @return bool|string
+ */
+ public function matchBrowseNode($nodeName)
+ {
+ $str = '';
+
+ //music nodes above mp3 download nodes
+ switch ($nodeName) {
+ case 'Action':
+ case 'Adventure':
+ case 'Arcade':
+ case 'Board Games':
+ case 'Cards':
+ case 'Casino':
+ case 'Flying':
+ case 'Puzzle':
+ case 'Racing':
+ case 'Rhythm':
+ case 'Role-Playing':
+ case 'Simulation':
+ case 'Sports':
+ case 'Strategy':
+ case 'Trivia':
+ $str = $nodeName;
+ break;
+ }
+
+ return ($str !== '') ? $str : false;
+ }
+}
\ No newline at end of file
diff --git a/lib/copy_this/www/lib/GiantBombAPI.php b/lib/copy_this/www/lib/GiantBombAPI.php
new file mode 100644
index 000000000..96ba3d650
--- /dev/null
+++ b/lib/copy_this/www/lib/GiantBombAPI.php
@@ -0,0 +1,435 @@
+api_key = $key;
+
+ // Now set the api response type, Default to json
+ $this->resp_type = $resp;
+
+ // Init new instance of curl
+ $this->ch = curl_init();
+
+ // set default options for curl
+ curl_setopt_array(
+ $this->ch,
+ array(
+ CURLOPT_HEADER => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_NOPROGRESS => true,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31'
+ )
+ );
+ }
+
+ /**
+ * Destructor
+ * deletes curl instance
+ *
+ * @void
+ */
+ public function __destruct()
+ {
+ // Close request to clear up some resources
+ if (!is_null($this->ch)) {
+ curl_close($this->ch);
+ }
+ }
+
+ /**
+ * Send call to API
+ *
+ * @param string $module string name of url suffix
+ * @param array $params array get parameters to send to API
+ *
+ * @return mixed|array response of API
+ * @throws GiantBombException
+ */
+ private function call($module, $params = array())
+ {
+ // set api data
+ $params['api_key'] = $this->api_key;
+ $params['format'] = $this->resp_type;
+
+ // build URL
+ $url = $this->endpoint . $module . '?' . http_build_query($params);
+
+ // Set URL
+ curl_setopt($this->ch, CURLOPT_URL, $url);
+
+ // Send the request & save response to $resp
+ $resp["data"] = curl_exec($this->ch);
+ if (curl_errno($this->ch)) {
+ throw new GiantBombException('API call failed: ' . curl_error($this->ch));
+ }
+
+ // save http response code
+ $resp["httpCode"] = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
+
+ if (!$resp || !$resp["data"]) {
+ throw new GiantBombException("Couldn't get information from API");
+ }
+
+ return $resp;
+ }
+
+ /**
+ * Format filter array to string
+ *
+ * @param $filters array list of filters
+ *
+ * @return string combined filter string
+ */
+ private function format_filter($filters = array())
+ {
+ $filters_merged = array();
+ foreach ($filters as $ky => $vl) {
+ $filters_merged[] = $ky . ':' . $vl;
+ }
+
+ return implode(',', $filters_merged);
+ }
+
+ /**
+ * Get information about given object type
+ *
+ * @param string $type
+ * @param string $id string ID to request
+ * @param array $field_list array list of fields to response
+ *
+ * @return array response
+ * @throws GiantBombException
+ */
+ public function get_object($type, $id, $field_list = array())
+ {
+ $resp = $this->call($type . '/' . $id . '/',
+ array('field_list' => implode(',', $field_list)));
+
+ // No game with given game id found
+ if ($resp["httpCode"] == 404) {
+ throw new GiantBombException('Couldn\'t find ' . $type . ' with game id "' . $id . '"');
+ }
+
+ return $this->parse_result($resp["data"]);
+ }
+
+ /**
+ * Get list of objects by given filters
+ *
+ * @param $type
+ * @param $filter array filter by given values - no "," accepted
+ * @param $limit integer limit result count by given limit
+ * @param $offset integer offset of results
+ * @param $platform integer ID of platform to limit
+ * @param $sort array list of keys to sort, format key => asc/desc,
+ * @param $field_list array list of field to result
+ *
+ * @return mixed|array response
+ */
+ public function get_objects($type, $filter = array(), $limit = 100, $offset = 0,
+ $platform = null, $sort = array(), $field_list = array())
+ {
+ $resp = $this->call($type . '/',
+ array(
+ 'field_list' => implode(',', $field_list),
+ 'limit' => $limit,
+ 'offset' => $offset,
+ 'platforms' => $platform,
+ 'sort' => $this->format_filter($sort),
+ 'filter' => $this->format_filter($filter)
+ ));
+
+ return $this->parse_result($resp["data"]);
+ }
+
+ /**
+ * Get information about a game
+ *
+ * @param $id string ID to request
+ * @param $field_list array list of fields to response
+ *
+ * @return array response
+ */
+ public function game($id, $field_list = array())
+ {
+ return $this->get_object('game', $id, $field_list);
+ }
+
+ /**
+ * List games by filters
+ *
+ * @param $filter array filter by given values - no "," accepted
+ * @param $limit integer limit result count by given limit
+ * @param $offset integer offset of results
+ * @param $platform integer ID of platform to limit
+ * @param $sort array list of keys to sort, format key => asc/desc,
+ * @param $field_list array list of field to result
+ *
+ * @return array list of games
+ */
+ public function games($filter = array(), $limit = 100, $offset = 0, $platform = null,
+ $sort = array(), $field_list = array())
+ {
+ return $this->get_objects('games', $filter, $limit, $offset, $platform, $sort, $field_list);
+ }
+
+ /**
+ * Get review by id
+ *
+ * @param $review_id string ID to request
+ * @param $field_list array list of fields to response
+ *
+ * @return array response
+ */
+ public function review($review_id, $field_list = array())
+ {
+ return $this->get_object('review', $review_id, $field_list);
+ }
+
+ /**
+ * Get game_rating by id
+ *
+ * @param $rating_id string ID to request
+ * @param $field_list array list of fields to response
+ *
+ * @return array response
+ */
+ public function game_rating($rating_id, $field_list = array())
+ {
+ return $this->get_object('game_rating', $rating_id, $field_list);
+ }
+
+ /**
+ * Get company by id
+ *
+ * @param $company_id string ID to request
+ * @param $field_list array list of fields to response
+ *
+ * @return array response
+ */
+ public function company($company_id, $field_list = array())
+ {
+ return $this->get_object('company', $company_id, $field_list);
+ }
+
+ /**
+ * Get character by id
+ *
+ * @param $character_id string ID to request
+ * @param $field_list array list of fields to response
+ *
+ * @return array response
+ */
+ public function character($character_id, $field_list = array())
+ {
+ return $this->get_object('character', $character_id, $field_list);
+ }
+
+ /**
+ * Perform a search with given keyword
+ *
+ * @param $query string keyword to search
+ * @param $field_list array list of fields to response
+ * @param $limit integer limit result count by given limit
+ * @param $page
+ * @param $resources
+ *
+ * @return array response
+ */
+ public function search($query, $field_list = array(), $limit = 100, $page = 0, $resources = array())
+ {
+ if (!is_array($field_list)) {
+ $field_list = (array)$field_list;
+ }
+ if (!is_array($resources)) {
+ $resources = (array)$resources;
+ }
+
+ $resp = $this->call(
+ 'search/',
+ array(
+ 'field_list' => implode(',', $field_list),
+ 'limit' => $limit,
+ 'page' => $page,
+ 'query' => $query,
+ 'resources' => implode(',', $resources)
+ )
+ );
+
+ return $this->parse_result($resp['data']);
+ }
+
+ /**
+ * List genres
+ *
+ * @param $field_list array list of field to result
+ * @param $limit integer limit result count by given limit
+ * @param $offset integer offset of results
+ *
+ * @return array list of games
+ */
+ public function genres($field_list = array(), $limit = 100, $offset = 0)
+ {
+ $resp = $this->call(
+ 'genres/',
+ array(
+ 'field_list' => implode(',', $field_list),
+ 'limit' => $limit,
+ 'offset' => $offset
+ )
+ );
+
+ return $this->parse_result($resp['data']);
+ }
+
+ /**
+ * List platforms by filter
+ *
+ * @param $field_list array list of field to result
+ * @param $limit integer limit result count by given limit
+ * @param $offset integer offset of results
+ * @param $filter array filter by given values - no "," accepted
+ * @param $sort array list of keys to sort, format key => asc/desc,
+ *
+ * @return array list of games
+ */
+ public function platforms($field_list = array(), $limit = 100, $offset = 0, $filter = array(),
+ $sort = array())
+ {
+ $resp = $this->call(
+ 'platforms/',
+ array(
+ 'field_list' => implode(',', $field_list),
+ 'limit' => $limit,
+ 'offset' => $offset,
+ 'sort' => $this->format_filter($sort),
+ 'filter' => $this->format_filter($filter)
+ )
+ );
+
+ return $this->parse_result($resp["data"]);
+ }
+
+ /**
+ * Return parsed result of api response
+ *
+ * @param $data string result of API
+ *
+ * @return mixed|SimpleXMLElement parsed version of input string(object)
+ * @throws GiantBombException
+ */
+ private function parse_result($data)
+ {
+ try {
+ if ($this->resp_type == "json") {
+ $result = @json_decode($data);
+ } else {
+ $result = @simplexml_load_string($data);
+ }
+ } catch (Exception $e) {
+ throw new GiantBombException("Parse error occoured", null, $e);
+ }
+
+ if (empty($result) || !empty($result->error) && strtoupper($result->error) != "OK") {
+ throw new GiantBombException("Following error encountered: " . $result->error);
+ }
+
+ return $result;
+ }
+}
+
+/**
+ * Define a custom exception class for api wrapper
+ */
+class GiantBombException extends Exception
+{
+
+ /**
+ * Redefine the exception so message isn't optional
+ *
+ * @param $message string message to set in exception
+ * @param $code integer error code
+ * @param $previous Exception previous Exception to save
+ *
+ * @void
+ */
+ public function __construct($message, $code = 0, Exception $previous = null)
+ {
+ // make sure everything is assigned properly
+ parent::__construct($message, $code, $previous);
+ }
+
+ /**
+ * convert exception to string
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
+ }
+}
\ No newline at end of file
diff --git a/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Client.php b/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Client.php
index 992227b61..1d0f24c77 100644
--- a/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Client.php
+++ b/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Client.php
@@ -69,16 +69,10 @@
// Warn about PHP bugs
if (version_compare(PHP_VERSION, '5.2.11') === 0) {
- trigger_error('PHP bug #16657 breaks feof() on socket streams! '
- . 'Connection consistency might be compromised!', E_USER_WARNING
- );
+ trigger_error('PHP bug #16657 breaks feof() on socket streams! Connection consistency might be compromised!', E_USER_WARNING);
}
-/**
- *
- */
require_once 'PEAR.php';
-//require_once 'Net/NNTP/Error.php';
require_once 'Responsecode.php';
// {{{ constants
@@ -105,7 +99,7 @@ define('NET_NNTP_PROTOCOL_CLIENT_DEFAULT_PORT', '119');
/**
* Low level NNTP Client
*
- * Implements the client part of the NNTP standard acording to:
+ * Implements the client part of the NNTP standard according to:
* - RFC 977,
* - RFC 2980,
* - RFC 850/1036, and
@@ -117,11 +111,11 @@ define('NET_NNTP_PROTOCOL_CLIENT_DEFAULT_PORT', '119');
* class (and should therefore currently not be extended
* directly outside of the Net_NNTP package). Therefore its
* API is NOT required to be fully stable, for as long as such
- * changes doesn't affect the public API of
+ * changes do not affect the public API of
* the Net_NNTP_Client class, which is considered stable.
*
- * TODO: cmdListActiveTimes()
- * cmdDistribPats()
+ * TODO: cmdListActiveTimes()
+ * cmdDistribPats()
*
* @category Net
* @package Net_NNTP
@@ -139,119 +133,105 @@ class Net_NNTP_Protocol_Client extends PEAR
* The socket resource being used to connect to the NNTP server.
*
* @var resource
- * @access private
+ * @access protected
*/
- var $_socket = null;
+ protected $_socket = null;
/**
- * Contains the last recieved status response code and text
+ * Contains the last received status response code and text.
*
* @var array
- * @access private
+ * @access protected
*/
- var $_currentStatusResponse = null;
+ protected $_currentStatusResponse = null;
/**
- *
+ * Optional logger class to use for debugging.
*
* @var object
* @access private
*/
- var $_logger = null;
+ private $_logger = null;
- // }}}
- // {{{ constructor
+ /**
+ * Seconds to wait for the blocking socket to timeout.
+ *
+ * @var int
+ */
+ protected $_socketTimeout = 120;
/**
* Constructor
*
* @access public
*/
- function Net_NNTP_Protocol_Client()
+ public function Net_NNTP_Protocol_Client()
{
- //
-// parent::PEAR('Net_NNTP_Error');
+ // Init PEAR.
parent::PEAR();
}
- // }}}
- // {{{ getPackageVersion()
-
/**
- *
+ * Get current package version.
*
* @access public
*/
- function getPackageVersion()
+ public function getPackageVersion()
{
return '1.5.0';
}
- // }}}
- // {{{ getApiVersion()
-
/**
- *
+ * Get current API version.
*
* @access public
*/
- function getApiVersion()
+ public function getApiVersion()
{
return '0.9.0';
}
- // }}}
- // {{{ setLogger()
-
/**
- *
+ * Set the debug logger instance object.
*
* @param object $logger
*
* @access protected
*/
- function setLogger($logger)
+ protected function setLogger($logger)
{
$this->_logger = $logger;
}
- // }}}
- // {{{ setDebug()
-
/**
* @deprecated
*/
- function setDebug($debug = true)
+ public function setDebug($debug = true)
{
- trigger_error('You are using deprecated API v1.0 in '
- . 'Net_NNTP_Protocol_Client: setDebug() ! Debugging in now '
- . 'automatically handled when a logger is given.', E_USER_NOTICE
+ trigger_error(
+ 'You are using deprecated API v1.0 in Net_NNTP_Protocol_Client: setDebug() ! Debugging in now automatically handled when a logger is given.',
+ E_USER_NOTICE
);
}
- // }}}
- // {{{ _sendCommand()
-
/**
- * Send command
+ * Send a command to usenet.
*
* Send a command to the server. A carriage return / linefeed
- * (CRLF) sequence will be appended to each command string before
- * it is sent to the IMAP server.
+ * (CRLF) sequence will be appended to each command string before it is sent to the IMAP server.
*
* @param string $cmd The command to launch, ie: "ARTICLE 1004853"
*
- * @return mixed (int) response code on success or (object)
- * pear_error on failure
- * @access private
+ * @return mixed (int) response code on success
+ * (object) pear_error on failure
+ * @access protected
*/
- function _sendCommand($cmd)
+ protected function _sendCommand($cmd)
{
// NNTP/RFC977 only allows command up to 512 (-2) chars.
- if (!strlen($cmd) > 510)
- return $this->throwError(
- 'Failed writing to socket! (Command to long - max 510 chars)'
- );
+ if (strlen($cmd) > 510) {
+ return $this->throwError('Failed writing to socket! (Command to long - max 510 chars)');
+ }
/***************************************************************
* Credit: *
@@ -262,192 +242,154 @@ class Net_NNTP_Protocol_Client extends PEAR
* function with user input, by appending a new line *
* character followed by the injection. *
***************************************************************
+
* Prevent new line (and possible future) characters in the NNTP
* commands Net_NNTP does not support pipelined commands.
- * Inserting a new line charecter allows sending multiple
+ * Inserting a new line character allows sending multiple
* commands and thereby making the communication between
* NET_NNTP and the server out of sync...
*/
if (preg_match_all('/\r?\n/', $cmd, $matches, PREG_PATTERN_ORDER)) {
- foreach ($matches[0] as $key => $match) {
- $this->_logger->debug("Illegal character in command: " .
- htmlentities(str_replace(array("\r", "\n"),
- array("'Carriage Return'", "'New Line'"), $match
+ if ($this->_logger) {
+ foreach ($matches[0] as $match) {
+ $this->_logger->debug(
+ "Illegal character in command: " . htmlentities(str_replace(array("\r", "\n"),
+ array("'Carriage Return'", "'New Line'"), $match
+ )
)
- )
- );
+ );
+ }
}
return $this->throwError("Illegal character(s) in NNTP command!");
}
- // Check if connected
+ // Check if connected.
if (!$this->_isConnected()) {
return $this->throwError('Failed to write to socket! (connection lost!)');
}
- // Send the command
- $R = @fwrite($this->_socket, $cmd . "\r\n");
- if ($R === false) {
+ // Send the command.
+ if (@fwrite($this->_socket, $cmd . "\r\n") === false) {
return $this->throwError('Failed to write to socket!');
}
- //
+ // Log sent message.
if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) {
$this->_logger->debug('C: ' . $cmd);
}
- //
return $this->_getStatusResponse();
}
- // }}}
- // {{{ _getStatusResponse()
-
/**
* Get servers status response after a command.
*
- * @return mixed (int) statuscode on success or
- * (object) pear_error on failure
+ * @return mixed (int) response code on success
+ * (object) pear_error on failure
* @access private
*/
- function _getStatusResponse()
+ private function _getStatusResponse()
{
- // Retrieve a line (terminated by "\r\n") from the server.
- // RFC says max is 510, but IETF says "be liberal in what you accept"...
+ // Retrieve a line (terminated by "\r\n") from the server. RFC says max is 510, but IETF says "be liberal in what you accept"...
$response = @fgets($this->_socket, 4096);
if ($response === false) {
return $this->throwError('Failed to read from socket...!');
}
- //
+ // Log incoming message.
if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) {
$this->_logger->debug('S: ' . rtrim($response, "\r\n"));
}
- /* Trim the start of the response in case of
- * misplased whitespace (should not be needen!!!)
- */
+ // Trim the start of the response in case of misplaced whitespace (should not be needed).
$response = ltrim($response);
- $this->_currentStatusResponse =
- array((int)substr($response, 0, 3),
- (string)rtrim(substr($response, 4))
- );
+ // Store the response in an array, 0 => response code, 1 => response message.
+ $this->_currentStatusResponse = array((int)substr($response, 0, 3), (string)rtrim(substr($response, 4)));
- //
return $this->_currentStatusResponse[0];
}
- // }}}
- // {{{ _getTextResponse()
-
/**
* Retrieve textural data
*
* Get data until a line with only a '.' in it is read and return data.
*
- * @return mixed (array) text response on success or
- * (object) pear_error on failure
- * @access private
+ * @return mixed (array) text response on success
+ * (object) pear_error on failure
+ * @access protected
*/
- function _getTextResponse()
+ protected function _getTextResponse()
{
+ // Buffer to hold the received lines.
$data = array();
- $line = '';
- //
- $debug = $this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG);
+ $debug = ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG));
- // Continue until connection is lost
+ // Continue until connection is lost.
while (!feof($this->_socket)) {
// Retrieve and append up to 1024 characters from the server.
- $recieved = @fgets($this->_socket, 1024);
+ $line = @fgets($this->_socket, 1024);
- if ($recieved === false) {
+ if ($line === false) {
return $this->throwError('Failed to read line from socket.', null);
}
- $line .= $recieved;
-
- // Continue if the line is not terminated by CRLF
- if (substr($line, -2) != "\r\n" || strlen($line) < 2) {
+ // Continue if the line is not terminated by CR LF.
+ if (substr($line, -2) !== "\r\n" || strlen($line) < 2) {
continue;
}
- // Validate recieved line
- if (false) {
- // Lines should/may not be longer than 998+2 chars (RFC2822 2.3)
- if (strlen($line) > 1000) {
- if ($this->_logger) {
- $this->_logger->notice('Max line length...');
- }
-
- return $this->throwError('Invalid line recieved!', null);
- }
- }
-
- // Remove CRLF from the end of the line
+ // Remove CR LF from the end of the line.
$line = substr($line, 0, -2);
- // Check if the line terminates the textresponse
- if ($line == '.') {
+ // Check if the line terminates the text response.
+ if ($line === '.') {
if ($this->_logger) {
$this->_logger->debug('T: ' . $line);
}
- // return all previous lines
+ // Return all previous lines.
return $data;
}
- // If 1st char is '.' it's doubled (NNTP/RFC977 2.4.1)
- if (substr($line, 0, 2) == '..') {
+ // If 1st char is '.' it's doubled (NNTP/RFC977 2.4.1).
+ if (substr($line, 0, 2) === '..') {
$line = substr($line, 1);
}
- //
if ($debug) {
$this->_logger->debug('T: ' . $line);
}
- // Add the line to the array of lines
+ // Add the line to the array of lines.
$data[] = $line;
-
- // Reset/empty $line
- $line = '';
}
if ($this->_logger) {
- $this->_logger->warning('Broke out of reception loop! '
- . 'This souldn\'t happen unless connection has been lost?'
- );
+ $this->_logger->warning('Broke out of reception loop! This souldn\'t happen unless connection has been lost?');
}
- //
return $this->throwError('End of stream! Connection lost?', null);
}
- // }}}
- // {{{ _sendText()
-
/**
+ * Send an article to usenet.
*
+ * @note Data should be in the format specified by RFC850.
*
* @access private
*/
- function _sendArticle($article)
+ private function _sendArticle($article)
{
- /* data should be in the format specified by RFC850 */
-
switch (true) {
case is_string($article):
- //
@fwrite($this->_socket, $article);
@fwrite($this->_socket, "\r\n.\r\n");
- //
if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) {
foreach (explode("\r\n", $article) as $line) {
$this->_logger->debug('D: ' . $line);
@@ -472,7 +414,6 @@ class Net_NNTP_Protocol_Client extends PEAR
@fwrite($this->_socket, $header);
@fwrite($this->_socket, "\r\n");
- //
if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) {
foreach (explode("\r\n", $header) as $line) {
$this->_logger->debug('D: ' . $line);
@@ -491,7 +432,6 @@ class Net_NNTP_Protocol_Client extends PEAR
@fwrite($this->_socket, $body);
@fwrite($this->_socket, "\r\n.\r\n");
- //
if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) {
foreach (explode("\r\n", $body) as $line) {
$this->_logger->debug('D: ' . $line);
@@ -507,116 +447,63 @@ class Net_NNTP_Protocol_Client extends PEAR
return true;
}
- // }}}
- // {{{ _currentStatusResponse()
-
/**
+ * Return the last received response message.
*
- *
- * @return string status text
+ * @return string The response message.
* @access private
*/
- function _currentStatusResponse()
+ private function _currentStatusResponse()
{
return $this->_currentStatusResponse[1];
}
- // }}}
- // {{{ _handleUnexpectedResponse()
-
- /**
- *
- *
- * @param int $code Status code number
- * @param string $text Status text
- *
- * @return mixed
- * @access private
- */
- function _handleUnexpectedResponse($code = null, $text = null)
- {
- if ($code === null) {
- $code = $this->_currentStatusResponse[0];
- }
-
- if ($text === null) {
- $text = $this->_currentStatusResponse();
- }
-
- switch ($code) {
- /* 502, 'access restriction or permission denied'
- * / service permanently unavailable
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED:
- return $this->throwError('Command not permitted / Access'
- . ' restriction / Permission denied', $code, $text
- );
- break;
- default:
- return $this->throwError("Unexpected response: '$text'",
- $code, $text
- );
- }
- }
-
- // }}}
-
/* Session administration commands */
- // {{{ Connect()
-
/**
* Connect to a NNTP server
*
- * @param string $host (optional) The address of the
- * NNTP-server to connect to, defaults to 'localhost'.
- * @param mixed $encryption (optional)
- * @param int $port (optional) The port number to connect to,
- * defaults to 119.
- * @param int $timeout (optional)
+ * @param string $host (optional) The address of the NNTP-server to connect to, defaults to 'localhost'.
+ * @param mixed $encryption (optional) Use TLS/SSL on the connection?
+ * (string) 'tcp' => Use no encryption.
+ * 'ssl', 'sslv3', 'tls' => Use encryption.
+ * (null)|(false) Use no encryption.
+ * @param int $port (optional) The port number to connect to, defaults to 119.
+ * @param int $timeout (optional) How many seconds to wait before giving up when connecting.
+ * @param int $socketTimeout (optional) How many seconds to wait before timing out the (blocked) socket.
*
- * @return mixed (bool) on success (true when posting allowed,
- * otherwise false) or (object) pear_error on failure
+ * @return mixed (bool) On success: True when posting allowed, otherwise false.
+ * (object) On failure: pear_error
* @access protected
*/
- function connect($host = null, $encryption = null, $port = null, $timeout = 15)
+ protected function connect($host = null, $encryption = null, $port = null, $timeout = 15, $socketTimeout = 120)
{
- //
- if ($this->_isConnected()) {
+ if ($this->_isConnected() ) {
return $this->throwError('Already connected, disconnect first!', null);
}
// v1.0.x API
if (is_int($encryption)) {
- trigger_error('You are using deprecated API v1.0 in '
- . 'Net_NNTP_Protocol_Client: connect() !', E_USER_NOTICE
- );
+ trigger_error('You are using deprecated API v1.0 in Net_NNTP_Protocol_Client: connect() !', E_USER_NOTICE);
$port = $encryption;
$encryption = false;
}
- //
if (is_null($host)) {
$host = 'localhost';
}
- /* Choose transport based on encryption, and if no port is
- * given, use default for that encryption
- */
+ // Choose transport based on encryption, and if no port is given, use default for that encryption.
switch ($encryption) {
case null:
-
case 'tcp':
-
case false:
$transport = 'tcp';
$port = is_null($port) ? 119 : $port;
break;
case 'sslv3':
-
case 'ssl':
-
case 'tls':
$transport = $encryption;
$port = is_null($port) ? 563 : $port;
@@ -628,29 +515,40 @@ class Net_NNTP_Protocol_Client extends PEAR
return $this->throwError($message);
}
- // Open Connection
- $R = @stream_socket_client($transport . '://' . $host . ':' . $port, $errno, $errstr, $timeout);
- if ($R === false) {
+ // Attempt to connect to usenet.
+ $socket = @stream_socket_client(
+ $transport . '://' . $host . ':' . $port, $errorNumber, $errorString, $timeout
+ );
+
+ if ($socket === false) {
+
$message = "Connection to $transport://$host:$port failed.";
+
if (preg_match('/tls|ssl/', $transport)) {
$message .= ' Try disabling SSL/TLS, and/or try a different port.';
}
- $message .= ' [ERROR ' . $errno . ': ' . $errstr . ']';
+
+ $message .= ' [ERROR ' . $errorNumber . ': ' . $errorString . ']';
+
if ($this->_logger) {
$this->_logger->notice($message);
}
return $this->throwError($message);
}
- $this->_socket = $R;
- stream_set_timeout($this->_socket, 120);
+ // Store the socket resource as property.
+ $this->_socket = $socket;
+
+ $this->_socketTimeout = (is_numeric($socketTimeout) ? $socketTimeout : $this->_socketTimeout);
+
+ // Set the socket timeout.
+ stream_set_timeout($this->_socket, $this->_socketTimeout);
- //
if ($this->_logger) {
$this->_logger->info("Connection to $transport://$host:$port has been established.");
}
- // Retrive the server's initial response.
+ // Retrieve the server's initial response.
$response = $this->_getStatusResponse();
if ($this->isError($response)) {
return $response;
@@ -661,65 +559,30 @@ class Net_NNTP_Protocol_Client extends PEAR
case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_ALLOWED:
// TODO: Set some variable before return
return true;
- break;
// 201, Posting NOT allowed
case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED:
- //
if ($this->_logger) {
$this->_logger->info('Posting not allowed!');
}
// TODO: Set some variable before return
return false;
- break;
-
- case 400:
- return $this->throwError('Server refused connection',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- /* 502, 'access restriction or permission denied'
- * / service permanently unavailable
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED:
- return $this->throwError('Server refused connection',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ disconnect()
-
- /**
- * alias for cmdQuit()
- *
- * @access protected
- */
- function disconnect()
- {
- return $this->cmdQuit();
- }
-
- // }}}
- // {{{ cmdCapabilities()
-
/**
* Returns servers capabilities
*
- * @return mixed (array) list of capabilities on success or
- * (object) pear_error on failure
+ * @return mixed (array) list of capabilities on success or
+ * (object) pear_error on failure
* @access protected
*/
- function cmdCapabilities()
+ protected function cmdCapabilities()
{
- // tell the newsserver we want an article
$response = $this->_sendCommand('CAPABILITIES');
if ($this->isError($response)) {
return $response;
@@ -733,26 +596,21 @@ class Net_NNTP_Protocol_Client extends PEAR
return $data;
}
return $data;
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdModeReader()
-
/**
*
*
- * @return mixed (bool) true when posting allowed, false when
- * postind disallowed or (object) pear_error on failure
+ * @return mixed (bool) true when posting allowed, false when posting disallowed
+ * (object) pear_error on failure
* @access protected
*/
- function cmdModeReader()
+ protected function cmdModeReader()
{
- // tell the newsserver we want an article
$response = $this->_sendCommand('MODE READER');
if ($this->isError($response)) {
return $response;
@@ -763,7 +621,6 @@ class Net_NNTP_Protocol_Client extends PEAR
case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_ALLOWED:
// TODO: Set some variable before return
return true;
- break;
// 201, RFC2980: 'Hello, you can't post'
case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED:
@@ -772,46 +629,43 @@ class Net_NNTP_Protocol_Client extends PEAR
}
// TODO: Set some variable before return
return false;
- break;
-
- /* 502, 'access restriction or permission denied'
- * / service permanently unavailable
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED:
- return $this->throwError('Connection being closed, '
- . 'since service so permanently unavailable',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdQuit()
+ /**
+ * Alias for cmdQuit()
+ *
+ * @access protected
+ */
+ protected function disconnect()
+ {
+ return $this->cmdQuit();
+ }
/**
* Disconnect from the NNTP server
*
- * @return mixed (bool) true on success or
- * (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdQuit()
+ protected function cmdQuit()
{
- // Tell the server to close the connection
$response = $this->_sendCommand('QUIT');
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- case 205: // RFC977: 'closing connection - goodbye!'
+ // RFC977: 'closing connection - goodbye!'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_REQUESTED:
// If socket is still open, close it.
- if ($this->_isConnected()) {
- fclose($this->_socket);
+ $disconnected = true;
+ if ($this->_isConnected(false)) {
+ $disconnected = (bool)stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR);
}
if ($this->_logger) {
@@ -820,27 +674,20 @@ class Net_NNTP_Protocol_Client extends PEAR
$this->_currentStatusResponse = null;
$this->_socket = null;
- return true;
- break;
+ return $disconnected;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
-
- // }}}
-
- /* */
-
- // {{{ cmdStartTLS()
-
/**
+ * Request TLS encryption to the news server.
*
- *
- * @return mixed (bool) on success or (object) pear_error on failure
+ * @return mixed (bool) on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdStartTLS()
+ protected function cmdStartTLS()
{
$response = $this->_sendCommand('STARTTLS');
if ($this->isError($response)) {
@@ -848,75 +695,53 @@ class Net_NNTP_Protocol_Client extends PEAR
}
switch ($response) {
- case 382: // RFC4642: 'continue with TLS negotiation'
- $encrypted = stream_socket_enable_crypto($this->_socket,
- true, STREAM_CRYPTO_METHOD_TLS_CLIENT
- );
+ // RFC4642: 'continue with TLS negotiation'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TLS_AUTHENTICATION_CONTINUE:
+ $encrypted = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
switch (true) {
case $encrypted === true:
if ($this->_logger) {
$this->_logger->info('TLS encryption started.');
}
return true;
- break;
- case $encrypted === true:
+ case $encrypted === false:
if ($this->_logger) {
$this->_logger->info('TLS encryption failed.');
}
- return $this->throwError('Could not initiate '
- . 'TLS negotiation', $response,
- $this->_currentStatusResponse()
- );
- break;
+ return $this->throwError('Could not initiate TLS negotiation', $response, $this->_currentStatusResponse());
case is_int($encrypted):
- return $this->throwError('', $response,
- $this->_currentStatusResponse()
- );
- break;
+ return $this->throwError('TLS encryption failed.', $response, $this->_currentStatusResponse());
default:
- return $this->throwError('Internal error - '
- . 'unknown response from'
- . 'stream_socket_enable_crypto()',
- $response, $this->_currentStatusResponse()
+ return $this->throwError(
+ 'Internal error - unknown response from stream_socket_enable_crypto()',
+ $response,
+ $this->_currentStatusResponse()
);
}
- break;
-
- case 580: // RFC4642: 'can not initiate TLS negotiation'
- return $this->throwError('', $response,
- $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
- /* Article posting and retrieval */
-
/* Group and article selection */
- // {{{ cmdGroup()
-
/**
* Selects a news group (issue a GROUP command to the server)
*
* @param string $newsgroup The newsgroup name
*
- * @return mixed (array) groupinfo on success or
- * (object) pear_error on failure
+ * @return mixed (array) group info on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdGroup($newsgroup)
+ protected function cmdGroup($newsgroup)
{
- $response = $this->_sendCommand('GROUP ' . $newsgroup);
+ $response = $this->_sendCommand('GROUP '.$newsgroup);
if ($this->isError($response)) {
return $response;
}
@@ -924,49 +749,35 @@ class Net_NNTP_Protocol_Client extends PEAR
switch ($response) {
// 211, RFC977: 'n f l s group selected'
case NET_NNTP_PROTOCOL_RESPONSECODE_GROUP_SELECTED:
- $response_arr = explode(' ',
- trim($this->_currentStatusResponse())
- );
+ $response_arr = explode(' ', trim($this->_currentStatusResponse()));
if ($this->_logger) {
- $this->_logger->info('Group selected: '
- . $response_arr[3]
- );
+ $this->_logger->info('Group selected: ' . $response_arr[3]);
}
- return array('group' => $response_arr[3],
- 'first' => $response_arr[1],
- 'last' => $response_arr[2],
- 'count' => $response_arr[0]
+ return array(
+ 'group' => $response_arr[3],
+ 'first' => $response_arr[1],
+ 'last' => $response_arr[2],
+ 'count' => $response_arr[0]
);
- break;
-
- // 411, RFC977: 'no such news group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_GROUP:
- return $this->throwError('No such news group on server',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdListgroup()
-
/**
+ * Gets a group overview.
*
+ * @param string $newsgroup (optional)
+ * @param mixed $range (optional)
*
- * @param optional string $newsgroup
- * @param optional mixed $range
- *
- * @return optional mixed (array) on success or
- * (object) pear_error on failure
+ * @return mixed (array) On success
+ * (object) pear_error On failure
* @access protected
*/
- function cmdListgroup($newsgroup = null, $range = null)
+ protected function cmdListgroup($newsgroup = null, $range = null)
{
if (is_null($newsgroup)) {
$command = 'LISTGROUP';
@@ -979,7 +790,7 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -992,194 +803,110 @@ class Net_NNTP_Protocol_Client extends PEAR
return $articles;
}
- $response_arr = explode(' ',
- trim($this->_currentStatusResponse()), 4
- );
+ $response_arr = explode(' ', trim($this->_currentStatusResponse()), 4);
- /* If server does not return group summary in
- * status response, return null'ed array
- */
+ // If server does not return group summary in status response, return null array.
if (!is_numeric($response_arr[0]) ||
!is_numeric($response_arr[1]) ||
!is_numeric($response_arr[2]) ||
empty($response_arr[3])
) {
- return array('group' => null,
- 'first' => null,
- 'last' => null,
- 'count' => null,
- 'articles' => $articles
+ return array(
+ 'group' => null,
+ 'first' => null,
+ 'last' => null,
+ 'count' => null,
+ 'articles' => $articles
);
}
- return array('group' => $response_arr[3],
- 'first' => $response_arr[1],
- 'last' => $response_arr[2],
- 'count' => $response_arr[0],
- 'articles' => $articles
+ return array(
+ 'group' => $response_arr[3],
+ 'first' => $response_arr[1],
+ 'last' => $response_arr[2],
+ 'count' => $response_arr[0],
+ 'articles' => $articles
);
- break;
-
- // 412, RFC2980: 'Not currently in newsgroup'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('Not currently in newsgroup',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // RFC2980: 'no permission'
- case 502:
- return $this->throwError('No permission', $response,
- $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdLast()
-
/**
+ * Select the previous article in current group.
*
- *
- * @return mixed (array) or (string) or (int) or
- * (object) pear_error on failure
+ * @return mixed (array) or (string) or (int) On success
+ * (object) pear_error On failure
* @access protected
*/
- function cmdLast()
+ protected function cmdLast()
{
- //
$response = $this->_sendCommand('LAST');
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- /* 223, RFC977: 'n a article retrieved - request text
- * separately (n = article number, a = unique article id)'
- */
+ // 223, RFC977: 'n a article retrieved - request text separately (n = article number, a = unique article id)'
case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED:
- $response_arr = explode(' ',
- trim($this->_currentStatusResponse())
- );
+ $response_arr = explode(' ', trim($this->_currentStatusResponse()));
if ($this->_logger) {
- $this->_logger->info('Selected previous article: ' .
- $response_arr[0] . ' - ' . $response_arr[1]
- );
+ $this->_logger->info('Selected previous article: ' . $response_arr[0] . ' - ' . $response_arr[1]);
}
- return array($response_arr[0], (string)$response_arr[1]);
- break;
-
- // 412, RFC977: 'no newsgroup selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC977: 'no current article has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 422, RFC977: 'no previous article in this group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_PREVIOUS_ARTICLE:
- return $this->throwError('No previous article in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
+ return array($response_arr[0], (string) $response_arr[1]);
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdNext()
-
/**
+ * Select the next article in current group.
*
- *
- * @return mixed (array) or (string) or (int) or
- * (object) pear_error on failure
+ * @return mixed (array) or (string) or (int) On success
+ * (object) pear_error On failure
* @access protected
*/
- function cmdNext()
+ protected function cmdNext()
{
- //
$response = $this->_sendCommand('NEXT');
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- /* 223, RFC977: 'n a article retrieved - request text
- * separately (n = article number, a = unique article id)'
- */
+ // 223, RFC977: 'n a article retrieved - request text separately (n = article number, a = unique article id)'
case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED:
$response_arr = explode(' ',
- trim($this->_currentStatusResponse())
- );
+ trim($this->_currentStatusResponse()));
if ($this->_logger) {
- $this->_logger->info('Selected previous article: ' .
- $response_arr[0] . ' - ' . $response_arr[1]
- );
+ $this->_logger->info('Selected previous article: ' . $response_arr[0] . ' - ' . $response_arr[1]);
}
- return array($response_arr[0], (string)$response_arr[1]);
- break;
-
- // 412, RFC977: 'no newsgroup selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC977: 'no current article has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 421, RFC977: 'no next article in this group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_NEXT_ARTICLE:
- return $this->throwError('No next article in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
+ return array($response_arr[0], (string) $response_arr[1]);
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
/* Retrieval of articles and article sections */
- // {{{ cmdArticle()
-
/**
* Get an article from the currently open connection.
*
- * @param mixed $article Either a message-id or a message-number
- * of the article to fetch. If null or '', then use current article.
+ * @param mixed $article Either a message-id or a message-number of the article to fetch.
+ * If null or '', then use current article.
*
- * @return mixed (array) article on success or
- * (object) pear_error on failure
+ * @return mixed (array) article on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdArticle($article = null)
+ protected function cmdArticle($article = null)
{
if (is_null($article)) {
$command = 'ARTICLE';
@@ -1187,16 +914,13 @@ class Net_NNTP_Protocol_Client extends PEAR
$command = 'ARTICLE ' . $article;
}
- // tell the newsserver we want an article
$response = $this->_sendCommand($command);
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- /* 220, RFC977: 'n article retrieved - head and
- * body follow (n = article number, = message-id)'
- */
+ // 220, RFC977: 'n article retrieved - head and body follow (n = article number, = message-id)'
case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_FOLLOWS:
$data = $this->_getTextResponse();
if ($this->isError($data)) {
@@ -1204,62 +928,26 @@ class Net_NNTP_Protocol_Client extends PEAR
}
if ($this->_logger) {
- $this->_logger->info(($article == null ?
- 'Fetched current article' : 'Fetched article: ' .
- $article)
- );
+ $this->_logger->info(($article == null ? 'Fetched current article' : 'Fetched article: ' . $article));
}
return $data;
- break;
-
- // 412, RFC977: 'no newsgroup has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC977: 'no current article has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 423, RFC977: 'no such article number in this group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
- return $this->throwError('No such article number in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 430, RFC977: 'no such article found'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID:
- return $this->throwError('No such article found',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdHead()
-
/**
* Get the headers of an article from the currently open connection.
*
- * @param mixed $article Either a message-id or a message-number
- * of the article to fetch the headers from. If null or '',
- * then use current article.
+ * @param mixed $article Either a message-id or a message-number of the article to fetch the headers from.
+ * If null or '', then use current article.
*
- * @return mixed (array) headers on success or
- * (object) pear_error on failure
+ * @return mixed (array) headers on success or
+ * (object) pear_error on failure
* @access protected
*/
- function cmdHead($article = null)
+ protected function cmdHead($article = null)
{
if (is_null($article)) {
$command = 'HEAD';
@@ -1267,7 +955,6 @@ class Net_NNTP_Protocol_Client extends PEAR
$command = 'HEAD ' . $article;
}
- // tell the newsserver we want the header of an article
$response = $this->_sendCommand($command);
if ($this->isError($response)) {
return $response;
@@ -1282,63 +969,27 @@ class Net_NNTP_Protocol_Client extends PEAR
}
if ($this->_logger) {
- $this->_logger->info(($article == null ?
- 'Fetched current article header' : 'Fetched '
- . 'article header for article: ' . $article)
- );
+ $this->_logger->info(($article == null ? 'Fetched current article header' : 'Fetched article header for article: ' . $article));
}
return $data;
- break;
-
- // 412, RFC977: 'no newsgroup has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC977: 'no current article has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 423, RFC977: 'no such article number in this group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
- return $this->throwError('No such article number in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 430, RFC977: 'no such article found'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID:
- return $this->throwError('No such article found',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdBody()
-
/**
* Get the body of an article from the currently open connection.
*
- * @param mixed $article Either a message-id or a message-number of
- * the article to fetch the body from. If null or '',
- * then use current article.
+ * @param mixed $article Either a message-id or a message-number of the article to fetch the body from.
+ * If null or '', then use current article.
*
- * @return mixed (array) body on success or
- * (object) pear_error on failure
+ * @return mixed (array) body on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdBody($article = null)
+ protected function cmdBody($article = null)
{
if (is_null($article)) {
$command = 'BODY';
@@ -1346,7 +997,6 @@ class Net_NNTP_Protocol_Client extends PEAR
$command = 'BODY ' . $article;
}
- // tell the newsserver we want the body of an article
$response = $this->_sendCommand($command);
if ($this->isError($response)) {
return $response;
@@ -1361,61 +1011,26 @@ class Net_NNTP_Protocol_Client extends PEAR
}
if ($this->_logger) {
- $this->_logger->info(($article == null ?
- 'Fetched current article body' : 'Fetched '
- . 'article body for article: ' . $article)
- );
+ $this->_logger->info(($article == null ? 'Fetched current article body' : 'Fetched article body for article: ' . $article));
}
return $data;
- break;
-
- // 412, RFC977: 'no newsgroup has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC977: 'no current article has been selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 423, RFC977: 'no such article number in this group'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
- return $this->throwError('No such article number in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 430, RFC977: 'no such article found'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID:
- return $this->throwError('No such article found',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdStat
-
/**
- *
+ * Selects an article by article message-number.
*
* @param mixed $article
*
- * @return mixed (array) or (string) or (int) or
- * (object) pear_error on failure
+ * @return mixed (array) or (string) or (int) on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdStat($article = null)
+ protected function cmdStat($article = null)
{
if (is_null($article)) {
$command = 'STAT';
@@ -1423,7 +1038,6 @@ class Net_NNTP_Protocol_Client extends PEAR
$command = 'STAT ' . $article;
}
- // tell the newsserver we want an article
$response = $this->_sendCommand($command);
if ($this->isError($response)) {
return $response;
@@ -1436,67 +1050,30 @@ class Net_NNTP_Protocol_Client extends PEAR
*/
case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED:
$response_arr = explode(' ',
- trim($this->_currentStatusResponse())
- );
+ trim($this->_currentStatusResponse()));
if ($this->_logger) {
- $this->_logger->info('Selected article: ' .
- $response_arr[0] . ' - ' . $response_arr[1]
- );
+ $this->_logger->info('Selected article: ' . $response_arr[0] . ' - ' . $response_arr[1]);
}
- return array($response_arr[0], (string)$response_arr[1]);
- break;
-
- /* 412, RFC977: 'no newsgroup has been selected'
- * (actually not documented, but copied from the
- * ARTICLE command)
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No newsgroup has been selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- /* 423, RFC977: 'no such article number in this group'
- * (actually not documented, but copied from the
- * ARTICLE command)
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
- return $this->throwError('No such article number in this group',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- /* 430, RFC977: 'no such article found' (actually not
- * documented, but copied from the ARTICLE command)
- */
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID:
- return $this->throwError('No such article found',
- $response, $this->_currentStatusResponse()
- );
- break;
+ return array($response_arr[0], (string) $response_arr[1]);
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
/* Article posting */
- // {{{ cmdPost()
-
/**
* Post an article to a newsgroup.
*
- * @return mixed (bool) true on success or (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdPost()
+ protected function cmdPost()
{
- // tell the newsserver we want to post an article
$response = $this->_sendCommand('POST');
if ($this->isError($response)) {
return $response;
@@ -1506,40 +1083,29 @@ class Net_NNTP_Protocol_Client extends PEAR
// 340, RFC977: 'send article to be posted. End with .'
case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SEND:
return true;
- break;
- // 440, RFC977: 'posting not allowed'
- case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_PROHIBITED:
- return $this->throwError('Posting not allowed',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdPost2()
-
/**
* Post an article to a newsgroup.
*
+ * @note Should be presented in the format specified by RFC850.
+ *
* @param mixed $article (string/array)
*
- * @return mixed (bool) true on success or
- * (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdPost2($article)
+ protected function cmdPost2($article)
{
- /* should be presented in the format specified by RFC850 */
-
- //
$this->_sendArticle($article);
- // Retrive server's response.
+ // Retrieve server's response.
$response = $this->_getStatusResponse();
if ($this->isError($response)) {
return $response;
@@ -1549,199 +1115,145 @@ class Net_NNTP_Protocol_Client extends PEAR
// 240, RFC977: 'article posted ok'
case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SUCCESS:
return true;
- break;
-
- // 441, RFC977: 'posting failed'
- case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_FAILURE:
- return $this->throwError('Posting failed', $response,
- $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdIhave()
-
/**
+ * Tell the news server we want to upload an article, the server will check if it has the message-id first.
*
+ * @param string $id Message-ID.
*
- * @param string $id
- *
- * @return mixed (bool) true on success or
- * (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdIhave($id)
+ protected function cmdIhave($id)
{
- // tell the newsserver we want to post an article
$response = $this->_sendCommand('IHAVE ' . $id);
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SEND: // 335
- return true;
- break;
-
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_UNWANTED: // 435
- return $this->throwError('Article not wanted',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE: // 436
- return $this->throwError
- ('Transfer not possible; try again later',
- $response, $this->_currentStatusResponse()
- );
- break;
+ // 335, RFC997: 'Send article to be transferred'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SEND:
+ return true;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdIhave2()
-
/**
+ * Tell the news server we have an article to upload, the server will check if it has it first.
*
+ * @note Should be presented in the format specified by RFC850.
*
* @param mixed $article (string/array)
*
- * @return mixed (bool) true on success or (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdIhave2($article)
+ protected function cmdIhave2($article)
{
- /* should be presented in the format specified by RFC850 */
-
- //
$this->_sendArticle($article);
- // Retrive server's response.
+ // Retrieve server's response.
$response = $this->_getStatusResponse();
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SUCCESS: // 235
- return true;
- break;
-
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE: // 436
- return $this->throwError
- ('Transfer not possible; try again later',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_REJECTED: // 437
- return $this->throwError
- ('Transfer rejected; do not retry',
- $response, $this->_currentStatusResponse()
- );
- break;
+ // 235, RFC977: 'Article transferred OK'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SUCCESS:
+ return true;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
/* Information commands */
- // {{{ cmdDate()
-
/**
- * Get the date from the newsserver format of returned date
+ * Get the date from the news server.
*
- * @return mixed (string) 'YYYYMMDDhhmmss' / (int) timestamp on
- * success or (object) pear_error on failure
+ * @return mixed (string) or (int) 'YYYYMMDDhhmmss', timestamp on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdDate()
+ protected function cmdDate()
{
$response = $this->_sendCommand('DATE');
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
switch ($response) {
- // 111, RFC2980: 'YYYYMMDDhhmmss'
+ // 111, RFC2980: '(string of numbers representing the date and time)'
case NET_NNTP_PROTOCOL_RESPONSECODE_SERVER_DATE:
return $this->_currentStatusResponse();
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdHelp()
/**
- * Returns the server's help text
+ * Returns the server's help text.
*
* @return mixed (array) help text on success or
- * (object) pear_error on failure
+ * (object) pear_error on failure
* @access protected
*/
- function cmdHelp()
+ protected function cmdHelp()
{
- // tell the newsserver we want an article
$response = $this->_sendCommand('HELP');
if ($this->isError($response)) {
return $response;
}
switch ($response) {
- case NET_NNTP_PROTOCOL_RESPONSECODE_HELP_FOLLOWS: // 100
- $data = $this->_getTextResponse();
+ // 100, RFC977: 'Help text follows'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_HELP_FOLLOWS:
+ $data = $this->_getTextResponse();
if ($this->isError($data)) {
return $data;
}
return $data;
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdNewgroups()
-
/**
* Fetches a list of all newsgroups created since a specified date.
*
- * @param int $time Last time you checked for groups (timestamp).
- * @param optional string $distributions (deprecaded in rfc draft)
+ * @param int $time Last time you checked for groups (timestamp).
+ * @param string $distributions (optional) (deprecaded in rfc draft)
*
- * @return mixed (array) nested array with informations about
- * existing newsgroups on success or (object) pear_error on failure
+ * @return mixed (array) nested array with informations about existing newsgroups on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdNewgroups($time, $distributions = null)
+ protected function cmdNewgroups($time, $distributions = null)
{
$date = gmdate('ymd His', $time);
if (is_null($distributions)) {
$command = 'NEWGROUPS ' . $date . ' GMT';
} else {
- $command = 'NEWGROUPS ' . $date . ' GMT <' .
- $distributions . '>';
+ $command = 'NEWGROUPS ' . $date . ' GMT <' . $distributions . '>';
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -1754,13 +1266,14 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$groups = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$arr = explode(' ', trim($line));
- $group = array('group' => $arr[0],
- 'last' => $arr[1],
- 'first' => $arr[2],
- 'posting' => $arr[3]
+ $group = array(
+ 'group' => $arr[0],
+ 'last' => $arr[1],
+ 'first' => $arr[2],
+ 'posting' => $arr[3]
);
$groups[$group['group']] = $group;
@@ -1768,24 +1281,21 @@ class Net_NNTP_Protocol_Client extends PEAR
return $groups;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdNewnews()
-
/**
*
*
- * @param timestamp $time
- * @param mixed $newsgroups (string or array of strings)
+ * @param int $time Unix timestamp.
+ * @param mixed $newsgroups (string or array of strings)
* @param mixed $distribution (string or array of strings)
*
* @return mixed
* @access protected
*/
- function cmdNewnews($time, $newsgroups, $distribution = null)
+ protected function cmdNewnews($time, $newsgroups, $distribution = null)
{
$date = gmdate('ymd His', $time);
@@ -1796,18 +1306,18 @@ class Net_NNTP_Protocol_Client extends PEAR
if (is_null($distribution)) {
$command = 'NEWNEWS ' . $newsgroups . ' ' . $date . ' GMT';
} else {
+
if (is_array($distribution)) {
$distribution = implode(',', $distribution);
}
- $command = 'NEWNEWS ' . $newsgroups . ' ' . $date . ' GMT <'
- . $distribution . '>';
+ $command = 'NEWNEWS ' . $newsgroups . ' ' . $date . ' GMT <' . $distribution . '>';
}
- // TODO: the lenght of the request string may not exceed 510 chars
+ // TODO: the length of the request string may not exceed 510 chars.
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -1815,34 +1325,29 @@ class Net_NNTP_Protocol_Client extends PEAR
// 230, RFC977: 'list of new articles by message-id follows'
case NET_NNTP_PROTOCOL_RESPONSECODE_NEW_ARTICLES_FOLLOW:
$messages = array();
- foreach ($this->_getTextResponse() as $line) {
+ foreach($this->_getTextResponse() as $line) {
$messages[] = $line;
}
return $messages;
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
/* The LIST commands */
- // {{{ cmdList()
-
/**
- * Fetches a list of all avaible newsgroups
+ * Fetches a list of all available newsgroups.
*
- * @return mixed (array) nested array with informations about
- * existing newsgroups on success or (object) pear_error on failure
+ * @return mixed (array) nested array with informations about existing newsgroups on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdList()
+ protected function cmdList()
{
$response = $this->_sendCommand('LIST');
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -1855,47 +1360,44 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$groups = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$arr = explode(' ', trim($line));
- $group = array('group' => $arr[0],
- 'last' => $arr[1],
- 'first' => $arr[2],
- 'posting' => $arr[3]
+ $group = array(
+ 'group' => $arr[0],
+ 'last' => $arr[1],
+ 'first' => $arr[2],
+ 'posting' => $arr[3]
);
$groups[$group['group']] = $group;
}
return $groups;
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdListActive()
-
/**
- * Fetches a list of all avaible newsgroups
+ * Fetches a list of all available newsgroups.
*
- * @param string $wildmat
+ * @param string $wildMat
*
- * @return mixed (array) nested array with informations about
- * existing newsgroups on success or (object) pear_error on failure
+ * @return mixed (array) nested array with informations about existing newsgroups on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdListActive($wildmat = null)
+ protected function cmdListActive($wildMat = null)
{
- if (is_null($wildmat)) {
+ if (is_null($wildMat)) {
$command = 'LIST ACTIVE';
} else {
- $command = 'LIST ACTIVE ' . $wildmat;
+ $command = 'LIST ACTIVE ' . $wildMat;
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -1908,13 +1410,14 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$groups = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$arr = explode(' ', trim($line));
- $group = array('group' => $arr[0],
- 'last' => $arr[1],
- 'first' => $arr[2],
- 'posting' => $arr[3]
+ $group = array(
+ 'group' => $arr[0],
+ 'last' => $arr[1],
+ 'first' => $arr[2],
+ 'posting' => $arr[3]
);
$groups[$group['group']] = $group;
@@ -1925,36 +1428,31 @@ class Net_NNTP_Protocol_Client extends PEAR
}
return $groups;
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdListNewsgroups()
-
/**
* Fetches a list of (all) avaible newsgroup descriptions.
*
- * @param string $wildmat Wildmat of the groups, that is to be
- * listed, defaults to null;
+ * @param string $wildMat Wildmat of the groups, that is to be listed, defaults to null;
*
- * @return mixed (array) nested array with description of existing
- * newsgroups on success or (object) pear_error on failure
+ * @return mixed (array) nested array with description of existing newsgroups on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdListNewsgroups($wildmat = null)
+ protected function cmdListNewsgroups($wildMat = null)
{
- if (is_null($wildmat)) {
+ if (is_null($wildMat)) {
$command = 'LIST NEWSGROUPS';
} else {
- $command = 'LIST NEWSGROUPS ' . $wildmat;
+ $command = 'LIST NEWSGROUPS ' . $wildMat;
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -1968,18 +1466,11 @@ class Net_NNTP_Protocol_Client extends PEAR
$groups = array();
- foreach ($data as $line) {
- if (preg_match("/^(\S+)\s+(.*)$/", ltrim($line),
- $matches
- )
- ) {
- $groups[$matches[1]] = (string)$matches[2];
- } else {
- if ($this->_logger) {
- $this->_logger->warning
- ("Recieved non-standard line: '$line'"
- );
- }
+ foreach($data as $line) {
+ if (preg_match('/^(\S+)\s+(.*)$/', ltrim($line), $matches)) {
+ $groups[$matches[1]] = (string) $matches[2];
+ } else if ($this->_logger) {
+ $this->_logger->warning("Recieved non-standard line: '$line'");
}
}
@@ -1988,40 +1479,26 @@ class Net_NNTP_Protocol_Client extends PEAR
}
return $groups;
- break;
-
- // RFC2980: 'program error, function not performed'
- case 503:
- return $this->throwError
- ('Internal server error, function not performed',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
-
/* Article field access commands */
- // {{{ cmdOver()
-
/**
* Fetch message header from message number $first until $last
*
- * The format of the returned array is:
- * $messages[][header_name]
+ * @info The format of the returned array is: $messages[][header_name]
*
- * @param optional string $range articles to fetch
+ * @param string $range (optional) articles to fetch
*
- * @return mixed (array) nested array of message and there headers
- * on success or (object) pear_error on failure
+ * @return mixed (array) nested array of message and there headers on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdOver($range = null)
+ protected function cmdOver($range = null)
{
if (is_null($range)) {
$command = 'OVER';
@@ -2030,7 +1507,7 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -2047,69 +1524,32 @@ class Net_NNTP_Protocol_Client extends PEAR
}
if ($this->_logger) {
- $this->_logger->info('Fetched overview ' .
- ($range == null ?
- 'for current article' : 'for range: ' . $range)
- );
+ $this->_logger->info('Fetched overview ' . ($range == null ? 'for current article' : 'for range: ' . $range));
}
return $data;
- break;
-
- // 412, RFC2980: 'No news group current selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No news group current selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC2980: 'No article(s) selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No article(s) selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 423:, Draft27: 'No articles in that range'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
- return $this->throwError('No articles in that range',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // RFC2980: 'no permission'
- case 502:
- return $this->throwError('No permission',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdXOver()
-
/**
* Fetch message header from message number $first until $last
*
- * The format of the returned array is:
- * $messages[message_id][header_name]
+ * @info The format of the returned array is: $messages[message_id][header_name]
*
- * @param optional string $range articles to fetch
+ * @param string $range (optional) articles to fetch
*
- * @return mixed (array) nested array of message and there headers
- * on success or (object) pear_error on failure
+ * @return mixed (array) nested array of message and there headers on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdXOver($range = null)
+ protected function cmdXOver($range = null)
{
- // deprecated API (the code _is_ still in alpha state)
+ // Deprecated API (the code _is_ still in alpha state).
if (func_num_args() > 1) {
- die('The second parameter in cmdXOver() has been '
- . 'deprecated! Use x-y instead...');
+ exit('The second parameter in cmdXOver() has been deprecated! Use x-y instead...');
}
if (is_null($range)) {
@@ -2119,7 +1559,7 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -2136,56 +1576,27 @@ class Net_NNTP_Protocol_Client extends PEAR
}
if ($this->_logger) {
- $this->_logger->info('Fetched overview ' .
- ($range == null ?
- 'for current article' : 'for range: ' . $range)
- );
+ $this->_logger->info('Fetched overview ' . ($range == null ? 'for current article' : 'for range: ' . $range));
}
return $data;
- break;
-
- // 412, RFC2980: 'No news group current selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No news group current selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC2980: 'No article(s) selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No article(s) selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // RFC2980: 'no permission'
- case 502:
- return $this->throwError('No permission',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdListOverviewFmt()
-
/**
- * Returns a list of avaible headers which are send from newsserver
- * to client for every news message
+ * Returns a list of available headers which are sent from tge news server to the client for every news message.
*
* @return mixed (array) of header names on success or
- * (object) pear_error on failure
+ * (object) pear_error on failure
* @access protected
*/
- function cmdListOverviewFmt()
+ protected function cmdListOverviewFmt()
{
$response = $this->_sendCommand('LIST OVERVIEW.FMT');
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -2201,7 +1612,7 @@ class Net_NNTP_Protocol_Client extends PEAR
foreach ($data as $line) {
- // Check if postfixed by ':full' (case-insensitive)
+ // Check if post fixed by ':full' (case-insensitive)
if (0 == strcasecmp(substr($line, -5, 5), ':full')) {
// ':full' is _not_ included in tag, but value set to true
$format[substr($line, 0, -5)] = true;
@@ -2215,38 +1626,26 @@ class Net_NNTP_Protocol_Client extends PEAR
$this->_logger->info('Fetched overview format');
}
return $format;
- break;
-
- // RFC2980: 'program error, function not performed'
- case 503:
- return $this->throwError
- ('Internal server error, function not performed',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdXHdr()
-
/**
*
*
* The format of the returned array is:
* $messages[message_id]
*
- * @param optional string $field
- * @param optional string $range articles to fetch
+ * @param string $field (optional)
+ * @param string $range (optional) articles to fetch
*
- * @return mixed (array) nested array of message and there header
- * on success or (object) pear_error on failure
+ * @return mixed (array) nested array of message and there header on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdXHdr($field, $range = null)
+ protected function cmdXHdr($field, $range = null)
{
if (is_null($range)) {
$command = 'XHDR ' . $field;
@@ -2255,84 +1654,51 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
switch ($response) {
// 221, RFC2980: 'Header follows'
- case 221:
- $data = $this->_getTextResponse();
+ case NET_NNTP_PROTOCOL_RESPONSECODE_HEAD_FOLLOWS:
+ $data = $this->_getTextResponse();
if ($this->isError($data)) {
return $data;
}
$return = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$line = explode(' ', trim($line), 2);
$return[$line[0]] = $line[1];
}
return $return;
- break;
-
- // 412, RFC2980: 'No news group current selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No news group current selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC2980: 'No current article selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No current article selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 430, RFC2980: 'No such article'
- case 430:
- return $this->throwError('No such article',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // RFC2980: 'no permission'
- case 502:
- return $this->throwError('No permission',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdXGTitle()
-
/**
- * Fetches a list of (all) avaible newsgroup descriptions.
- * Depresated as of RFC2980.
+ * Fetches a list of (all) available newsgroup descriptions.
+ * Deprecated as of RFC2980.
*
- * @param string $wildmat Wildmat of the groups, that is
- * to be listed, defaults to '*';
+ * @param string $wildMat Wildmat of the groups, that is to be listed, defaults to '*';
*
- * @return mixed (array) nested array with description of
- * existing newsgroups on success or (object) pear_error on failure
+ * @return mixed (array) nested array with description of existing newsgroups on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdXGTitle($wildmat = '*')
+ protected function cmdXGTitle($wildMat = '*')
{
- $response = $this->_sendCommand('XGTITLE ' . $wildmat);
- if ($this->isError($response)) {
+ $response = $this->_sendCommand('XGTITLE ' . $wildMat);
+ if ($this->isError($response)){
return $response;
}
switch ($response) {
// RFC2980: 'list of groups and descriptions follows'
- case 282:
+ case NET_NNTP_PROTOCOL_RESPONSECODE_XGTITLE_GROUPS_FOLLOW:
$data = $this->_getTextResponse();
if ($this->isError($data)) {
return $data;
@@ -2340,44 +1706,32 @@ class Net_NNTP_Protocol_Client extends PEAR
$groups = array();
- foreach ($data as $line) {
- preg_match("/^(.*?)\s(.*?$)/", trim($line), $matches);
- $groups[$matches[1]] = (string)$matches[2];
+ foreach($data as $line) {
+ preg_match('/^(.*?)\s(.*?$)/', trim($line), $matches);
+ $groups[$matches[1]] = (string) $matches[2];
}
return $groups;
- break;
-
- case 481: // RFC2980: 'Groups and descriptions unavailable'
- return $this->throwError
- ('Groups and descriptions unavailable',
- $response, $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdXROver()
-
/**
* Fetch message references from message number $first to $last
*
- * @param optional string $range articles to fetch
+ * @param string $range (optional) articles to fetch
*
- * @return mixed (array) assoc. array of message references on
- * success or (object) pear_error on failure
+ * @return mixed (array) assoc. array of message references on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdXROver($range = null)
+ protected function cmdXROver($range = null)
{
// Warn about deprecated API (the code _is_ still in alpha state)
- if (func_num_args() > 1) {
- die('The second parameter in cmdXROver() has been '
- . 'deprecated! Use x-y instead...');
+ if (func_num_args() > 1 ) {
+ exit('The second parameter in cmdXROver() has been deprecated! Use x-y instead...');
}
if (is_null($range)) {
@@ -2387,7 +1741,7 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$response = $this->_sendCommand($command);
- if ($this->isError($response)) {
+ if ($this->isError($response)){
return $response;
}
@@ -2400,63 +1754,36 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$return = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$line = explode(' ', trim($line), 2);
$return[$line[0]] = $line[1];
}
return $return;
- break;
-
- // 412, RFC2980: 'No news group current selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
- return $this->throwError('No news group current selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // 420, RFC2980: 'No article(s) selected'
- case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
- return $this->throwError('No article(s) selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- // RFC2980: 'no permission'
- case 502:
- return $this->throwError('No permission', $response,
- $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdXPat()
-
/**
*
*
* @param string $field
* @param string $range
- * @param mixed $wildmat
+ * @param mixed $wildMat
*
- * @return mixed (array) nested array of message and there
- * headers on success or (object) pear_error on failure
+ * @return mixed (array) nested array of message and there headers on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdXPat($field, $range, $wildmat)
+ protected function cmdXPat($field, $range, $wildMat)
{
- if (is_array($wildmat)) {
- $wildmat = implode(' ', $wildmat);
+ if (is_array($wildMat)) {
+ $wildMat = implode(' ', $wildMat);
}
- $response = $this->_sendCommand('XPAT ' . $field . ' ' .
- $range . ' ' . $wildmat
- );
- if ($this->isError($response)) {
+ $response = $this->_sendCommand('XPAT ' . $field . ' ' . $range . ' ' . $wildMat);
+ if ($this->isError($response)){
return $response;
}
@@ -2468,34 +1795,18 @@ class Net_NNTP_Protocol_Client extends PEAR
}
$return = array();
- foreach ($data as $line) {
+ foreach($data as $line) {
$line = explode(' ', trim($line), 2);
$return[$line[0]] = $line[1];
}
return $return;
- break;
-
- case 430: // 430, RFC2980: 'No such article'
- return $this->throwError('No current article selected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- case 502: // RFC2980: 'no permission'
- return $this->throwError('No permission', $response,
- $this->_currentStatusResponse()
- );
- break;
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdAuthinfo()
-
/**
* Authenticate using 'original' method
*
@@ -2503,13 +1814,14 @@ class Net_NNTP_Protocol_Client extends PEAR
* @param string $pass The password to authenticate with.
*
* @return mixed (bool) true on success or
- * (object) pear_error on failure
+ * (object) pear_error on failure
+ *
* @access protected
*/
- function cmdAuthinfo($user, $pass)
+ protected function cmdAuthinfo($user, $pass)
{
// Send the username
- $response = $this->_sendCommand('AUTHINFO user ' . $user);
+ $response = $this->_sendCommand('AUTHINFO user '.$user);
if ($this->isError($response)) {
return $response;
}
@@ -2517,7 +1829,7 @@ class Net_NNTP_Protocol_Client extends PEAR
// Send the password, if the server asks
if (($response == 381) && ($pass !== null)) {
// Send the password
- $response = $this->_sendCommand('AUTHINFO pass ' . $pass);
+ $response = $this->_sendCommand('AUTHINFO pass '.$pass);
if ($this->isError($response)) {
return $response;
}
@@ -2532,39 +1844,12 @@ class Net_NNTP_Protocol_Client extends PEAR
// TODO: Set some variable before return
return true;
- break;
-
- case 381: // RFC2980: 'More authentication information required'
- return $this->throwError('Authentication uncompleted',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- case 482: // RFC2980: 'Authentication rejected'
- return $this->throwError('Authentication rejected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- case 502: // RFC2980: 'No permission'
- return $this->throwError('Authentication rejected',
- $response, $this->_currentStatusResponse()
- );
- break;
-
- /*case 500:
- case 501:
- return $this->throwError('Authentication failed', $response, $this->_currentStatusResponse());
- break;*/
default:
- return $this->_handleUnexpectedResponse($response);
+ return $this->_handleErrorResponse($response);
}
}
- // }}}
- // {{{ cmdAuthinfoSimple()
-
/**
* Authenticate using 'simple' method
*
@@ -2574,60 +1859,139 @@ class Net_NNTP_Protocol_Client extends PEAR
* @return mixed (bool) true on success or (object) pear_error on failure
* @access protected
*/
- function cmdAuthinfoSimple($user, $pass)
+ protected function cmdAuthinfoSimple($user, $pass)
{
- return $this->throwError
- ("The auth mode: 'simple' is has not been implemented yet",
- null
- );
+ return $this->throwError("The auth mode: 'simple' is has not been implemented yet", null);
}
- // }}}
- // {{{ cmdAuthinfoGeneric()
-
/**
* Authenticate using 'generic' method
*
* @param string $user The username to authenticate as.
* @param string $pass The password to authenticate with.
*
- * @return mixed (bool) true on success or (object) pear_error on failure
+ * @return mixed (bool) true on success
+ * (object) pear_error on failure
* @access protected
*/
- function cmdAuthinfoGeneric($user, $pass)
+ protected function cmdAuthinfoGeneric($user, $pass)
{
- return $this->throwError
- ("The auth mode: 'generic' is has not been implemented yet",
- null
- );
+ return $this->throwError("The auth mode: 'generic' is has not been implemented yet", null);
}
- // }}}
- // {{{ _isConnected()
-
/**
* Test whether we are connected or not.
*
+ * @param bool $feof Check for the end of file pointer.
+ *
* @return bool true or false
* @access protected
*/
- function _isConnected()
+ protected function _isConnected($feof = true)
{
- return (is_resource($this->_socket) && (!feof($this->_socket)));
+ return (is_resource($this->_socket) && ($feof ? !feof($this->_socket) : true));
}
- // }}}
+ /**
+ * Verify NNTP error code and return PEAR error.
+ *
+ * @param int $response NET_NNTP Response code
+ *
+ * @return object PEAR error
+ * @access protected
+ */
+ protected function _handleErrorResponse(&$response)
+ {
+ switch ($response) {
-}
+ // 381, RFC2980: 'More authentication information required'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_CONTINUE:
+ return $this->throwError('More authentication information required', $response, $this->_currentStatusResponse());
-// }}}
+ // 400, RFC977: 'Service discontinued'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_FORCED:
+ return $this->throwError('Server refused connection', $response, $this->_currentStatusResponse());
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * c-hanging-comment-ender-p: nil
- * End:
- */
+ // 411, RFC977: 'no such news group'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_GROUP:
+ return $this->throwError('No such news group on server', $response, $this->_currentStatusResponse());
-?>
\ No newline at end of file
+ // 412, RFC2980: 'No news group current selected'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED:
+ return $this->throwError('No news group current selected', $response, $this->_currentStatusResponse());
+
+ // 420, RFC2980: 'Current article number is invalid'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED:
+ return $this->throwError('Current article number is invalid', $response, $this->_currentStatusResponse());
+
+ // 421, RFC977: 'no next article in this group'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_NEXT_ARTICLE:
+ return $this->throwError('No next article in this group', $response, $this->_currentStatusResponse());
+
+ // 422, RFC977: 'no previous article in this group'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_PREVIOUS_ARTICLE:
+ return $this->throwError('No previous article in this group', $response, $this->_currentStatusResponse());
+
+ // 423, RFC977: 'No such article number in this group'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER:
+ return $this->throwError('No such article number in this group', $response, $this->_currentStatusResponse());
+
+ // 430, RFC977: 'No such article found'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID:
+ return $this->throwError('No such article found', $response, $this->_currentStatusResponse());
+
+ // 435, RFC977: 'Article not wanted'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_UNWANTED:
+ return $this->throwError('Article not wanted', $response, $this->_currentStatusResponse());
+
+ // 436, RFC977: 'Transfer failed - try again later'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE:
+ return $this->throwError('Transfer failed - try again later', $response, $this->_currentStatusResponse());
+
+ // 437, RFC977: 'Article rejected - do not try again'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_REJECTED:
+ return $this->throwError('Article rejected - do not try again', $response, $this->_currentStatusResponse());
+
+ // 440, RFC977: 'posting not allowed'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_PROHIBITED:
+ return $this->throwError('Posting not allowed', $response, $this->_currentStatusResponse());
+
+ // 441, RFC977: 'posting failed'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_FAILURE:
+ return $this->throwError('Posting failed', $response, $this->_currentStatusResponse());
+
+ // 481, RFC2980: 'Groups and descriptions unavailable'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_XGTITLE_GROUPS_UNAVAILABLE:
+ return $this->throwError('Groups and descriptions unavailable', $response, $this->_currentStatusResponse());
+
+ // 482, RFC2980: 'Authentication rejected'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_REJECTED:
+ return $this->throwError('Authentication rejected', $response, $this->_currentStatusResponse());
+
+ // 500, RFC977: 'Command not recognized'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_UNKNOWN_COMMAND:
+ return $this->throwError('Command not recognized', $response, $this->_currentStatusResponse());
+
+ // 501, RFC977: 'Command syntax error'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_SYNTAX_ERROR:
+ return $this->throwError('Command syntax error', $response, $this->_currentStatusResponse());
+
+ // 502, RFC2980: 'No permission'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED:
+ return $this->throwError('No permission', $response, $this->_currentStatusResponse());
+
+ // 503, RFC2980: 'Program fault - command not performed'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_SUPPORTED:
+ return $this->throwError('Internal server error, function not performed', $response, $this->_currentStatusResponse());
+
+ // RFC4642: 'Can not initiate TLS negotiation'
+ case NET_NNTP_PROTOCOL_RESPONSECODE_TLS_FAILED_NEGOTIATION:
+ return $this->throwError('Can not initiate TLS negotiation', $response, $this->_currentStatusResponse());
+
+ default:
+ $text = $this->_currentStatusResponse();
+ return $this->throwError("Unexpected response: '$text'", $response, $text);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Responsecode.php b/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Responsecode.php
index dc1a054b7..54dcee6ad 100644
--- a/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Responsecode.php
+++ b/lib/copy_this/www/lib/Net_NNTP/NNTP/Protocol/Responsecode.php
@@ -91,17 +91,15 @@ define('NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED', 201);
* 'Closing connection - goodbye!' (RFC977)
*
* @access public
- * @since ?
*/
-//define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_REQUESTED', 205); ///// goodbye
+define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_REQUESTED', 205);
/**
* 'Service discontinued' (RFC977)
*
* @access public
- * @since ?
*/
-//define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_FORCED', 400); ///// unavailable / discontinued
+define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_FORCED', 400);
/**
@@ -168,6 +166,12 @@ define('NET_NNTP_PROTOCOL_RESPONSECODE_GROUP_SELECTED', 211);
*/
define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_GROUP', 411);
+/**
+ * 'Groups and descriptions unavailable'
+ *
+ * @access public
+ */
+define('NET_NNTP_PROTOCOL_RESPONSECODE_XGTITLE_GROUPS_UNAVAILABLE', 481);
// }}}
// {{{ Constants: Article retrieval
@@ -249,6 +253,13 @@ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER', 423);
*/
define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID', 430);
+/**
+ * 'List of groups and descriptions follows' (RFC2980)
+ *
+ * @access public
+ */
+define('NET_NNTP_PROTOCOL_RESPONSECODE_XGTITLE_GROUPS_FOLLOW', 482);
+
// }}}
// {{{ Constants: Transferring
@@ -383,6 +394,13 @@ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_REQUIRED', 480);
*/
define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_CONTINUE', 381);
+/**
+ * 'Continue with TLS negotiation' (RFC4642)
+ *
+ * @access public
+ */
+define('NET_NNTP_PROTOCOL_RESPONSECODE_TLS_AUTHENTICATION_CONTINUE', 382);
+
/**
* 'Authentication accepted' (RFC2980)
*
@@ -491,6 +509,14 @@ define('NET_NNTP_PROTOCOL_RESPONSECODE_INTERNAL_FAULT', 403);
*/
define('NET_NNTP_PROTOCOL_RESPONSECODE_BASE64_ENCODING_ERROR', 504);
+/**
+ * 'Can not initiate TLS negotiation' (RFC4642)
+ *
+ * @access public
+ */
+define('NET_NNTP_PROTOCOL_RESPONSECODE_TLS_FAILED_NEGOTIATION', 580);
+
+
// }}}
/*
diff --git a/lib/copy_this/www/lib/genres.php b/lib/copy_this/www/lib/genres.php
new file mode 100644
index 000000000..6c6b89b96
--- /dev/null
+++ b/lib/copy_this/www/lib/genres.php
@@ -0,0 +1,58 @@
+query($sql, $usecache);
+ }
+
+ /**
+ * Add new genre.
+ */
+ public function getOrAddGenreKey($genreName, &$genreassoc)
+ {
+ if (in_array(strtolower($genreName), $genreassoc))
+ {
+ $genreKey = array_search(strtolower($genreName), $genreassoc);
+ }
+ else
+ {
+ $db = new DB();
+ $genreKey = $db->queryInsert(sprintf("INSERT INTO genres (`title`, `type`) VALUES (%s, %d)", $db->escapeString($genreName), Genres::MUSIC_TYPE));
+ $genreassoc[$genreKey] = strtolower($genreName);
+ }
+
+ return $genreKey;
+ }
+}
\ No newline at end of file
diff --git a/lib/copy_this/www/lib/nntp.php b/lib/copy_this/www/lib/nntp.php
index 277bf1efc..0d75d59f5 100644
--- a/lib/copy_this/www/lib/nntp.php
+++ b/lib/copy_this/www/lib/nntp.php
@@ -1,5 +1,4 @@
queryInsert($sql);
}
- public function update($id, $uname, $email, $grabs, $role, $notes, $invites, $movieview, $musicview, $consoleview, $bookview, $queueType = '', $nzbgetURL = '', $nzbgetUsername = '', $nzbgetPassword = '', $saburl = '', $sabapikey = '', $sabpriority = '', $sabapikeytype = '', $nzbvortexServerUrl = false, $nzbvortexApiKey = false)
+ public function update($id, $uname, $email, $grabs, $role, $notes, $invites, $movieview, $musicview, $gameview, $consoleview, $bookview, $queueType = '', $nzbgetURL = '', $nzbgetUsername = '', $nzbgetPassword = '', $saburl = '', $sabapikey = '', $sabpriority = '', $sabapikeytype = '', $nzbvortexServerUrl = false, $nzbvortexApiKey = false)
{
$db = new DB();
@@ -190,6 +190,7 @@ class Users
$sql[] = sprintf('invites = %d', $invites);
$sql[] = sprintf('movieview = %d', $movieview);
$sql[] = sprintf('musicview = %d', $musicview);
+ $sql[] = sprintf('gameview = %d', $gameview);
$sql[] = sprintf('consoleview = %d', $consoleview);
$sql[] = sprintf('bookview = %d', $bookview);
diff --git a/lib/copy_this/www/pages/browse.php b/lib/copy_this/www/pages/browse.php
new file mode 100644
index 000000000..3148c4fa2
--- /dev/null
+++ b/lib/copy_this/www/pages/browse.php
@@ -0,0 +1,82 @@
+isLoggedIn())
+ $page->show403();
+
+$category = -1;
+if (isset($_REQUEST["t"]) && ctype_digit($_REQUEST["t"]))
+ $category = $_REQUEST["t"];
+
+$grp = array();
+if (isset($_REQUEST["g"]))
+ $grp = explode(",", $_REQUEST["g"]);
+
+$catarray = array();
+$catarray[] = $category;
+
+$page->smarty->assign('category', $category);
+$browsecount = $releases->getBrowseCount($catarray, -1, $page->userdata["categoryexclusions"], $grp);
+
+$offset = (isset($_REQUEST["offset"]) && ctype_digit($_REQUEST['offset'])) ? $_REQUEST["offset"] : 0;
+$ordering = $releases->getBrowseOrdering();
+$orderby = isset($_REQUEST["ob"]) && in_array($_REQUEST['ob'], $ordering) ? $_REQUEST["ob"] : '';
+
+$results = array();
+$results = $releases->getBrowseRange($catarray, $offset, ITEMS_PER_PAGE, $orderby, -1, $page->userdata["categoryexclusions"], $grp);
+
+$page->smarty->assign('pagertotalitems',$browsecount);
+$page->smarty->assign('pageroffset',$offset);
+$page->smarty->assign('pageritemsperpage',ITEMS_PER_PAGE);
+$page->smarty->assign('pagerquerybase', WWW_TOP."/browse?t=".$category.(count($grp) > 0 ? "&g=".$grp[0] : "")."&ob=".$orderby."&offset=");
+$page->smarty->assign('pagerquerysuffix', "#results");
+
+$pager = $page->smarty->fetch("pager.tpl");
+$page->smarty->assign('pager', $pager);
+
+$section = '';
+if ($category == -1 && count($grp) == 0)
+ $page->smarty->assign("catname","All");
+elseif ($category != -1 && count($grp) == 0)
+{
+ $cat = new Category();
+ $cdata = $cat->getById($category);
+
+ if ($cdata) {
+ $page->smarty->assign('catname',$cdata["title"]);
+ if ($cdata['parentID'] == Category::CAT_PARENT_GAME || $cdata['ID'] == Category::CAT_PARENT_GAME)
+ $section = 'console';
+ elseif ($cdata['ID'] == Category::CAT_BOOK_EBOOK)
+ $section = 'books';
+ elseif ($cdata['parentID'] == Category::CAT_PARENT_MOVIE || $cdata['ID'] == Category::CAT_PARENT_MOVIE)
+ $section = 'movies';
+ elseif ($cdata['parentid'] == Category::CAT_PARENT_PC || $cdata['ID'] == Category::CAT_PC_GAMES)
+ $section = 'games';
+ elseif ($cdata['parentID'] == Category::CAT_PARENT_MUSIC || $cdata['ID'] == Category::CAT_PARENT_MUSIC)
+ $section = 'music';
+ } else {
+ $page->show404();
+ }
+}
+elseif (count($grp) > 0)
+{
+ $page->smarty->assign('catname',$grp[0]);
+}
+$page->smarty->assign('section',$section);
+
+foreach($ordering as $ordertype)
+ $page->smarty->assign('orderby'.$ordertype, WWW_TOP."/browse?t=".$category."&ob=".$ordertype."&offset=0".(count($grp) > 0 ? "&g=".$grp[0] : ""));
+
+$page->smarty->assign('lastvisit',$page->userdata['lastlogin']);
+
+$page->smarty->assign('results',$results);
+
+$page->meta_title = "Browse Nzbs";
+$page->meta_keywords = "browse,nzb,description,details";
+$page->meta_description = "Browse for Nzbs";
+
+$page->content = $page->smarty->fetch('browse.tpl');
+$page->render();
\ No newline at end of file
diff --git a/lib/copy_this/www/pages/games.php b/lib/copy_this/www/pages/games.php
new file mode 100644
index 000000000..81149c7b6
--- /dev/null
+++ b/lib/copy_this/www/pages/games.php
@@ -0,0 +1,97 @@
+isLoggedIn()) {
+ $page->show403();
+}
+
+$games = new Games();
+$cat = new Category();
+$gen = new Genres();
+
+$concats = $cat->getChildren(Category::CAT_PARENT_PC);
+$ctmp = array();
+foreach ($concats as $ccat) {
+ $ctmp[$ccat['ID']] = $ccat;
+}
+$category = Category::CAT_PC_GAMES;
+if (isset($_REQUEST["t"]) && array_key_exists($_REQUEST['t'], $ctmp)) {
+ $category = $_REQUEST["t"] + 0;
+}
+
+$catarray = array();
+$catarray[] = $category;
+
+$page->smarty->assign('catlist', $ctmp);
+$page->smarty->assign('category', $category);
+
+$browsecount = $games->getgamesCount($catarray, -1, $page->userdata["categoryexclusions"]);
+
+$offset = (isset($_REQUEST["offset"]) && ctype_digit($_REQUEST['offset'])) ? $_REQUEST["offset"] : 0;
+$ordering = $games->getgamesOrdering();
+
+$orderby = isset($_REQUEST["ob"]) && in_array($_REQUEST['ob'], $ordering) ? $_REQUEST["ob"] : '';
+
+$results = $games2 = array();
+$results = $games->getgamesRange($catarray, $offset, ITEMS_PER_PAGE_SMALL, $orderby, -1, $page->userdata["categoryexclusions"]);
+$maxwords = 50;
+foreach ($results as $result) {
+ if (!empty($result['review'])) {
+ $words = explode(' ', $result['review']);
+ if (sizeof($words) > $maxwords) {
+ $newwords = array_slice($words, 0, $maxwords);
+ $result['review'] = implode(' ', $newwords) . '...';
+ }
+ }
+ $games2[] = $result;
+}
+$platform = (isset($_REQUEST['platform']) && !empty($_REQUEST['platform'])) ? stripslashes($_REQUEST['platform']) : '';
+$page->smarty->assign('platform', $platform);
+
+$title = (isset($_REQUEST['title']) && !empty($_REQUEST['title'])) ? stripslashes($_REQUEST['title']) : '';
+$page->smarty->assign('title', $title);
+
+$genres = $gen->getGenres(Genres::GAME_TYPE, true);
+$tmpgnr = array();
+foreach ($genres as $gn) {
+ $tmpgnr[$gn['ID']] = $gn['title'];
+}
+$genre = (isset($_REQUEST['genre']) && array_key_exists($_REQUEST['genre'], $tmpgnr)) ? $_REQUEST['genre'] : '';
+$page->smarty->assign('genres', $genres);
+$page->smarty->assign('genre', $genre);
+
+$browseby_link = '&title=' . $title . '&platform=' . $platform;
+
+$page->smarty->assign('pagertotalitems', $browsecount);
+$page->smarty->assign('pageroffset', $offset);
+$page->smarty->assign('pageritemsperpage', ITEMS_PER_PAGE_SMALL);
+$page->smarty->assign('pagerquerybase', WWW_TOP . "/games?t=" . $category . $browseby_link . "&ob=" . $orderby . "&offset=");
+$page->smarty->assign('pagerquerysuffix', "#results");
+
+$pager = $page->smarty->fetch("pager.tpl");
+$page->smarty->assign('pager', $pager);
+
+if ($category == -1) {
+ $page->smarty->assign("catname", "All");
+} else {
+ $cdata = $cat->getById($category);
+ if ($cdata) {
+ $page->smarty->assign('catname', $cdata["title"]);
+ } else {
+ $page->show404();
+ }
+}
+
+foreach ($ordering as $ordertype) {
+ $page->smarty->assign('orderby' . $ordertype, WWW_TOP . "/games?t=" . $category . $browseby_link . "&ob=" . $ordertype . "&offset=0");
+}
+
+$page->smarty->assign('results', $games2);
+
+$page->meta_title = "Browse Games";
+$page->meta_keywords = "browse,nzb,games,description,details";
+$page->meta_description = "Browse for Games";
+
+$page->content = $page->smarty->fetch('games.tpl');
+$page->render();
\ No newline at end of file
diff --git a/lib/copy_this/www/pages/profileedit.php b/lib/copy_this/www/pages/profileedit.php
index f98f7fd46..eedcf5e7e 100644
--- a/lib/copy_this/www/pages/profileedit.php
+++ b/lib/copy_this/www/pages/profileedit.php
@@ -67,6 +67,7 @@ switch ($action) {
$data["invites"],
(isset($_POST['movieview']) ? "1" : "0"),
(isset($_POST['musicview']) ? "1" : "0"),
+ (isset($_POST['gameview']) ? "1" : "0"),
(isset($_POST['consoleview']) ? "1" : "0"),
(isset($_POST['bookview']) ? "1" : "0"),
$_POST['queuetypeids'],
diff --git a/lib/copy_this/www/templates/nntmux/images/icons/giantbomb.png b/lib/copy_this/www/templates/nntmux/images/icons/giantbomb.png
new file mode 100644
index 000000000..e1f450c5f
Binary files /dev/null and b/lib/copy_this/www/templates/nntmux/images/icons/giantbomb.png differ
diff --git a/lib/copy_this/www/templates/nntmux/views/admin/site-edit.tpl b/lib/copy_this/www/templates/nntmux/views/admin/site-edit.tpl
index 6bac44d41..0b3f0fc19 100644
--- a/lib/copy_this/www/templates/nntmux/views/admin/site-edit.tpl
+++ b/lib/copy_this/www/templates/nntmux/views/admin/site-edit.tpl
@@ -232,6 +232,14 @@
The amazon associate tag. Used for cover lookups.
+
+ Giant Bomb API Key:
+
+
+
+ The giantbomb key. Used for game lookups.
+
+
@@ -981,5 +989,4 @@
-
-
+
\ No newline at end of file
diff --git a/lib/copy_this/www/templates/nntmux/views/admin/user-edit.tpl b/lib/copy_this/www/templates/nntmux/views/admin/user-edit.tpl
index a6b5d445e..47fece2d0 100644
--- a/lib/copy_this/www/templates/nntmux/views/admin/user-edit.tpl
+++ b/lib/copy_this/www/templates/nntmux/views/admin/user-edit.tpl
@@ -1,4 +1,4 @@
-
+
{$page->title}
{if $error != ''}
@@ -31,7 +31,7 @@
{if $user.ID}
Only enter a password if you want to change it.
{/if}
-
+
{if $user.ID}
@@ -63,6 +63,13 @@
+
+ Game View:
+
+
+
+
+
Console View:
@@ -95,16 +102,16 @@
-
+
{if $user.ID != ""}
-
-
+
+
diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/games.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/games.tpl
new file mode 100644
index 000000000..1b53d0424
--- /dev/null
+++ b/lib/copy_this/www/templates/nntmux/views/frontend/games.tpl
@@ -0,0 +1,231 @@
+{if $site->adbrowse}
+ {$site->adbrowse}
+{/if}
+Browse Games
+
+
+
+
+{if $results|@count > 0}
+
+{else}
+ There doesn't seem to be any releases here. Please try the list view.
+{/if}
+
+
\ No newline at end of file
diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/headermenu.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/headermenu.tpl
index 7ae0eb403..f8f3281c3 100644
--- a/lib/copy_this/www/templates/nntmux/views/frontend/headermenu.tpl
+++ b/lib/copy_this/www/templates/nntmux/views/frontend/headermenu.tpl
@@ -1,4 +1,4 @@
-
-
+
{foreach from=$downloadlist item=download}
{if $download@iteration == 10}
show all...
@@ -121,7 +122,7 @@
comment
-
+
{foreach from=$commentslist item=comment}
{$comment.createddate|date_format}
diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/profileedit.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/profileedit.tpl
index 6ea33ee5b..a2361234b 100644
--- a/lib/copy_this/www/templates/nntmux/views/frontend/profileedit.tpl
+++ b/lib/copy_this/www/templates/nntmux/views/frontend/profileedit.tpl
@@ -60,6 +60,13 @@
Browse music covers. Only shows music with known lookup info.
+
+ View Game Page:
+
+
+ Browse game covers. Only shows games with known lookup info.
+
+
View Console Page:
diff --git a/lib/getGames.php b/lib/getGames.php
new file mode 100644
index 000000000..08d617eed
--- /dev/null
+++ b/lib/getGames.php
@@ -0,0 +1,36 @@
+query(
+ sprintf("SELECT searchname FROM releases WHERE gamesinfo_id IS NULL AND categoryID = 4050 ORDER BY ID DESC LIMIT 100")
+);
+$total = count($res);
+if ($total > 0) {
+ echo $c->header("Updating game info for " . number_format($total) . " releases.");
+
+ foreach ($res as $arr) {
+ $starttime = microtime(true);
+ $gameInfo = $game->parseTitle($arr['searchname']);
+ if ($gameInfo !== false) {
+ $gameData = $game->updateGamesInfo($gameInfo);
+ if ($gameData === false) {
+ echo $c->primary($gameInfo['release'] . ' not found');
+ }
+ }
+
+ // amazon limits are 1 per 1 sec
+ $diff = floor((microtime(true) - $starttime) * 1000000);
+ if (1000000 - $diff > 0) {
+ echo $c->alternate("Sleeping");
+ usleep(1000000 - $diff);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/updateGamesImages.php b/lib/updateGamesImages.php
new file mode 100644
index 000000000..c9d221da6
--- /dev/null
+++ b/lib/updateGamesImages.php
@@ -0,0 +1,45 @@
+error("\nThis script will check all images in covers/games and compare to db->gamesinfo.\nTo run:\nphp $argv[0] true\n"));
+}
+$path2covers = WWW_DIR . 'covers/games' . '/';
+
+$dirItr = new RecursiveDirectoryIterator($path2covers);
+$itr = new RecursiveIteratorIterator($dirItr, RecursiveIteratorIterator::LEAVES_ONLY);
+foreach ($itr as $filePath) {
+ if (is_file($filePath) && preg_match('/\d+\.jpg/', $filePath)) {
+ preg_match('/(\d+)\.jpg/', basename($filePath), $match);
+ if (isset($match[1])) {
+ $run = $pdo->queryDirect("UPDATE gamesinfo SET cover = 1 WHERE cover = 0 AND id = " . $match[1]);
+ if ($run !== false) {
+ if ($run->rowCount() >= 1) {
+ $covers++;
+ } else {
+ $run = $pdo->queryDirect("SELECT id FROM gamesinfo WHERE id = " . $match[1]);
+ if ($run !== false && $run->rowCount() == 0) {
+ echo $c->info($filePath . " not found in db.");
+ }
+ }
+ }
+ }
+ }
+}
+
+$qry = $pdo->queryDirect("SELECT id FROM gamesinfo WHERE cover = 1");
+foreach ($qry as $rows) {
+ if (!is_file($path2covers . $rows['id'] . '.jpg')) {
+ $pdo->queryDirect("UPDATE gamesinfo SET cover = 0 WHERE cover = 1 AND id = " . $rows['id']);
+ echo $c->info($path2covers . $rows['id'] . ".jpg does not exist.");
+ $deleted++;
+ }
+}
+echo $c->header($covers . " covers set.");
+echo $c->header($deleted . " games unset.");
\ No newline at end of file
diff --git a/start.php b/start.php
index d06b4fe37..fd90fed7e 100644
--- a/start.php
+++ b/start.php
@@ -15,7 +15,7 @@ $tmux = $t->get();
$patch = (isset($tmux->sqlpatch)) ? $tmux->sqlpatch : 0;
// Check database patch version
-if ($patch < 51) {
+if ($patch < 55) {
exit($c->error("\nYour database is not up to date. Please update.\nphp ${DIR}/lib/DB/patchDB.php\n"));
}
$tmux_session = (isset($tmux->tmux_session)) ? $tmux->tmux_session : 0;