diff options
Diffstat (limited to 'r7r_repo/models.php')
-rw-r--r-- | r7r_repo/models.php | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/r7r_repo/models.php b/r7r_repo/models.php new file mode 100644 index 0000000..1eb7caf --- /dev/null +++ b/r7r_repo/models.php @@ -0,0 +1,396 @@ +<?php + +require_once(dirname(__FILE__) . "/db.php"); +require_once(dirname(__FILE__) . "/utils.php"); + +/* Exceptions copied from Ratatöskr */ +class DoesNotExistError extends Exception { } +class AlreadyExistsError extends Exception { } +class NotAllowedError extends Exception { } + +/* copied from Ratatöskr: */ +abstract class BySQLRowEnabled +{ + protected function __construct() { } + + abstract protected function populate_by_sqlrow($sqlrow); + + protected static function by_sqlrow($sqlrow) + { + $obj = new static(); + $obj->populate_by_sqlrow($sqlrow); + return $obj; + } +} + +/* SettingsIterator ans Settings copied from Ratatöskr */ + +class SettingsIterator implements Iterator +{ + private $index; + private $keys; + private $settings_obj; + + public function __construct($settings_obj, $keys) + { + $this->index = 0; + $this->settings_obj = $settings_obj; + $this->keys = $keys; + } + + /* Iterator implementation */ + public function current() { return $this->settings_obj[$this->keys[$this->index]]; } + public function key() { return $this->keys[$this->index]; } + public function next() { ++$this->index; } + public function rewind() { $this->index = 0; } + public function valid() { return $this->index < count($this->keys); } +} + +/* + * Class: Settings + * A class that holds the Settings of Ratatöskr. + * You can access settings like an array. + */ +class Settings implements ArrayAccess, IteratorAggregate, Countable +{ + /* Singleton implementation */ + private function __copy() {} + private static $instance = NULL; + /* + * Constructor: get_instance + * Get an instance of this class. + * All instances are equal (ie. this is a singleton), so you can also use + * the global <$ratatoeskr_settings> instance. + */ + public static function get_instance() + { + if(self::$instance === NULL) + self::$instance = new self; + return self::$instance; + } + + private $buffer; + private $to_be_deleted; + private $to_be_created; + private $to_be_updated; + + private function __construct() + { + $this->buffer = array(); + $result = qdb("SELECT `key`, `value` FROM `PREFIX_settings_kvstorage` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $this->buffer[$sqlrow["key"]] = unserialize(base64_decode($sqlrow["value"])); + + $this->to_be_created = array(); + $this->to_be_deleted = array(); + $this->to_be_updated = array(); + } + + public function save() + { + foreach($this->to_be_deleted as $k) + qdb("DELETE FROM `PREFIX_settings_kvstorage` WHERE `key` = '%s'", $k); + foreach($this->to_be_updated as $k) + qdb("UPDATE `PREFIX_settings_kvstorage` SET `value` = '%s' WHERE `key` = '%s'", base64_encode(serialize($this->buffer[$k])), $k); + foreach($this->to_be_created as $k) + qdb("INSERT INTO `PREFIX_settings_kvstorage` (`key`, `value`) VALUES ('%s', '%s')", $k, base64_encode(serialize($this->buffer[$k]))); + $this->to_be_created = array(); + $this->to_be_deleted = array(); + $this->to_be_updated = array(); + } + + /* ArrayAccess implementation */ + public function offsetExists($offset) + { + return isset($this->buffer[$offset]); + } + public function offsetGet($offset) + { + return $this->buffer[$offset]; + } + public function offsetSet ($offset, $value) + { + if(!$this->offsetExists($offset)) + { + if(in_array($offset, $this->to_be_deleted)) + { + $this->to_be_updated[] = $offset; + unset($this->to_be_deleted[array_search($offset, $this->to_be_deleted)]); + } + else + $this->to_be_created[] = $offset; + } + elseif((!in_array($offset, $this->to_be_created)) and (!in_array($offset, $this->to_be_updated))) + $this->to_be_updated[] = $offset; + $this->buffer[$offset] = $value; + } + public function offsetUnset($offset) + { + if(in_array($offset, $this->to_be_created)) + unset($this->to_be_created[array_search($offset, $this->to_be_created)]); + else + $this->to_be_deleted[] = $offset; + unset($this->buffer[$offset]); + } + + /* IteratorAggregate implementation */ + public function getIterator() { return new SettingsIterator($this, array_keys($this->buffer)); } + + /* Countable implementation */ + public function count() { return count($this->buffer); } +} + +$settings = Settings::get_instance(); + +/* users */ +class User extends BySQLRowEnabled +{ + private $name; + private $id; + + public $pwhash; + public $isadmin; + + protected function __construct() {} + + protected function populate_by_sqlrow($sqlrow) + { + $this->id = $sqlrow["id"]; + $this->name = $sqlrow["name"]; + $this->pwhash = $sqlrow["pwhash"]; + $this->isadmin = $sqlrow["isadmin"] == 1; + } + + function get_id() { return $this->id; } + function get_name() { return $this->name; } + + public static function create($name) + { + try + { + self::by_name($name); + throw new AlreadyExistsError(); + } + catch(DoesNotExistError $e) + { + $obj = new self; + $obj->name = $name; + $obj->pwhash = ""; + $obj->isadmin = False; + qdb("INSERT INTO `PREFIX_users` (`name`, `pwhash`, `isadmin`) VALUES ('%s', '', 0)", $name); + $obj->id = mysql_insert_id(); + return $obj; + } + } + + public static function by_id($id) + { + $result = qdb("SELECT `id`, `name`, `pwhash`, `isadmin` FROM `PREFIX_users` WHERE `id` = %d", $id); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + return self::by_sqlrow($sqlrow); + } + + public static function by_name($name) + { + $result = qdb("SELECT `id`, `name`, `pwhash`, `isadmin` FROM `PREFIX_users` WHERE `name` = '%s'", $name); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + return self::by_sqlrow($sqlrow); + } + + public static function all() + { + $rv = array(); + $result = qdb("SELECT `id`, `name`, `pwhash`, `isadmin` FROM `PREFIX_users` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_sqlrow($sqlrow); + return $rv; + } + + public function get_packages() + { + $rv = array(); + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE `user` = %d", $this->id); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = Package::by_sqlrow($result); + return $rv; + } + + public function save() + { + qdb("UPDATE `PREFIX_users` SET `isadmin` = %d, `pwhash` = '%s' WHERE `id` = %d", ($this->isadmin ? 1 : 0), $this->pwhash, $this->id); + } + + public function delete() + { + qdb("DELETE FROM `PREFIX_users` WHERE `id` = %d", $this->id); + } +} + +class Package extends BySQLRowEnabled +{ + private $id; + private $name; + private $user; + + public $lastversion; + public $description; + public $lastupdate; + public $txtversion; + + public function get_id() { return $id; } + public function get_name() { return $name; } + public function get_user() { return $user; } + + protected function __construct() {} + + protected function populate_by_sqlrow($sqlrow) + { + $this->id = $sqlrow["id"]; + $this->name = $sqlrow["name"]; + $this->user = User::by_id($sqlrow["user"]); + $this->lastversion = $sqlrow["lastversion"]; + $this->description = $sqlrow["description"]; + $this->lastupdate = $sqlrow["lastupdate"]; + $this->txtversion = $sqlrow["txtversion"]; + } + + public static function create($name, $user) + { + if(preg_match("/^[0-9a-zA-Z_\\-]+$/", $name) != 1) + throw new InvalidArgumentException("Invalid package name (must be min 1 char, 0-9A-Za-z_-"); + try + { + self::by_name($name); + throw new AlreadyExistsError(); + } + catch(DoesNotExistError $e) + { + $obj = new self; + $obj->name = $name; + $obj->user = $user; + $obj->lastupdate = time(); + $obj->lastversion = 0; + $obj->txtversion = ""; + $obj->description = ""; + + qdb("INSERT INTO `PREFIX_packages` (`name`, `user`, `lastupdate`, `lastversion`, `txtversion`, description`, `description`) VALUES ('%s', %d, UNIX_TIMESTAMP(), 0, '', '')", $name, $user->get_id()); + $obj->id = mysql_insert_id(); + + mkdir(dirname(__FILE__) . "/../packages/" . $this->name); + + return $obj; + } + } + + public static function by_id($id) + { + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE `id` = %d", $id); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + return self::by_sqlrow($sqlrow); + } + + public static function by_name($name) + { + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE `name` = '%s'", $name); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + return self::by_sqlrow($sqlrow); + } + + public static function update_lists() + { + $packagelist = array(); + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $packagelist[] = array($sqlrow["name"], $sqlrow["lastversion"], $sqlrow["description"]); + file_put_contents(dirname(__FILE__) . "/../packagelist", serialize($packagelist)); + } + + public static function all() + { + $rv = array(); + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_sqlrow($sqlrow); + return $rv; + } + + public static function latest() + { + $rv = array(); + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE 1 ORDER BY `lastupdate` DESC LIMIT 0,15"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_sqlrow($sqlrow); + return $rv; + } + + public static function search($search) + { + $rv = array(); + $result = qdb("SELECT `id`, `name`, `user`, `lastversion`, `description`, `lastupdate`, `txtversion` FROM `PREFIX_packages` WHERE `name` LIKE '%%%s%%' OR `description` LIKE '%%%s%%'", $search, $search); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_sqlrow($sqlrow); + return $rv; + } + + public function newversion($pgk) + { + global $settings; + if($pkg->name != $this->name) + throw new NotAllowedError("Package name not equal."); + if($pkg->versioncount <= $this->lastversion) + throw new NotAllowedError("Older or same version."); + $pkg->updatepath = $settings["root_url"] . "/packages/" . urlencode($this->name) . "/update"; + + $pkg_ser = $pkg->save(); + file_put_contents(dirname(__FILE__) . "/../packages/" . urlencode($this>name) . "/versions/" . $pkg->versioncount, $pkg_ser); + file_put_contents(dirname(__FILE__) . "/../packages/" . urlencode($this>name) . "/versions/current", $pkg_ser); + $meta = $pkg->extract_meta(); + file_put_contents(dirname(__FILE__) . "/../packages/" . urlencode($this>name) . "/meta", serialize($meta)); + + $this->lastversion = $pkg->versioncount; + $this->txtversion = $pkg->versiontext; + $this->description = $pkg->short_description; + $this->lastupdate = time(); + $this->save(); + + $update_info = array( + "current-version" => $this->lastversion, + "dl-path" => $settings["root_url"] . "/packages/" . urlencode($this->name) . "/versions/" . $this->lastversion + ); + + file_put_contents(dirname(__FILE__) . "/../packages/" . urlencode($this>name) . "/update", serialize($update_info)); + + self::update_lists(); + } + + public function save() + { + qdb("UPDATE `PREFIX_packages` SET `lastversion` = %d, `lastupdate` = %d, `txtversion` = '%s', `description` = '%s' WHERE `id` = %d", $this->lastversion, $this->lastupdate, $this->txtversion, $this->description, $this->id); + } + + public function delete() + { + qdb("DELETE FROM `PREFIX_packages` WHERE `id` = %d", $this->id); + delete_directory(dirname(__FILE__) . "/../packages/" . $this->name); + self::update_lists(); + } +} + +function update_repometa() +{ + global $settings; + file_put_contents(dirname(__FILE__) . "/../repometa", serialize(array( + "name" => $settings["repo_name"], + "description" => $settings["repo_description"] + ))); +} + +?> |