diff options
49 files changed, 3665 insertions, 2900 deletions
diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..ee4ed5a0 --- /dev/null +++ b/INSTALL @@ -0,0 +1,102 @@ +Setup on Arch Linux: +==================== +1) Install Apache, MySQL, PHP, git and php-pear + # pacman -Syu apache mysql php git php-pear + +2) Set a local 'hostname' of 'aur' + - Edit /etc/hosts and append 'aur' to loopback address + 127.0.0.1 localhost aur + +3) Configure Apache + + - Edit /etc/httpd/conf/httpd.conf and enable PHP support + by adding the following lines. + + LoadModule php5_module modules/libphp5.so + Include conf/extra/php5_module.conf + + - Also append the following snippet to enable the aur + Virtual Host in /etc/httpd/conf/extra/httpd-vhosts.conf. + Comment out the example vhosts and replace MYUSER with your username. + (You could put aur in /srv/http/aur and then create a symlink in ~ ) + + <VirtualHost aur:80> + Servername aur + DocumentRoot /home/MYUSER/aur/web/html + ErrorLog /var/log/httpd/aur-error.log + CustomLog /var/log/httpd/aur-access.log combined + <Directory /home/MYUSER/aur/web/html> + Options Indexes FollowSymLinks + AllowOverride All + Order allow,deny + Allow from all + </Directory> + </VirtualHost> + + - In httpd.conf, uncomment this line: + + Include conf/extra/httpd-vhosts.conf + +4) Clone the AUR project (using the MYUSER from above) + $ cd + $ git clone git://projects.archlinux.org/aur.git + +5) Configure PHP + Make sure you have mysql and json enabled in PHP. + + - Edit php.ini and uncomment/add these lines: + extension=mysql.so + extension=json.so + + If those php extensions are separate packages on your system, install + them. + + AUR requires PEAR and the Archive_Tar module. + Installing PEAR will vary depending on the system and may already + be included with PHP. You can also find it in the PHP source + distribution. + + PHP sources: http://www.php.net/downloads.php + Archive_Tar PEAR module: http://pear.php.net/package/Archive_Tar + + - Install the Archive_Tar PEAR package: + # pear install Archive_Tar + +6) Configure MySQL + - Start the MySQL service. Example: + # /etc/rc.d/mysqld start + + - Create database + # mysqladmin -p create AUR + + - Connect to the mysql client + # mysql -uroot -p AUR + + - Issue the following commands to the mysql client + mysql> GRANT ALL PRIVILEGES ON AUR.* to aur@localhost + > identified by 'aur'; + mysql> FLUSH PRIVILEGES; + mysql> quit + + - Load the schema file + # mysql -uaur -p AUR < ~/aur/support/schema/aur-schema.sql + (give password 'aur' at the prompt) + + - Optionally load some test data for development purposes. + # pacman -S words mysql-python + # cd ~/aur/support/schema/ + # python gendummydata.py dummy-data.sql + # bzip2 dummy-data.sql + # bzcat dummy-data.sql.bz2 | mysql -uaur -p AUR + (give password 'aur' at the prompt) + + If your test data consists of real people and real email addresses consider + inserting bogus addressess to avoid sending unwanted spam from testing. You + can insert garbage addresses with: + mysql> UPDATE Users SET Email = RAND() * RAND(); + +7) Copy the config.inc.php.proto file to config.inc.php. Modify as needed. + # cd ~/aur/web/lib/ + # cp config.inc.php.proto config.inc.php + +8) Point your browser to http://aur @@ -1,107 +1,67 @@ -This is the finalized draft of the project requirements for the -new Arch package submittal process. AUR (Arch User-community Repo). -The sub-directories contain more specific implementation notes -for each component of the project. - - -Requirements: -------------- -1) User accounts (users, TUs) - - Create account. (email address required) - - Update account (change password/email address) - - Log in/out - -2) Search for packages (public) - - needs knowledge of ALL pkgs (OfficalRepos/AUR/Unsupported). This - should be easy enough if this site lives on the same machine as - the current package database (dragon?), or is allowed to query - the db. - - Display official repo (current/extra) a package lives in. - -3) Manual voting (requires user acct) - - reset/clear all votes (for starting over, this can be added later - if there is any demand for it) - -4) Package Management - - A package can be submitted by anyone (as long as they create - an account with a valid email address on the web site). From - there, a TU inspects the package and works with the submitter - to resolve any bugs/issues. Once approved, the TU can place the - package in the AUR. From there, if the package is popular enough - (or deemed necessary), a developer can move the package from the - AUR to extra/current/etc. A developer can also downgrade a - package from extra/current/etc to the AUR. - - The person that uploaded the new package can make changes to - it before it has been added to the AUR. - - TUs need to be able to purge packages in "Unsupported" if the - package is no longer maintained and there is no interest in - keeping it. - - Packages in the AUR/Unsupported need some sort of 'flag out of - date' support. - - Interested users can download the package from "Unsupported" - and build/install it by hand. - - Provide a separate installation of flyspray for tracking bugs - for packages living in the AUR. All bugs should be resolved - in either flyspray (AUR/official) prior to a package being - promoted/demoted. - -5) Reports - - package popularity by number of votes - -6) Wiki Docs (UID/GID db, provides db, irc nicks/names TUs/devs) - - Move the appropriate dev wiki pages to the new system's - wiki area. The devs will just need to consult the UID/GID - list from the new system site rather than our own wiki. - -7) Submitting 'new' packages by users. Initially start with - a simple web upload page where users submit a tgz containing - the PKGBUILD, scriptlets, patches, etc. The script will - unpack the tgz in an appropriate location and update the - backend database to 'register' the pacakge. - -8) TU package management - - A TU adopts a package from "Unsupported" and that shows users - and other TUs that the package is being reviewed. - - When the TU is ready to move the package to the AUR, they - use a custom utility/script that allows them to upload the - pkg.tar.gz (web uploads are inadequate for this process). - The upload utility/script has a server counterpart that - performs TU authentication and updates the database. - - A cronjob on the server can handle the new AUR package, - update the database, and rebuild the AUR sync db, and send - email notices to the TU about errors if any occur. - - The TUs should also be able to demote a package from the - AUR via the web interface. - - TUs will use cvs/svn interface (just like devs) to pull - down the PKGBUILD tree. This tree should reflect the same - layout as extra for easier package migration. They make - changes to their local copy, test, and then commit. They - use the xfer utility to upload the binary package to the - server. No shell access is required. - - -Automated Voting Tool (similar to ArchStats client) -===================== - -Requirements: -------------- - 1) Name of tool is 'pkgvote' - - 2) Requires registered account on web - email address not required - - 3) Casts 'yes' votes for all installed packages (except itself?) - -Implementation: ---------------- - A statically compiled C program that gathers the list of installed - packages and casts the vote to the web site. Very similar to the - way that ArchStats works now. When making the HTTP Post, it adds - a custom HEADER that the PHP script(s) can detect to know that it - is receiving a vote from a 'pkgvote' client. If the PHP script - does not see the special HEADER, it assumes it is a web browser - and gives the user HTML output. - - Once installed, the user edits the config file and supplies their - username/password. If no username/password exists in the config - file when it starts, it spits out an error message and exits. - +=================== +Arch User Repository (AUR) +=================== + +About: +===== +The Arch User Repository (AUR) is a framework for hosting a collection of +packaging scripts that are created and submitted by the Arch community. The +scripts contained in the repository (PKGBUILDS) can be built using the Arch +building/packaging script (makepkg) and installed via the Arch pacman manager +(pacman). The AUR project aims to provide the necessary web interface, database +schema, and scripts for a multi-lingual community-driven repository. + +Functionality: +========= +-Users may submit source packages that contain a PKGBUILD +-User accounts with varying permission levels (User, Trusted User, Developer) +-Ability to search for specific submitted packages (based on package name, +package description, package submitter, package maintainer) +-Display submitted package information by parsing PKGBUILD (description, +license, package dependencies, etc) +-Users can make comments on package information page +-Mark packages as out-of-date +-Vote for well-done and popular user submitted packages +-Trusted User and Developer have ability to search for and modify accounts +-Area for Trusted Users +and Developers to post AUR-related proposals and vote on them + +File Hierarchy: +========== + +Directory Layout: +------------------- +./po - Translation files for strings in the AUR web + interface. +./scripts - aurblup package blacklist tool. Scripts for AUR + maintenance. +./support - Schema for SQL database. Script for dummy data generation. +./web - Web interface for the AUR. + +Files: +------ +AUTHORS - List of maintainers, contributors, and translators for AUR + project. +COPYING - License information for AUR project (GPL version 2). +HACKING - Guidelines for modifying source and submitting + patches. +INSTALL - Installation procedure for AUR. +TODO - List of potential features and changes to be made to the AUR. +TRANSLATING - Directions for creating and updating string translations. +UPGRADING - Changes needed to upgrade older AUR version to newer version. + +Code: +===== +Official repository hosted at git://projects.archlinux.org/aur.git +See HACKING for information on submitting patches + +Bugs: +===== +Discovered bugs can be submitted to the AUR bug tracker: +https://bugs.archlinux.org/index.php?project=2 + +Contact: +======== +Questions, comments, and patches related to the AUR can be sent to the AUR +development mailing list: aur-dev@archlinux.org +Mailing list archives: http://mailman.archlinux.org/mailman/listinfo/aur-dev @@ -1,6 +1,18 @@ Upgrading ========= +From 1.9.1 to 2.0.0 +------------------- + +1. Add new "Users" table login date column: + +---- +ALTER TABLE Users ADD COLUMN LastLogin BIGINT NOT NULL DEFAULT 0; +ALTER TABLE Users ADD COLUMN PGPKey VARCHAR(40) NULL DEFAULT NULL; +---- + +2. Merge "web/lib/config.inc.php.proto" with "web/lib/config.inc.php". + From 1.9.0 to 1.9.1 ------------------- diff --git a/scripts/aurblup/aurblup.c b/scripts/aurblup/aurblup.c index 6a67d68d..32365548 100644 --- a/scripts/aurblup/aurblup.c +++ b/scripts/aurblup/aurblup.c @@ -11,7 +11,7 @@ #include "config.h" -#define alpm_die(...) die(__VA_ARGS__, alpm_strerrorlast()); +#define alpm_die(...) die(__VA_ARGS__, alpm_strerror(alpm_errno(handle))); #define mysql_die(...) die(__VA_ARGS__, mysql_error(c)); static void die(const char *, ...); @@ -34,6 +34,8 @@ static char *mysql_db = NULL; static MYSQL *c; +static alpm_handle_t *handle; + static void die(const char *format, ...) { @@ -52,12 +54,13 @@ static alpm_list_t * pkglist_append(alpm_list_t *pkglist, const char *pkgname) { int len = strcspn(pkgname, "<=>"); - if (!len) len = strlen(pkgname); + if (!len) + len = strlen(pkgname); char *s = malloc(len + 1); strncpy(s, pkgname, len); - s[len] = 0; + s[len] = '\0'; if (alpm_list_find_str(pkglist, s)) free(s); @@ -74,7 +77,7 @@ blacklist_get_pkglist() MYSQL_ROW row; alpm_list_t *pkglist = NULL; - if (mysql_query(c, "SELECT Name FROM PackageBlacklist;")) + if (mysql_query(c, "SELECT Name FROM PackageBlacklist")) mysql_die("failed to read blacklist from MySQL database: %s\n"); if (!(res = mysql_store_result(c))) @@ -96,7 +99,7 @@ blacklist_add(const char *name) mysql_real_escape_string(c, esc, name, strlen(name)); snprintf(query, 1024, "INSERT INTO PackageBlacklist (Name) " - "VALUES ('%s');", esc); + "VALUES ('%s')", esc); free(esc); if (mysql_query(c, query)) @@ -110,7 +113,7 @@ blacklist_remove(const char *name) char query[1024]; mysql_real_escape_string(c, esc, name, strlen(name)); - snprintf(query, 1024, "DELETE FROM PackageBlacklist WHERE Name = '%s';", esc); + snprintf(query, 1024, "DELETE FROM PackageBlacklist WHERE Name = '%s'", esc); free(esc); if (mysql_query(c, query)) @@ -125,16 +128,16 @@ blacklist_sync(alpm_list_t *pkgs_cur, alpm_list_t *pkgs_new) pkgs_add = alpm_list_diff(pkgs_new, pkgs_cur, (alpm_list_fn_cmp)strcmp); pkgs_rem = alpm_list_diff(pkgs_cur, pkgs_new, (alpm_list_fn_cmp)strcmp); - if (mysql_query(c, "START TRANSACTION;")) + if (mysql_query(c, "START TRANSACTION")) mysql_die("failed to start MySQL transaction: %s\n"); for (p = pkgs_add; p; p = alpm_list_next(p)) - blacklist_add(alpm_list_getdata(p)); + blacklist_add(p->data); for (p = pkgs_rem; p; p = alpm_list_next(p)) - blacklist_remove(alpm_list_getdata(p)); + blacklist_remove(p->data); - if (mysql_query(c, "COMMIT;")) + if (mysql_query(c, "COMMIT")) mysql_die("failed to commit MySQL transaction: %s\n"); alpm_list_free(pkgs_add); @@ -148,25 +151,29 @@ dblist_get_pkglist(alpm_list_t *dblist) alpm_list_t *pkglist = NULL; for (d = dblist; d; d = alpm_list_next(d)) { - pmdb_t *db = alpm_list_getdata(d); + alpm_db_t *db = d->data; - if (alpm_trans_init(0, NULL, NULL, NULL)) + if (alpm_trans_init(handle, 0)) alpm_die("failed to initialize ALPM transaction: %s\n"); if (alpm_db_update(0, db) < 0) alpm_die("failed to update ALPM database: %s\n"); - if (alpm_trans_release()) + if (alpm_trans_release(handle)) alpm_die("failed to release ALPM transaction: %s\n"); for (p = alpm_db_get_pkgcache(db); p; p = alpm_list_next(p)) { - pmpkg_t *pkg = alpm_list_getdata(p); + alpm_pkg_t *pkg = p->data; pkglist = pkglist_append(pkglist, alpm_pkg_get_name(pkg)); - for (q = alpm_pkg_get_provides(pkg); q; q = alpm_list_next(q)) - pkglist = pkglist_append(pkglist, alpm_list_getdata(q)); + for (q = alpm_pkg_get_provides(pkg); q; q = alpm_list_next(q)) { + alpm_depend_t *provide = q->data; + pkglist = pkglist_append(pkglist, provide->name); + } - for (q = alpm_pkg_get_replaces(pkg); q; q = alpm_list_next(q)) - pkglist = pkglist_append(pkglist, alpm_list_getdata(q)); + for (q = alpm_pkg_get_replaces(pkg); q; q = alpm_list_next(q)) { + alpm_depend_t *replace = q->data; + pkglist = pkglist_append(pkglist, replace->name); + } } } @@ -181,20 +188,20 @@ dblist_create(void) int i; for (i = 0; i < sizeof(alpm_repos) / sizeof(char *); i++) { - if (!alpm_db_register_sync(alpm_repos[i])) + if (!alpm_db_register_sync(handle, alpm_repos[i], 0)) alpm_die("failed to register sync db \"%s\": %s\n", alpm_repos[i]); } - if (!(dblist = alpm_option_get_syncdbs())) + if (!(dblist = alpm_option_get_syncdbs(handle))) alpm_die("failed to get sync DBs: %s\n"); for (d = dblist; d; d = alpm_list_next(d)) { - pmdb_t *db = alpm_list_getdata(d); + alpm_db_t *db = d->data; char server[1024]; snprintf(server, 1024, ALPM_MIRROR, alpm_db_get_name(db)); - if (alpm_db_setserver(db, server)) + if (alpm_db_add_server(db, server)) alpm_die("failed to set server \"%s\": %s\n", server); } @@ -217,10 +224,14 @@ read_config(const char *fn) t = &mysql_host; u = &mysql_socket; } - else if (strstr(line, CONFIG_KEY_USER)) t = &mysql_user; - else if (strstr(line, CONFIG_KEY_PASSWD)) t = &mysql_passwd; - else if (strstr(line, CONFIG_KEY_DB)) t = &mysql_db; - else t = NULL; + else if (strstr(line, CONFIG_KEY_USER)) + t = &mysql_user; + else if (strstr(line, CONFIG_KEY_PASSWD)) + t = &mysql_passwd; + else if (strstr(line, CONFIG_KEY_DB)) + t = &mysql_db; + else + t = NULL; if (t) { strtok(line, "\""); @@ -261,6 +272,7 @@ read_config(const char *fn) static void init(void) { + enum _alpm_errno_t alpm_err; if (mysql_library_init(0, NULL, NULL)) mysql_die("could not initialize MySQL library: %s\n"); if (!(c = mysql_init(NULL))) @@ -269,24 +281,20 @@ init(void) mysql_db, 0, mysql_socket, 0)) mysql_die("failed to initiate MySQL connection to %s: %s\n", mysql_host); - if (alpm_initialize()) - alpm_die("failed to initialize ALPM: %s\n"); - if (alpm_option_set_root("/")) - alpm_die("failed to set ALPM root: %s\n"); - if (alpm_option_set_dbpath(ALPM_DBPATH)) - alpm_die("failed to set ALPM database path: %s\n"); + if ((handle = alpm_initialize("/", ALPM_DBPATH, &alpm_err)) == NULL) + die("failed to initialize ALPM: %s\n", alpm_strerror(alpm_err)); } static void cleanup(void) { - if (mysql_host) free(mysql_host); - if (mysql_socket) free(mysql_socket); - if (mysql_user) free(mysql_user); - if (mysql_passwd) free(mysql_passwd); - if (mysql_db) free(mysql_db); + free(mysql_host); + free(mysql_socket); + free(mysql_user); + free(mysql_passwd); + free(mysql_db); - alpm_release(); + alpm_release(handle); mysql_close(c); mysql_library_end(); } diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql index 88d074e3..726fd2f3 100644 --- a/support/schema/aur-schema.sql +++ b/support/schema/aur-schema.sql @@ -31,7 +31,9 @@ CREATE TABLE Users ( RealName VARCHAR(64) NOT NULL DEFAULT '', LangPreference VARCHAR(5) NOT NULL DEFAULT 'en', IRCNick VARCHAR(32) NOT NULL DEFAULT '', + PGPKey VARCHAR(40) NULL DEFAULT NULL, LastVoted BIGINT UNSIGNED NOT NULL DEFAULT 0, + LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (ID), UNIQUE (Username), UNIQUE (Email), @@ -190,8 +192,8 @@ CREATE TABLE PackageBlacklist ( -- CREATE TABLE IF NOT EXISTS TU_VoteInfo ( ID int(10) unsigned NOT NULL auto_increment, - Agenda text COLLATE utf8_general_ci NOT NULL, - User VARCHAR(32) COLLATE utf8_general_ci NOT NULL, + Agenda text NOT NULL, + User VARCHAR(32) NOT NULL, Submitted bigint(20) unsigned NOT NULL, End bigint(20) unsigned NOT NULL, SubmitterID int(10) unsigned NOT NULL, diff --git a/support/schema/gendummydata.py b/support/schema/gendummydata.py index d0b8b718..160dde5c 100755 --- a/support/schema/gendummydata.py +++ b/support/schema/gendummydata.py @@ -29,22 +29,17 @@ MAX_USERS = 300 # how many users to 'register' MAX_DEVS = .1 # what percentage of MAX_USERS are Developers MAX_TUS = .2 # what percentage of MAX_USERS are Trusted Users MAX_PKGS = 900 # how many packages to load -PKG_FILES = (8, 30) # min/max number of files in a package PKG_DEPS = (1, 5) # min/max depends a package has PKG_SRC = (1, 3) # min/max sources a package has PKG_CMNTS = (1, 5) # min/max number of comments a package has CATEGORIES_COUNT = 17 # the number of categories from aur-schema VOTING = (0, .30) # percentage range for package voting -RANDOM_PATHS = ( # random path locations for package files - "/usr/bin", "/usr/lib", "/etc", "/etc/rc.d", "/usr/share", "/lib", - "/var/spool", "/var/log", "/usr/sbin", "/opt", "/usr/X11R6/bin", - "/usr/X11R6/lib", "/usr/libexec", "/usr/man/man1", "/usr/man/man3", - "/usr/man/man5", "/usr/X11R6/man/man1", "/etc/profile.d" -) +OPEN_PROPOSALS = 5 # number of open trusted user proposals +CLOSE_PROPOSALS = 15 # number of closed trusted user proposals RANDOM_TLDS = ("edu", "com", "org", "net", "tw", "ru", "pl", "de", "es") RANDOM_URL = ("http://www.", "ftp://ftp.", "http://", "ftp://") RANDOM_LOCS = ("pub", "release", "files", "downloads", "src") -FORTUNE_CMD = "/usr/bin/fortune -l" +FORTUNE_CMD = "/usr/bin/fortune" # setup logging logformat = "%(levelname)s: %(message)s" @@ -61,6 +56,12 @@ if not os.path.exists(SEED_FILE): log.error("Please install the 'words' Arch package") raise SystemExit +# make sure comments can be created +# +if not os.path.exists(FORTUNE_CMD): + log.error("Please install the 'fortune-mod' Arch package") + raise SystemExit + # track what users/package names have been used # seen_users = {} @@ -188,20 +189,14 @@ for p in list(seen_pkgs.keys()): else: muid = trustedusers[random.randrange(0,len(trustedusers))] if count % 20 == 0: # every so often, there are orphans... - muid = 0 + muid = "NULL" uuid = genUID() # the submitter/user - if muid == 0: - s = ("INSERT INTO Packages (ID, Name, Version, CategoryID," - " SubmittedTS, SubmitterUID, MaintainerUID) VALUES" - " (%d, '%s', '%s', %d, %d, %d, NULL);\n") - s = s % (seen_pkgs[p], p, genVersion(), genCategory(), NOW, uuid) - else: - s = ("INSERT INTO Packages (ID, Name, Version, CategoryID," - " SubmittedTS, SubmitterUID, MaintainerUID) VALUES " - " (%d, '%s', '%s', %d, %d, %d, %d);\n") - s = s % (seen_pkgs[p], p, genVersion(), genCategory(), NOW, uuid, muid) + s = ("INSERT INTO Packages (ID, Name, Version, CategoryID," + " SubmittedTS, SubmitterUID, MaintainerUID) VALUES " + " (%d, '%s', '%s', %d, %d, %d, %s);\n") + s = s % (seen_pkgs[p], p, genVersion(), genCategory(), NOW, uuid, muid) out.write(s) count += 1 @@ -271,6 +266,30 @@ for p in list(seen_pkgs.keys()): s = s % (seen_pkgs[p], src) out.write(s) +# Create trusted user proposals +# +log.debug("Creating SQL statements for trusted user proposals.") +count=0 +for t in range(0, OPEN_PROPOSALS+CLOSE_PROPOSALS): + fortune = subprocess.getoutput(FORTUNE_CMD).replace("'","") + now = int(time.time()) + if count < CLOSE_PROPOSALS: + start = now - random.randrange(3600*24*7, 3600*24*21) + end = now - random.randrange(0, 3600*24*7) + else: + start = now + end = now + random.randrange(3600*24, 3600*24*7) + if count % 5 == 0: # Don't make the vote about anyone once in a while + user = "" + else: + user = user_keys[random.randrange(0,len(user_keys))] + suid = trustedusers[random.randrange(0,len(trustedusers))] + s = ("INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End," + " SubmitterID) VALUES ('%s', '%s', %d, %d, %d);\n") + s = s % (fortune, user, start, end, suid) + out.write(s) + count += 1 + # close output file # out.write("COMMIT;\n") @@ -1,187 +1,104 @@ -Setup on Arch Linux: -==================== -1) Install Apache, MySQL, PHP, and git - # pacman -Syu apache mysql php git - -2) Set a local 'hostname' of 'aur' - - Edit /etc/hosts and append 'aur' to loopback address - 127.0.0.1 localhost aur - -3) Configure Apache - - - Edit /etc/httpd/conf/httpd.conf and enable PHP support - by adding the following lines. - - LoadModule php5_module modules/libphp5.so - Include conf/extra/php5_module.conf - - - Also append the following snippet to enable the aur - Virtual Host (Replace MYUSER with your username). - - <VirtualHost aur:80> - Servername aur - DocumentRoot /home/MYUSER/aur/web/html - ErrorLog /var/log/httpd/aur-error.log - CustomLog /var/log/httpd/aur-access.log combined - <Directory /home/MYUSER/aur/web/html> - Options Indexes FollowSymLinks - AllowOverride All - Order allow,deny - Allow from all - </Directory> - </VirtualHost> - -4) Clone the AUR project (using the MYUSER from above) - $ cd - $ git clone git://projects.archlinux.org/aur.git - -5) Configure PHP - Make sure you have mysql and json enabled in PHP. - - - Edit php.ini and uncomment/add these lines: - extension=mysql.so - extension=json.so - - If those php extensions are separate packages on your system, install - them. - - AUR requires PEAR and the Archive_Tar module. - Installing PEAR will vary depending on the system and may already - be included with PHP. You can also find it in the PHP source - distribution. - - PHP sources: http://www.php.net/downloads.php - Archive_Tar PEAR module: http://pear.php.net/package/Archive_Tar - - - Install the Archive_Tar PEAR package: - # pear install Archive_Tar - - - Put PEAR in your php include_path in php.ini: - - include_path = ".:/usr/share/pear" - - PEAR's path may vary depending on your set up. - -6) Configure MySQL - - Start the MySQL service. Example: - # /etc/rc.d/mysqld start - - - Connect to the mysql client - # mysql -uroot - - - Issue the following commands to the mysql client - mysql> CREATE DATABASE AUR; - mysql> GRANT ALL PRIVILEGES ON AUR.* to aur@localhost - > identified by 'aur'; - mysql> FLUSH PRIVILEGES; - mysql> quit - - - Load the schema file - # mysql -uaur -p AUR < ~/aur/support/schema/aur-schema.sql - (give password 'aur' at the prompt) - - - Optionally load some test data for development purposes. - # pacman -S words mysql-python - # cd ~/aur/support/schema/ - # python gendummydata.py dummy-data.sql - # bzip2 dummy-data.sql - # bzcat dummy-data.sql.bz2 | mysql -uaur -p AUR - (give password 'aur' at the prompt) - - If your test data consists of real people and real email addresses consider - inserting bogus addressess to avoid sending unwanted spam from testing. You - can insert garbage addresses with: - mysql> UPDATE Users SET Email = RAND() * RAND(); - -7) Copy the config.inc.php.proto file to config.inc.php. Modify as needed. - # cd ~/aur/web/lib/ - # cp config.inc.php.proto config.inc.php - -8) Point your browser to http://aur - - -Web Interface: ============== - -Directory Layout: ------------------ -./html - DocumentRoot for AUR, where the PHP scripts live. -./html/css - CSS stylesheets -./html/images - Any AUR images live here. -./lib - Supporting PHP include files. Access denied to Apache. -./template - Where most of the html markup resides and minimal - amount of PHP scripting. - - There is also a template to model the site's top pages - in template.phps - - -Scripts: --------- -- lib/aur.inc - This is where we can stick functions that can be shared - between the various scripts. Also a good place to put the - MySQL authentication variables since it should live outside - the DocumentRoot. - -- html/login.php (probably index.php) - PHP script to handle logging users into the AUR web site. It - authenticates using the email address and a password against - the Users table. Once authenticated, a session id is generated - and stored in the Sessions table and sent as a cookie to the - user's browser. - -- html/logout.php - PHP script to logout. It clears the session id from the - Sessions table and unsets the cookie. - -- html/account.php - PHP script to handle registering for a new account. It prompts - the visitor for account information: Email, password, real name, - irc nick. The info is recorded in the Users table. Perhaps later, - we can add a preferences field that allows the user to request to - be notified when new packages are submitted so that they can cast - votes for them? - - If a TU is logged into the system, they can edit accounts and set - the account type (regular user or TU). If a Dev is logged in, they - can also set the account type to Dev. TUs and Devs are able to - delete accounts. If an account is deleted, all "Unsupported" - packages are orphaned (the MaintainerUID field in the Packages - table is set to NULL). - -- html/packages.php - PHP script to search the package database. It should support - searching by name, category, maintainer, popularity, etc. It - should resemble the packages.php script on archlinux.org. A - checkbox should be included next to each package to allow - users to flag a package out of date, adopt it, and vote for - it (and reverse operations). - -- html/pkgsubmit.php - This is the PHP script that allows users to upload a new package. - The package format will be a tgz containing the PKGBUILD, - scriptlets, and patches necessary to build the package from - source. Initially, the user submitting the package can select - its category (network, devel, etc) but that can be modified - later by the adopting TU. The script makes appropriate entries - into the database (and perhaps notifies interested users of the - new package). - +AUR Web Interface +============== Terms and Definitions: -====================== -AUR - Arch Linux User-Community Repository - Includes: - - the AUR web site, - - the [unsupported] 'repository' - - the [community] repository managed by the TUs +================ +AUR - Arch User Repository + Repository made up of a collection of build scripts that are + created and submitted by the Arch community. TU - Trusted User A user that can add binary packages to the [community] repository and administer AUR. [unsupported] - The collection of package build files hosted via the AUR web - site. + The collection of package build files hosted via the AUR website. +File Hierachy +========= + +Directory Layout: +------------------- +./html - DocumentRoot for AUR, where the PHP scripts live. +./html/css - CSS for AUR appearance +./html/css/navbar - CSS for Arch navigation bar appearance +./html/images - Any AUR images live here. +./lib - Supporting PHP include files. Access denied to Apache. +./locale +./template - Where most of the html markup resides and minimal + amount of PHP scripting. +./template/stats + +./html Files: +------------- +account.php - + PHP script to handle registering for a new account. It prompts + the visitor for account information: desired username, E-mail, + password, real name, IRC nick, and default language. The info is + recorded in the Users table. + + A logged-in user can change any of their own account information. If a + TU or Developer is logged into the system, they can search for and + edit accounts. A TU can change an account to a TU or User account. A + Developer can also change an account to the Developer type. TUs and + Developers are able to suspend accounts. If an account is suspended, + all packages are orphaned (the MaintainerUID field in the Packages + table is set to NULL). + +addvote.php - + A form to submit proposals relating to the AUR. Only accessible to TUs + and Developers. Can be used to vote on a potential new TU, or any + other proposal that needs a vote. Length of the vote can be specified. + +index.php - + Main page for the AUR. Provides links to all other pages in the AUR. + Gives a brief synopsis of what the AUR is and where to go for more + information. + +logout.php - + Logs out a logged-in user. Clears the session id from the Sessions + table and unsets the cookie. + +packages.php - + Page used to search the package database. Supports searching by name, + category, maintainer, popularity, etc. Also provides the ability to go + to a package page which has specific information for that package. + A specific package page includes the name, description, votes, etc. + As well as the ability to perform actions on the packages, such as + flagging or leaving a comment on the package. + +passreset.php - + A page for a user to enter their e-mail and receive a reset e-mail to + replace the forgotten password. + +pkgsubmit.php - + Page for users to upload a new package. Only allows upload of a + tarball that has been compressed with gzip. Tarball must contain the + PKGBUILD, scriptlets, and any other files necessary to build the + package from source. The user can select a category for the package. + The page makes appropriate entries into the database for tracking the + newly added source package and associated information. + +rpc.php - + A frontend for tools to obtain raw information from the AUR. Features + the ability to search for a package, return information on a package, + return information on multiple packages, and search for a specific + package maintainer. Functionality through HTTP GET. + +rss.php - + Generates RDF Site Summary (RSS) feed with the latest packages updated + in the AUR. Lists most recent 20 packages. Includes package name, link + to package page, package description, time of update, source listing, + maintainer name. + +tu.php - + Page only available to TUs and Developers. Shows ongoing votes for + proposals and past votes for proposals. Current votes can be voted on + with a "Yes" vote, "No" vote, or an "Abstain" vote. Developers and TUs + can only vote once. Cannot vote on a proposal about themselves. + +voters.php - + Page only available to TUs and Developers. Shows list of users that + voted for a specific package. Each username links to the user's + account information page. diff --git a/web/html/account.php b/web/html/account.php index 5a0ef50d..b0906d91 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -12,9 +12,8 @@ html_header(__('Accounts')); # Main page processing here # -echo "<div class=\"pgbox\">\n"; -echo " <div class=\"pgboxtitle\"><span class=\"f3\">".__("Accounts")."</span></div>\n"; -echo " <div class=\"pgboxbody\">\n"; +echo "<div class=\"box\">\n"; +echo " <h2>".__("Accounts")."</h2>\n"; $action = in_request("Action"); @@ -33,7 +32,8 @@ if (isset($_COOKIE["AURSID"])) { # search_results_page($atype, in_request("O"), in_request("SB"), in_request("U"), in_request("T"), in_request("S"), - in_request("E"), in_request("R"), in_request("I")); + in_request("E"), in_request("R"), in_request("I"), + in_request("K")); } else { # a non-privileged user is trying to access the search page @@ -44,17 +44,10 @@ if (isset($_COOKIE["AURSID"])) { } elseif ($action == "DisplayAccount") { # the user has clicked 'edit', display the account details in a form # - $q = "SELECT Users.*, AccountTypes.AccountType "; - $q.= "FROM Users, AccountTypes "; - $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; - $q.= "AND Users.ID = ".intval(in_request("ID")); - $result = db_query($q, $dbh); - if (!mysql_num_rows($result)) { + $row = account_details(in_request("ID"), in_request("U")); + if (empty($row)) { print __("Could not retrieve information for the specified user."); - } else { - $row = mysql_fetch_assoc($result); - # double check to make sure logged in user can edit this account # if ($atype == "User" || ($atype == "Trusted User" && $row["AccountType"] == "Developer")) { @@ -64,27 +57,20 @@ if (isset($_COOKIE["AURSID"])) { display_account_form($atype, "UpdateAccount", $row["Username"], $row["AccountType"], $row["Suspended"], $row["Email"], "", "", $row["RealName"], $row["LangPreference"], - $row["IRCNick"], $row["ID"]); + $row["IRCNick"], $row["PGPKey"], $row["ID"]); } } } elseif ($action == "AccountInfo") { # no editing, just looking up user info # - $q = "SELECT Users.*, AccountTypes.AccountType "; - $q.= "FROM Users, AccountTypes "; - $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; - $q.= "AND Users.ID = ".intval(in_request("ID")); - $result = db_query($q, $dbh); - if (!mysql_num_rows($result)) { + $row = account_details(in_request("ID"), in_request("U")); + if (empty($row)) { print __("Could not retrieve information for the specified user."); } else { - $row = mysql_fetch_assoc($result); - display_account_info($row["Username"], - $row["AccountType"], $row["Email"], $row["RealName"], - $row["IRCNick"]); + include("account_details.php"); } - + } elseif ($action == "UpdateAccount") { # user is submitting their modifications to an existing account # @@ -93,10 +79,8 @@ if (isset($_COOKIE["AURSID"])) { in_request("U"), in_request("T"), in_request("S"), in_request("E"), in_request("P"), in_request("C"), in_request("R"), in_request("L"), in_request("I"), - in_request("ID")); + in_request("K"), in_request("ID")); } - - } else { if ($atype == "Trusted User" || $atype == "Developer") { # display the search page if they're a TU/dev @@ -108,18 +92,10 @@ if (isset($_COOKIE["AURSID"])) { # A normal user, give them the ability to edit # their own account # - $q = "SELECT Users.*, AccountTypes.AccountType "; - $q.= "FROM Users, AccountTypes, Sessions "; - $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; - $q.= "AND Users.ID = Sessions.UsersID "; - $q.= "AND Sessions.SessionID = '"; - $q.= db_escape_string($_COOKIE["AURSID"])."'"; - $result = db_query($q, $dbh); - if (!mysql_num_rows($result)) { + $row = own_account_details($_COOKIE["AURSID"]); + if (empty($row)) { print __("Could not retrieve information for the specified user."); - } else { - $row = mysql_fetch_assoc($result); # don't need to check if they have permissions, this is a # normal user editing themselves. # @@ -129,7 +105,7 @@ if (isset($_COOKIE["AURSID"])) { display_account_form($atype, "UpdateAccount", $row["Username"], $row["AccountType"], $row["Suspended"], $row["Email"], "", "", $row["RealName"], $row["LangPreference"], - $row["IRCNick"], $row["ID"]); + $row["IRCNick"], $row["PGPKey"], $row["ID"]); } } } @@ -145,7 +121,7 @@ if (isset($_COOKIE["AURSID"])) { process_account_form("","new", "NewAccount", in_request("U"), 1, 0, in_request("E"), in_request("P"), in_request("C"), in_request("R"), - in_request("L"), in_request("I")); + in_request("L"), in_request("I"), in_request("K")); } else { # display the account request form @@ -155,7 +131,6 @@ if (isset($_COOKIE["AURSID"])) { } } -echo " </div>"; echo "</div>"; html_footer(AUR_VERSION); diff --git a/web/html/addvote.php b/web/html/addvote.php index a5ec4a1f..d3bd7d4b 100644 --- a/web/html/addvote.php +++ b/web/html/addvote.php @@ -5,16 +5,19 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); include_once("aur.inc.php"); set_lang(); check_sid(); -html_header(); + +$title = __("Add Proposal"); + +html_header($title); if (isset($_COOKIE["AURSID"])) { $atype = account_from_sid($_COOKIE["AURSID"]); + $uid = uid_from_sid($_COOKIE["AURSID"]); } else { $atype = ""; } -if ($atype == "Trusted User" OR $atype == "Developer") { - $dbh = db_connect(); +if ($atype == "Trusted User" || $atype == "Developer") { if (!empty($_POST['addVote']) && !check_token()) { $error = __("Invalid token for user action."); @@ -24,29 +27,11 @@ if ($atype == "Trusted User" OR $atype == "Developer") { $error = ""; if (!empty($_POST['user'])) { - $qcheck = "SELECT * FROM Users WHERE Username = '" . db_escape_string($_POST['user']) . "'"; - $result = db_query($qcheck, $dbh); - if ($result) { - $check = mysql_num_rows($result); - } - else { - $check = 0; - } - - if ($check == 0) { + if (!valid_user($_POST['user'])) { $error.= __("Username does not exist."); } else { - $qcheck = "SELECT * FROM TU_VoteInfo WHERE User = '" . db_escape_string($_POST['user']) . "'"; - $qcheck.= " AND End > UNIX_TIMESTAMP()"; - $result = db_query($qcheck, $dbh); - if ($result) { - $check = mysql_num_rows($result); - } - else { - $check = 0; - } - if ($check != 0) { + if (open_user_proposals($_POST['user'])) { $error.= __("%s already has proposal running for them.", htmlentities($_POST['user'])); } } @@ -70,13 +55,8 @@ if ($atype == "Trusted User" OR $atype == "Developer") { } if (!empty($_POST['addVote']) && empty($error)) { - $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, SubmitterID) VALUES "; - $q.= "('" . db_escape_string($_POST['agenda']) . "', "; - $q.= "'" . db_escape_string($_POST['user']) . "', "; - $q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . db_escape_string($len); - $q.= ", " . uid_from_sid($_COOKIE["AURSID"]) . ")"; + add_tu_proposal($_POST['agenda'], $_POST['user'], $len, $uid); - db_query($q, $dbh); print "<p class=\"pkgoutput\">" . __("New proposal submitted.") . "</p>\n"; } else { ?> @@ -85,29 +65,28 @@ if ($atype == "Trusted User" OR $atype == "Developer") { <p style="color: red;" class="pkgoutput"><?php print $error ?></p> <?php endif; ?> -<div class="pgbox"> -<div class="pgboxtitle"><?php print __("Submit a proposal to vote on.") ?></div> -<div class="pgboxbody"> -<form action='addvote.php' method='post'> -<p> -<b><?php print __('Applicant/TU') ?></b> -<input type='text' name='user' value='<?php if (!empty($_POST['user'])) { print htmlentities($_POST['user'], ENT_QUOTES); } ?>' /> -<?php print __("(empty if not applicable)") ?> -</p> -<p> -<b><?php print __('Length in days') ?></b> -<input type='text' name='length' value='<?php if (!empty($_POST['length'])) { print htmlentities($_POST['length'], ENT_QUOTES); } ?>' /> -<?php print __("(defaults to 7 if empty)") ?> -</p> -<p> -<b><?php print __('Proposal') ?></b><br /> -<textarea name='agenda' rows='25' cols='80'><?php if (!empty($_POST['agenda'])) { print htmlentities($_POST['agenda']); } ?></textarea><br /> -<input type='hidden' name='addVote' value='1' /> -<input type='hidden' name='token' value='<?php print htmlspecialchars($_COOKIE['AURSID']) ?>' /> -<input type='submit' class='button' value='<?php print __('Submit'); ?>' /> -</p> -</form> -</div> +<div class="box"> + <h2><?php print __("Submit a proposal to vote on.") ?></h2> + + <form action="addvote.php" method="post"> + <p> + <b><?php print __("Applicant/TU") ?></b> + <input type="text" name="user" value="<?php if (!empty($_POST['user'])) { print htmlentities($_POST['user'], ENT_QUOTES); } ?>" /> + <?php print __("(empty if not applicable)") ?> + </p> + <p> + <b><?php print __("Length in days") ?></b> + <input type="text" name="length" value="<?php if (!empty($_POST['length'])) { print htmlentities($_POST['length'], ENT_QUOTES); } ?>" /> + <?php print __("(defaults to 7 if empty)") ?> + </p> + <p> + <b><?php print __("Proposal") ?></b><br /> + <textarea name="agenda" rows="15" cols="80"><?php if (!empty($_POST['agenda'])) { print htmlentities($_POST['agenda']); } ?></textarea><br /> + <input type="hidden" name="addVote" value="1" /> + <input type="hidden" name="token" value="<?php print htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button" value="<?php print __("Submit"); ?>" /> + </p> + </form> </div> <?php } diff --git a/web/html/css/arch.css b/web/html/css/arch.css deleted file mode 100644 index eec02eec..00000000 --- a/web/html/css/arch.css +++ /dev/null @@ -1,424 +0,0 @@ -* { margin: 0; padding: 0; } -* ul { padding: 20px; } -body { - min-width: 600px; - background-color: white; - color: #555; - font-family: "DejaVu Sans", sans-serif; - font-size: 12px; -} -/* Divs */ -#title { - display: block; - position: relative; - height: 123px; -} -#main_nav, -#sub_nav { - list-style: none; - font-size: 13px; - line-height: 26px; - padding: 0 32px; -} -#main_nav { - background-color: #333; - text-align: right; -} -#sub_nav { - min-width: 700px; - background-color: #1793d1; - text-align: right; -} -#main_nav a.selected { - background-color: #1793d1; -} -#sub_nav a.selected { - background-color: #333; -} -#main_nav a, -#sub_nav a { - padding: 5px 9px; - line-height: 26px; - color: #fff; - font-weight: bold; - text-decoration: none; -} -#main_nav a:hover { - background-color: #1793d1; -} -#sub_nav a:hover { - background-color: #333; -} -#lang_sub { - display: block; - font-size: 10pt; - text-align: right; - margin-bottom: 40px; - margin-right: 35px; - margin-left: 35px; -} -#lang_sub ul { - list-style: none; - padding: 0px; -} -#lang_sub ul a { - text-decoration: none; -} -#lang_sub ul a:hover { - text-decoration: underline; -} -#lang_sub ul li { - display: inline; - padding-right: 1px; -} -#login_bar { - display: block; - margin-bottom: 10px; -} -#login_bar input { - margin-right: 5px; -} -#login_bar .button { - margin: 2px; -} -#updates { - font-size: small; - /*position: relative;*/ - top: 0px; - background-color: #e7f0f6; - border: 1px solid #92cbe8; - padding: 10px; -} -#logo { - z-index: 1; - position: relative; - top: 10px; - left: 25px; - width: 350px; -} -#logo h1#archtitle { - background: transparent url("../images/titlelogo.png") no-repeat top left; - margin: 0px; - padding: 0px; -} -#logo h1#archtitle a { - color: transparent; - display: block; - width: 350px; - height: 103px; -} -.clear { - clear: both; - margin: 0px; - padding: 0px; -} -.right { - float: right; - width: 320px; - padding: 0px 10px 10px 0px; -} -.left { - padding: 10px; - margin-right: 360px; -} -.left p { - padding-bottom: 10px; -} -.box { - padding: 10px; -} -.greybox { - padding: 10px; - background-color: #f6f3dd; - border: 1px solid #d9d6c2; -} -div.listing { - padding-right: 10px; -} -.error { - color: #dd0000; - font-size: small; -} -.foot { - clear: both; - text-align: center; - font-size: 0.75em; -} -#search { - float: right; - position: relative; - top: -2em; - font-size: 0.8em; -} -#search input { - background-color: #f6f3dd; - border: 1px solid #d9d6c2; -} -.smalltext { - text-align: right; - font-size: x-small; -} -/* Headers */ -h2 { - margin: 20px 0px 10px 0px; -} -h2.title { - border-bottom: 1px solid #46494d; -} -h3 { - margin-bottom: 10px; -} -h3.title { - text-align: right; - border-bottom: 1px solid #46494d; -} -h4.title { - border-bottom: 1px solid #46494d; -} -h4.news { - border-bottom: 1px dotted #0771a6; - margin-bottom: .25em; - padding-bottom: .2em; -} -div.listing h4 { - color: #fff; - background-color: #0771a6; - padding: 3px; -} -/* Paragraphs, Anchors, Images */ -p { - padding-bottom: 20px; -} -p.news { - font-size: small; -} -a { - color: #0771a6; -} -a:hover { - color: #333; -} -#about { - position: relative; - top: -9px; -} -ol { - padding-left: 45px; -} -ul.small { - list-style: none; - font-size: x-small; -} -ul.links { - list-style: none; - font-size: small; - padding: 0px 0px 20px 20px; -} -img { - border: none; -} -hr { - border: none; - border-top: 1px solid #46494d; -} -.greybox input, -button, -textarea, -select { - background-color: #e1e3e6; - border: 1px solid #8faecd; -} -.box input, button { - padding: 2px; - background-color: #c1c3f6; - font-size: x-small; - border: 1px solid #8faecd; -} -button#f_trigger { - background-color: #e1e3e6; -} -/* Table stuff */ -table.center { - margin-left: auto; - margin-right: auto; -} -table.results { - padding: 0px; - border-collapse: collapse; -} -.results th { - background-color: #e1e3e6; - border-bottom: 1px solid #46494d; - border-top: 1px solid #46494d; - padding: 0px 5px 0px 0px; -} -.results th>a { - text-decoration: none; - color: #46494d; -} -.results td { - padding-right: 5px; - vertical-align: top; - font-size: 0.8em; -} -.listing th { - font-size: small; - vertical-align: top; - padding: 2px; -} -.listing td { - font-size: small; - padding: 2px; -} -blockquote.code { - background-color: #f3f3f3; - border: 1px solid #ccc; - margin-left: auto; - margin-right: auto; - white-space: nowrap; - padding: 5px; - font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Courier, "Courier New", Monospace; - color: #333; - font-size: .95em; -} -.pkg_search_results_footer { - overflow: auto; -} -.pkg_search_results_footer .legend_and_actions { - float: left; -} -.pkg_search_results_footer .legend { - margin-bottom: 3px; -} -.pkg_search_results_footer .page_links { - float: right; - margin: 0 0; - padding: 0 0; -} - - -/* AUR Styles */ -.pgbox { - margin: 0 25px; - margin-bottom: 1%; - background-color: #fff; - border: 2px solid #ddd; - padding: 3px; -} -.frontpgboxbody { - padding: 10px; -} -.frontpgboxbody > table { - width: 100%; -} -.pgboxtitle { - border: 2px solid #ddd; - border-top: 1px solid #fff; - border-left: 1px solid #fff; - background-color: #f1f2f4; - padding: 2px 10px 2px 10px; -} -.pgboxbody, -.pgboxbody-comment { - padding: 10px; -} -.pgboxbody input { - margin-right: 10px; -} -.pgboxbody-comment > table { - border-collapse: separate; - border-spacing: 0px 15px; -} - -#advanced-search li { - font-size: 11px; - list-style: none; - display: inline; - padding-right: 15px; - text-decoration: none; -} - -.page_nav { - margin: 5px 0; -} -.page_nav .page_num { - border: 1px solid #ddd; - padding: 2px; - color: #0771a6; -} -.page_nav .page_num:hover { - border: 1px solid #8faecd; - color: #333; -} -.page_nav .page_sel { - border: 1px solid #8faecd; - padding: 2px; - color: #333; - font-weight: bold; -} - -.comment-header { - background-color: #f1f2f4; - color: #888; - font-size: 14px; - font-weight: bold; - margin-left: 5px; - margin-top: 5px; - padding: 2px; -} - -.comment-body { - margin-left: 5px; - padding: 2px; - font-family: monospace; -} - -.pkgoutput { - margin: 0 25px; - font-size: 18px; - font-weight: bold; -} - -div.version { - font-weight:bold; - font-size:14px; - text-align:right; -} - - - - -/** - * - * =============== Language-specific declarations ====================== - * - * (e.g. right-to-left texts for Hebrew) - * - * */ - - -/** - * RIGHT - TO - LEFT - * - * Too add a language, just add it's language code to all - * :lang()-pseudo-classes, delimited by a hyphen ("-"). - * */ - -body:lang(he) { - direction: rtl; -} -th:lang(he) { - text-align: right; -} -#lang_sub:lang(he) { - text-align: left; -} -.pkg_search_results_footer:lang(he) .legend_and_actions { - float: right; -} -.pkg_search_results_footer:lang(he) .page_links { - float: left; -} -div.version:lang(he) { - text-align: left; -} diff --git a/web/html/css/archweb.css b/web/html/css/archweb.css new file mode 100644 index 00000000..cafae777 --- /dev/null +++ b/web/html/css/archweb.css @@ -0,0 +1,1052 @@ +/* + * ARCH LINUX DJANGO (MAIN SITE) + * + * Font sizing based on 16px browser defaults (use em): + * 14px = 0.875em + * 13px = 0.812em + * 12px = 0.75em + * 11px = 0.6875em + * + */ + +/* import the global navbar stylesheet */ +@import url('archnavbar/archnavbar.css'); + +/* simple reset */ +* { + margin: 0; + padding: 0; + line-height: 1.4; +} + +/* general styling */ +body { + min-width: 650px; + background: #f6f9fc; + color: #222; + font: normal 100% sans-serif; + text-align: center; +} + +p { + margin: .33em 0 1em; +} + +ol, +ul { + margin-bottom: 1em; + padding-left: 2em; +} + + ul { + list-style: square; + } + +code { + font: 1.2em monospace; + background: #ffd; + padding: 0.15em 0.25em; +} + +pre { + font: 1.2em monospace; + border: 1px solid #bdb; + background: #dfd; + padding: 0.5em; + margin: 1em; +} + + pre code { + display: block; + background: none; + } + +blockquote { + margin: 1.5em 2em; +} + +input { + vertical-align: middle; +} + +select[multiple] { + padding: 1px 0; +} + + select[multiple] option { + padding: 0 0.5em 0 0.3em; + } + +input[type=submit] { + padding: 0 0.6em; +} + +.clear { + clear: both; +} + +.hide { + display: none; +} + +hr { + border: none; + border-top: 1px solid #888; +} + +img { + border: 0; +} + +/* scale fonts down to a sane default (16 * .812 = 13px) */ +#content { + font-size: 0.812em; +} + +/* link style */ +a { + text-decoration: none; +} + + a:link, + th a:visited { + color: #07b; + } + + a:visited { + color: #666; + } + + a:hover { + text-decoration: underline; + color: #666; + } + + a:active { + color: #e90; + } + +/* special anchor elements */ +a.headerlink { + visibility: hidden; + padding-left: 0.5em; +} + +h3:hover > a.headerlink { + visibility: visible; +} + +/* headings */ +h2 { + font-size: 1.5em; + margin-bottom: 0.5em; + border-bottom: 1px solid #888; +} + +h3 { + font-size: 1.25em; + margin-top: .5em; +} + +h4 { + font-size: 1.15em; + margin-top: 1em; +} + +h5 { + font-size: 1em; + margin-top: 1em; +} + +/* general layout */ +div#content { + width: 95%; + margin: 0 auto; + text-align: left; +} + +div#content-left-wrapper { + float: left; + width: 100%; /* req to keep content above sidebar in source code */ +} + +div#content-left { + margin: 0 340px 0 0; +} + +div#content-right { + float: left; + width: 300px; + margin-left: -300px; +} + +div.box { + margin-bottom: 1.5em; + padding: 0.65em; + background: #ecf2f5; + border: 1px solid #bcd; +} + +div#footer { + clear: both; + margin: 2em 0 1em; +} + + div#footer p { + margin: 0; + text-align: center; + font-size: 0.85em; + } + +/* alignment */ +div.center, +table.center, +img.center { + width: auto; + margin-left: auto; + margin-right: auto; +} + +p.center, +td.center, +th.center { + text-align: center; +} + +/* table generics */ +table { + width: 100%; + border-collapse: collapse; +} + + table .wrap { + white-space: normal; + } + +th, +td { + white-space: nowrap; + text-align: left; +} + + th { + vertical-align: middle; + font-weight: bold; + } + + td { + vertical-align: top; + } + +/* table pretty styles */ +table.pretty1 { + width: auto; + margin-top: 0.25em; + margin-bottom: 0.5em; + border-collapse: collapse; + border: 1px solid #bcd; +} + + table.pretty1 th { + padding: 0.35em; + background: #e4eeff; + border: 1px solid #bcd; + } + + table.pretty1 td { + padding: 0.35em; + border: 1px dotted #bcd; + } + +table.pretty2 { + width: auto; + margin-top: 0.25em; + margin-bottom: 0.5em; + border-collapse: collapse; + border: 1px solid #bbb; +} + + table.pretty2 th { + padding: 0.35em; + background: #eee; + border: 1px solid #bbb; + } + + /* additional styles for JS sorting */ + table.pretty2 th.header { + padding-right: 20px; + background-image: url(nosort.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; + } + + table.pretty2 th.headerSortDown { + background-image: url(desc.gif); + } + + table.pretty2 th.headerSortUp { + background-image: url(asc.gif); + } + + table.pretty2 td { + padding: 0.35em; + border: 1px dotted #bbb; + } + +/* definition lists */ +dl { + clear: both; +} + + dl dt, + dl dd { + margin-bottom: 4px; + padding: 8px 0px 4px; + font-weight: bold; + border-top: 1px dotted #bbb; + } + + dl dt { + color: #333; + float:left; + padding-right:15px; + } + +/* forms and input styling */ +form p { + margin: 0.5em 0; +} + +fieldset { + border: 0; +} + +label { + width: 12em; + vertical-align: top; + display: inline-block; + font-weight: bold; +} + +input[type=text], +input[type=password], +textarea { + padding: 0.10em; +} + +form.general-form label, +form.general-form .form-help { + width: 10em; + vertical-align: top; + display: inline-block; +} + +form.general-form input[type=text], +form.general-form textarea { + width: 45%; +} + +/* archdev navbar */ +div#archdev-navbar { + margin: 1.5em 0; +} + + div#archdev-navbar ul { + list-style: none; + margin: -0.5em 0; + padding: 0; + } + + div#archdev-navbar li { + display: inline; + margin: 0; + padding: 0; + font-size: 0.9em; + } + + div#archdev-navbar li a { + padding: 0 0.5em; + color: #07b; + } + +/* error/info messages (x pkg is already flagged out-of-date, etc) */ +#sys-message { + width: 35em; + text-align: center; + margin: 1em auto; + padding: 0.5em; + background: #fff; + border: 1px solid #f00; +} + + #sys-message p { + margin: 0; + } + +ul.errorlist { + color: red; +} + +/** + * PAGE SPECIFIC STYLES + */ + +/* home: introduction */ +#intro p.readmore { + margin: -0.5em 0 0 0; + font-size: .9em; + text-align: right; +} + +/* home: news */ +#news { + margin-top: 1.5em; +} + + #news h3 { + float: left; + padding-bottom: .5em + } + + #news div { + margin-bottom: 1em; + } + + #news div p { + margin-bottom: 0.5em; + } + + #news .more { + font-weight: normal; + } + + #news .rss-icon { + float: right; + margin-top: 1em; + } + + #news h4 { + clear: both; + font-size: 1em; + margin-top: 1.5em; + border-bottom: 1px dotted #bbb; + } + + #news .timestamp { + float: right; + font-size: 0.85em; + margin: -1.8em 0.5em 0 0; + } + +/* home: arrowed headings */ +#news h3 a { + display: block; + background: #1794D1; + font-size: 15px; + padding: 2px 10px; + color: white; +} + + #news a:active { + color: white; + } + +h3 span.arrow { + display: block; + width: 0px; + height: 0px; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid #1794D1; + margin: 0 auto; + font-size: 0px; + line-height: 0px; +} + +/* home: pkgsearch box */ +#pkgsearch { + padding: 1em 0.75em; + background: #3ad; + color: #fff; + border: 1px solid #08b; +} + + #pkgsearch label { + width: auto; + padding: 0.1em 0; + } + + #pkgsearch input { + width: 10em; + float: right; + font-size: 1em; + color: #000; + background: #fff; + border: 1px solid #09c; + } + +/* home: recent pkg updates */ +#pkg-updates h3 { + margin: 0 0 0.3em; +} + + #pkg-updates .more { + font-weight: normal; + } + + #pkg-updates .rss-icon { + float: right; + margin: -2em 0 0 0; + } + + #pkg-updates table { + margin: 0; + } + + #pkg-updates td.pkg-name { + white-space: normal; + } + + #pkg-updates td.pkg-arch { + text-align: right; + } + + #pkg-updates span.testing { + font-style: italic; + } + + #pkg-updates span.staging { + font-style: italic; + color: #ff8040; + } + +/* home: sidebar navigation */ +div#nav-sidebar ul { + list-style: none; + margin: 0.5em 0 0.5em 1em; + padding: 0; +} + +/* home: sponsor banners */ +div#arch-sponsors img { + padding: 0.3em 0; +} + +/* home: sidebar components (navlist, sponsors, pkgsearch, etc) */ +div.widget { + margin-bottom: 1.5em; +} + +/* feeds page */ +#rss-feeds .rss { + padding-right: 20px; + background: url(rss.png) top right no-repeat; +} + +/* artwork: logo images */ +#artwork img.inverted { + background: #333; + padding: 0; +} + +#artwork div.imagelist img { + display: inline; + margin: 0.75em; +} + +/* news: article list */ +.news-nav { + float: right; + margin-top: -2.2em; +} + + .news-nav .prev, + .news-nav .next { + margin: 0 1em; + } + +/* news: article pages */ +div.news-article .article-info { + margin: 0; + color: #999; +} + +/* news: add/edit article */ +form#newsform { + width: 60em; +} + + form#newsform input[type=text], + form#newsform textarea { + width: 75%; + } + +/* donate: donor list */ +div#donor-list ul { + width: 100%; +} + /* max 4 columns, but possibly fewer if screen size doesn't allow for more */ + div#donor-list li { + float: left; + width: 25%; + min-width: 20em; + } + +/* download page */ +#arch-downloads h3 { + border-bottom: 1px dotted #bbb; +} + +table#download-torrents .cpu-arch { + text-align: center; +} + +/* pkglists/devlists */ +table.results { + font-size: 0.846em; + border-top: 1px dotted #999; + border-bottom: 1px dotted #999; +} + + table.results th { + padding: 0.5em 1em 0.25em 0.25em; + border-bottom: 1px solid #999; + white-space: nowrap; + background-color:#fff; + } + + /* additional styles for JS sorting */ + table.results th.header { + padding-right: 20px; + background-image: url(nosort.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; + } + + table.results th.headerSortDown { + background-color: #e4eeff; + background-image: url(desc.gif); + } + + table.results th.headerSortUp { + background-color: #e4eeff; + background-image: url(asc.gif); + } + + table.results td { + padding: .3em 1em .3em 3px; + } + + table.results tr.odd { + background: #fff; + } + + table.results tr.even { + background: #e4eeff; + } + + table.results .flagged { + color: red; + } + +/* pkglist: layout */ +div#pkglist-about { + margin-top: 1.5em; +} + +/* pkglist: results navigation */ +.pkglist-stats { + font-size: 0.85em; +} + +#pkglist-results .pkglist-nav { + float: right; + margin-top: -2.2em; +} + +.pkglist-nav .prev { + margin-right: 1em; +} + +.pkglist-nav .next { + margin-right: 1em; +} + +/* search fields and other filter selections */ +.filter-criteria { + margin-bottom: 1em; +} + +.filter-criteria h3 { + font-size: 1em; + margin-top: 0; +} + +.filter-criteria div { + float: left; + margin-right: 1.65em; + font-size: 0.85em; +} + +.filter-criteria legend { + display: none; +} + +.filter-criteria label { + width: auto; + display: block; + font-weight: normal; +} + +/* pkgdetails: details links that float on the right */ +#pkgdetails #detailslinks { + float: right; +} + + #pkgdetails #detailslinks h4 { + margin-top: 0; + margin-bottom: 0.25em; + } + + #pkgdetails #detailslinks ul { + list-style: none; + padding: 0; + margin-bottom: 0; + font-size: 0.846em; + } + + #pkgdetails #detailslinks > div { + padding: 0.5em; + margin-bottom: 1em; + background: #eee; + border: 1px solid #bbb; + } + +#pkgdetails #actionlist .flagged { + color: red; + font-size: 0.9em; + font-style: italic; +} + +/* pkgdetails: pkg info */ +#pkgdetails #pkginfo { + width: auto; +} + + #pkgdetails #pkginfo td { + padding: 0.25em 0 0.25em 1.5em; + } + + #pkgdetails #pkginfo .userdata { + font-size: 0.85em; + padding: 0.5em; + } + +/* pkgdetails: flag package */ +form#flag-pkg-form label { + width: 10em; +} + +form#flag-pkg-form textarea, +form#flag-pkg-form input[type=text] { + width: 45%; +} + +/* pkgdetails: deps, required by and file lists */ +#pkgdetails #metadata { + clear: both; +} + +#pkgdetails #metadata h3 { + background: #555; + color: #fff; + font-size: 1em; + margin-bottom: 0.5em; + padding: 0.2em 0.35em; +} + +#pkgdetails #metadata ul { + list-style: none; + margin: 0; + padding: 0; +} + +#pkgdetails #metadata li { + padding-left: 0.5em; +} + +#pkgdetails #metadata p { + padding-left: 0.5em; +} + +#pkgdetails #metadata .message { + font-style: italic; +} + +#pkgdetails #metadata br { + clear: both; +} + +#pkgdetails #pkgdeps { + float: left; + width: 48%; + margin-right: 2%; +} + +#pkgdetails #metadata .virtual-dep, +#pkgdetails #metadata .testing-dep, +#pkgdetails #metadata .opt-dep, +#pkgdetails #metadata .dep-desc { + font-style: italic; +} +#pkgdetails #pkgreqs { + float: left; + width: 50%; +} + +#pkgdetails #pkgfiles { + clear: left; + padding-top: 1em; +} + + #pkgdetails #pkgfiles li.d { + color: #666; + } + + #pkgdetails #pkgfiles li.f { + } + +/* mirror stuff */ +table td.country { + white-space: normal; +} + +form#list-generator div ul { + list-style: none; + display: inline; + padding-left: 0; +} + + form#list-generator div ul li { + display: inline; + } + +/* dev/TU biographies */ +div#arch-bio-toc { + width: 75%; + margin: 0 auto; + text-align: center; +} + + div#arch-bio-toc a { + white-space: nowrap; + } + +table.arch-bio-entry { + width: 75%; + min-width: 640px; + margin: 0 auto; +} + + table.arch-bio-entry td.pic { + vertical-align: top; + padding-right: 15px; + padding-top: 2.25em; + } + + table.arch-bio-entry td.pic img { + padding: 4px; + border: 1px solid #ccc; + } + + table.arch-bio-entry td h3 { + border-bottom: 1px dotted #ccc; + margin-bottom: 0.5em; + } + + table.arch-bio-entry table.bio { + margin-bottom: 2em; + } + + table.arch-bio-entry table.bio th { + color: #666; + font-weight: normal; + text-align: right; + padding-right: 0.5em; + vertical-align: top; + white-space: nowrap; + } + + table.arch-bio-entry table.bio td { + width: 100%; + padding-bottom: 0.25em; + } + +/* dev: login/out */ +table#dev-login { + width: auto; +} + +/* dev dashboard: flagged packages */ +form#dash-pkg-notify { + text-align: right; + padding: 1em 0 0; + margin-top: 1em; + font-size: 0.85em; + border-top: 1px dotted #bbb; +} + + form#dash-pkg-notify label { + width: auto; + font-weight: normal; + } + + form#dash-pkg-notify input { + vertical-align: middle; + margin: 0 0.25em; + } + + form#dash-pkg-notify input[type=submit] { + margin-top: -0.25em; + } + + form#dash-pkg-notify p { + margin: 0; + } + +table.dash-stats .key { + width: 50%; +} + +/* dev dashboard: admin actions (add news items, todo list, etc) */ +ul.admin-actions { + float: right; + list-style: none; + margin-top: -2.5em; +} + + ul.admin-actions li { + display: inline; + padding-left: 1.5em; + } + +/* todo lists (public and private) */ +.todo-table .complete { + color: green; +} + +.todo-table .incomplete { + color: red; +} +.todo-info { + margin: 0; color: #999; +} + +.todo-list h4 { + margin-top: 0; + margin-bottom: 0.4em; +} + +/* dev: signoff page */ +#dev-signoffs tr:hover { + background: #ffd; +} + +ul.signoff-list { + list-style: none; + margin: 0; + padding: 0; +} + +.signoff-yes { + color: green; + font-weight: bold; +} + +.signoff-no { + color: red; +} + +.signoff-bad { + color: darkorange; +} + +.signoff-disabled { + color: gray; +} + +/* iso testing feedback form */ +#releng-feedback label { + width: auto; + display: inline; + font-weight: normal; +} + +#releng-feedback ul { + padding-left: 1em; +} + +#releng-feedback li { + list-style: none; +} + +#releng-feedback ul+.helptext { + position: relative; top: -0.9em; +} + +#releng-result .success-yes { + color: green; +} + +#releng-result .success-no { + color: red; +} + +#key-status .signed-yes { + color: green; +} + +#key-status .signed-no { + color: red; +} + +/* highlight current website in the navbar */ +#archnavbar.anb-home ul li#anb-home a, +#archnavbar.anb-packages ul li#anb-packages a, +#archnavbar.anb-download ul li#anb-download a { + color: white !important; +} + +/* visualizations page */ +.visualize-buttons { + margin: 0.5em 0.33em; +} + + .visualize-buttons button.active { + depressed: true; + } + +.visualize-chart { + position: relative; + height: 500px; + margin: 0.33em; +} + +#visualize-archrepo .treemap-cell { + border: solid 1px white; + overflow: hidden; + position: absolute; +} + + #visualize-archrepo .treemap-cell span { + padding: 3px; + font-size: 0.85em; + line-height: 1em; + } + +#visualize-keys svg { + width: 100%; + height: 100%; +} diff --git a/web/html/css/aur.css b/web/html/css/aur.css new file mode 100644 index 00000000..741446e4 --- /dev/null +++ b/web/html/css/aur.css @@ -0,0 +1,4 @@ +/* AUR-specific customizations to "archweb.css". */ +#lang_sub { + float: right; +} diff --git a/web/html/css/containers.css b/web/html/css/containers.css deleted file mode 100644 index 237950f5..00000000 --- a/web/html/css/containers.css +++ /dev/null @@ -1,188 +0,0 @@ -body,table,td,img { - border: none; - margin: 0; - padding: 0; -} -/* Main Wrapper Data Format */ -td.preHeader { - background-color: #000; - border-bottom: 1px solid #455471; - height: 16px; - text-align: right; -} -td.headerFill { - background-color: #6c83b0; - border-bottom: 1px solid #000; -} -td.headerDisplay { - background-color: #6c83b0; - padding-left: 16px; -} -td.mainLinks { - background-color: #eee; - border-bottom: 1px solid #000; - height: 22px; - padding-left: 12px; -} -td.sideBar { - background-color: #fff; - text-align: center; - vertical-align: top; - width: 150px; -} -td.sideBarGrey { - background-color: #eee; - border-bottom: 1px solid #000; - vertical-align: top; - width: 150px; -} -td.sideBarSmall { - background-color: #6c83b0; - border-bottom: 1px solid #000; - height: 16px; - text-align: right; - width: 150px; -} -td.sideBarSmallHeader { - background-color: #6c83b0; - vertical-align: top; - height: 16px; - padding-top: 1px; - padding-bottom: 2px; - text-align: right; - width: 150px; -} -td.subLinks { - background-color: #ffe4e8; - border-right: 1px solid #000; - color: #787878; - padding-left: 12px; - height: 19px; -} -td.contentDisplay { - background-color: #fff; - border: 1px solid #000; - border-top: none; - text-align: center; - vertical-align: top; - padding: 10px; -} -td.footerDisplay { - background-color: #eee; - border-bottom: 1px solid #000; - text-align: center; -} -/* Containers Used Globally */ -table.boxSoft { - width: 90%; - background-color: #ddd; -} -td.boxSoft { - background-color: #fff; - padding: 2px; -} -td.boxSoftColumn { - padding-left: 16px; - padding-right: 16px; - text-align: justify; - vertical-align: top; - text-indent: 20px; -} -td.div { - background-color: #eee; - width: 3px; -} -.boxSoftTitle { - border-bottom: 1px solid #fff; - border-top: 1px solid #fff; - background-color: #f1f2f4; - padding: 1px 0 0 3px; -} -table.boxSoftSmall { - width: 94px; - background-color: #ddd; -} -td.boxSoftSmall { - background-color: #fff; - text-align: center; - padding-top: 2px; - padding-bottom: 2px; -} -td.boxSoftSmallTitle { - border-bottom: 1px solid #ccc; - background-color: #f1f2f4; - padding-left: 10px; -} -/* ss = small space */ -td.ss { - padding-left: 6px; - vertical-align: top; -} -td.display { - border-bottom: 1px solid #000; - padding-bottom: 6px; -} -td.features { - padding: 4px; - text-align: justify; - vertical-align:top; -} -td.formLeft { - padding: 6px; - vertical-align: top; -} -td.data1 { - background-color: #eee; - vertical-align: top; - padding-left: .3em; -} -td.data2 { - background-color: #ddd; - vertical-align: top; - padding-left: .3em; -} -.outofdate { - background-color: #faa; - padding-left: .3em; -} -.legend span { - padding: 1px; - margin-left: .3em; - border: solid 1px #888; -} -td.text { - color: #000; - font-size: 12px; -} -th { - text-align: left; -} -th.header { - border-bottom: #666 1px solid; - vertical-align: bottom; -} -fieldset { - border: none; -} -input, -textarea, -select { - background-color: #6c83b0; - font-family: monospace; - font-size: 12px; - background-color: #ccc; - border: #000 1px solid; - color: #111; -} -input.button { - background-color: #fff; - color: #6c83b0; - border: 1px solid #6c83b0; - font-size: 12px; - padding: 2px 8px; -} -input[type=image] { - border: 0; - background: none; -} - diff --git a/web/html/css/fonts.css b/web/html/css/fonts.css deleted file mode 100644 index 9dea9354..00000000 --- a/web/html/css/fonts.css +++ /dev/null @@ -1,115 +0,0 @@ -/* Standard Fonts */ -span /* Applicable by default in all fonts */ -{ - color: #555; - font-family: Bitstream Vera Sans, Lucida Grande, Arial, sans-serif; -} -span.f1 /* Important */ -{ - font-size: 20px; - letter-spacing: 1px; -} -span.f2 /* Title */ -{ - font-size: 14px; - color: #6c83b0; - font-weight: bold; -} -span.f3 /* Sub Title */ -{ - color: #888; - font-size: 14px; - font-weight: bold; - padding-right: 2px; -} -span.f4 /* Content Text */ -{ - color: #444; - font-size: 12px; -} -span.f5 /* Content Small */ -{ - color: #333; - font-size: 11px; -} -span.f6 /* Red Message */ -{ - color: #b06d6e; - font-size: 14px; - font-weight: bold; -} -span.f7 /* Green Message */ -{ - color: #6db06d; - font-size: 14px; - font-weight: bold; -} -span.f8 /* Internal Sources in Package Details */ -{ - color: #888; - font-size: 12px; - font-weight: bold; -} -span.fix /* Monospace fixed-font */ -{ - color: #000; - font-family: monospace, fixed, terminal; - font-size: 12px; -} -span.error /* Content Text */ -{ - color: #900; - font-size: 12px; -} -span.warning /* Content Text */ -{ - color: #c0c000; - font-size: 12px; -} -/* Font Attribute Change (#6c83b0)*/ -.blue { color: #6c83b0; } -.white { color: #fff; } -.black { color: #000; } -.green { color: #6db06d; } -/* Better contrast on out-of-date rows (FS#20514) */ -.outofdate .blue { color: #444; } -.link -{ - color: #6c83b0; - font-weight: bold; -} -/* Misc (c9d1e2) */ -span.preHeader -{ - color: #c9d1e2; - font-weight: bold; - font-size: 11px; - padding-right: 8px; - word-spacing: 8px; -} -span.sideBarSmallHeader -{ - color: #fff; - font-weight: bold; - font-size: 11px; - padding-right: 8px; -} -a { - color: #0771a6; - text-decoration: none; - font-weight: bold; -} -a:hover { - color: #333; - text-decoration: none; - font-weight: bold; -} -h1, h2, h3, h4 { - font-size: 16pt; -} - -.important { - font-weight: bold; - color: #f00; -} - diff --git a/web/html/index.php b/web/html/index.php index ffc5f008..48f5e00a 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -10,75 +10,114 @@ include_once('stats.inc.php'); html_header( __("Home") ); -include('pkg_search_form.php'); - $dbh = db_connect(); ?> -<div class="pgbox"> -<div class="pgboxtitle"> -<span class="f3">AUR <?php print __("Home"); ?></span> +<div id="content-left-wrapper"> + <div id="content-left"> + <div id="intro" class="box"> + <h2>AUR <?php print __("Home"); ?></h2> + <p> + <?php + echo __( + 'Welcome to the AUR! Please read the %sAUR User Guidelines%s and %sAUR TU Guidelines%s for more information.', + '<a href="http://wiki.archlinux.org/index.php/AUR_User_Guidelines">', + '</a>', + '<a href="http://wiki.archlinux.org/index.php/AUR_Trusted_User_Guidelines">', + '</a>' + ); + ?> + </p> + <p> + <?php + echo __( + 'Contributed PKGBUILDs %smust%s conform to the %sArch Packaging Standards%s otherwise they will be deleted!', + '<b>', '</b>', + '<a href="http://wiki.archlinux.org/index.php/Arch_Packaging_Standards">', + '</a>' + ); + ?> + </p> + <p> + <?php echo __('Remember to vote for your favourite packages!'); ?> + <?php echo __('Some packages may be provided as binaries in [community].'); ?> + </p> + <p> + <h4><?php echo __('Discussion') ?></h4> + <?php + echo __( + 'General discussion regarding the Arch User Repository (AUR) and Trusted User structure takes place on %saur-general%s. This list can be used for package orphan requests, merge requests, and deletion requests. For discussion relating to the development of the AUR, use the %saur-dev%s mailing list.', + '<a href="http://mailman.archlinux.org/mailman/listinfo/aur-general">', + '</a>', + '<a href="http://mailman.archlinux.org/mailman/listinfo/aur-dev">', + '</a>' + ); + ?> + </p> + <h4><?php echo __('Bug Reporting') ?></h4> + <?php + echo __( + 'If you find a bug in the AUR, please fill out a bug report on our %sbug tracker%s. Use the tracker to report bugs in the AUR %sonly%s. To report packaging bugs contact the package maintainer or leave a comment on the appropriate package page.', + '<a href="https://bugs.archlinux.org/index.php?project=2">', + '</a>', + '<strong>', + '</strong>' + ); + ?> + </p> + + <div class="important"> + <b><?php echo __('DISCLAIMER') ?> :</b> + <br /> + <?php echo __('Unsupported packages are user produced content. Any use of the provided files is at your own risk.'); ?> + </div> + </div> + <?php if (!empty($_COOKIE["AURSID"])): ?> + <div id="pkg-updates" class="widget box"> + <table> + <tr> + <td class="pkg-name"> + <?php + $userid = uid_from_sid($_COOKIE["AURSID"]); + user_table($userid, $dbh); + ?> + </td> + </tr> + </table> + </div> + <?php endif; ?> + </div> </div> -<div class="frontpgboxbody"> -<p> - -<?php -echo __( - 'Welcome to the AUR! Please read the %hAUR User Guidelines%h and %hAUR TU Guidelines%h for more information.', - '<a href="http://wiki.archlinux.org/index.php/AUR_User_Guidelines">', - '</a>', - '<a href="http://wiki.archlinux.org/index.php/AUR_Trusted_User_Guidelines">', - '</a>' - ); -?> - -<br /> +<div id="content-right"> + <div id="pkgsearch" class="widget"> + <form id="pkgsearch-form" method="get" action="packages.php"> + <fieldset> + <label for="pkgsearch-field">Package Search:</label> + <input type="hidden" name="O" value="0" /> + <input type="text" name="K" size="30" value="<?php if (isset($_REQUEST["K"])) { print stripslashes(trim(htmlspecialchars($_REQUEST["K"], ENT_QUOTES))); } ?>" maxlength="35" /> + </fieldset> + </form> + </div> + <div id="pkg-updates" class="widget box"> + <table> + <tr> + <td class="pkg-name"> + <?php updates_table($dbh); ?> + </td> + </tr> + </table> + </div> + <div id="pkg-updates" class="widget box"> + <table> + <tr> + <td class="pkg-name"> + <?php general_stats_table($dbh); ?> + </td> + </tr> + </table> + </div> -<?php -echo __( - 'Contributed PKGBUILDs %hmust%h conform to the %hArch Packaging Standards%h otherwise they will be deleted!', - '<b>', '</b>', - '<a href="http://wiki.archlinux.org/index.php/Arch_Packaging_Standards">', - '</a>' - ); -?> - -</p> -<p> -<?php echo __('Remember to vote for your favourite packages!'); ?> -<br /> -<?php echo __('Some packages may be provided as binaries in [community].'); ?> -</p> -<table border='0' cellpadding='0' cellspacing='3' width='90%'> -<tr> -<td class='boxSoft' valign='top'> -<?php updates_table($dbh); ?> -</td> -<td class='boxSoft' valign='top'> -<?php -if (!empty($_COOKIE["AURSID"])) { - $user = username_from_sid($_COOKIE["AURSID"]); - user_table($user, $dbh); - echo '<br />'; -} - -general_stats_table($dbh); -?> - -</td> -</tr> -</table> - -<br /> -<div class="important"><?php -echo __('DISCLAIMER') . ':<br />'; -echo __('Unsupported packages are user produced content. Any use of the provided files is at your own risk.'); -?></div> - -</div> </div> - <?php html_footer(AUR_VERSION); - diff --git a/web/html/login.php b/web/html/login.php new file mode 100644 index 00000000..7f4f3420 --- /dev/null +++ b/web/html/login.php @@ -0,0 +1,55 @@ +<?php +set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); + +include_once("aur.inc.php"); +set_lang(); +check_sid(); + +if (!$DISABLE_HTTP_LOGIN || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])) { + $login = try_login(); + $login_error = $login['error']; +} + +html_header('AUR ' . __("Login")); +?> +<div id="dev-login" class="box"> + <h2>AUR <?php echo __('Login') ?></h2> + <?php if (isset($_COOKIE["AURSID"])): ?> + <p> + <?php echo __("Logged-in as: %s", '<strong>' . username_from_sid($_COOKIE["AURSID"]) . '</strong>'); ?> + <a href="logout.php">[<?php print __("Logout"); ?>]</a> + </p> + <?php elseif (!$DISABLE_HTTP_LOGIN || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])): ?> + <form method="post" action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES) ?>"> + <fieldset> + <legend><?php echo __('Enter login credentials') ?></legend> + <?php if (!empty($login_error)): ?> + <ul class="errorlist"><li><?php echo $login_error ?></li></ul> + <?php endif; ?> + <p> + <label for="id_username"><?php print __('Username') . ':'; ?></label> + <input id="id_username" type="text" name="user" size="30" maxlength="<?php print USERNAME_MAX_LEN; ?>" value="<?php if (isset($_POST['user'])) { print htmlspecialchars($_POST['user'], ENT_QUOTES); } ?>" /> + </p> + <p> + <label for="id_password"><?php print __('Password') . ':'; ?></label> + <input id="id_password" type="password" name="passwd" size="30" maxlength="<?php print PASSWD_MAX_LEN; ?>" /> + </p> + <p> + <input type="checkbox" name="remember_me" id="id_remember_me" /> + <label for="id_remember_me"><?php print __("Remember me"); ?></label> + </p> + <p> + <input type="submit" class="button" value="<?php print __("Login"); ?>" /> + <a href="passreset.php">[<?php echo __('Forgot Password') ?>]</a> + </p> + </fieldset> + </form> + <?php else: ?> + <p> + <?php printf(__("HTTP login is disabled. Please %sswitch to HTTPs%s if you want to login."), + '<a href="' . $AUR_LOCATION . htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES) . '">', '</a>'); ?> + </p> + <?php endif; ?> +</div> +<?php +html_footer(AUR_VERSION); diff --git a/web/html/logout.php b/web/html/logout.php index 45ab564e..fe8ffb01 100644 --- a/web/html/logout.php +++ b/web/html/logout.php @@ -10,16 +10,15 @@ include_once("acctfuncs.inc.php"); # access AUR common functions # sending any HTML output. # if (isset($_COOKIE["AURSID"])) { - $dbh = db_connect(); - $q = "DELETE FROM Sessions WHERE SessionID = '"; - $q.= db_escape_string($_COOKIE["AURSID"]) . "'"; - db_query($q, $dbh); + if (!$dbh) { + $dbh = db_connect(); + } + delete_session_id($_COOKIE["AURSID"], $dbh); # setting expiration to 1 means '1 second after midnight January 1, 1970' setcookie("AURSID", "", 1, "/", null, !empty($_SERVER['HTTPS']), true); unset($_COOKIE['AURSID']); + clear_expired_sessions($dbh); } -clear_expired_sessions(); - header('Location: index.php'); diff --git a/web/html/packages.php b/web/html/packages.php index 7f31d3d8..ec76e41a 100644 --- a/web/html/packages.php +++ b/web/html/packages.php @@ -10,6 +10,8 @@ check_sid(); # see if they're still logged in # Set the title to the current query if required if (isset($_GET['ID']) && ($pkgname = pkgname_from_id($_GET['ID']))) { $title = $pkgname; +} else if (isset($_GET['N'])) { + $title = $pkgname = $_GET['N']; } else if (!empty($_GET['K'])) { $title = __("Search Criteria") . ": " . $_GET['K']; } else { @@ -89,16 +91,24 @@ html_header($title); <?php if (isset($_GET['ID'])) { + $pkgid = intval($_GET['ID']); +} else if (isset($_GET['N'])) { + $pkgid = pkgid_from_name($_GET['N']); +} else { + unset($pkgid); +} + +if (isset($pkgid)) { include('pkg_search_form.php'); - if (!$_GET['ID'] = intval($_GET['ID'])) { - print __("Error trying to retrieve package details.")."<br />\n"; - } else { + if ($pkgid) { if (isset($_COOKIE["AURSID"])) { - package_details($_GET['ID'], $_COOKIE["AURSID"]); + package_details($pkgid, $_COOKIE["AURSID"]); } else { - package_details($_GET['ID'], null); + package_details($pkgid, null); } + } else { + print __("Error trying to retrieve package details.")."<br />\n"; } } else { if (!isset($_GET['K']) && !isset($_GET['SB'])) { diff --git a/web/html/passreset.php b/web/html/passreset.php index 97fbebb0..cb88e5ab 100644 --- a/web/html/passreset.php +++ b/web/html/passreset.php @@ -30,25 +30,10 @@ if (isset($_GET['resetkey'], $_POST['email'], $_POST['password'], $_POST['confir } if (empty($error)) { - $dbh = db_connect(); $salt = generate_salt(); $hash = salted_hash($password, $salt); - # The query below won't affect any records unless the ResetKey - # and Email combination is correct and ResetKey is nonempty - $q = "UPDATE Users - SET Passwd = '$hash', - Salt = '$salt', - ResetKey = '' - WHERE ResetKey != '' - AND ResetKey = '".db_escape_string($resetkey)."' - AND Email = '".db_escape_string($email)."'"; - $result = db_query($q, $dbh); - if (!mysql_affected_rows($dbh)) { - $error = __('Invalid e-mail and reset key combination.'); - } else { - header('Location: passreset.php?step=complete'); - exit(); - } + + $error = password_reset($hash, $salt, $resetkey, $email); } } elseif (isset($_POST['email'])) { $email = $_POST['email']; @@ -56,22 +41,18 @@ if (isset($_GET['resetkey'], $_POST['email'], $_POST['password'], $_POST['confir if ($uid != NULL && $uid != 'None') { # We (ab)use new_sid() to get a random 32 characters long string $resetkey = new_sid(); - $dbh = db_connect(); - $q = "UPDATE Users - SET ResetKey = '" . $resetkey . "' - WHERE ID = " . $uid; - db_query($q, $dbh); + create_resetkey($resetkey, $uid); # Send email with confirmation link $body = __('A password reset request was submitted for the account '. 'associated with your e-mail address. If you wish to reset '. 'your password follow the link below, otherwise ignore '. 'this message and nothing will happen.'). "\n\n". - 'https://aur.archlinux.org/passreset.php?'. + "{$AUR_LOCATION}/passreset.php?". "resetkey={$resetkey}"; $body = wordwrap($body, 70); - $headers = "To: {$email}\nReply-to: nobody@archlinux.org\nFrom:aur-notify@archlinux.org\nX-Mailer: PHP\nX-MimeOLE: Produced By AUR"; - @mail(' ', 'AUR Password Reset', $body, $headers); + $headers = "Reply-to: nobody@archlinux.org\nFrom:aur-notify@archlinux.org\nX-Mailer: PHP\nX-MimeOLE: Produced By AUR"; + @mail($email, 'AUR Password Reset', $body, $headers); } header('Location: passreset.php?step=confirm'); @@ -84,54 +65,49 @@ html_header(__("Password Reset")); ?> -<div class="pgbox"> - <div class="pgboxtitle"> - <span class="f3"><?php print __("Password Reset"); ?></span> - </div> - <div class="pgboxbody"> - <?php - if ($error) { - echo '<p><span class="error">'.$error.'</span></p>'; - } - ?> - <?php - if ($step == 'confirm') { - echo __('Check your e-mail for the confirmation link.'); - } elseif ($step == 'complete') { - echo __('Your password has been reset successfully.'); - } elseif (isset($_GET['resetkey'])) { - ?> - <form action="" method="post"> - <table> - <tr> - <td><?php echo __("Confirm your e-mail address:"); ?></td> - <td><input type="text" name="email" size="30" maxlength="64" /></td> - </tr> - <tr> - <td><?php echo __("Enter your new password:"); ?></td> - <td><input type="password" name="password" size="30" maxlength="32" /></td> - </tr> - <tr> - <td><?php echo __("Confirm your new password:"); ?></td> - <td><input type="password" name="confirm" size="30" maxlength="32" /></td> - </tr> - </table> - <br /> - <input type="submit" class="button" value="<?php echo __('Continue') ?>" /> - </form> - <?php - } else { - ?> - <p><?php echo __('If you have forgotten the e-mail address you used to register, please send a message to the %haur-general%h mailing list.', - '<a href="http://mailman.archlinux.org/mailman/listinfo/aur-general">', - '</a>'); ?></p> - <form action="" method="post"> - <p><?php echo __("Enter your e-mail address:"); ?> - <input type="text" name="email" size="30" maxlength="64" /></p> - <input type="submit" class="button" value="<?php echo __('Continue') ?>" /> - </form> - <?php } ?> - </div> +<div class="box"> + <h2><?php print __("Password Reset"); ?></h2> + + <?php if ($error): ?> + <p><span class="error"><?php echo $error ?></span></p> + <?php endif;?> + <?php + if ($step == 'confirm') { + echo __('Check your e-mail for the confirmation link.'); + } elseif ($step == 'complete') { + echo __('Your password has been reset successfully.'); + } elseif (isset($_GET['resetkey'])) { + ?> + <form action="" method="post"> + <table> + <tr> + <td><?php echo __("Confirm your e-mail address:"); ?></td> + <td><input type="text" name="email" size="30" maxlength="64" /></td> + </tr> + <tr> + <td><?php echo __("Enter your new password:"); ?></td> + <td><input type="password" name="password" size="30" maxlength="32" /></td> + </tr> + <tr> + <td><?php echo __("Confirm your new password:"); ?></td> + <td><input type="password" name="confirm" size="30" maxlength="32" /></td> + </tr> + </table> + <br /> + <input type="submit" class="button" value="<?php echo __('Continue') ?>" /> + </form> + <?php + } else { + ?> + <p><?php echo __('If you have forgotten the e-mail address you used to register, please send a message to the %saur-general%s mailing list.', + '<a href="http://mailman.archlinux.org/mailman/listinfo/aur-general">', + '</a>'); ?></p> + <form action="" method="post"> + <p><?php echo __("Enter your e-mail address:"); ?> + <input type="text" name="email" size="30" maxlength="64" /></p> + <input type="submit" class="button" value="<?php echo __('Continue') ?>" /> + </form> + <?php } ?> </div> <?php diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index c566cb47..65e2f6db 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -33,10 +33,23 @@ if ($uid): } # Before processing, make sure we even have a file - if (!$error) { - if ($_FILES['pfile']['size'] == 0){ + switch($_FILES['pfile']['error']) { + case UPLOAD_ERR_INI_SIZE: + $maxsize = ini_get('upload_max_filesize'); + $error = __("Error - Uploaded file larger than maximum allowed size (%s)", $maxsize); + break; + case UPLOAD_ERR_PARTIAL: + $error = __("Error - File partially uploaded"); + break; + case UPLOAD_ERR_NO_FILE: $error = __("Error - No file uploaded"); - } + break; + case UPLOAD_ERR_NO_TMP_DIR: + $error = __("Error - Could not locate temporary upload folder"); + break; + case UPLOAD_ERR_CANT_WRITE: + $error = __("Error - File could not be written"); + break; } # Check whether the file is gzip'ed @@ -72,23 +85,25 @@ if ($uid): $pkgbuild_raw = ''; $dircount = 0; foreach ($tar->listContent() as $tar_file) { - if (preg_match('/^[^\/]+\/PKGBUILD$/', $tar_file['filename'])) { - $pkgbuild_raw = $tar->extractInString($tar_file['filename']); + if ($tar_file['typeflag'] == 0) { + if (strchr($tar_file['filename'], '/') === false) { + $error = __("Error - source tarball may not contain files outside a directory."); + break; + } + elseif (substr($tar_file['filename'], -9) == '/PKGBUILD') { + $pkgbuild_raw = $tar->extractInString($tar_file['filename']); + } } - elseif (preg_match('/^[^\/]+\/$/', $tar_file['filename'])) { - if (++$dircount > 1) { + elseif ($tar_file['typeflag'] == 5) { + if (substr_count($tar_file['filename'], "/") > 1) { + $error = __("Error - source tarball may not contain nested subdirectories."); + break; + } + elseif (++$dircount > 1) { $error = __("Error - source tarball may not contain more than one directory."); break; } } - elseif (preg_match('/^[^\/]+$/', $tar_file['filename'])) { - $error = __("Error - source tarball may not contain files outside a directory."); - break; - } - elseif (preg_match('/^[^\/]+\/[^\/]+\//', $tar_file['filename'])) { - $error = __("Error - source tarball may not contain nested subdirectories."); - break; - } } if (!$error && empty($pkgbuild_raw)) { @@ -280,7 +295,7 @@ if ($uid): $error = __( "Could not create directory %s.", $incoming_pkgdir); } } else { - $error = __( "You are not allowed to overwrite the %h%s%h package.", "<b>", $pkg_name, "</b>"); + $error = __( "You are not allowed to overwrite the %s%s%s package.", "<b>", $pkg_name, "</b>"); } if (!$error) { @@ -304,13 +319,10 @@ if ($uid): # Update the backend database if (!$error) { - $dbh = db_connect(); - db_query("BEGIN", $dbh); + begin_atomic_commit($dbh); - $q = "SELECT * FROM Packages WHERE Name = '" . db_escape_string($new_pkgbuild['pkgname']) . "'"; - $result = db_query($q, $dbh); - $pdata = mysql_fetch_assoc($result); + $pdata = pkgdetails_by_pkgname($new_pkgbuild['pkgname'], $dbh); if (isset($new_pkgbuild['epoch']) && (int)$new_pkgbuild['epoch'] > 0) { $pkg_version = sprintf('%d:%s-%s', $new_pkgbuild['epoch'], $new_pkgbuild['pkgver'], $new_pkgbuild['pkgrel']); @@ -337,46 +349,20 @@ if ($uid): $packageID = $pdata["ID"]; # Flush out old data that will be replaced with new data - $q = "DELETE FROM PackageDepends WHERE PackageID = " . $packageID; - db_query($q, $dbh); - $q = "DELETE FROM PackageSources WHERE PackageID = " . $packageID; - db_query($q, $dbh); + remove_pkg_deps($packageID, $dbh); + remove_pkg_sources($packageID, $dbh); # If a new category was chosen, change it to that if ($category_id > 1) { - $q = sprintf( "UPDATE Packages SET CategoryID = %d WHERE ID = %d", - $category_id, - $packageID); - - db_query($q, $dbh); + update_pkg_category($packageID, $category_id); } # Update package data - $q = sprintf("UPDATE Packages SET ModifiedTS = UNIX_TIMESTAMP(), Name = '%s', Version = '%s', License = '%s', Description = '%s', URL = '%s', OutOfDateTS = NULL, MaintainerUID = %d WHERE ID = %d", - db_escape_string($new_pkgbuild['pkgname']), - db_escape_string($pkg_version), - db_escape_string($new_pkgbuild['license']), - db_escape_string($new_pkgbuild['pkgdesc']), - db_escape_string($new_pkgbuild['url']), - $uid, - $packageID); - - db_query($q, $dbh); - + update_pkgdetails($packageID, $new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, "", $new_pkgbuild['pkgdesc'], $new_pkgbuild['url'], "", $uid, $dbh); } else { # This is a brand new package - $q = sprintf("INSERT INTO Packages (Name, License, Version, CategoryID, Description, URL, SubmittedTS, ModifiedTS, SubmitterUID, MaintainerUID) VALUES ('%s', '%s', '%s', %d, '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), %d, %d)", - db_escape_string($new_pkgbuild['pkgname']), - db_escape_string($new_pkgbuild['license']), - db_escape_string($pkg_version), - $category_id, - db_escape_string($new_pkgbuild['pkgdesc']), - db_escape_string($new_pkgbuild['url']), - $uid, - $uid); - - db_query($q, $dbh); - $packageID = mysql_insert_id($dbh); + new_pkgdetails($new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $category_id, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url'], $uid, $dbh); + $packageID = last_insert_id($dbh); } @@ -393,23 +379,15 @@ if ($uid): else if ($deppkgname == "#") { break; } - - $q = sprintf("INSERT INTO PackageDepends (PackageID, DepName, DepCondition) VALUES (%d, '%s', '%s')", - $packageID, - db_escape_string($deppkgname), - db_escape_string($depcondition)); - - db_query($q, $dbh); + add_pkg_dep($packageID, $deppkgname, $depcondition, $dbh); } } # Insert sources - $sources = explode(" ", $new_pkgbuild['source']); - foreach ($sources as $src) { - if ($src != "" ) { - $q = "INSERT INTO PackageSources (PackageID, Source) VALUES ("; - $q .= $packageID . ", '" . db_escape_string($src) . "')"; - db_query($q, $dbh); + if (!empty($new_pkgbuild['source'])) { + $sources = explode(" ", $new_pkgbuild['source']); + foreach ($sources as $src) { + add_pkg_src($packageID, $src, $dbh); } } @@ -420,7 +398,7 @@ if ($uid): } # Entire package creation process is atomic - db_query("COMMIT", $dbh); + end_atomic_commit($dbh); header('Location: packages.php?ID=' . $packageID); } @@ -438,11 +416,8 @@ html_header("Submit"); <p class="pkgoutput"><?php print $error ?></p> <?php endif; ?> -<div class="pgbox"> - <div class="pgboxtitle"> - <span class="f3"><?php print __("Submit"); ?></span> - </div> - <div class="pgboxbody"> +<div class="box"> + <h2><?php echo __("Submit"); ?></h2> <p><?php echo __("Upload your source packages here. Create source packages with `makepkg --source`.") ?></p> <?php @@ -454,39 +429,36 @@ html_header("Submit"); $pkg_categories = pkgCategories(); ?> -<form action='pkgsubmit.php' method='post' enctype='multipart/form-data'> - <div> <input type='hidden' name='pkgsubmit' value='1' /> - <input type='hidden' name='token' value='<?php print htmlspecialchars($_COOKIE['AURSID']) ?>' /> </div> - <table border='0' cellspacing='5'> - <tr> - <td class='f4' align='right'><?php print __("Package Category"); ?>:</td> - <td class='f4' align='left'> - <select name='category'> - <option value='1'><?php print __("Select Category"); ?></option> +<form action="pkgsubmit.php" method="post" enctype="multipart/form-data"> + <fieldset> + <div> + <input type="hidden" name="pkgsubmit" value="1" /> + <input type="hidden" name="token" value="<?php print htmlspecialchars($_COOKIE['AURSID']) ?>" /> </div> + </div> + <p> + <label for="id_category"><?php print __("Package Category"); ?>:</label> + <select id="id_category" name="category"> + <option value="1"><?php print __("Select Category"); ?></option> <?php foreach ($pkg_categories as $num => $cat): - print "<option value='" . $num . "'"; + print '<option value="' . $num . '"'; if (isset($_POST['category']) && $_POST['category'] == $cat): - print " selected='selected'"; + print ' selected="selected"'; endif; - print ">" . $cat . "</option>"; + print '>' . $cat . '</option>'; endforeach; ?> </select> - </td> - </tr> - <tr> - <td class='f4' align='right'><?php print __("Upload package file"); ?>:</td> - <td class='f4' align='left'> - <input type='file' name='pfile' size='30' /> - </td> - </tr> - <tr> - <td align='left'> - <input class='button' type='submit' value='<?php print __("Upload"); ?>' /> - </td> - </tr> - </table> + </p> + <p> + <label for="id_file"><?php print __("Upload package file"); ?>:</label> + <input id="id_file" type="file" name="pfile" size='30' /> + </p> + <p> + <label></label> + <input class="button" type="submit" value="<?php print __("Upload"); ?>" /> + </p> + </fieldset> </form> <?php @@ -511,7 +483,6 @@ else: endif; ?> - </div> </div> <?php diff --git a/web/html/rpc.php b/web/html/rpc.php index ee7cda3d..415dcb82 100644 --- a/web/html/rpc.php +++ b/web/html/rpc.php @@ -18,7 +18,7 @@ else { // here. ?> <html><body> -<p>The methods currently allowed are:</p> +<h2>Allowed methods</h2> <ul> <li><tt>search</tt></li> <li><tt>info</tt></li> @@ -29,7 +29,14 @@ else { <pre>type=<em>methodname</em>&arg=<em>data</em></pre> <p>Where <em>methodname</em> is the name of an allowed method, and <em>data</em> is the argument to the call.</p> <p>If you need jsonp type callback specification, you can provide an additional variable <em>callback</em>.</p> -<p>Example URL: <tt>http://aur-url/rpc.php?type=search&arg=foobar&callback=jsonp1192244621103</tt></p> +<h2>Examples</h2> +<dl> + <dt><tt>search</tt></dt><dd><tt>http://aur-url/rpc.php?type=search&arg=foobar</tt></li></dd> + <dt><tt>info</tt></dt><dd><tt>http://aur-url/rpc.php?type=info&arg=foobar</tt></dd> + <dt><tt>multiinfo</tt></dt><dd><tt>http://aur-url/rpc.php?type=multiinfo&arg[]=foo&arg[]=bar</tt></dd> + <dt><tt>msearch</tt></dt><dd><tt>http://aur-url/rpc.php?type=msearch&arg=john</tt></li></dd> + <dt>Callback</dt><dd><tt>http://aur-url/rpc.php?type=search&arg=foobar&callback=jsonp1192244621103</tt></dd> +</dl> </body></html> <?php // close if statement diff --git a/web/html/rss.php b/web/html/rss.php index c7de4c65..6f057bfe 100644 --- a/web/html/rss.php +++ b/web/html/rss.php @@ -37,13 +37,9 @@ $image->description = "AUR Newest Packages Feed"; $rss->image = $image; #Get the latest packages and add items for them -$dbh = db_connect(); -$q = "SELECT * FROM Packages "; -$q.= "ORDER BY SubmittedTS DESC "; -$q.= "LIMIT 20"; -$result = db_query($q, $dbh); +$packages = latest_pkgs(20); -while ($row = mysql_fetch_assoc($result)) { +while (list($indx, $row) = each($packages)) { $item = new FeedItem(); $item->title = $row["Name"]; $item->link = "{$protocol}://{$host}/packages.php?ID={$row["ID"]}"; diff --git a/web/html/tu.php b/web/html/tu.php index 59cac1a2..86199039 100644 --- a/web/html/tu.php +++ b/web/html/tu.php @@ -5,7 +5,10 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); include_once("aur.inc.php"); set_lang(); check_sid(); -html_header(); + +$title = __("Trusted User"); + +html_header($title); # Default votes per page $pp = 10; @@ -16,49 +19,22 @@ if (isset($_COOKIE["AURSID"])) { $atype = account_from_sid($_COOKIE["AURSID"]); } -if ($atype == "Trusted User" OR $atype == "Developer") { +if ($atype == "Trusted User" || $atype == "Developer") { if (isset($_GET['id'])) { if (is_numeric($_GET['id'])) { - - $q = "SELECT * FROM TU_VoteInfo "; - $q.= "WHERE ID = " . $_GET['id']; - - $dbh = db_connect(); - $results = db_query($q, $dbh); - $row = mysql_fetch_assoc($results); + $row = vote_details($_GET['id']); if (empty($row)) { print __("Could not retrieve proposal details."); } else { $isrunning = $row['End'] > time() ? 1 : 0; - $qvoted = "SELECT * FROM TU_Votes WHERE "; - $qvoted.= "VoteID = " . $row['ID'] . " AND "; - $qvoted.= "UserID = " . uid_from_sid($_COOKIE["AURSID"]); - $result = db_query($qvoted, $dbh); - if ($result) { - $hasvoted = mysql_num_rows($result); - } - else { - $hasvoted = 0; - } - # List voters of a proposal. - $qwhoVoted = "SELECT tv.UserID,U.Username - FROM TU_Votes tv, Users U - WHERE tv.VoteID = {$row['ID']} - AND tv.UserID = U.ID - ORDER BY Username"; - $result = db_query($qwhoVoted,$dbh); - if (mysql_num_rows($result) > 0) { - $whovoted = ''; - while ($who = mysql_fetch_assoc($result)) { - $whovoted.= '<a href="account.php?Action=AccountInfo&ID='.$who['UserID'].'">'.$who['Username'].'</a> '; - } - } + $whovoted = voter_list($row['ID']); $canvote = 1; + $hasvoted = 0; $errorvote = ""; if ($isrunning == 0) { $canvote = 0; @@ -66,8 +42,9 @@ if ($atype == "Trusted User" OR $atype == "Developer") { } else if ($row['User'] == username_from_sid($_COOKIE["AURSID"])) { $canvote = 0; $errorvote = __("You cannot vote in an proposal about you."); - } else if ($hasvoted != 0) { + } else if (tu_voted($row['ID'], uid_from_sid($_COOKIE["AURSID"]))) { $canvote = 0; + $hasvoted = 1; $errorvote = __("You've already voted for this proposal."); } @@ -81,25 +58,18 @@ if ($atype == "Trusted User" OR $atype == "Developer") { $myvote = "Abstain"; } - $qvote = "UPDATE TU_VoteInfo SET " . $myvote . " = " . ($row[$myvote] + 1) . " WHERE ID = " . $row['ID']; - db_query($qvote, $dbh); - $qvote = "INSERT INTO TU_Votes (VoteID, UserID) VALUES (" . $row['ID'] . ", " . uid_from_sid($_COOKIE["AURSID"]) . ")"; - db_query($qvote, $dbh); + cast_proposal_vote($row['ID'], uid_from_sid($_COOKIE["AURSID"]), $myvote, $row[$myvote] + 1); # Can't vote anymore # $canvote = 0; $errorvote = __("You've already voted for this proposal."); - # Update if they voted - $result = db_query($qvoted, $dbh); - if ($result) { - $hasvoted = mysql_num_rows($result); - } - $results = db_query($q, $dbh); - if ($results) { - $row = mysql_fetch_assoc($results); + # Update if they voted + if (tu_voted($row['ID'], uid_from_sid($_COOKIE["AURSID"]))) { + $hasvoted = 1; } + $row = vote_details($_GET['id']); } } include("tu_details.php"); @@ -109,8 +79,6 @@ if ($atype == "Trusted User" OR $atype == "Developer") { } } else { - $dbh = db_connect(); - $limit = $pp; if (isset($_GET['off'])) $offset = $_GET['off']; @@ -120,7 +88,7 @@ if ($atype == "Trusted User" OR $atype == "Developer") { else $by = 'desc'; - if (!empty($offset) AND is_numeric($offset)) { + if (!empty($offset) && is_numeric($offset)) { if ($offset >= 1) { $off = $offset; } else { @@ -134,34 +102,33 @@ if ($atype == "Trusted User" OR $atype == "Developer") { $lim = ($limit > 0) ? " LIMIT $limit OFFSET $off" : ""; $by_next = ($by == 'desc') ? 'asc' : 'desc'; - $q = "SELECT * FROM TU_VoteInfo WHERE End > " . time() . " ORDER BY Submitted " . $order; - $result = db_query($q, $dbh); - + $result = current_proposal_list($order); $type = __("Current Votes"); include("tu_list.php"); ?> <?php - $q = "SELECT * FROM TU_VoteInfo WHERE End < " . time() . " ORDER BY Submitted " . $order . $lim; - $result = db_query($q, $dbh); + $result = past_proposal_list($order, $lim); $type = __("Past Votes"); include("tu_list.php"); - $qnext = "SELECT ID FROM TU_VoteInfo"; - $nextresult = db_query($qnext, $dbh); + $nextresult = proposal_count(); ?> -<div class="pgbox"> -<p><a href='addvote.php'><?php print __("Add Proposal") ?></a></p> - - <?php if (mysql_num_rows($result)) { $by = htmlentities($by, ENT_QUOTES); ?> - <?php if ($off != 0) { $back = (($off - $limit) <= 0) ? 0 : $off - $limit; ?> - <a href='tu.php?off=<?php print $back ?>&by=<?php print $by ?>'><?php print __("Back") ?></a> - <?php } ?> - <?php if (($off + $limit) < mysql_num_rows($nextresult)) { $forw = $off + $limit; ?> - <a href='tu.php?off=<?php print $forw ?>&by=<?php print $by ?>'><?php print __("Next") ?></a> - <?php } ?> - <?php } ?> +<div class="box"> + <p><a href="addvote.php"><?php print __("Add Proposal") ?></a></p> + + <?php if ($result): + $by = htmlentities($by, ENT_QUOTES); ?> + <?php if ($off != 0): + $back = (($off - $limit) <= 0) ? 0 : $off - $limit; ?> + <a href='tu.php?off=<?php print $back ?>&by=<?php print $by ?>'><?php print __("Back") ?></a> + <?php endif; ?> + <?php if (($off + $limit) < $nextresult): + $forw = $off + $limit; ?> + <a href="tu.php?off=<?php print $forw ?>&by=<?php print $by ?>"><?php print __("Next") ?></a> + <?php endif; ?> + <?php endif; ?> </div> <?php } diff --git a/web/html/voters.php b/web/html/voters.php index 02abe290..231e3230 100644 --- a/web/html/voters.php +++ b/web/html/voters.php @@ -3,38 +3,29 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); include('aur.inc.php'); include('pkgfuncs.inc.php'); -function getvotes($pkgid) { - $dbh = db_connect(); - $pkgid = db_escape_string($pkgid); - - $result = db_query("SELECT UsersID,Username FROM PackageVotes LEFT JOIN Users on (UsersID = ID) WHERE PackageID = $pkgid ORDER BY Username", $dbh); - return $result; -} - $SID = $_COOKIE['AURSID']; $pkgid = intval($_GET['ID']); $votes = getvotes($pkgid); -$account = account_from_sid($SID); +$atype = account_from_sid($SID); -if ($account == 'Trusted User' || $account == 'Developer') { -?> -<html> -<body> -<h3><?php echo account_from_sid($SID) ?></h3> -<h2>Votes for <a href="packages.php?ID=<?php echo $pkgid ?>"><?php echo pkgname_from_id($pkgid) ?></a></h2> -<?php - while ($row = mysql_fetch_assoc($votes)) { - $uid = $row['UsersID']; - $username = $row['Username']; +html_header(__("Voters")); + +if ($atype == 'Trusted User' || $atype== 'Developer'): ?> -<a href="account.php?Action=AccountInfo&ID=<?php echo $uid ?>"> -<?php echo htmlspecialchars($username) ?></a><br /> + +<div class="box"> + <h2>Votes for <a href="packages.php?ID=<?php echo $pkgid ?>"><?php echo pkgname_from_id($pkgid) ?></a></h2> + <div class="boxbody"> + <?php - } -?> -</body> -</html> + while (list($indx, $row) = each($votes)): ?> + <a href="account.php?Action=AccountInfo&ID=<?php echo $row['UsersID'] ?>"><?php echo htmlspecialchars($row['Username']) ?></a><br /> + <?php endwhile; ?> + </div> +</div> + <?php -} +endif; +html_footer(AUR_VERSION); diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index b7c3ee8f..a41a4e7d 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -8,10 +8,28 @@ function in_request($name) { return ""; } +# Format PGP key fingerprint +function html_format_pgp_fingerprint($fingerprint) { + if (strlen($fingerprint) != 40 || !ctype_xdigit($fingerprint)) { + return $fingerprint; + } + + return htmlspecialchars(substr($fingerprint, 0, 4) . " " . + substr($fingerprint, 4, 4) . " " . + substr($fingerprint, 8, 4) . " " . + substr($fingerprint, 12, 4) . " " . + substr($fingerprint, 16, 4) . " " . + substr($fingerprint, 20, 4) . " " . + substr($fingerprint, 24, 4) . " " . + substr($fingerprint, 28, 4) . " " . + substr($fingerprint, 32, 4) . " " . + substr($fingerprint, 36, 4) . " ", ENT_QUOTES); +} + # Display the standard Account form, pass in default values if any function display_account_form($UTYPE,$A,$U="",$T="",$S="", - $E="",$P="",$C="",$R="",$L="",$I="",$UID=0) { + $E="",$P="",$C="",$R="",$L="",$I="",$K="",$UID=0) { # UTYPE: what user type the form is being displayed for # A: what "form" name to use # U: value to display for username @@ -28,124 +46,7 @@ function display_account_form($UTYPE,$A,$U="",$T="",$S="", global $SUPPORTED_LANGS; - print "<form action='account.php' method='post'>\n"; - print "<fieldset>"; - print "<input type='hidden' name='Action' value='".$A."' />\n"; - if ($UID) { - print "<input type='hidden' name='ID' value='".$UID."' />\n"; - print "<input type='hidden' name='token' value='".htmlspecialchars($_COOKIE['AURSID'])."' />\n"; - } - print "</fieldset>"; - print "<table border='0' cellpadding='0' cellspacing='0' width='80%' style=\"margin:0 auto;\">\n"; - print "<tr><td colspan='2'> </td></tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Username").":</td>"; - print "<td align='left'><input type='text' size='30' maxlength='64'"; - print " name='U' value='".htmlspecialchars($U,ENT_QUOTES)."' /> (".__("required").")</td>"; - print "</tr>\n"; - - # Only TUs or Devs can promote/demote/suspend a user - if ($UTYPE == "Trusted User" || $UTYPE == "Developer") { - print "<tr>"; - print "<td align='left'>".__("Account Type").":</td>"; - print "<td align='left'><select name=T>\n"; - print "<option value='1'"; - $T == "User" ? print " selected>" : print ">"; - print __("Normal user")."\n"; - print "<option value='2'"; - $T == "Trusted User" ? print " selected>" : print ">"; - print __("Trusted user")."\n"; - - # Only developers can make another account a developer - if ($UTYPE == "Developer") { - print "<option value='3'"; - $T == "Developer" ? print " selected>" : print ">"; - print __("Developer")."\n"; - } - print "</select></td>"; - print "</tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Account Suspended").":</td>"; - print "<td align='left'><input type='checkbox' name='S'"; - if ($S) { - print " checked=\"checked\" />"; - } else { - print " />"; - } - print "</tr>\n"; - } - - print "<tr>"; - print "<td align='left'>".__("Email Address").":</td>"; - print "<td align='left'><input type='text' size='30' maxlength='64'"; - print " name='E' value='".htmlspecialchars($E,ENT_QUOTES)."' /> (".__("required").")</td>"; - print "</tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Password").":</td>"; - print "<td align='left'><input type='password' size='30' maxlength='32'"; - print " name='P' value='".$P."' />"; - if ($A != "UpdateAccount") { - print " (".__("required").")"; - } - print "</td></tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Re-type password").":</td>"; - print "<td align='left'><input type='password' size='30' maxlength='32'"; - print " name='C' value='".$C."' />"; - if ($A != "UpdateAccount") { - print " (".__("required").")"; - } - print "</td></tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Real Name").":</td>"; - print "<td align='left'><input type='text' size='30' maxlength='32'"; - print " name='R' value='".htmlspecialchars($R,ENT_QUOTES)."' /></td>"; - print "</tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("IRC Nick").":</td>"; - print "<td align='left'><input type='text' size='30' maxlength='32'"; - print " name='I' value='".htmlspecialchars($I,ENT_QUOTES)."' /></td>"; - print "</tr>\n"; - - print "<tr>"; - print "<td align='left'>".__("Language").":</td>"; - print "<td align='left'><select name=L>\n"; - - reset($SUPPORTED_LANGS); - while (list($code, $lang) = each($SUPPORTED_LANGS)) { - if ($L == $code) { - print "<option value=".$code." selected> ".$lang."\n"; - } else { - print "<option value=".$code."> ".$lang."\n"; - } - } - print "</select></td>"; - print "</tr>\n"; - - print "<tr><td colspan='2'> </td></tr>\n"; - print "<tr>"; - print "<td> </td>"; - print "<td align='left'>"; - - if ($A == "UpdateAccount") { - print "<input type='submit' class='button'"; - print " value='".__("Update")."' /> "; - } else { - print "<input type='submit' class='button'"; - print " value='".__("Create")."' /> "; - } - print "<input type='reset' class='button' value='".__("Reset")."' />"; - print "</td>"; - print "</tr>\n"; - - print "</table>\n"; - print "</form>\n"; + include("account_edit_form.php"); return; } # function display_account_form() @@ -153,7 +54,7 @@ function display_account_form($UTYPE,$A,$U="",$T="",$S="", # process form input from a new/edit account form # function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", - $P="",$C="",$R="",$L="",$I="",$UID=0) { + $P="",$C="",$R="",$L="",$I="",$K="",$UID=0,$dbh=NULL) { # UTYPE: The user's account type # TYPE: either "edit" or "new" # A: what parent "form" name to use @@ -172,14 +73,17 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", # error check and process request for a new/modified account global $SUPPORTED_LANGS; + if (!$dbh) { + $dbh = db_connect(); + } + if(isset($_COOKIE['AURSID'])) { - $editor_user = uid_from_sid($_COOKIE['AURSID']); + $editor_user = uid_from_sid($_COOKIE['AURSID'], $dbh); } else { $editor_user = null; } - $dbh = db_connect(); $error = ""; if (empty($E) || empty($U)) { $error = __("Missing a required field."); @@ -197,7 +101,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", } } - if (!$error && !valid_username($U) && !user_is_privileged($editor_user)) + if (!$error && !valid_username($U) && !user_is_privileged($editor_user, $dbh)) $error = __("The username is invalid.") . "<ul>\n" ."<li>" . __("It must be between %s and %s characters long", USERNAME_MIN_LEN, USERNAME_MAX_LEN ) @@ -215,6 +119,11 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if (!$error && !valid_email($E)) { $error = __("The email address is invalid."); } + + if (!$error && $K != '' && !valid_pgp_fingerprint($K)) { + $error = __("The PGP key fingerprint is invalid."); + } + if ($UTYPE == "Trusted User" && $T == 3) { $error = __("A Trusted User cannot assign Developer status."); } @@ -234,7 +143,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if ($result) { $row = mysql_fetch_array($result); if ($row[0]) { - $error = __("The username, %h%s%h, is already in use.", + $error = __("The username, %s%s%s, is already in use.", "<b>", htmlspecialchars($U,ENT_QUOTES), "</b>"); } } @@ -252,7 +161,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if ($result) { $row = mysql_fetch_array($result); if ($row[0]) { - $error = __("The address, %h%s%h, is already in use.", + $error = __("The address, %s%s%s, is already in use.", "<b>", htmlspecialchars($E,ENT_QUOTES), "</b>"); } } @@ -260,26 +169,26 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if ($error) { print "<span class='error'>".$error."</span><br/>\n"; display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "", - $R, $L, $I, $UID); + $R, $L, $I, $K, $UID); } else { if ($TYPE == "new") { # no errors, go ahead and create the unprivileged user $salt = generate_salt(); $P = salted_hash($P, $salt); $escaped = array_map('db_escape_string', - array($U, $E, $P, $salt, $R, $L, $I)); + array($U, $E, $P, $salt, $R, $L, $I, str_replace(" ", "", $K))); $q = "INSERT INTO Users (" . "AccountTypeID, Suspended, Username, Email, Passwd, Salt" . - ", RealName, LangPreference, IRCNick) " . + ", RealName, LangPreference, IRCNick, PGPKey) " . "VALUES (1, 0, '" . implode("', '", $escaped) . "')"; $result = db_query($q, $dbh); if (!$result) { - print __("Error trying to create account, %h%s%h: %s.", + print __("Error trying to create account, %s%s%s: %s.", "<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh)); } else { # account created/modified, tell them so. # - print __("The account, %h%s%h, has been successfully created.", + print __("The account, %s%s%s, has been successfully created.", "<b>", htmlspecialchars($U,ENT_QUOTES), "</b>"); print "<p>\n"; print __("Click on the Home link above to login."); @@ -308,13 +217,14 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", $q.= ", RealName = '".db_escape_string($R)."'"; $q.= ", LangPreference = '".db_escape_string($L)."'"; $q.= ", IRCNick = '".db_escape_string($I)."'"; + $q.= ", PGPKey = '".db_escape_string(str_replace(" ", "", $K))."'"; $q.= " WHERE ID = ".intval($UID); $result = db_query($q, $dbh); if (!$result) { - print __("Error trying to modify account, %h%s%h: %s.", + print __("Error trying to modify account, %s%s%s: %s.", "<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh)); } else { - print __("The account, %h%s%h, has been successfully modified.", + print __("The account, %s%s%s, has been successfully modified.", "<b>", htmlspecialchars($U,ENT_QUOTES), "</b>"); } } @@ -333,7 +243,7 @@ function search_accounts_form() { # search results page # function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="", - $S="",$E="",$R="",$I="") { + $S="",$E="",$R="",$I="",$K="",$dbh=NULL) { # UTYPE: what account type the user belongs to # O: what row offset we're at # SB: how to sort the results @@ -388,6 +298,10 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="", $q.= "AND IRCNick LIKE '%".db_escape_like($I)."%' "; $search_vars[] = "I"; } + if ($K) { + $q.= "AND PGPKey LIKE '%".db_escape_like(str_replace(" ", "", $K))."%' "; + $search_vars[] = "K"; + } switch ($SB) { case 't': $q.= "ORDER BY AccountTypeID, Username "; @@ -408,182 +322,18 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="", $search_vars[] = "SB"; $q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET; - $dbh = db_connect(); - - $result = db_query($q, $dbh); - if (!$result) { - print __("No results matched your search criteria."); - } else { - $num_rows = mysql_num_rows($result); - if ($num_rows) { - print "<table border='0' cellpadding='0'"; - print " cellspacing='0' width='90%'"; - print " style=\"margin:0 auto\">\n"; - print "<tr>"; - print "<td colspan='2'>"; - print "<table border='0' cellpadding='0'"; - print " cellspacing='0' width='100%'>\n"; - print "<tr>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Username")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Type")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Status")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Real Name")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("IRC Nick")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Last Voted")."</span></th>"; - print "<th class='header'>"; - print "<span class='f2'>".__("Edit Account")."</span></th>"; - print "</tr>\n"; - $i = 0; - while ($row = mysql_fetch_assoc($result)) { - if ($i % 2) { - $c = "data1"; - } else { - $c = "data2"; - } - print "<tr>"; - print "<td class='".$c."'>"; - print "<span class='f5'><a href='packages.php?SeB=m&K=".$row["Username"]."'>".$row["Username"]."</a></span></td>"; - print "<td class='".$c."'>"; - print "<span class='f5'>".$row["AccountType"]; - print "</span></td>"; - print "<td class='".$c."'><span class='f5'>"; - if ($row["Suspended"]) { - print __("Suspended"); - } else { - print __("Active"); - } - print "</span></td>"; - print "<td class='".$c."'><span class='f5'>"; - $row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print " "; - print "</span></td>"; - print "<td class='".$c."'><span class='f5'>"; - $row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print " "; - print "</span></td>"; - print "<td class='".$c."'><span class='f5'>"; - $row["LastVoted"] - ? print date("Ymd", $row["LastVoted"]) - : print __("Never"); - print "</span></td>"; - print "<td class='".$c."'><span class='f5'>"; - if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") { - # TUs can't edit devs - # - print " </span></td>"; - } else { - $edit_url = "account.php?Action=DisplayAccount&ID=".$row["ID"]; - print "<a href='".$edit_url . "'>"; - print "Edit</a></span></td>"; - } - print "</tr>\n"; - $i++; - } - print "</table>\n"; - print "</td></tr>\n"; - - print "<tr>"; - print "<td align='left'>"; - print "<form action='account.php' method='post'>\n"; - print "<fieldset>"; - print "<input type='hidden' name='Action' value='SearchAccounts' />\n"; - print "<input type='hidden' name='O'"; - print " value='".($OFFSET-$HITS_PER_PAGE)."' />\n"; - reset($search_vars); - while (list($k, $ind) = each($search_vars)) { - print "<input type='hidden' name='".$ind."'"; - print " value='".${$ind}."' />\n"; - } - print "<input type='submit' class='button'"; - print " value='<-- ".__("Less")."' />"; - print "</fieldset>"; - print "</form>\n"; - print "</td>"; - print "<td align='right'>"; - print "<form action='account.php' method='post'>\n"; - print "<fieldset>"; - print "<input type='hidden' name='Action' value='SearchAccounts' />\n"; - print "<input type='hidden' name='O'"; - print " value='".($OFFSET+$HITS_PER_PAGE)."' />\n"; - reset($search_vars); - while (list($k, $ind) = each($search_vars)) { - print "<input type='hidden' name='".$ind."'"; - print " value='".${$ind}."' />\n"; - } - print "<input type='submit' class='button'"; - print " value='".__("More")." -->' />"; - print "</fieldset>"; - print "</form>\n"; - print "</td>"; - print "</tr>\n"; - print "</table>\n"; - } else { - print "<p style=\"text-align:center;\">\n"; - print __("No more results to display."); - print "</p>\n"; - } + if (!$dbh) { + $dbh = db_connect(); } - return; -} -# Display non-editable account info -# -function display_account_info($U="", $T="", $E="", $R="", $I="") { - # U: value to display for username - # T: value to display for account type - # E: value to display for email address - # R: value to display for RealName - # I: value to display for IRC nick + $result = db_query($q, $dbh); + $num_rows = mysql_num_rows($result); - global $SUPPORTED_LANGS; + while ($row = mysql_fetch_assoc($result)) { + $userinfo[] = $row; + } - print "<table border='0' cellpadding='0' cellspacing='0' width='33%' style=\"margin:0 auto;\">\n"; - print " <tr>\n"; - print " <td colspan='2'> </td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td align='left'>".__("Username").":</td>\n"; - print " <td align='left'>".$U."</td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td align='left'>".__("Account Type").":</td>\n"; - print " <td align='left'>"; - if ($T == "User") { - print __("User"); - } elseif ($T == "Trusted User") { - print __("Trusted User"); - } elseif ($T == "Developer") { - print __("Developer"); - } - print " </td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td align='left'>".__("Email Address").":</td>\n"; - print " <td align='left'><a href='mailto:".htmlspecialchars($E,ENT_QUOTES)."'>".htmlspecialchars($E,ENT_QUOTES)."</a></td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td align='left'>".__("Real Name").":</td>\n"; - print " <td align='left'>".htmlspecialchars($R,ENT_QUOTES)."</td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td align='left'>".__("IRC Nick").":</td>\n"; - print " <td align='left'>".htmlspecialchars($I,ENT_QUOTES)."</td>\n"; - print " </tr>\n"; - - print " <tr>\n"; - print " <td colspan='2'><a href='packages.php?K=".$U."&SeB=m'>".__("View this user's packages")."</a></td>\n"; - print " </tr>\n"; - - print "</table>\n"; + include("account_search_results.php"); return; } @@ -591,7 +341,7 @@ function display_account_info($U="", $T="", $E="", $R="", $I="") { * Returns SID (Session ID) and error (error message) in an array * SID of 0 means login failed. */ -function try_login() { +function try_login($dbh=NULL) { global $MAX_SESSIONS_PER_USER, $PERSISTENT_COOKIE_TIMEOUT; $login_error = ""; @@ -599,21 +349,22 @@ function try_login() { $userID = null; if ( isset($_REQUEST['user']) || isset($_REQUEST['passwd']) ) { + if (!$dbh) { + $dbh = db_connect(); + } + $userID = valid_user($_REQUEST['user'], $dbh); - $userID = valid_user($_REQUEST['user']); - - if ( user_suspended( $userID ) ) { + if ( user_suspended($userID, $dbh) ) { $login_error = "Account Suspended."; } elseif ( $userID && isset($_REQUEST['passwd']) - && valid_passwd($userID, $_REQUEST['passwd']) ) { + && valid_passwd($userID, $_REQUEST['passwd'], $dbh) ) { $logged_in = 0; $num_tries = 0; # Account looks good. Generate a SID and store it. - $dbh = db_connect(); while (!$logged_in && $num_tries < 5) { if ($MAX_SESSIONS_PER_USER) { # Delete all user sessions except the @@ -644,8 +395,11 @@ function try_login() { } if ($logged_in) { - # set our SID cookie + $q = "UPDATE Users SET LastLogin = UNIX_TIMESTAMP() "; + $q.= "WHERE ID = '$userID'"; + db_query($q, $dbh); + # set our SID cookie if (isset($_POST['remember_me']) && $_POST['remember_me'] == "on") { # Set cookies for 30 days. @@ -684,8 +438,7 @@ function try_login() { * Returns the username if it is valid * Returns nothing if it isn't valid */ -function valid_username( $user ) -{ +function valid_username($user) { if (!empty($user)) { #Is username at not too short or too long? @@ -711,11 +464,14 @@ function valid_username( $user ) * Checks if the username is valid and if it exists in the database * Returns the username ID or nothing */ -function valid_user( $user ) -{ +function valid_user($user, $dbh=NULL) { /* if ( $user = valid_username($user) ) { */ - if ( $user ) { + + if(!$dbh) { $dbh = db_connect(); + } + + if ( $user ) { $q = "SELECT ID FROM Users WHERE Username = '" . db_escape_string($user). "'"; @@ -729,8 +485,72 @@ function valid_user( $user ) return; } -function good_passwd( $passwd ) -{ +# Check for any open proposals about a user. Used to prevent multiple proposals. +function open_user_proposals($user, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT * FROM TU_VoteInfo WHERE User = '" . db_escape_string($user) . "'"; + $q.= " AND End > UNIX_TIMESTAMP()"; + $result = db_query($q, $dbh); + if (mysql_num_rows($result)) { + return true; + } + else { + return false; + } +} + +# Creates a new trusted user proposal from entered agenda. +# Optionally takes proposal about specific user. Length of vote set by submitter. +function add_tu_proposal($agenda, $user, $votelength, $submitteruid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, SubmitterID) VALUES "; + $q.= "('" . db_escape_string($agenda) . "', "; + $q.= "'" . db_escape_string($user) . "', "; + $q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . db_escape_string($votelength); + $q.= ", " . $submitteruid . ")"; + db_query($q, $dbh); + +} + +# Add a reset key for a specific user +function create_resetkey($resetkey, $uid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "UPDATE Users "; + $q.= "SET ResetKey = '" . $resetkey . "' "; + $q.= "WHERE ID = " . $uid; + db_query($q, $dbh); +} + +# Change a password and save the salt only if reset key and email are correct +function password_reset($hash, $salt, $resetkey, $email, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "UPDATE Users "; + $q.= "SET Passwd = '$hash', "; + $q.= "Salt = '$salt', "; + $q.= "ResetKey = '' "; + $q.= "WHERE ResetKey != '' "; + $q.= "AND ResetKey = '".db_escape_string($resetkey)."' "; + $q.= "AND Email = '".db_escape_string($email)."'"; + $result = db_query($q, $dbh); + + if (!mysql_affected_rows($dbh)) { + $error = __('Invalid e-mail and reset key combination.'); + return $error; + } else { + header('Location: passreset.php?step=complete'); + exit(); + } +} + +function good_passwd($passwd) { if ( strlen($passwd) >= PASSWD_MIN_LEN ) { return true; } @@ -740,11 +560,11 @@ function good_passwd( $passwd ) /* Verifies that the password is correct for the userID specified. * Returns true or false */ -function valid_passwd( $userID, $passwd ) -{ - if ( strlen($passwd) > 0 ) { +function valid_passwd($userID, $passwd, $dbh=NULL) { + if (!$dbh) { $dbh = db_connect(); - + } + if ( strlen($passwd) > 0 ) { # get salt for this user $salt = get_salt($userID); if ($salt) { @@ -783,14 +603,23 @@ function valid_passwd( $userID, $passwd ) } /* + * Checks if the PGP key fingerprint is valid (must be 40 hexadecimal digits). + */ +function valid_pgp_fingerprint($fingerprint) { + $fingerprint = str_replace(" ", "", $fingerprint); + return (strlen($fingerprint) == 40 && ctype_xdigit($fingerprint)); +} + +/* * Is the user account suspended? */ -function user_suspended( $id ) -{ +function user_suspended($id, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } if (!$id) { return false; } - $dbh = db_connect(); $q = "SELECT Suspended FROM Users WHERE ID = " . $id; $result = db_query($q, $dbh); if ($result) { @@ -805,9 +634,10 @@ function user_suspended( $id ) /* * This should be expanded to return something */ -function user_delete( $id ) -{ - $dbh = db_connect(); +function user_delete($id, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } $q = "DELETE FROM Users WHERE ID = " . $id; db_query($q, $dbh); return; @@ -817,26 +647,38 @@ function user_delete( $id ) * A different way of determining a user's privileges * rather than account_from_sid() */ -function user_is_privileged( $id ) -{ - $dbh = db_connect(); +function user_is_privileged($id, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } $q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id; $result = db_query($q, $dbh); if ($result) { $row = mysql_fetch_row($result); - if( $result[0] > 1) { - return $result[0]; + if($row[0] > 1) { + return $row[0]; } } return 0; } +# Remove session on logout +function delete_session_id($sid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $q = "DELETE FROM Sessions WHERE SessionID = '"; + $q.= db_escape_string($sid) . "'"; + db_query($q, $dbh); +} + # Clear out old expired sessions. -function clear_expired_sessions($dbh = null) { +function clear_expired_sessions($dbh=NULL) { global $LOGIN_TIMEOUT; - if (empty($dbh)) { + if(!$dbh) { $dbh = db_connect(); } @@ -846,3 +688,150 @@ function clear_expired_sessions($dbh = null) { return; } +function account_details($uid, $username, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT Users.*, AccountTypes.AccountType "; + $q.= "FROM Users, AccountTypes "; + $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; + if (!empty($uid)) { + $q.= "AND Users.ID = ".intval($uid); + } else { + $q.= "AND Users.Username = '".db_escape_string($username) . "'"; + } + $result = db_query($q, $dbh); + + if ($result) { + $row = mysql_fetch_assoc($result); + } + + return $row; +} + +function own_account_details($sid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT Users.*, AccountTypes.AccountType "; + $q.= "FROM Users, AccountTypes, Sessions "; + $q.= "WHERE AccountTypes.ID = Users.AccountTypeID "; + $q.= "AND Users.ID = Sessions.UsersID "; + $q.= "AND Sessions.SessionID = '"; + $q.= db_escape_string($sid)."'"; + $result = db_query($q, $dbh); + + if ($result) { + $row = mysql_fetch_assoc($result); + } + + return $row; +} + +function tu_voted($voteid, $uid, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT * FROM TU_Votes WHERE VoteID = " . intval($voteid) . " AND UserID = " . intval($uid); + $result = db_query($q, $dbh); + if (mysql_num_rows($result)) { + return true; + } + else { + return false; + } +} + +function current_proposal_list($order, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT * FROM TU_VoteInfo WHERE End > " . time() . " ORDER BY Submitted " . $order; + $result = db_query($q, $dbh); + + $details = array(); + while ($row = mysql_fetch_assoc($result)) { + $details[] = $row; + } + + return $details; +} + +function past_proposal_list($order, $lim, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT * FROM TU_VoteInfo WHERE End < " . time() . " ORDER BY Submitted " . $order . $lim; + $result = db_query($q, $dbh); + + $details = array(); + while ($row = mysql_fetch_assoc($result)) { + $details[] = $row; + } + + return $details; +} + +function proposal_count($dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT COUNT(*) FROM TU_VoteInfo"; + $result = db_query($q, $dbh); + $row = mysql_fetch_row($result); + + return $row[0]; +} + +function vote_details($voteid, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT * FROM TU_VoteInfo "; + $q.= "WHERE ID = " . intval($voteid); + + $result = db_query($q, $dbh); + $row = mysql_fetch_assoc($result); + + return $row; +} + +function voter_list($voteid, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $whovoted = ''; + + $q = "SELECT tv.UserID,U.Username "; + $q.= "FROM TU_Votes tv, Users U "; + $q.= "WHERE tv.VoteID = " . intval($voteid); + $q.= " AND tv.UserID = U.ID "; + $q.= "ORDER BY Username"; + + $result = db_query($q, $dbh); + if ($result) { + while ($row = mysql_fetch_assoc($result)) { + $whovoted.= '<a href="account.php?Action=AccountInfo&ID='.$row['UserID'].'">'.$row['Username'].'</a> '; + } + } + return $whovoted; +} + +function cast_proposal_vote($voteid, $uid, $vote, $newtotal, $dbh=NULL) { + if (!$dbh) { + $dbh = db_connect(); + } + + $q = "UPDATE TU_VoteInfo SET " . $vote . " = " . ($newtotal) . " WHERE ID = " . $voteid; + db_query($q, $dbh); + + $q = "INSERT INTO TU_Votes (VoteID, UserID) VALUES (" . $voteid . ", " . $uid . ")"; + db_query($q, $dbh); + +} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index 8b9f31ec..1a6164ed 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -52,9 +52,7 @@ function check_sid($dbh=NULL) { } elseif ($failed == 2) { # session id timeout was reached and they must login again. # - $q = "DELETE FROM Sessions WHERE SessionID = '"; - $q.= db_escape_string($_COOKIE["AURSID"]) . "'"; - db_query($q, $dbh); + delete_session_id($_COOKIE["AURSID"], $dbh); setcookie("AURSID", "", 1, "/", null, !empty($_SERVER['HTTPS']), true); unset($_COOKIE['AURSID']); @@ -90,14 +88,18 @@ function check_token() { # verify that an email address looks like it is legitimate # function valid_email($addy) { - return (filter_var($addy, FILTER_VALIDATE_EMAIL) !== false); -} + // check against RFC 3696 + if (filter_var($addy, FILTER_VALIDATE_EMAIL) === false) { + return false; + } -# a new seed value for mt_srand() -# -function make_seed() { - list($usec, $sec) = explode(' ', microtime()); - return (float) $sec + ((float) $usec * 10000); + // check dns for mx, a, aaaa records + list($local, $domain) = explode('@', $addy); + if (!(checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A') || checkdnsrr($domain, 'AAAA'))) { + return false; + } + + return true; } # generate a (hopefully) unique session id @@ -282,77 +284,11 @@ function db_query($query="", $db_handle="") { return $result; } -# set up the visitor's language -# -function set_lang($dbh=NULL) { - global $LANG; - global $SUPPORTED_LANGS; - global $PERSISTENT_COOKIE_TIMEOUT; - global $streamer, $l10n; - - $update_cookie = 0; - if (isset($_REQUEST['setlang'])) { - # visitor is requesting a language change - # - $LANG = $_REQUEST['setlang']; - $update_cookie = 1; - - } elseif (isset($_COOKIE['AURLANG'])) { - # If a cookie is set, use that - # - $LANG = $_COOKIE['AURLANG']; - - } elseif (isset($_COOKIE["AURSID"])) { - # No language but a session; use default lang preference - # - if(!$dbh) { - $dbh = db_connect(); - } - $q = "SELECT LangPreference FROM Users, Sessions "; - $q.= "WHERE Users.ID = Sessions.UsersID "; - $q.= "AND Sessions.SessionID = '"; - $q.= db_escape_string($_COOKIE["AURSID"])."'"; - $result = db_query($q, $dbh); - - if ($result) { - $row = mysql_fetch_array($result); - $LANG = $row[0]; - } - $update_cookie = 1; - } - - # Set $LANG to default if nothing is valid. - if (!array_key_exists($LANG, $SUPPORTED_LANGS)) { - $LANG = DEFAULT_LANG; - } - - if ($update_cookie) { - $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; - setcookie("AURLANG", $LANG, $cookie_time, "/"); - } - - $streamer = new FileReader('../locale/' . $LANG . - '/LC_MESSAGES/aur.mo'); - $l10n = new gettext_reader($streamer, true); - - return; -} - - # common header # function html_header($title="") { - global $_SERVER; - global $_COOKIE; - global $_POST; global $LANG; global $SUPPORTED_LANGS; - global $DISABLE_HTTP_LOGIN; - - if (!$DISABLE_HTTP_LOGIN || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])) { - $login = try_login(); - $login_error = $login['error']; - } $title = htmlspecialchars($title, ENT_QUOTES); @@ -441,8 +377,7 @@ function chmod_group($path) { # obtain the uid given a Users.Username # -function uid_from_username($username="", $dbh=NULL) -{ +function uid_from_username($username="", $dbh=NULL) { if (!$username) { return ""; } @@ -462,8 +397,7 @@ function uid_from_username($username="", $dbh=NULL) # obtain the uid given a Users.Email # -function uid_from_email($email="", $dbh=NULL) -{ +function uid_from_email($email="", $dbh=NULL) { if (!$email) { return ""; } @@ -483,8 +417,7 @@ function uid_from_email($email="", $dbh=NULL) # check user privileges # -function check_user_privileges() -{ +function check_user_privileges() { $type = account_from_sid($_COOKIE['AURSID']); return ($type == 'Trusted User' || $type == 'Developer'); } @@ -523,8 +456,7 @@ function mkurl($append) { return substr($out, 5); } -function get_salt($user_id, $dbh=NULL) -{ +function get_salt($user_id, $dbh=NULL) { if(!$dbh) { $dbh = db_connect(); } @@ -537,8 +469,7 @@ function get_salt($user_id, $dbh=NULL) return; } -function save_salt($user_id, $passwd, $dbh=NULL) -{ +function save_salt($user_id, $passwd, $dbh=NULL) { if(!$dbh) { $dbh = db_connect(); } @@ -549,21 +480,18 @@ function save_salt($user_id, $passwd, $dbh=NULL) return db_query($salting_q, $dbh); } -function generate_salt() -{ +function generate_salt() { return md5(uniqid(mt_rand(), true)); } -function salted_hash($passwd, $salt) -{ +function salted_hash($passwd, $salt) { if (strlen($salt) != 32) { trigger_error('Salt does not look like an md5 hash', E_USER_WARNING); } return md5($salt . $passwd); } -function parse_comment($comment) -{ +function parse_comment($comment) { $url_pattern = '/(\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' . '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS'; @@ -585,3 +513,43 @@ function parse_comment($comment) return $html; } + +function begin_atomic_commit($dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + db_query("BEGIN", $dbh); +} + +function end_atomic_commit($dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + db_query("COMMIT", $dbh); +} + +function last_insert_id($dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + return mysql_insert_id($dbh); +} + +function latest_pkgs($numpkgs, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $q = "SELECT * FROM Packages "; + $q.= "ORDER BY SubmittedTS DESC "; + $q.= "LIMIT " .intval($numpkgs); + $result = db_query($q, $dbh); + + if ($result) { + while ($row = mysql_fetch_assoc($result)) { + $packages[] = $row; + } + } + + return $packages; +} diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index 6c7725c0..c1b079a4 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -18,11 +18,14 @@ class AurJSON { 'search', 'info', 'multiinfo', 'msearch' ); private static $fields = array( - 'Packages.ID', 'Name', 'Version', 'CategoryID', - 'Description', 'URL', 'License', - 'NumVotes', '(OutOfDateTS IS NOT NULL) AS OutOfDate', + 'Packages.ID', 'Name', 'Version', 'CategoryID', 'Description', 'URL', + 'License', 'NumVotes', 'OutOfDateTS AS OutOfDate', 'SubmittedTS AS FirstSubmitted', 'ModifiedTS AS LastModified' ); + private static $numeric_fields = array( + 'ID', 'CategoryID', 'NumVotes', 'OutOfDate', 'FirstSubmitted', + 'LastModified' + ); /** * Handles post data, and routes the request. @@ -100,7 +103,7 @@ class AurJSON { private function json_error($msg) { // set content type header to app/json header('content-type: application/json'); - return $this->json_results('error', $msg); + return $this->json_results('error', 0, $msg); } /** @@ -109,8 +112,8 @@ class AurJSON { * @param $data The result data to return * @return mixed A json formatted result response. **/ - private function json_results($type, $data) { - return json_encode( array('type' => $type, 'results' => $data) ); + private function json_results($type, $count, $data) { + return json_encode( array('type' => $type, 'resultcount' => $count, 'results' => $data) ); } private function process_query($type, $where_condition) { @@ -121,12 +124,21 @@ class AurJSON { "WHERE ${where_condition}"; $result = db_query($query, $this->dbh); - if ( $result && (mysql_num_rows($result) > 0) ) { + $resultcount = mysql_num_rows($result); + if ( $result && $resultcount > 0 ) { $search_data = array(); while ( $row = mysql_fetch_assoc($result) ) { $name = $row['Name']; $row['URLPath'] = URL_DIR . substr($name, 0, 2) . "/" . $name . "/" . $name . ".tar.gz"; + /* Unfortunately, mysql_fetch_assoc() returns all fields as + * strings. We need to coerce numeric values into integers to + * provide proper data types in the JSON response. + */ + foreach (self::$numeric_fields as $field) { + $row[$field] = intval($row[$field]); + } + if ($type == 'info') { $search_data = $row; break; @@ -137,10 +149,10 @@ class AurJSON { } mysql_free_result($result); - return $this->json_results($type, $search_data); + return $this->json_results($type, $resultcount, $search_data); } else { - return $this->json_error('No results found'); + return $this->json_results($type, 0, array()); } } diff --git a/web/lib/config.inc.php.proto b/web/lib/config.inc.php.proto index 79f5e4c4..1e2699e3 100644 --- a/web/lib/config.inc.php.proto +++ b/web/lib/config.inc.php.proto @@ -8,7 +8,6 @@ define( "AUR_db_user", "aur" ); define( "AUR_db_pass", "aur" ); # Configuration of directories where things live -define( "UPLOAD_DIR", "/srv/aur/unsupported-temp/" ); define( "INCOMING_DIR", "/srv/aur/unsupported/" ); define( "URL_DIR", "/packages/" ); @@ -33,34 +32,6 @@ define("SQL_DEBUG", 0); # to '127.0.0.1:11211'. #define("MEMCACHE_SERVERS", '127.0.0.1:11211'); -# Languages we have translations for -$SUPPORTED_LANGS = array( - "ca" => "Català", - "cs" => "česky", - "da" => "Dansk", - "de" => "Deutsch", - "en" => "English", - "el" => "Ελληνικά", - "es" => "Español", - "fi" => "Finnish", - "fr" => "Français", - "he" => "עברית", - "hr" => "Hrvatski", - "hu" => "Magyar", - "it" => "Italiano", - "nb" => "Norsk", - "nl" => "Dutch", - "pl" => "Polski", - "pt_BR" => "Português (Brasil)", - "pt_PT" => "Português (Portugal)", - "ro" => "Română", - "ru" => "Русский", - "sr" => "Srpski", - "tr" => "Türkçe", - "uk" => "Українська", - "zh_CN" => "简体中文" -); - # Session limit per user $MAX_SESSIONS_PER_USER = 8; @@ -77,3 +48,6 @@ $MAX_FILESIZE_UNCOMPRESSED = 1024 * 1024 * 8; # Allow HTTPs logins only $DISABLE_HTTP_LOGIN = true; + +# Web URL used in email links and absolute redirects, no trailing slash +$AUR_LOCATION = "http://localhost"; diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 88b18b88..0009b93b 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -200,6 +200,56 @@ function package_comments($pkgid, $dbh=NULL) { return $comments; } +# Add a comment to a package page and send out appropriate notifications +# TODO: Move notification logic to separate function where it belongs +function add_package_comment($pkgid, $uid, $comment, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $q = 'INSERT INTO PackageComments '; + $q.= '(PackageID, UsersID, Comments, CommentTS) VALUES ('; + $q.= intval($pkgid) . ', ' . $uid . ', '; + $q.= "'" . db_escape_string($comment) . "', "; + $q.= 'UNIX_TIMESTAMP())'; + db_query($q, $dbh); + + # Send email notifications + $q = 'SELECT CommentNotify.*, Users.Email '; + $q.= 'FROM CommentNotify, Users '; + $q.= 'WHERE Users.ID = CommentNotify.UserID '; + $q.= 'AND CommentNotify.UserID != ' . $uid . ' '; + $q.= 'AND CommentNotify.PkgID = ' . intval($pkgid); + $result = db_query($q, $dbh); + $bcc = array(); + + if (mysql_num_rows($result)) { + while ($row = mysql_fetch_assoc($result)) { + array_push($bcc, $row['Email']); + } + + $q = 'SELECT Packages.* '; + $q.= 'FROM Packages '; + $q.= 'WHERE Packages.ID = ' . intval($pkgid); + $result = db_query($q, $dbh); + $row = mysql_fetch_assoc($result); + + # TODO: native language emails for users, based on their prefs + # Simply making these strings translatable won't work, users would be + # getting emails in the language that the user who posted the comment was in + $body = + 'from ' . $AUR_LOCATION . '/packages.php?ID=' + . $pkgid . "\n" + . username_from_sid($_COOKIE['AURSID'], $dbh) . " wrote:\n\n" + . $comment + . "\n\n---\nIf you no longer wish to receive notifications about this package, please go the the above package page and click the UnNotify button."; + $body = wordwrap($body, 70); + $bcc = implode(', ', $bcc); + $headers = "Bcc: $bcc\nReply-to: nobody@archlinux.org\nFrom: aur-notify@archlinux.org\nX-Mailer: AUR\n"; + @mail('undisclosed-recipients: ;', "AUR Comment for " . $row['Name'], $body, $headers); + } +} + # grab package sources # function package_sources($pkgid, $dbh=NULL) { @@ -269,20 +319,37 @@ function pkgnotify_from_sid($sid="", $dbh=NULL) { # get name of package based on pkgid # -function pkgname_from_id($pkgid, $dbh=NULL) { - $pkgid = intval($pkgid); - $name = ""; - if ($pkgid > 0) { +function pkgname_from_id($pkgids, $dbh=NULL) { + if (is_array($pkgids)) { + $pkgids = sanitize_ids($pkgids); + $names = array(); + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT Name FROM Packages WHERE ID IN (" . + implode(",", $pkgids) . ")"; + $result = db_query($q, $dbh); + if (mysql_num_rows($result) > 0) { + while ($row = mysql_fetch_assoc($result)) { + $names[] = $row['Name']; + } + } + return $names; + } + elseif ($pkgids > 0) { if(!$dbh) { $dbh = db_connect(); } - $q = "SELECT Name FROM Packages WHERE ID = " . $pkgid; + $q = "SELECT Name FROM Packages WHERE ID = " . $pkgids; $result = db_query($q, $dbh); if (mysql_num_rows($result) > 0) { $name = mysql_result($result, 0); } + return $name; + } + else { + return NULL; } - return $name; } # Check if a package name is blacklisted. @@ -301,6 +368,8 @@ function pkgname_is_blacklisted($name, $dbh=NULL) { # display package details # function package_details($id=0, $SID="", $dbh=NULL) { + global $AUR_LOCATION; + if(!$dbh) { $dbh = db_connect(); } @@ -312,12 +381,12 @@ function package_details($id=0, $SID="", $dbh=NULL) { $results = db_query($q, $dbh); if (!$results) { - print __("Error retrieving package details.") . "<br />\n"; + print "<p>" . __("Error retrieving package details.") . "</p>\n"; } else { $row = mysql_fetch_assoc($results); if (empty($row)) { - print __("Package details could not be found.") . "<br />\n"; + print "<p>" . __("Package details could not be found.") . "</p>\n"; } else { @@ -326,6 +395,10 @@ function package_details($id=0, $SID="", $dbh=NULL) { # Actions Bar if ($SID) { include('actions_form.php'); + if (isset($_REQUEST['comment']) && check_token()) { + $uid = uid_from_sid($SID, $dbh); + add_package_comment($id, $uid, $_REQUEST['comment'], $dbh); + } include('pkg_comment_form.php'); } @@ -563,8 +636,8 @@ function pkg_search_page($SID="", $dbh=NULL) { $templ_pages = array(); if ($current > 1) { - $templ_pages[__('First')] = 0; - $templ_pages[__('Previous')] = ($current - 2) * $per_page; + $templ_pages['« ' . __('First')] = 0; + $templ_pages['‹ ' . __('Previous')] = ($current - 2) * $per_page; } if ($current - 5 > 1) @@ -578,11 +651,16 @@ function pkg_search_page($SID="", $dbh=NULL) { $templ_pages["... "] = false; if ($current < $pages) { - $templ_pages[__('Next')] = $current * $per_page; - $templ_pages[__('Last')] = ($pages - 1) * $per_page; + $templ_pages[__('Next') . ' ›'] = $current * $per_page; + $templ_pages[__('Last') . ' »'] = ($pages - 1) * $per_page; } include('pkg_search_form.php'); + + while ($row = mysql_fetch_assoc($result)) { + $searchresults[] = $row; + } + include('pkg_search_results.php'); return; @@ -618,6 +696,8 @@ function sanitize_ids($ids) { * @return string Translated success or error messages */ function pkg_flag ($atype, $ids, $action=true, $dbh=NULL) { + global $AUR_LOCATION; + if (!$atype) { if ($action) { return __("You must be logged in before you can flag packages."); @@ -664,7 +744,7 @@ function pkg_flag ($atype, $ids, $action=true, $dbh=NULL) { if (mysql_num_rows($result)) { while ($row = mysql_fetch_assoc($result)) { # construct email - $body = "Your package " . $row['Name'] . " has been flagged out of date by " . $f_name . " [1]. You may view your package at:\nhttps://aur.archlinux.org/packages.php?ID=" . $row['ID'] . "\n\n[1] - https://aur.archlinux.org/account.php?Action=AccountInfo&ID=" . $f_uid; + $body = "Your package " . $row['Name'] . " has been flagged out of date by " . $f_name . " [1]. You may view your package at:\n" . $AUR_LOCATION . "/packages.php?ID=" . $row['ID'] . "\n\n[1] - " . $AUR_LOCATION . "/account.php?Action=AccountInfo&ID=" . $f_uid; $body = wordwrap($body, 70); $headers = "Reply-to: nobody@archlinux.org\nFrom:aur-notify@archlinux.org\nX-Mailer: PHP\nX-MimeOLE: Produced By AUR\n"; @mail($row['Email'], "AUR Out-of-date Notification for ".$row['Name'], $body, $headers); @@ -708,6 +788,44 @@ function pkg_delete ($atype, $ids, $mergepkgid, $dbh=NULL) { } if ($mergepkgid) { + $mergepkgname = pkgname_from_id($mergepkgid, $dbh); + } + + # Send email notifications + foreach ($ids as $pkgid) { + $q = 'SELECT CommentNotify.*, Users.Email '; + $q.= 'FROM CommentNotify, Users '; + $q.= 'WHERE Users.ID = CommentNotify.UserID '; + $q.= 'AND CommentNotify.UserID != ' . uid_from_sid($_COOKIE['AURSID']) . ' '; + $q.= 'AND CommentNotify.PkgID = ' . $pkgid; + $result = db_query($q, $dbh); + $bcc = array(); + + while ($row = mysql_fetch_assoc($result)) { + array_push($bcc, $row['Email']); + } + if (!empty($bcc)) { + $pkgname = pkgname_from_id($pkgid); + + # TODO: native language emails for users, based on their prefs + # Simply making these strings translatable won't work, users would be + # getting emails in the language that the user who posted the comment was in + $body = ""; + if ($mergepkgid) { + $body .= username_from_sid($_COOKIE['AURSID']) . " merged \"".$pkgname."\" into \"$mergepkgname\".\n\n"; + $body .= "You will no longer receive notifications about this package, please go to https://aur.archlinux.org/packages.php?ID=".$mergepkgid." and click the Notify button if you wish to recieve them again."; + } else { + $body .= username_from_sid($_COOKIE['AURSID']) . " deleted \"".$pkgname."\".\n\n"; + $body .= "You will no longer receive notifications about this package."; + } + $body = wordwrap($body, 70); + $bcc = implode(', ', $bcc); + $headers = "Bcc: $bcc\nReply-to: nobody@archlinux.org\nFrom: aur-notify@archlinux.org\nX-Mailer: AUR\n"; + @mail('undisclosed-recipients: ;', "AUR Package deleted: " . $pkgname, $body, $headers); + } + } + + if ($mergepkgid) { /* Merge comments */ $q = "UPDATE PackageComments "; $q.= "SET PackageID = " . intval($mergepkgid) . " "; @@ -889,6 +1007,71 @@ function pkg_vote ($atype, $ids, $action=true, $dbh=NULL) { } } +# Get all usernames and ids for a specifc package id +function getvotes($pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $pkgid = db_escape_string($pkgid); + + $q = "SELECT UsersID,Username FROM PackageVotes "; + $q.= "LEFT JOIN Users on (UsersID = ID) "; + $q.= "WHERE PackageID = ". $pkgid . " "; + $q.= "ORDER BY Username"; + $result = db_query($q, $dbh); + + if (!$result) { + return; + } + + while ($row = mysql_fetch_assoc($result)) { + $votes[] = $row; + } + + return $votes; +} + +# Determine if a user has already voted for a specific package +function user_voted($uid, $pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $uid = db_escape_string($uid); + $pkgid = db_escape_string($pkgid); + + $q = "SELECT * FROM PackageVotes WHERE UsersID = ". $uid; + $q.= " AND PackageID = ".$pkgid; + $result = db_query($q, $dbh); + if (mysql_num_rows($result)) { + return true; + } + else { + return false; + } +} + +# Determine if a user wants notifications for a specific package +function user_notify($uid, $pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + + $uid = db_escape_string($uid); + $pkgid = db_escape_string($pkgid); + + $q = "SELECT * FROM CommentNotify WHERE UserID = ". $uid; + $q.= " AND PkgID = ".$pkgid; + $result = db_query($q, $dbh); + if (mysql_num_rows($result)) { + return true; + } + else { + return false; + } +} + /** * Toggle notification of packages * @@ -1046,8 +1229,8 @@ function pkg_change_category($atype, $dbh=NULL) { } $uid = uid_from_sid($_COOKIE["AURSID"], $dbh); - if ($uid == $pkg["MaintainerUID"] or - ($atype == "Developer" or $atype == "Trusted User")) { + if ($uid == $pkg["MaintainerUID"] || + ($atype == "Developer" || $atype == "Trusted User")) { $q = "UPDATE Packages "; $q.= "SET CategoryID = ".intval($category_id)." "; $q.= "WHERE ID = ".intval($pid); @@ -1057,3 +1240,100 @@ function pkg_change_category($atype, $dbh=NULL) { return __("You are not allowed to change this package category."); } } + +function pkgdetails_by_pkgname($pkgname, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT * FROM Packages WHERE Name = '" . db_escape_string($pkgname) . "'"; + $result = db_query($q, $dbh); + if ($result) { + $pdata = mysql_fetch_assoc($result); + } + return $pdata; +} + +function new_pkgdetails($pkgname, $license, $pkgver, $category_id, $pkgdesc, $pkgurl, $uid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = sprintf("INSERT INTO Packages (Name, License, Version, CategoryID, Description, URL, SubmittedTS, ModifiedTS, SubmitterUID, MaintainerUID) VALUES ('%s', '%s', '%s', %d, '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), %d, %d)", + db_escape_string($pkgname), + db_escape_string($license), + db_escape_string($pkgver), + $category_id, + db_escape_string($pkgdesc), + db_escape_string($pkgurl), + $uid, + $uid); + + db_query($q, $dbh); +} + +function update_pkgdetails($pkgname, $license, $pkgver, $pkgdesc, $pkgurl, $uid, $pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + # This is an overwrite of an existing package + $q = sprintf("UPDATE Packages SET ModifiedTS = UNIX_TIMESTAMP(), Name = '%s', Version = '%s', License = '%s', Description = '%s', URL = '%s', OutOfDateTS = NULL, MaintainerUID = %d WHERE ID = %d", + db_escape_string($pkgname), + db_escape_string($pkgver), + db_escape_string($license), + db_escape_string($pkgdesc), + db_escape_string($pkgurl), + $uid, + $pkgid); + + db_query($q, $dbh); +} + +function add_pkg_dep($pkgid, $depname, $depcondition, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = sprintf("INSERT INTO PackageDepends (PackageID, DepName, DepCondition) VALUES (%d, '%s', '%s')", + $pkgid, + db_escape_string($depname), + db_escape_string($depcondition)); + + db_query($q, $dbh); +} + +function add_pkg_src($pkgid, $pkgsrc, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "INSERT INTO PackageSources (PackageID, Source) VALUES ("; + $q .= $pkgid . ", '" . db_escape_string($pkgsrc) . "')"; + + db_query($q, $dbh); +} + +function update_pkg_category($pkgid, $category_id, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = sprintf( "UPDATE Packages SET CategoryID = %d WHERE ID = %d", + $category_id, + $pkgid); + + db_query($q, $dbh); +} + +function remove_pkg_deps($pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "DELETE FROM PackageDepends WHERE PackageID = " . $pkgid; + + db_query($q, $dbh); +} + +function remove_pkg_sources($pkgid, $dbh=NULL) { + if(!$dbh) { + $dbh = db_connect(); + } + $q = "DELETE FROM PackageSources WHERE PackageID = " . $pkgid; + + db_query($q, $dbh); +} diff --git a/web/lib/stats.inc.php b/web/lib/stats.inc.php index 8f0f7707..2828dc92 100644 --- a/web/lib/stats.inc.php +++ b/web/lib/stats.inc.php @@ -2,8 +2,7 @@ include_once('aur.inc.php'); -function updates_table($dbh) -{ +function updates_table($dbh) { $key = 'recent_updates'; if(!($newest_packages = get_cache_value($key))) { $q = 'SELECT * FROM Packages ORDER BY ModifiedTS DESC LIMIT 10'; @@ -18,18 +17,16 @@ function updates_table($dbh) include('stats/updates_table.php'); } -function user_table($user, $dbh) -{ - $escuser = db_escape_string($user); - $base_q = "SELECT count(*) FROM Packages,Users WHERE Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; +function user_table($userid, $dbh) { + $base_q = "SELECT count(*) FROM Packages WHERE Packages.MaintainerUID = " . $userid; $maintainer_unsupported_count = db_cache_value($base_q, $dbh, - 'user_unsupported_count:' . $escuser); + 'user_unsupported_count:' . $userid); - $q = "SELECT count(*) FROM Packages,Users WHERE Packages.OutOfDateTS IS NOT NULL AND Packages.MaintainerUID = Users.ID AND Users.Username='" . $escuser . "'"; + $q = "SELECT count(*) FROM Packages WHERE Packages.OutOfDateTS IS NOT NULL AND Packages.MaintainerUID = " . $userid; $flagged_outdated = db_cache_value($q, $dbh, - 'user_flagged_outdated:' . $escuser); + 'user_flagged_outdated:' . $userid); # If the user is a TU calculate the number of the packages $atype = account_from_sid($_COOKIE["AURSID"]); @@ -37,8 +34,7 @@ function user_table($user, $dbh) include('stats/user_table.php'); } -function general_stats_table($dbh) -{ +function general_stats_table($dbh) { # AUR statistics $q = "SELECT count(*) FROM Packages"; $unsupported_count = db_cache_value($q, $dbh, 'unsupported_count'); diff --git a/web/lib/translator.inc.php b/web/lib/translator.inc.php index 44c87bda..f269b937 100644 --- a/web/lib/translator.inc.php +++ b/web/lib/translator.inc.php @@ -5,12 +5,11 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib' . PATH_SEPARATOR # usage: # use the __() function for returning translated strings of -# text. The string can contain escape codes %h for HTML -# and %s for regular text. +# text. The string can contain escape codes "%s". # # examples: # print __("%s has %s apples.", "Bill", "5"); -# print __("This is a %hmajor%h problem!", "<b>", "</b>"); +# print __("This is a %smajor%s problem!", "<b>", "</b>"); include_once('config.inc.php'); include_once('gettext.php'); @@ -18,6 +17,34 @@ include_once('streams.php'); global $streamer, $l10n; +# Languages we have translations for +$SUPPORTED_LANGS = array( + "ca" => "Català", + "cs" => "česky", + "da" => "Dansk", + "de" => "Deutsch", + "en" => "English", + "el" => "Ελληνικά", + "es" => "Español", + "fi" => "Finnish", + "fr" => "Français", + "he" => "עברית", + "hr" => "Hrvatski", + "hu" => "Magyar", + "it" => "Italiano", + "nb" => "Norsk", + "nl" => "Dutch", + "pl" => "Polski", + "pt_BR" => "Português (Brasil)", + "pt_PT" => "Português (Portugal)", + "ro" => "Română", + "ru" => "Русский", + "sr" => "Srpski", + "tr" => "Türkçe", + "uk" => "Українська", + "zh_CN" => "简体中文" +); + function __() { global $LANG; global $l10n; @@ -26,25 +53,73 @@ function __() { $args = func_get_args(); # First argument is always string to be translated - $tag = $args[0]; + $tag = array_shift($args); # Translate using gettext_reader initialized before. $translated = $l10n->translate($tag); $translated = htmlspecialchars($translated, ENT_QUOTES); - $num_args = sizeof($args); - # Subsequent arguments are strings to be formatted - # - # TODO: make this more robust. - # '%%' should translate to a literal '%' + if (count($args) > 0) { + $translated = vsprintf($translated, $args); + } + + return $translated; +} + +# set up the visitor's language +# +function set_lang($dbh=NULL) { + global $LANG; + global $SUPPORTED_LANGS; + global $PERSISTENT_COOKIE_TIMEOUT; + global $streamer, $l10n; + + $update_cookie = 0; + if (isset($_REQUEST['setlang'])) { + # visitor is requesting a language change + # + $LANG = $_REQUEST['setlang']; + $update_cookie = 1; - if ( $num_args > 1 ) { - for ($i = 1; $i < $num_args; $i++) { - $translated = preg_replace("/\%[sh]/", $args[$i], $translated, 1); + } elseif (isset($_COOKIE['AURLANG'])) { + # If a cookie is set, use that + # + $LANG = $_COOKIE['AURLANG']; + + } elseif (isset($_COOKIE["AURSID"])) { + # No language but a session; use default lang preference + # + if(!$dbh) { + $dbh = db_connect(); + } + $q = "SELECT LangPreference FROM Users, Sessions "; + $q.= "WHERE Users.ID = Sessions.UsersID "; + $q.= "AND Sessions.SessionID = '"; + $q.= mysql_real_escape_string($_COOKIE["AURSID"])."'"; + $result = db_query($q, $dbh); + + if ($result) { + $row = mysql_fetch_array($result); + $LANG = $row[0]; } + $update_cookie = 1; } - return $translated; + # Set $LANG to default if nothing is valid. + if (!array_key_exists($LANG, $SUPPORTED_LANGS)) { + $LANG = DEFAULT_LANG; + } + + if ($update_cookie) { + $cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT; + setcookie("AURLANG", $LANG, $cookie_time, "/"); + } + + $streamer = new FileReader('../locale/' . $LANG . + '/LC_MESSAGES/aur.mo'); + $l10n = new gettext_reader($streamer, true); + + return; } diff --git a/web/template/account_details.php b/web/template/account_details.php new file mode 100644 index 00000000..f4c31c66 --- /dev/null +++ b/web/template/account_details.php @@ -0,0 +1,57 @@ +<table> + <tr> + <td colspan="2"> </td> + </tr> + + <tr> + <td align="left"><?php echo __("Username") . ":" ?></td> + <td align="left"><?php echo $row["Username"] ?></td> + </tr> + + <tr> + <td align="left"><?php echo __("Account Type") . ":" ?></td> + <td align="left"> + <?php + if ($row["AccountType"] == "User") { + print __("User"); + } elseif ($row["AccountType"] == "Trusted User") { + print __("Trusted User"); + } elseif ($row["AccountType"] == "Developer") { + print __("Developer"); + } + ?> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("Email Address") . ":" ?></td> + <td align="left"><a href="mailto:<?php echo htmlspecialchars($row["Email"], ENT_QUOTES) ?>"><?php echo htmlspecialchars($row["Email"], ENT_QUOTES) ?></a></td> + </tr> + + <tr> + <td align="left"><?php echo __("Real Name") . ":" ?></td> + <td align="left"><?php echo htmlspecialchars($row["RealName"], ENT_QUOTES) ?></td> + </tr> + + <tr> + <td align="left"><?php echo __("IRC Nick") . ":" ?></td> + <td align="left"><?php echo htmlspecialchars($row["IRCNick"], ENT_QUOTES) ?></td> + </tr> + + <tr> + <td align="left"><?php echo __("PGP Key Fingerprint") . ":" ?></td> + <td align="left"><?php echo html_format_pgp_fingerprint($row["PGPKey"]) ?></td> + </tr> + + <tr> + <td align="left"><?php echo __("Last Voted") . ":" ?></td> + <td align="left"> + <?php print $row["LastVoted"] ? date("Y-m-d", $row["LastVoted"]) : __("Never"); ?> + </td> + </tr> + + <tr> + <td colspan="2"><a href="packages.php?K=<?php echo $row['Username'] ?>&SeB=m"><?php echo __("View this user's packages") ?></a></td> + </tr> + +</table> diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php new file mode 100644 index 00000000..c32eb94d --- /dev/null +++ b/web/template/account_edit_form.php @@ -0,0 +1,139 @@ +<form action="account.php" method="post"> + <fieldset> + <input type="hidden" name="Action" value="<?php echo $A ?>" /> + <?php if ($UID): ?> + <input type="hidden" name="ID" value="<?php echo $UID ?>" /> + <input type="hidden" name="token" value="<?php print htmlspecialchars($_COOKIE['AURSID']) ?>" /> </div> + <?php endif; ?> + </fieldset> + <table> + <tr> + <td colspan="2"> </td> + </tr> + + <tr> + <td align="left"><?php echo __("Username") ?>:</td> + <td align="left"><input type="text" size="30" maxlength="64" name="U" value="<?php echo htmlspecialchars($U,ENT_QUOTES) ?>" /> (<?php echo __("required") ?>)</td> + </tr> + <?php + # Only TUs or Devs can promote/demote/suspend a user + if ($UTYPE == "Trusted User" || $UTYPE == "Developer"): + ?> + <tr> + <td align="left"><?php echo __("Account Type") ?>:</td> + <td align="left"> + <select name=T> + <?php if ($T == "User"): ?> + <option value="1" selected><?php echo __("Normal user") ?> + <?php else: ?> + <option value="1"><?php echo __("Normal user") ?> + <?php endif; ?> + <?php if ($T == "Trusted User"): ?> + <option value="2" selected><?php echo __("Trusted user") ?> + <?php else: ?> + <option value="2"><?php echo __("Trusted user") ?> + <?php endif; ?> + <?php + # Only developers can make another account a developer + if ($UTYPE == "Developer"): + ?> + <option value="3" + <?php $T == "Developer" ? print " selected>" : print ">"; + print __("Developer")."\n"; ?> + <?php endif; ?> + </select> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("Account Suspended") ?>:</td> + + <?php if ($S): ?> + <td align="left"><input type="checkbox" name="S" checked="checked" /> + <?php else: ?> + <td align="left"><input type="checkbox" name="S" /> + <?php endif; ?> + </tr> + <?php endif; ?> + + <tr> + <td align="left"><?php echo __("Email Address") ?>:</td> + <td align="left"><input type="text" size="30" maxlength="64" name="E" value="<?php echo htmlspecialchars($E,ENT_QUOTES) ?>" /> (<?php echo __("required") ?>)</td> + </tr> + + <tr> + <td align="left"><?php echo __("Password") ?>:</td> + <td align="left"> + <input type="password" size="30" maxlength="32" name="P" value="<?php echo $P ?>" /> + <?php if ($A != "UpdateAccount"): + print " (".__("required").")"; + endif; ?> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("Re-type password") ?>:</td> + <td align="left"> + <input type="password" size="30" maxlength="32" name="C" value="<?php echo $C ?>" /> + <?php if ($A != "UpdateAccount"): + print " (".__("required").")"; + endif; ?> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("Real Name") ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="32" name="R" value="<?php echo htmlspecialchars($R,ENT_QUOTES) ?>" /> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("IRC Nick") ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="32" name="I" value="<?php echo htmlspecialchars($I,ENT_QUOTES) ?>" /> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("PGP Key Fingerprint") ?>:</td> +<td align="left"> + <input type="text" size="30" maxlength="50" name="K" value="<?php echo html_format_pgp_fingerprint($K) ?>" /> + </td> + </tr> + + <tr> + <td align="left"><?php echo __("Language") ?>:</td> + <td align="left"> + <select name=L> +<?php + reset($SUPPORTED_LANGS); + while (list($code, $lang) = each($SUPPORTED_LANGS)) { + if ($L == $code) { + print "<option value=".$code." selected> ".$lang."\n"; + } else { + print "<option value=".$code."> ".$lang."\n"; + } + } +?> + </select> + </td> + </tr> + + <tr> + <td colspan="2"> </td> + </tr> + <tr> + <td> </td> + <td align="left"> + <?php if ($A == "UpdateAccount"): ?> + <input type="submit" class="button" value="<?php echo __("Update") ?>" /> + <?php else: ?> + <input type="submit" class="button" value="<?php echo __("Create") ?>" /> + <?php endif; ?> + <input type="reset" class="button" value="<?php echo __("Reset") ?>" /> + </td> + </tr> + + </table> +</form> diff --git a/web/template/account_search_results.php b/web/template/account_search_results.php new file mode 100644 index 00000000..f2ed62e1 --- /dev/null +++ b/web/template/account_search_results.php @@ -0,0 +1,102 @@ +<?php +if (!$result): + print __("No results matched your search criteria."); +else: + if ($num_rows): +?> + <table class="results"> + <thead> + <tr> + <th><?php echo __("Username") ?></th> + <th><?php echo __("Type") ?></th> + <th><?php echo __("Status") ?></th> + <th><?php echo __("Real Name") ?></th> + <th><?php echo __("IRC Nick") ?></th> + <th><?php echo __("PGP Key Fingerprint") ?></th> + <th><?php echo __("Last Voted") ?></th> + <th><?php echo __("Edit Account") ?></th> + </tr> + </thead> + <?php + $i = 0; + while (list($indx, $row) = each($userinfo)): + if ($i % 2): + $c = "even"; + else: + $c = "odd"; + endif; + ?> + <tbody> + <tr class ="<?php echo $c ?>"> + <td><a href="packages.php?SeB=m&K=<?php echo $row["Username"] ?>"><?php echo $row["Username"] ?></a></td> + <td><?php echo $row["AccountType"] ?></td> + <td> + <?php + if ($row["Suspended"]): + print __("Suspended"); + else: + print __("Active"); + endif; + ?> + </td> + <td><?php $row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print " " ?></td> + <td><?php $row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print " " ?></td> + <td><?php $row["PGPKey"] ? print html_format_pgp_fingerprint($row["PGPKey"]) : print " " ?></td> + <td><?php $row["LastVoted"] ? print date("Y-m-d", $row["LastVoted"]) : print __("Never") ?></td> + <td> + <?php + if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer"): + # TUs can't edit devs + print " "; + else: + ?> + <a href="account.php?Action=DisplayAccount&ID=<?php echo $row["ID"] ?>"><?php echo __("Edit") ?></a> + <?php endif; ?> + </td> + </tr> + <?php + $i++; + endwhile; + ?> + </table> + + <table class="results"> + <tr> + <td align="left"> + <form action="account.php" method="post"> + <fieldset> + <input type="hidden" name="Action" value="SearchAccounts" /> + <input type="hidden" name="O" value="<?php echo ($OFFSET-$HITS_PER_PAGE) ?>" /> + <?php + reset($search_vars); + while (list($k, $ind) = each($search_vars)): + ?> + <input type="hidden" name="<?php echo $ind ?>" value="<?php echo ${$ind} ?>" /> + <?php endwhile; ?> + <input type="submit" class="button" value="<-- <?php echo __("Less") ?>" /> + </fieldset> + </form> + </td> + <td align="right"> + <form action="account.php" method="post"> + <fieldset> + <input type="hidden" name="Action" value="SearchAccounts" /> + <input type="hidden" name="O" value="<?php echo ($OFFSET+$HITS_PER_PAGE) ?>" /> + <?php + reset($search_vars); + while (list($k, $ind) = each($search_vars)): + ?> + <input type="hidden" name="<?php echo $ind ?>" value="<?php echo ${$ind} ?>" /> + <?php endwhile; ?> + <input type="submit" class="button" value="<?php echo __("More") ?> -->" /> + </fieldset> + </form> + </td> + </tr> + </table> + <?php else: ?> + <p style="text-align:center;"> + <?php print __("No more results to display."); ?> + </p> + <?php endif; ?> +<?php endif; ?> diff --git a/web/template/actions_form.php b/web/template/actions_form.php index fa6ad72f..ff0fd4e5 100644 --- a/web/template/actions_form.php +++ b/web/template/actions_form.php @@ -1,66 +1,43 @@ -<div class="pgbox"> +<div class="box"> <form action="packages.php?ID=<?php echo $row['ID'] ?>" method="post"> <fieldset> - <input type='hidden' name='IDs[<?php echo $row['ID'] ?>]' value='1' /> - <input type='hidden' name='ID' value="<?php echo $row['ID'] ?>" /> - <input type='hidden' name='token' value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> -<?php - # Voting Button - # - $q = "SELECT * FROM PackageVotes WHERE UsersID = ". $uid; - $q.= " AND PackageID = ".$row["ID"]; - $result = db_query($q, $dbh); - if ($result) { - if (!mysql_num_rows($result)) { - echo " <input type='submit' class='button' name='do_Vote'"; - echo " value='".__("Vote")."' /> "; - } else { - echo "<input type='submit' class='button' name='do_UnVote'"; - echo " value='".__("UnVote")."' /> "; - } - } + <input type="hidden" name="IDs[<?php echo $row['ID'] ?>]" value="1" /> + <input type="hidden" name="ID" value="<?php echo $row['ID'] ?>" /> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> - # Comment Notify Button - # - $q = "SELECT * FROM CommentNotify WHERE UserID = ". $uid; - $q.= " AND PkgID = ".$row["ID"]; - $result = db_query($q, $dbh); - if ($result) { - if (!mysql_num_rows($result)) { - echo "<input type='submit' class='button' name='do_Notify'"; - echo " value='".__("Notify")."' title='".__("New Comment Notification")."' /> "; - } else { - echo "<input type='submit' class='button' name='do_UnNotify'"; - echo " value='".__("UnNotify")."' title='".__("No New Comment Notification")."' /> "; - } - } + <?php if (user_voted($uid, $row['ID'])): ?> + <input type="submit" class="button" name="do_UnVote" value="<?php echo __("UnVote") ?>" /> + <?php else: ?> + <input type="submit" class="button" name="do_Vote" value="<?php echo __("Vote") ?>" /> + <?php endif; ?> - if ($row["OutOfDateTS"] === NULL) { - echo "<input type='submit' class='button' name='do_Flag'"; - echo " value='".__("Flag Out-of-date")."' />\n"; - } else { - echo "<input type='submit' class='button' name='do_UnFlag'"; - echo " value='".__("UnFlag Out-of-date")."' />\n"; - } - - if ($row["MaintainerUID"] === NULL) { - echo "<input type='submit' class='button' name='do_Adopt'"; - echo " value='".__("Adopt Packages")."' />\n"; - } else if ($uid == $row["MaintainerUID"] || - $atype == "Trusted User" || $atype == "Developer") { - echo "<input type='submit' class='button' name='do_Disown'"; - echo " value='".__("Disown Packages")."' />\n"; - } + <?php if (user_notify($uid, $row['ID'])): ?> + <input type="submit" class="button" name="do_UnNotify" value="<?php echo __("UnNotify") ?>" title="<?php echo __("No New Comment Notification") ?>" /> + <?php else: ?> + <input type="submit" class="button" name="do_Notify" value="<?php echo __("Notify") ?>" title="<?php echo __("New Comment Notification") ?>" /> + <?php endif; ?> + + <?php if ($row["OutOfDateTS"] === NULL): ?> + <input type="submit" class="button" name="do_Flag" value="<?php echo __("Flag Out-of-date") ?>" /> + <?php else: ?> + <input type="submit" class="button" name="do_UnFlag" value="<?php echo __("UnFlag Out-of-date") ?>" /> + <?php endif; ?> - if ($atype == "Trusted User" || $atype == "Developer") { - echo "<input type='submit' class='button' name='do_Delete'"; - echo " value='".__("Delete Packages")."' />\n"; - echo "<label for='merge_Into'>".__("Merge into")."</label>\n"; - echo "<input type='text' id='merge_Into' name='merge_Into' /> "; - echo "<input type='checkbox' name='confirm_Delete' value='1' /> "; - echo __("Confirm")."\n"; - } -?> + <?php if ($row["MaintainerUID"] === NULL): ?> + <input type="submit" class="button" name="do_Adopt" value="<?php echo __("Adopt Packages") ?>" /> + <?php elseif ($uid == $row["MaintainerUID"] || + $atype == "Trusted User" || $atype == "Developer"): ?> + <input type="submit" class="button" name="do_Disown" value="<?php echo __("Disown Packages") ?>" /> + <?php endif; ?> + + <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> + <input type="submit" class="button" name="do_Delete" value="<?php echo __("Delete Packages") ?>" /> + <label for="merge_Into" ><?php echo __("Merge into") ?></label> + <input type="text" id="merge_Into" name="merge_Into" /> + <input type="checkbox" name="confirm_Delete" value="1" /> + <?php echo __("Confirm") ?> + <?php endif; ?> + </fieldset> </form> </div> diff --git a/web/template/footer.php b/web/template/footer.php index 0948f686..1b1b1d2a 100644 --- a/web/template/footer.php +++ b/web/template/footer.php @@ -1,9 +1,13 @@ - <!-- End of main content --> -<?php - if ($ver) { - echo "<div class=\"pgbox version\">" . htmlspecialchars($ver) . "</div>"; - } -?> + <!-- End of main content --> + + <div id="footer"> + <?php if ($ver): ?> + <p>AUR <?php echo htmlspecialchars($ver) ?></p> + <?php endif; ?> + <p>Copyright © 2004-2012 AUR Development Team.</p> + <p><?php echo __('Unsupported packages are user produced content. Any use of the provided files is at your own risk.') ?></p> + </div> + </div> </body> </html> diff --git a/web/template/header.php b/web/template/header.php index 8749dae6..6dd52f7e 100644 --- a/web/template/header.php +++ b/web/template/header.php @@ -5,10 +5,8 @@ xml:lang="<?php print htmlspecialchars($LANG, ENT_QUOTES) ?>" lang="<?php print htmlspecialchars($LANG, ENT_QUOTES) ?>"> <head> <title>AUR (<?php print htmlspecialchars($LANG); ?>)<?php if ($title != "") { print " - " . htmlspecialchars($title); } ?></title> - <link rel='stylesheet' type='text/css' href='css/fonts.css' /> - <link rel='stylesheet' type='text/css' href='css/containers.css' /> - <link rel='stylesheet' type='text/css' href='css/arch.css' /> - <link rel='stylesheet' type='text/css' href='css/archnavbar/archnavbar.css' /> + <link rel='stylesheet' type='text/css' href='css/archweb.css' /> + <link rel='stylesheet' type='text/css' href='css/aur.css' /> <link rel='shortcut icon' href='images/favicon.ico' /> <link rel='alternate' type='application/rss+xml' title='Newest Packages RSS' href='rss.php' /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> @@ -23,40 +21,48 @@ <li id="anb-forums"><a href="https://bbs.archlinux.org/" title="Community forums">Forums</a></li> <li id="anb-wiki"><a href="https://wiki.archlinux.org/" title="Community documentation">Wiki</a></li> <li id="anb-bugs"><a href="https://bugs.archlinux.org/" title="Report and track bugs">Bugs</a></li> - <li id="anb-aur"><a href="https://aur.archlinux.org/" title="Arch Linux User Repository">AUR</a></li> + <li id="anb-aur"><a href="/" title="Arch Linux User Repository">AUR</a></li> <li id="anb-download"><a href="http://www.archlinux.org/download/" title="Get Arch Linux">Download</a></li> </ul> </div> </div><!-- #archnavbar --> - <div id="archdev-navbar"> - <ul> - <li><a href="index.php">AUR <?php print __("Home"); ?></a></li> - <li><a href="account.php"><?php print __("Accounts"); ?></a></li> - <li><a href="packages.php"><?php print __("Packages"); ?></a></li> - <li><a href="http://bugs.archlinux.org/index.php?tasks=all&project=2"><?php print __("Bugs"); ?></a></li> - <li><a href="http://archlinux.org/mailman/listinfo/aur-general"><?php print __("Discussion"); ?></a></li> - <?php if (isset($_COOKIE['AURSID'])): ?> - <?php if (check_user_privileges()): ?><li><a href="tu.php"><?php print __("Trusted User"); ?></a></li><?php endif; ?> - <li><a href="packages.php?SeB=m&K=<?php print username_from_sid($_COOKIE["AURSID"]); ?>"><?php print __("My Packages"); ?></a></li> - <li><a href="pkgsubmit.php"><?php print __("Submit"); ?></a></li> - <?php endif; ?> - </ul> - </div><!-- #archdev-navbar --> - - <?php include("login_form.php"); ?> - - <div id="lang_sub"> -<?php -reset($SUPPORTED_LANGS); -foreach ($SUPPORTED_LANGS as $lang => $lang_name) { - print '<a href="' - . htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES) - ."?setlang=" . htmlspecialchars($lang, ENT_QUOTES) . "\" title=\"" . htmlspecialchars($lang_name, ENT_QUOTES) . "\">" - . htmlspecialchars(strtolower($lang)) . "</a>\n"; -} -?> - </div> - <!-- Start of main content --> + <div id="content"> + <div id="lang_sub"> + <form method="get" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES) ?>"> + <fieldset> + <div> + <select name="setlang" id="id_setlang"> + <?php + reset($SUPPORTED_LANGS); + foreach ($SUPPORTED_LANGS as $lang => $lang_name) { + print '<option value="' . strtolower($lang) . '"' . + ($lang == $LANG ? ' selected="selected"' : '') . + '>' . strtolower($lang) . "</option>\n"; + } + ?> + </select> + <input type="submit" value="Go" /> + </div> + </fieldset> + </form> + </div> + <div id="archdev-navbar"> + <ul> + <li><a href="index.php">AUR <?php print __("Home"); ?></a></li> + <li><a href="packages.php"><?php print __("Packages"); ?></a></li> + <?php if (isset($_COOKIE['AURSID'])): ?> + <li><a href="packages.php?SeB=m&K=<?php print username_from_sid($_COOKIE["AURSID"]); ?>"><?php print __("My Packages"); ?></a></li> + <li><a href="pkgsubmit.php"><?php print __("Submit"); ?></a></li> + <li><a href="account.php"><?php print __("Accounts"); ?></a></li> + <?php if (check_user_privileges()): ?><li><a href="tu.php"><?php print __("Trusted User"); ?></a></li><?php endif; ?> + <li><a href="logout.php"><?php print __("Logout"); ?></a></li> + <?php else: ?> + <li><a href="account.php"><?php print __("Register"); ?></a></li> + <li><a href="login.php"><?php print __("Login"); ?></a></li> + <?php endif; ?> + </ul> + </div><!-- #archdev-navbar --> + <!-- Start of main content --> diff --git a/web/template/login_form.php b/web/template/login_form.php deleted file mode 100644 index c27e9ba3..00000000 --- a/web/template/login_form.php +++ /dev/null @@ -1,38 +0,0 @@ -<div id="login_bar" class="pgbox"> -<?php -if (isset($_COOKIE["AURSID"])) { - print __("Logged-in as: %s", '<b>' . username_from_sid($_COOKIE["AURSID"]) . '</b>'); -?> - <a href="logout.php">[<?php print __("Logout"); ?>]</a> -<?php -} -elseif (!$DISABLE_HTTP_LOGIN || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])) { - if ($login_error) { - print "<span class='error'>" . $login_error . "</span><br />\n"; - } -?> -<form method="post" action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES) ?>"> - <div> - <label for="user"><?php print __('Username') . ':'; ?></label> - <input type="text" name="user" id="user" size="30" maxlength="<?php print USERNAME_MAX_LEN; ?>" value="<?php - if (isset($_POST['user'])) { - print htmlspecialchars($_POST['user'], ENT_QUOTES); - } ?>" /> - <label for="passwd"><?php print __('Password') . ':'; ?></label> - <input type="password" name="passwd" id="passwd" size="30" maxlength="<?php print PASSWD_MAX_LEN; ?>" /> - <input type="checkbox" name="remember_me" id="remember_me" /> - <label for="remember_me"><?php print __("Remember me"); ?></label> - <input type="submit" class="button" value="<?php print __("Login"); ?>" /> - <a href="passreset.php">[<?php echo __('Forgot Password') ?>]</a> - </div> -</form> -<?php -} -else { -?> -<span class='error'> - <?php printf(__("HTTP login is disabled. Please %sswitch to HTTPs%s if you want to login."), - '<a href="https://aur.archlinux.org' . htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES) . '">', '</a>'); ?> -</span> -<?php } ?> -</div> diff --git a/web/template/pkg_comment_form.php b/web/template/pkg_comment_form.php index 60816436..95d2cb05 100644 --- a/web/template/pkg_comment_form.php +++ b/web/template/pkg_comment_form.php @@ -1,69 +1,25 @@ +<div id="generic-form" class="box"> + <h2><?php echo __("Add Comment"); ?></h2> + <form call="general-form" action="<?php echo $_SERVER['REQUEST_URI'] ?>" method="post"> + <fieldset> <?php -# Add a comment to this package if (isset($_REQUEST['comment']) && check_token()) { - - # Insert the comment - $dbh = db_connect(); - $q = 'INSERT INTO PackageComments '; - $q.= '(PackageID, UsersID, Comments, CommentTS) VALUES ('; - $q.= intval($_REQUEST['ID']) . ', ' . uid_from_sid($_COOKIE['AURSID']) . ', '; - $q.= "'" . db_escape_string($_REQUEST['comment']) . "', "; - $q.= 'UNIX_TIMESTAMP())'; - db_query($q, $dbh); - - # Send email notifications - $q = 'SELECT CommentNotify.*, Users.Email '; - $q.= 'FROM CommentNotify, Users '; - $q.= 'WHERE Users.ID = CommentNotify.UserID '; - $q.= 'AND CommentNotify.UserID != ' . uid_from_sid($_COOKIE['AURSID']) . ' '; - $q.= 'AND CommentNotify.PkgID = ' . intval($_REQUEST['ID']); - $result = db_query($q, $dbh); - $bcc = array(); - - if (mysql_num_rows($result)) { - while ($row = mysql_fetch_assoc($result)) { - array_push($bcc, $row['Email']); - } - - $q = 'SELECT Packages.* '; - $q.= 'FROM Packages '; - $q.= 'WHERE Packages.ID = ' . intval($_REQUEST['ID']); - $result = db_query($q, $dbh); - $row = mysql_fetch_assoc($result); - - # TODO: native language emails for users, based on their prefs - # Simply making these strings translatable won't work, users would be - # getting emails in the language that the user who posted the comment was in - $body = - 'from https://aur.archlinux.org/packages.php?ID=' - . $_REQUEST['ID'] . "\n" - . username_from_sid($_COOKIE['AURSID']) . " wrote:\n\n" - . $_POST['comment'] - . "\n\n---\nIf you no longer wish to receive notifications about this package, please go the the above package page and click the UnNotify button."; - $body = wordwrap($body, 70); - $bcc = implode(', ', $bcc); - $headers = "Bcc: $bcc\nReply-to: nobody@archlinux.org\nFrom: aur-notify@archlinux.org\nX-Mailer: AUR\n"; - @mail(' ', "AUR Comment for " . $row['Name'], $body, $headers); - } -} - - # Prompt visitor for comment -?> -<div class="pgbox"> - <form action='<?php echo $_SERVER['REQUEST_URI'] ?>' method='post'> - <div style="padding: 1%"> -<?php -if (isset($_REQUEST['comment']) && check_token()) { - echo '<b>' . __('Comment has been added.') . '</b>'; + echo '<p>' . __('Comment has been added.') . '</p>'; } ?> - <input type='hidden' name='ID' value="<?php echo intval($_REQUEST['ID']) ?>" /> - <?php echo __('Enter your comment below.') ?><br /> - <textarea name='comment' cols='80' rows='10' style="width: 100%"></textarea><br /> - <input type='hidden' name='token' value='<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>' /> - <input type='submit' value="<?php echo __("Submit") ?>" /> - <input type='reset' value="<?php echo __("Reset") ?>" /> - </div> + <div> + <input type="hidden" name="ID" value="<?php echo intval($_REQUEST['ID']) ?>" /> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> + </div> + <p> + <label for="id_comment"><?php echo __("Comment") . ':' ?></label> + <textarea id="id_comment" name="comment" cols="80" rows="10"></textarea> + </p> + <p> + <label></label> + <input type="submit" value="<?php echo __("Add Comment") ?>" /> + </p> + </fieldset> </form> </div> diff --git a/web/template/pkg_comments.php b/web/template/pkg_comments.php index 9dd50041..02f49633 100644 --- a/web/template/pkg_comments.php +++ b/web/template/pkg_comments.php @@ -1,46 +1,43 @@ -<div class="pgbox"> <?php $uid = uid_from_sid($SID); -while (list($indx, $carr) = each($comments)) { ?> - <div class="comment-header"><?php - - if ($SID) { - $carr['UserName'] = "<a href=\"account.php?Action=AccountInfo&ID={$carr['UsersID']}\">{$carr['UserName']}</a>"; - } - - $commentHeader = '<p style="display:inline;">' . __('Comment by: %s on %s', $carr['UserName'], gmdate('r', $carr['CommentTS'])) . '</p>'; - - if (canDeleteCommentArray($carr, $atype, $uid)) { - $durl = '<form method="post" action="packages.php?ID='.$row['ID'].'">'; - $durl.= '<fieldset style="display:inline;">'; - $durl.= '<input type="hidden" name="action" value="do_DeleteComment" />'; - $durl.= '<input type="hidden" name="comment_id" value="'.$carr['ID'].'" />'; - $durl.= '<input type="hidden" name="token" value="'.htmlspecialchars($_COOKIE['AURSID']).'" />'; - $durl.= '<input type="image" src="images/x.png" '; - $durl.= ' alt="'.__("Delete comment").'" name="submit" value="1" '; - $durl.= ' /> '; - $durl.= '</fieldset>'; - - $commentHeader = $durl.$commentHeader."</form>"; - } - - echo $commentHeader; -?></div> - <blockquote class="comment-body"> - <div> -<?php echo parse_comment($carr['Comments']) ?> - </div> - </blockquote> -<?php -} +$count = package_comments_count($_GET['ID']); ?> +<div id="news"> + <h3> + <a href="<?php echo htmlentities($_SERVER['REQUEST_URI'], ENT_QUOTES) ?>&comments=all" title="<?php echo __('View all %s comments' , $count) ?>"><?php echo __('Latest Comments') ?></a> + <span class="arrow"></span> + </h3> + + <?php while (list($indx, $row) = each($comments)): ?> + <?php if ($SID): + $row['UserName'] = "<a href=\"account.php?Action=AccountInfo&ID={$row['UsersID']}\">{$row['UserName']}</a>"; + endif; ?> + <h4> + <?php if (canDeleteCommentArray($row, $atype, $uid)): ?> + <form method="post" action="packages.php?ID=<?php echo $row['ID'] ?>"> + <fieldset style="display:inline;"> + <input type="hidden" name="action" value="do_DeleteComment" /> + <input type="hidden" name="comment_id" value="<?php echo $row['ID'] ?>" /> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="image" src="images/x.png" alt="<?php echo __('Delete comment') ?> name="submit" value="1" /> + </fieldset> + </form> + <?php endif; ?> + <?php echo __('Comment by %s', $row['UserName']) ?> + </h4> + <p class="timestamp"><?php echo gmdate('Y-m-d H:i', $row['CommentTS']) ?></p> + <div class="article-content"> + <p> + <?php echo parse_comment($row['Comments']) ?> + </p> + </div> + <?php endwhile; ?> </div> -<?php -$count = package_comments_count($_GET['ID']); -if ($count > 10 && !isset($_GET['comments'])) { - echo '<div class="pgbox">'; - echo '<a href="'. $_SERVER['REQUEST_URI'] . '&comments=all">'. __('Show all %s comments', $count) . '</a>'; - echo '</div>'; -} -?> +<?php if ($count > 10 && !isset($_GET['comments'])): ?> +<div id="news"> + <h3> + <a href="<?php echo $_SERVER['REQUEST_URI'] ?>&comments=all" title="<?php echo __('View all %s comments', $count) ?>"><?php echo __('All comments', $count) ?></a> + </h3> +</div> +<?php endif; ?> diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index 193af848..b41fdede 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -3,177 +3,188 @@ $atype = account_from_sid($SID); $uid = uid_from_sid($SID); $pkgid = intval($_REQUEST['ID']); -if ($uid == $row["MaintainerUID"] or - ($atype == "Developer" or $atype == "Trusted User")) { - $catarr = pkgCategories(); - $edit_cat = "<form method='post' action='packages.php?ID=".$pkgid."'>\n"; - $edit_cat.= "<p>"; - $edit_cat.= "<input type='hidden' name='action' value='do_ChangeCategory' />"; - if ($SID) { - $edit_cat.= "<input type='hidden' name='token' value='".htmlspecialchars($_COOKIE['AURSID'])."' />"; - } - $edit_cat.= "<span class='f3'>" . __("Category") . ":</span> "; - $edit_cat.= "<select name='category_id'>\n"; - foreach ($catarr as $cid => $catname) { - $edit_cat.= "<option value='$cid'"; - if ($cid == $row["CategoryID"]) { - $edit_cat.=" selected='selected'"; - } - $edit_cat.=">".$catname."</option>"; - } - $edit_cat.= "</select> <input type='submit' value='" . __("Change category") . "' />"; - $edit_cat.= "</p>"; - $edit_cat.= "</form>"; +$catarr = pkgCategories(); -} -else { - $edit_cat = "<span class='f3'>" . __("Category") . ": " . $row['Category'] . "</span>"; -} +$submitter = username_from_id($row["SubmitterUID"]); +$maintainer = username_from_id($row["MaintainerUID"]); -if ($row["SubmitterUID"]) { - $submitter = username_from_id($row["SubmitterUID"]); - if ($SID) { - $submitter = '<a href="account.php?Action=AccountInfo&ID=' . htmlspecialchars($row['SubmitterUID'], ENT_QUOTES) . '">' . htmlspecialchars($submitter) . '</a>'; - } - -} else { - $submitter = "None"; -} - -if ($row["MaintainerUID"]) { - $maintainer = username_from_id($row["MaintainerUID"]); - if ($SID) { - $maintainer = '<a href="account.php?Action=AccountInfo&ID=' . htmlspecialchars($row['MaintainerUID'], ENT_QUOTES) . '">' . htmlspecialchars($maintainer) . '</a>'; - } - -} else { - $maintainer = "None"; -} - -$votes = __('Votes') . ': ' . $row['NumVotes']; -if ($atype == "Developer" or $atype == "Trusted User") { - $votes = "<a href=\"voters.php?ID=$pkgid\">$votes</a>"; -} +$votes = $row['NumVotes']; # In case of wanting to put a custom message $msg = __('unknown'); $license = empty($row['License']) ? $msg : $row['License']; # Print the timestamps for last updates -$updated_time = ($row["ModifiedTS"] == 0) ? $msg : gmdate("r", intval($row["ModifiedTS"])); -$submitted_time = ($row["SubmittedTS"] == 0) ? $msg : gmdate("r", intval($row["SubmittedTS"])); -$out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("r", intval($row["OutOfDateTS"])); +$updated_time = ($row["ModifiedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($row["ModifiedTS"])); +$submitted_time = ($row["SubmittedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($row["SubmittedTS"])); +$out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("Y-m-d", intval($row["OutOfDateTS"])); -?> -<div class="pgbox"> - <div class="pgboxtitle"><span class="f3"><?php echo __("Package Details") ?></span></div> - <div class="pgboxbody"> +$urlpath = URL_DIR . substr($row['Name'], 0, 2) . "/" . $row['Name']; - <p> - <span class='f2'><?php echo htmlspecialchars($row['Name']) . ' ' . htmlspecialchars($row['Version']) ?></span><br /> - <span class='f3'><a href="<?php echo htmlspecialchars($row['URL'], ENT_QUOTES) . '">' . htmlspecialchars($row['URL']) ?></a></span><br /> - <span class='f3'><?php echo htmlspecialchars($row['Description'], ENT_QUOTES); ?></span> - </p> +$deps = package_dependencies($row["ID"]); +$requiredby = package_required($row["Name"]); - <?php echo $edit_cat ?> - - <p> - <span class='f3'><?php echo __('Submitter') .': ' . $submitter ?></span><br /> - <span class='f3'><?php echo __('Maintainer') .': ' . $maintainer ?></span><br /> - <span class='f3'><?php echo $votes ?></span> - </p> - - <p><span class='f3'><?php echo __('License') . ': ' . htmlspecialchars($license) ?></span></p> - - <p> - <span class='f3'> - <?php echo __('Last Updated') . ': ' . $updated_time ?><br /> - <?php echo __('First Submitted') . ': '. $submitted_time ?> - </span> - </p> +# $sources[0] = 'src'; +$sources = package_sources($row["ID"]); +?> +<div id="pkgdetails" class="box"> + <h2><?php echo __('Package Details') . ': ' . htmlspecialchars($row['Name']) . ' ' . htmlspecialchars($row['Version']) ?></h2> + <div id="detailslinks" class="listing"> + <div id="actionlist"> + <h4>Package Actions</h4> + <ul class="small"> + <li><a href="<?php echo $urlpath ?>/PKGBUILD"><?php echo __('View PKGBUILD') ?></a></li> + <li><a href="<?php echo $urlpath . '/' . $row['Name'] ?>.tar.gz"><?php echo __('Download tarball') ?></a></li> + <li><span class="flagged"><?php if ($row["OutOfDateTS"] !== NULL) { echo __('Flagged out-of-date')." (${out_of_date_time})"; } ?></span></li> + </ul> + </div> + </div> - <p><span class='f3'> + <table id="pkginfo"> + <tr> + <th><?php echo __('Description') . ': ' ?></th> + <td class="wrap"><?php echo htmlspecialchars($row['Description']); ?></td> + </tr> + <tr> + <th>Upstream URL:</th> + <td><a href="<?php echo htmlspecialchars($row['URL'], ENT_QUOTES) ?>" title="<?php echo __('Visit the website for') . ' ' . htmlspecialchars( $row['Name'])?>"><?php echo htmlspecialchars($row['URL'], ENT_QUOTES) ?></a></td> + </tr> + <tr> + <th><?php echo __('Category') . ': ' ?></th> <?php - $urlpath = URL_DIR . substr($row['Name'], 0, 2) . "/" . $row['Name']; - print "<a href='$urlpath/" . $row['Name'] . ".tar.gz'>".__("Tarball")."</a> :: "; - print "<a href='$urlpath/PKGBUILD'>".__("PKGBUILD")."</a></span>"; - - if ($row["OutOfDateTS"] !== NULL) { - echo "<br /><span class='f6'>".__("This package has been flagged out of date.")." (${out_of_date_time})</span>"; - } +if ($SID && ($uid == $row["MaintainerUID"] || + ($atype == "Developer" || $atype == "Trusted User"))): ?> - </p> + <td> + <form method="post" action="packages.php?ID=<?php echo $pkgid ?>"> + <div> + <input type="hidden" name="action" value="do_ChangeCategory" /> + <?php if ($SID): ?> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <?php endif; ?> + <select name="category_id"> <?php - - $deps = package_dependencies($row["ID"]); - $requiredby = package_required($row["Name"]); - - if (count($deps) > 0 || count($requiredby) > 0) { - echo '<p>'; - } - - if (count($deps) > 0) { - echo "<span class='boxSoftTitle'><span class='f3'>". __("Dependencies")."</span></span>"; - - while (list($k, $darr) = each($deps)) { - # darr: (DepName, DepCondition, PackageID), where ID is NULL if it didn't exist - if (!is_null($darr[2])) { - echo " <a href='packages.php?ID=".$darr[2]."'>".$darr[0].$darr[1]."</a>"; - } else { - echo " <a href='http://www.archlinux.org/packages/?q=".urlencode($darr[0])."'>".$darr[0].$darr[1]."</a>"; - } - } - - if (count($requiredby) > 0) { - echo '<br />'; - } - } - - if (count($requiredby) > 0) { - echo "<span class='boxSoftTitle'><span class='f3'>". __("Required by")."</span></span>"; - - while (list($k, $darr) = each($requiredby)) { - # darr: (PackageName, PackageID) - echo " <a href='packages.php?ID=".$darr[1]."'>".$darr[0]."</a>"; - } - } - - if (count($deps) > 0 || count($requiredby) > 0) { - echo '</p>'; - } - - - # $sources[0] = 'src'; - $sources = package_sources($row["ID"]); - - if (count($sources) > 0) { - + foreach ($catarr as $cid => $catname): ?> - <div class='boxSoftTitle'><span class='f3'><?php echo __('Sources') ?></span></div> - <div> + <option value="<?php echo $cid ?>"<?php if ($cid == $row["CategoryID"]) { ?> selected="selected" <?php } ?>><?php echo $catname ?></option> + <?php endforeach; ?> + </select> + <input type="submit" value="<?php echo __('Change category') ?>"/> + </div> + </form> +<?php else: ?> + <td> + <a href="packages.php?C=<?php echo $row['CategoryID'] ?>"><?php print $row['Category'] ?></a> +<?php endif; ?> + </td> + <tr> + <th><?php echo __('License') . ': ' ?></th> + <td><?php echo htmlspecialchars($license) ?></td> + </tr> + <tr> + <th><?php echo __('Submitter') .': ' ?></th> <?php - while (list($k, $src) = each($sources)) { - $src = explode('::', $src); - $parsed_url = parse_url($src[0]); - - if (isset($parsed_url['scheme']) || isset($src[1])) { - # It is an external source - echo "<a href=\"" . htmlspecialchars((isset($src[1]) ? $src[1] : $src[0]), ENT_QUOTES) . "\">" . htmlspecialchars($src[0]) . "</a><br />\n"; - } - else { - $src = $src[0]; - # It is presumably an internal source - echo "<span class='f8'>" . htmlspecialchars($src) . "</span>"; - echo "<br />\n"; - } - } +if ($row["SubmitterUID"]): + if ($SID): ?> - </div> + <td><a href="account.php?Action=AccountInfo&ID=<?php echo htmlspecialchars($row['SubmitterUID'], ENT_QUOTES) ?>" title="<?php echo __('View account information for')?> <?php echo htmlspecialchars($submitter) ?>"><?php echo htmlspecialchars($submitter) ?></a></td> +<?php else: ?> + <td><?php echo htmlspecialchars($submitter) ?></td> + <?php endif; ?> +<?php else: ?> + <td>None</td> +<?php endif; ?> + <tr> + <th><?php echo __('Maintainer') .': ' ?></th> <?php - } - +if ($row["MaintainerUID"]): + if ($SID): +?> + <td><a href="account.php?Action=AccountInfo&ID=<?php echo htmlspecialchars($row['MaintainerUID'], ENT_QUOTES) ?>" title="<?php echo __('View account information for')?> <?php echo htmlspecialchars($maintainer) ?>"><?php echo htmlspecialchars($maintainer) ?></a></td> + <?php else: ?> + <td><?php echo htmlspecialchars($maintainer) ?></td> + <?php endif; ?> +<?php else: ?> + <td>None</td> +<?php endif; ?> + </tr> + <tr> + <th><?php echo __('Votes') . ': ' ?></th> +<?php +if ($atype == "Developer" || $atype == "Trusted User"): +?> + <td><a href="voters.php?ID=<?php echo$pkgid ?>"><?php echo $votes ?></a> +<?php else: ?> + <td><?php echo $votes ?></td> +<?php endif; ?> + </tr> + <tr> + <th><?php echo __('First Submitted') . ': ' ?></th> + <td><?php echo $submitted_time ?></td> + </tr> + <tr> + <th><?php echo __('Last Updated') . ': ' ?></th> + <td><?php echo $updated_time ?></td> + </tr> + </table> + + <div id="metadata"> + <div id="pkgdeps" class="listing"> + <h3><?php echo __('Dependencies') . " (" . count($deps) . ")"?></h3> +<?php if (count($deps) > 0): ?> + <ul> +<?php + while (list($k, $darr) = each($deps)): + # darr: (DepName, DepCondition, PackageID), where ID is NULL if it didn't exist + if (!is_null($darr[2])): +?> + <li><a href="packages.php?ID=<?php echo $darr[2]?>" title="<?php echo __('View packages details for').' '.$darr[0].$darr[1]?>"><?php echo $darr[0].$darr[1]?></a></li> + <?php else: ?> + <li><a href="http://www.archlinux.org/packages/?q=<?php echo urlencode($darr[0])?>" title="<?php echo __('View packages details for').' '.$darr[0].$darr[1] ?>"><?php echo $darr[0].$darr[1] ?></a></li> + <?php endif; ?> + <?php endwhile; ?> + </ul> + </div> +<?php endif; ?> + <div id="pkgreqs" class="listing"> + <h3><?php echo __('Required by') . " (" . count($requiredby) . ")"?></h3> +<?php if (count($requiredby) > 0): ?> + <ul> +<?php + # darr: (PackageName, PackageID) + while (list($k, $darr) = each($requiredby)): ?> + <li><a href="packages.php?ID=<?php echo $darr[1] ?>" title="<?php echo __('View packages details for').' '.$darr[0]?>"><?php echo $darr[0] ?></a></li> + <?php endwhile; ?> + </ul> +<?php endif; ?> + </div> + <div id="pkgfiles" class="listing"> + <h3><?php echo __('Sources') ?></h3> + </div> +<?php if (count($sources) > 0): ?> + <div> + <ul> +<?php + while (list($k, $src) = each($sources)): + $src = explode('::', $src); + $parsed_url = parse_url($src[0]); + # It is an external source + if (isset($parsed_url['scheme']) || isset($src[1])): +?> + <li><a href="<?php echo htmlspecialchars((isset($src[1]) ? $src[1] : $src[0]), ENT_QUOTES) ?>"><?php echo htmlspecialchars($src[0]) ?> </a></li> +<?php + else: + # It is presumably an internal source + $src = $src[0]; +?> + <li><?php echo htmlspecialchars($src) ?></li> + <?php endif; ?> + <?php endwhile; ?> + </ul> + </div> +<?php endif; ?> </div> </div> diff --git a/web/template/pkg_search_form.php b/web/template/pkg_search_form.php index 53d34fe3..7997bb1d 100644 --- a/web/template/pkg_search_form.php +++ b/web/template/pkg_search_form.php @@ -1,126 +1,128 @@ -<?php include_once('pkgfuncs.inc.php') ?> +<?php +include_once('pkgfuncs.inc.php'); + +$searchby = array( + 'nd' => __('Name, Description'), + 'n' => __('Name Only'), + 'x' => __('Exact name'), + 'm' => __('Maintainer'), + 's' => __('Submitter') +); + +$outdated_flags = array( + '' => __('All'), + 'on' => __('Flagged'), + 'off' => __('Not Flagged') +); + +$sortby = array( + 'n' => __('Name'), + 'c' => __('Category'), + 'v' => __('Votes'), + 'w' => __('Voted'), + 'o' => __('Notify'), + 'm' => __('Maintainer'), + 'a' => __('Age') +); + +$orderby = array( + 'a' => __('Ascending'), + 'd' => __('Descending') +); + +$pages = array(50, 100, 250); +?> + +<div id="pkglist-search" class="box filter-criteria"> +<h2><?php print __("Search Criteria"); ?></h2> -<div class='pgbox'> <form action='packages.php' method='get'> -<div class='pgboxtitle'> - <span class='f3'><?php print __("Search Criteria"); ?></span> - <input type='hidden' name='O' value='0' /> - <input type='text' name='K' size='30' value="<?php if (isset($_REQUEST["K"])) { print stripslashes(trim(htmlspecialchars($_REQUEST["K"], ENT_QUOTES))); } ?>" maxlength='35' /> - <input type='submit' style='min-width:80px' class='button' name='do_Search' value='<?php print __("Go"); ?>' /> - <?php if (!empty($_GET['detail'])): ?> - <input type='submit' style='min-width:80px' class='button' name='do_Orphans' value='<?php print __("Orphans"); ?>' /> - <?php endif; ?> - <a href="?<?php print mkurl('detail=' . ((!empty($_GET['detail'])) ? 0 : 1) ) ?>"><?php print __("Advanced"); ?></a> -</div> + <p><input type='hidden' name='O' value='0' /></p> - <?php if (!empty($_GET['detail'])): ?> - <div id="advanced-search" class="blue"> - <input type="hidden" name="detail" value="1" /> - <ul> - <li> - <label><?php print __("Category"); ?></label> - <select name='C'> - <option value='0'><?php print __("Any"); ?></option> - <?php - foreach (pkgCategories() as $id => $cat): - if (isset($_REQUEST['C']) && $_REQUEST['C'] == $id): - ?> - <option value="<?php print $id ?>" selected="selected"><?php print $cat; ?></option> - <?php else: ?> - <option value="<?php print $id ?>"><?php print $cat; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - <li> - <label><?php print __("Search by"); ?></label> - <select name='SeB'> - <?php - $searchby = array('nd' => __('Name, Description'), 'n' => __('Name Only'), 'x' => __('Exact name'), 'm' => __('Maintainer'), 's' => __('Submitter')); - foreach ($searchby as $k => $v): - if (isset($_REQUEST['SeB']) && $_REQUEST['SeB'] == $k): - ?> - <option value="<?php print $k; ?>" selected="selected"><?php print $v; ?></option> - <?php else: ?> - <option value="<?php print $k; ?>"><?php print $v; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - <li> - <label><?php print __("Sort by"); ?></label> - <select name='SB'> - <?php - $sortby = array('n' => __('Name'), 'c' => __('Category'), 'v' => __('Votes'), 'w' => __('Voted'), 'o' => __('Notify'), 'm' => __('Maintainer'), 'a' => __('Age')); - foreach ($sortby as $k => $v): - if (isset($_REQUEST['SB']) && $_REQUEST['SB'] == $k): - ?> - <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> - <?php else: ?> - <option value='<?php print $k; ?>'><?php print $v; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - <li> - <label><?php print __("Sort order"); ?></label> - <select name='SO'> - <?php - $orderby = array('a' => __('Ascending'), 'd' => __('Descending')); - foreach ($orderby as $k => $v): - if (isset($_REQUEST['SO']) && $_REQUEST['SO'] == $k): - ?> - <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> - <?php else: ?> - <option value='<?php print $k; ?>'><?php print $v; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - <li> - <label><?php print __("Per page"); ?></label> - <select name='PP'> - <?php - $pages = array(50, 100, 250); - foreach ($pages as $i): - if (isset($_REQUEST['PP']) && $_REQUEST['PP'] == $i): - ?> - <option value="<?php print $i; ?>" selected="selected"><?php print $i; ?></option> - <?php else: ?> - <option value="<?php print $i; ?>"><?php print $i; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - <li> - <label><?php echo __('Out of Date'); ?></label> - <select name='outdated'> - <?php - $outdated_flags = array('' => __('All'), 'on' => __('Flagged'), 'off' => __('Not Flagged')); - foreach ($outdated_flags as $k => $v): - if (isset($_REQUEST['outdated']) && $_REQUEST['outdated'] == $k): - ?> - <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> - <?php else: ?> - <option value='<?php print $k; ?>'><?php print $v; ?></option> - <?php - endif; - endforeach; - ?> - </select> - </li> - </ul> - </div> - <?php endif; ?> + <fieldset> + <legend><?php echo __('Enter search criteria') ?></legend> + <div> + <label for="id_category"><?php print __("Category"); ?></label> + <select name='C' id="id_category"> + <option value='0'><?php print __("Any"); ?></option> + <?php foreach (pkgCategories() as $id => $cat): ?> + <?php if (isset($_REQUEST['C']) && $_REQUEST['C'] == $id): ?> + <option value="<?php print $id ?>" selected="selected"><?php print $cat; ?></option> + <?php else: ?> + <option value="<?php print $id ?>"><?php print $cat; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label for="id_method"><?php print __("Search by"); ?></label> + <select name='SeB'> + <?php foreach ($searchby as $k => $v): ?> + <?php if (isset($_REQUEST['SeB']) && $_REQUEST['SeB'] == $k): ?> + <option value="<?php print $k; ?>" selected="selected"><?php print $v; ?></option> + <?php else: ?> + <option value="<?php print $k; ?>"><?php print $v; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label for="id_q"><?php print __("Keywords"); ?></label> + <input type='text' name='K' size='30' value="<?php if (isset($_REQUEST["K"])) { print stripslashes(trim(htmlspecialchars($_REQUEST["K"], ENT_QUOTES))); } ?>" maxlength='35' /> + </div> + <div> + <label for="id_out_of_date"><?php echo __('Out of Date'); ?></label> + <select name='outdated'> + <?php foreach ($outdated_flags as $k => $v): ?> + <?php if (isset($_REQUEST['outdated']) && $_REQUEST['outdated'] == $k): ?> + <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> + <?php else: ?> + <option value='<?php print $k; ?>'><?php print $v; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label for="id_sort_by"><?php print __("Sort by"); ?></label> + <select name='SB'> + <?php foreach ($sortby as $k => $v): ?> + <?php if (isset($_REQUEST['SB']) && $_REQUEST['SB'] == $k): ?> + <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> + <?php else: ?> + <option value='<?php print $k; ?>'><?php print $v; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label for="id_order_by"><?php print __("Sort order"); ?></label> + <select name='SO'> + <?php foreach ($orderby as $k => $v): ?> + <?php if (isset($_REQUEST['SO']) && $_REQUEST['SO'] == $k): ?> + <option value='<?php print $k; ?>' selected="selected"><?php print $v; ?></option> + <?php else: ?> + <option value='<?php print $k; ?>'><?php print $v; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label for="id_per_page"><?php print __("Per page"); ?></label> + <select name='PP'> + <?php foreach ($pages as $i): ?> + <?php if (isset($_REQUEST['PP']) && $_REQUEST['PP'] == $i): ?> + <option value="<?php print $i; ?>" selected="selected"><?php print $i; ?></option> + <?php else: ?> + <option value="<?php print $i; ?>"><?php print $i; ?></option> + <?php endif; ?> + <?php endforeach; ?> + </select> + </div> + <div> + <label> </label> + <input type='submit' class='button' name='do_Search' value='<?php print __("Go"); ?>' /> + <input type='submit' class='button' name='do_Orphans' value='<?php print __("Orphans"); ?>' /> + </div> + </fieldset> </form> </div> diff --git a/web/template/pkg_search_results.php b/web/template/pkg_search_results.php index 609dc191..90766751 100644 --- a/web/template/pkg_search_results.php +++ b/web/template/pkg_search_results.php @@ -1,140 +1,124 @@ -<?php if (!$result) { ?> - <div class='pgboxbody'><?php print __("Error retrieving package list.") ?></div> -<?php } elseif ($total == 0) { ?> - <div class='pgboxbody'><?php print __("No packages matched your search criteria.") ?></div> -<?php } else { ?> - <form action='packages.php?<?php echo htmlentities($_SERVER['QUERY_STRING']) ?>' method='post'> - <div class="pgbox"> - <div class="pgboxtitle"> - <span class='f3'><?php print __("Package Listing") ?></span> - </div> - - - - -<table width='100%' cellspacing='0' cellpadding='2'> -<tr> - <?php if ($SID): ?> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'> </th> - <?php endif; ?> - - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?<?php print mkurl('SB=c&SO=' . $SO_next) ?>'><?php print __("Category") ?></a> - </span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom; text-align: center;'><span class='f2'> - <a href='?<?php print mkurl('SB=n&SO=' . $SO_next) ?>'><?php print __("Name") ?></a> - </span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?<?php print mkurl('SB=v&SO=' . $SO_next) ?>'><?php print __("Votes") ?></a> - </span></th> - - <?php if ($SID): ?> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?<?php print mkurl('SB=w&SO=' . $SO_next) ?>'><?php print __("Voted") ?></a> - </span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?<?php print mkurl('SB=o&SO=' . $SO_next) ?>'><?php print __("Notify") ?></a> - </span></th> - <?php endif; ?> - <th style='border-bottom: #666 1px solid; vertical-align: bottom; text-align: center;'><span class='f2'><?php print __("Description") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?<?php print mkurl('SB=m&SO=' . $SO_next) ?>'><?php print __("Maintainer") ?></a> - </span></th> -</tr> - <?php if (isset($_COOKIE['AURSID'])) { $atype = account_from_sid($_COOKIE['AURSID']); } else { $atype = ""; } -for ($i = 0; $row = mysql_fetch_assoc($result); $i++) { - (($i % 2) == 0) ? $c = "data1" : $c = "data2"; - if ($row["OutOfDateTS"] !== NULL): $c = "outofdate"; endif; -?> -<tr> - <?php if ($SID): ?> - <td class='<?php print $c ?>'><input type='checkbox' name='IDs[<?php print $row["ID"] ?>]' value='1' /></td> - <?php endif; ?> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'><?php print htmlspecialchars($row["Category"]) ?></span></span></td> - <td class='<?php print $c ?>'><span class='f4'><a href='packages.php?ID=<?php print $row["ID"] ?>'><span class='black'><?php print htmlspecialchars($row["Name"]) ?> <?php print htmlspecialchars($row["Version"]) ?></span></a></span></td> - <td class='<?php print $c ?>' style="text-align: right"><span class='f5'><span class='blue'><?php print $row["NumVotes"] ?></span></span></td> - <?php if ($SID): ?> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'> - <?php if (isset($row["Voted"])): ?> - <?php print __("Yes") ?></span></span></td> - <?php else: ?> - </span></span></td> - <?php endif; ?> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'> - <?php if (isset($row["Notify"])): ?> - <?php print __("Yes") ?></span></span></td> - <?php else: ?> - </span></span></td> - <?php endif; ?> - <?php endif; ?> - <td class='<?php print $c ?>'><span class='f4'><span class='blue'> - <?php print htmlspecialchars($row['Description'], ENT_QUOTES); ?></span></span></td> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'> - <?php if (isset($row["Maintainer"])): ?> - <a href='packages.php?K=<?php print htmlspecialchars($row['Maintainer'], ENT_QUOTES) ?>&SeB=m'><?php print htmlspecialchars($row['Maintainer']) ?></a> - <?php else: ?> - <span style='color: blue; font-style: italic;'><?php print __("orphan") ?></span> - <?php endif; ?> - </span></span></td> -</tr> -<?php } ?> - </table> -</div> <!-- .pgbox ??! --> +if (!$result): ?> + <div class="box"><p><?php echo __("Error retrieving package list.") ?></p></div> +<?php elseif ($total == 0): ?> + <div class="box"><p><?php echo __("No packages matched your search criteria.") ?></p></div> +<?php else: ?> + <div id="pkglist-results" class="box"> + <div id="pkglist-stats-top"> + <p><?php echo __('%s Packages found. Showing %s - %s', $total, $first, $last) ?></p> + <p class="pkglist-nav"> + <?php foreach ($templ_pages as $pagenr => $pagestart): ?> + <?php if ($pagestart === false): ?> + <span class="page"><?php echo $pagenr ?></span> + <?php elseif ($pagestart + 1 == $first): ?> + <span class="page"><?php echo $pagenr ?></span> + <?php else: ?> + <a class="page" href="packages.php?<?php echo mkurl('O=' . $pagestart) ?>"><?php echo $pagenr ?></a> + <?php endif; ?> + <?php endforeach; ?> + </p> + </div> + + <form id="pkglist-results-form" method="post" action="packages.php?<?php echo htmlentities($_SERVER['QUERY_STRING']) ?>"> + <table class="results"> + <thead> + <tr> + <?php if ($SID): ?> + <th> </th> + <?php endif; ?> + <th><a href="?<?php echo mkurl('SB=c&SO=' . $SO_next) ?>"><?php echo __("Category") ?></a></th> + <th><a href="?<?php echo mkurl('SB=n&SO=' . $SO_next) ?>"><?php echo __("Name") ?></a></th> + <th><a href="?<?php echo mkurl('SB=v&SO=' . $SO_next) ?>"><?php echo __("Votes") ?></a></th> + <?php if ($SID): ?> + <th><a href="?<?php echo mkurl('SB=w&SO=' . $SO_next) ?>"><?php echo __("Voted") ?></a></th> + <th><a href="?<?php echo mkurl('SB=o&SO=' . $SO_next) ?>"><?php echo __("Notify") ?></a></th> + <?php endif; ?> + <th><?php echo __("Description") ?></th> + <th><a href="?<?php echo mkurl('SB=m&SO=' . $SO_next) ?>"><?php echo __("Maintainer") ?></a></th> + </tr> + </thead> + <tbody> + + <?php while (list($indx, $row) = each($searchresults)): ?> + <tr class="<?php echo ($indx % 2 == 0) ? 'odd' : 'even' ?>"> + <?php if ($SID): ?> + <td><input type="checkbox" name="IDs[<?php echo $row["ID"] ?>]" value="1" /></td> + <?php endif; ?> + <td><?php echo htmlspecialchars($row["Category"]) ?></td> + <td><a href="packages.php?ID=<?php echo $row["ID"] ?>"><?php echo htmlspecialchars($row["Name"]) . ' ' . htmlspecialchars($row["Version"]) ?></a></td> + <td><?php echo $row["NumVotes"] ?></td> + <?php if ($SID): ?> + <td> + <?php if (isset($row["Voted"])): ?> + <?php echo __("Yes") ?> + <?php endif; ?> + </td> + <td> + <?php if (isset($row["Notify"])): ?> + <?php echo __("Yes") ?> + <?php endif; ?> + </td> + <?php endif; ?> + <td><?php echo htmlspecialchars($row['Description'], ENT_QUOTES); ?></td> + <td> + <?php if (isset($row["Maintainer"])): ?> + <a href="packages.php?K=<?php echo htmlspecialchars($row['Maintainer'], ENT_QUOTES) ?>&SeB=m"><?php echo htmlspecialchars($row['Maintainer']) ?></a> + <?php else: ?> + <span><?php echo __("orphan") ?></span> + <?php endif; ?> + </td> + </tr> + <?php endwhile; ?> + + </tbody> + </table> + <div id="pkglist-stats-bottom"> + <p><?php echo __('%s Packages found. Showing %s - %s', $total, $first, $last) ?></p> + + <p class="pkglist-nav"> + <?php foreach ($templ_pages as $pagenr => $pagestart): ?> + <?php if ($pagestart === false): ?> + <span class="page"><?php echo $pagenr ?></span> + <?php elseif ($pagestart + 1 == $first): ?> + <span class="page"><?php echo $pagenr ?></span> + <?php else: ?> + <a class="page" href="packages.php?<?php echo mkurl('O=' . $pagestart) ?>"><?php echo $pagenr ?></a> + <?php endif; ?> + <?php endforeach; ?> + </p> + </div> - <div class="pgbox pkg_search_results_footer"> - <div class="legend_and_actions"> - <div class="legend"> - <span class='f3'><?php echo __('Legend') ?></span> - <span class="outofdate"><?php print __('Out of Date') ?></span> - </div> - <?php if ($SID): ?> - <div> - <select name='action'> - <option><?php print __("Actions") ?></option> - <option value='do_Flag'><?php print __("Flag Out-of-date") ?></option> - <option value='do_UnFlag'><?php print __("Unflag Out-of-date") ?></option> - <option value='do_Adopt'><?php print __("Adopt Packages") ?></option> - <option value='do_Disown'><?php print __("Disown Packages") ?></option> - <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> - <option value='do_Delete'><?php print __("Delete Packages") ?></option> - <?php endif; ?> - <option value='do_Notify'><?php print __("Notify") ?></option> - <option value='do_UnNotify'><?php print __("UnNotify") ?></option> - </select> + <?php if ($SID): ?> + <p> + <select name="action"> + <option><?php echo __("Actions") ?></option> + <option value="do_Flag"><?php echo __("Flag Out-of-date") ?></option> + <option value="do_UnFlag"><?php echo __("Unflag Out-of-date") ?></option> + <option value="do_Adopt"><?php echo __("Adopt Packages") ?></option> + <option value="do_Disown"><?php echo __("Disown Packages") ?></option> <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> - <label for='merge_Into'><?php print __("Merge into") ?></label> - <input type='text' id='merge_Into' name='merge_Into' /> - <input type='checkbox' name='confirm_Delete' value='1' /> <?php print __("Confirm") ?> + <option value="do_Delete"><?php echo __("Delete Packages") ?></option> <?php endif; ?> - <input type='hidden' name='token' value='<?php print htmlspecialchars($_COOKIE['AURSID']) ?>' /> - <input type='submit' class='button' style='width: 80px' value='<?php print __("Go") ?>' /> - </div> - <?php endif; # if ($SID) ?> - </div> <!-- .legend_and_actions --> - <div class="page_links"> - <div class="f4 blue"> - <?php print __("Showing results %s - %s of %s", $first, $last, $total) ?> - </div> - <div class="page_nav"> - <?php foreach($templ_pages as $pagenr => $pagestart) { ?> - <?php if ($pagestart === false) { ?> - <?php echo $pagenr ?> - <?php } else if ($pagestart + 1 == $first) { ?> - <span class="page_sel"><?php echo $pagenr ?></span> - <?php } else { ?> - <a class="page_num" href="packages.php?<?php print mkurl('O=' . ( $pagestart)) ?>"><?php echo $pagenr ?></a> - <?php } ?> - <?php } ?> - </div> - </div> <!-- .page_links --> - </div> <!-- .pgbox .pkg_search_results_footer --> - </form> -<?php } # search was successful and returned multiple results ?> + <option value="do_Notify"><?php echo __("Notify") ?></option> + <option value="do_UnNotify"><?php echo __("UnNotify") ?></option> + </select> + <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> + <label for="merge_Into"><?php echo __("Merge into") ?></label> + <input type="text" id="merge_Into" name="merge_Into" /> + <input type="checkbox" name="confirm_Delete" value="1" /> <?php echo __("Confirm") ?> + <?php endif; ?> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button" style="width: 80px" value="<?php echo __("Go") ?>" /> + </p> + <?php endif; # if ($SID) ?> + </form> + </div> +<?php endif; # search was successful and returned multiple results ?> diff --git a/web/template/search_accounts_form.php b/web/template/search_accounts_form.php index 9d6c40d0..9e8c241f 100644 --- a/web/template/search_accounts_form.php +++ b/web/template/search_accounts_form.php @@ -1,74 +1,74 @@ <br /> -<form action='account.php' method='post'> - <table border='0' cellpadding='0' cellspacing='0' width='80%' style="margin:0 auto;"> +<form action="account.php" method="post"> + <table> <tr> - <td align='left'><?php print __("Username"); ?>:</td> - <td align='left'> - <input type='text' size='30' maxlength='64' name='U' /> + <td align="left"><?php print __("Username"); ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="64" name="U" /> </td> </tr> <tr> - <td align='left'><?php print __("Account Type"); ?>:</td> - <td align='left'> + <td align="left"><?php print __("Account Type"); ?>:</td> + <td align="left"> <select name="T"> - <option value=''><?php print __("Any type"); ?></option> - <option value='u'><?php print __("Normal user"); ?></option> - <option value='t'><?php print __("Trusted user"); ?></option> - <option value='d'><?php print __("Developer"); ?></option> + <option value=""><?php print __("Any type"); ?></option> + <option value="u"><?php print __("Normal user"); ?></option> + <option value="t"><?php print __("Trusted user"); ?></option> + <option value="d"><?php print __("Developer"); ?></option> </select> </td> </tr> <tr> - <td align='left'><?php print __("Account Suspended"); ?>:</td> - <td align='left'> - <input type='checkbox' name='S' /> + <td align="left"><?php print __("Account Suspended"); ?>:</td> + <td align="left"> + <input type="checkbox" name="S" /> </td> </tr> <tr> - <td align='left'><?php print __("Email Address"); ?>:</td> - <td align='left'> - <input type='text' size='30' maxlength='64' name='E' /> + <td align="left"><?php print __("Email Address"); ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="64" name="E" /> </td> </tr> <tr> - <td align='left'><?php print __("Real Name"); ?>:</td> - <td align='left'> - <input type='text' size='30' maxlength='32' name='R' /> + <td align="left"><?php print __("Real Name"); ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="32" name="R" /> </td> </tr> <tr> - <td align='left'><?php print __("IRC Nick"); ?>:</td> - <td align='left'> - <input type='text' size='30' maxlength='32' name='I' /> + <td align="left"><?php print __("IRC Nick"); ?>:</td> + <td align="left"> + <input type="text" size="30" maxlength="32" name="I" /> </td> </tr> <tr> - <td align='left'><?php print __("Sort by"); ?>:</td> - <td align='left'> + <td align="left"><?php print __("Sort by"); ?>:</td> + <td align="left"> <select name="SB"> - <option value='u'><?php print __("Username"); ?></option> - <option value='t'><?php print __("Account Type"); ?></option> - <option value='r'><?php print __("Real Name"); ?></option> - <option value='i'><?php print __("IRC Nick"); ?></option> - <option value='v'><?php print __("Last vote"); ?></option> + <option value="u"><?php print __("Username"); ?></option> + <option value="t"><?php print __("Account Type"); ?></option> + <option value="r"><?php print __("Real Name"); ?></option> + <option value="i"><?php print __("IRC Nick"); ?></option> + <option value="v"><?php print __("Last vote"); ?></option> </select> </td> </tr> <tr> <td> </td> - <td align='left'> + <td align="left"> <br /> - <input type='hidden' name='Action' value='SearchAccounts' /> - <input type='submit' class='button' value="<?php print __("Search"); ?>" /> - <input type='reset' class='button' value="<?php print __("Reset"); ?>" /> + <input type="hidden" name="Action" value="SearchAccounts" /> + <input type="submit" class="button" value="<?php print __("Search"); ?>" /> + <input type="reset" class="button" value="<?php print __("Reset"); ?>" /> </td> </tr> diff --git a/web/template/stats/general_stats_table.php b/web/template/stats/general_stats_table.php index a100dfee..e2b12c7a 100644 --- a/web/template/stats/general_stats_table.php +++ b/web/template/stats/general_stats_table.php @@ -1,37 +1,36 @@ -<table class='boxSoft'> +<h3><?php echo __("Statistics") ?></h3> + +<table> <tr> - <th colspan='2' class='boxSoftTitle'><span class='f3'><?php print __("Statistics") ?></span></th> + <td><?php print __("Packages"); ?></td> + <td><?php print $unsupported_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Packages"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $unsupported_count; ?></span></td> + <td><?php print __("Orphan Packages"); ?></td> + <td><?php print $orphan_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Orphan Packages"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $orphan_count; ?></span></td> + <td><?php print __("Packages added in the past 7 days"); ?></td> + <td><?php print $add_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Packages added in the past 7 days"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $add_count; ?></span></td> + <td><?php print __("Packages updated in the past 7 days"); ?></td> + <td><?php print $update_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Packages updated in the past 7 days"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $update_count; ?></span></td> + <td><?php print __("Packages updated in the past year"); ?></td> + <td><?php print $update_year_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Packages updated in the past year"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $update_year_count; ?></span></td> + <td><?php print __("Packages never updated"); ?></td> + <td><?php print $never_update_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Packages never updated"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $never_update_count; ?></span></td> + <td><?php print __("Registered Users"); ?></td> + <td><?php print $user_count; ?></td> </tr> <tr> - <td class='boxSoft'><span class='f4'><?php print __("Registered Users"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $user_count; ?></span></td> - </tr> - <tr> - <td class='boxSoft'><span class='f4'><?php print __("Trusted Users"); ?></span></td> - <td class='boxSoft'><span class='f4'><?php print $tu_count; ?></span></td> + <td><?php print __("Trusted Users"); ?></td> + <td><?php print $tu_count; ?></td> </tr> </table> diff --git a/web/template/stats/updates_table.php b/web/template/stats/updates_table.php index 8da67320..b942dbcb 100644 --- a/web/template/stats/updates_table.php +++ b/web/template/stats/updates_table.php @@ -1,36 +1,16 @@ -<table class="boxSoft"> -<tr> -<th colspan="2" class="boxSoftTitle" style="text-align: right"> -<span class="f3"><?php print __("Recent Updates") ?><span class="f5"></span></span> -<a href="rss.php"><img src="images/feed-icon-14x14.png" alt="RSS Feed" /></a> -</th> -</tr> +<h3><?php echo __("Recent Updates") ?></h3> -<?php foreach ($newest_packages->getIterator() as $row): ?> -<tr> -<td class="boxSoft"> -<span class="f4"><span class="blue"> -<a href="packages.php?ID=<?php print intval($row["ID"]); ?>"> -<?php print htmlspecialchars($row["Name"]) . ' ' . htmlspecialchars($row["Version"]); ?> -</a></span></span> -</td> -<td class="boxSoft"> - -<?php -$mod_int = intval($row["ModifiedTS"]); -$sub_int = intval($row["SubmittedTS"]); - -if ($mod_int == $sub_int): - $modstring = '<img src="images/new.gif" alt="New!" /> ' . gmdate("r", $sub_int); -else: - $modstring = gmdate("r", $mod_int); -endif; -?> - -<span class="f4"><?php print $modstring; ?></span> -</td> -</tr> - -<?php endforeach; ?> +<a href="rss.php" title="Arch Package Updates RSS Feed" class="rss-icon"><img src="images/feed-icon-14x14.png" alt="RSS Feed" /></a> +<table> + <?php foreach ($newest_packages->getIterator() as $row): ?> + <tr> + <td> + <a href="packages.php?ID=<?php print intval($row["ID"]); ?>"><?php print htmlspecialchars($row["Name"]) . ' ' . htmlspecialchars($row["Version"]); ?></a> + </td> + <td> + <span><?php print gmdate("Y-m-d H:i", intval($row["ModifiedTS"])); ?></span> + </td> + </tr> + <?php endforeach; ?> </table> diff --git a/web/template/stats/user_table.php b/web/template/stats/user_table.php index 36a6b10c..0882119e 100644 --- a/web/template/stats/user_table.php +++ b/web/template/stats/user_table.php @@ -1,31 +1,21 @@ <?php - $username = username_from_sid($_COOKIE["AURSID"]); +$username = username_from_sid($_COOKIE["AURSID"]); ?> -<table class='boxSoft'> -<tr> -<th colspan='2' class='boxSoftTitle'> -<span class='f3'><?php print __("My Statistics"); ?></span> -</th> -</tr> -<tr> -<td class='boxSoft'> -<span class='f4'><a href="packages.php?SeB=m&L=2&K=<?php echo $username; ?>"> -<?php print __("Packages in unsupported"); ?></a></span> -</td> -<td class='boxSoft'> -<span class='f4'><?php print $maintainer_unsupported_count; ?></span> -</td> -</tr> -<tr> -<td class='boxSoft'> -<span class='f4'><a href="packages.php?SeB=m&outdated=on&K=<?php echo $username; ?>"> -<?php print __("Out of Date"); ?></a></span> -</td> -<td class='boxSoft'> -<span class='f4'> -<?php echo $flagged_outdated ?></span> -</td> -</tr> -</table> +<h3><?php echo __("My Statistics"); ?></h3> +<table> + <tr> + <td> + <a href="packages.php?SeB=m&L=2&K=<?php echo $username; ?>"> +<?php print __("Packages in unsupported"); ?></a> + </td> + <td><?php print $maintainer_unsupported_count; ?></td> + </tr> + <tr> + <td> + <a href="packages.php?SeB=m&outdated=on&K=<?php echo $username; ?>"><?php print __("Out of Date"); ?></a> + </td> + <td><?php echo $flagged_outdated ?></td> + </tr> +</table> diff --git a/web/template/tu_details.php b/web/template/tu_details.php index dde53a8c..38015e1e 100644 --- a/web/template/tu_details.php +++ b/web/template/tu_details.php @@ -1,79 +1,76 @@ -<div class="pgbox"> -<div class="pgboxtitle"><span class="f3"><?php print __("Proposal Details") ?></span></div> -<div class="pgboxbody"> -<?php -if ($isrunning == 1) { ?> -<p style='font-weight: bold; color: red'> -<?php print __("This vote is still running.") ?> -</p> -<?php -} ?> +<div class="box"> + <h2><?php print __("Proposal Details") ?></h2> -<p> -<?php echo __('User') ?>: <b> -<?php if (!empty($row['User'])) { ?> -<a href='packages.php?K=<?php print $row['User'] ?>&SeB=m'><?php print $row['User'] ?></a> -<?php } else { ?> -N/A -<?php } ?> -</b><br /> -<?php print __("Submitted: %s by %s", "<b>" . gmdate("r", $row['Submitted']) . "</b>", "<b>" . username_from_id($row['SubmitterID']) . "</b>") ?><br /> -<?php print __('End') ?>: <b><?php print gmdate("r", $row['End']) ?></b></p> + <?php if ($isrunning == 1): ?> + <p style="font-weight: bold; color: red"> + <?php print __("This vote is still running.") ?> + </p> + <?php endif; ?> -<p> -<?php print str_replace("\n", "<br />\n", htmlspecialchars($row['Agenda'])) ?> -</p> + <p> + <?php echo __("User") ?>: + <b> + <?php if (!empty($row['User'])): ?> + <a href="packages.php?K=<?php print $row['User'] ?>&SeB=m"><?php print $row['User'] ?></a> + <?php else: ?> + N/A + <?php endif; ?> + </b> + <br /> + <?php print __("Submitted: %s by %s", "<b>" . gmdate("Y-m-d H:i", $row['Submitted']) . "</b>", "<b>" . username_from_id($row['SubmitterID']) . "</b>") ?> + <br /> + <?php print __("End") ?>: + <b><?php print gmdate("Y-m-d H:i", $row['End']) ?></b> + </p> -<table class="boxSoft" width='100%' cellspacing='0' cellpadding='2'> -<tr> -<th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("Yes") ?></span></th> -<th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("No") ?></span></th> -<th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("Abstain") ?></span></th> -<th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("Total") ?></span></th> -<th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __('Voted') ?></span></th> -</tr> -<tr> -<td class='data1'><span class='f5'><span class='blue'><?php print $row['Yes'] ?></span></span></td> -<td class='data1'><span class='f5'><span class='blue'><?php print $row['No'] ?></span></span></td> -<td class='data1'><span class='f5'><span class='blue'><?php print $row['Abstain'] ?></span></span></td> -<td class='data1'><span class='f5'><span class='blue'><?php print ($row['Yes'] + $row['No'] + $row['Abstain']) ?></span></span></td> -<td class='data1'><span class='f5'><span class='blue'> -<?php if ($hasvoted == 0) { ?> -<span style='color: red; font-weight: bold'><?php print __("No") ?></span> -<?php } else { ?> -<span style='color: green; font-weight: bold'><?php print __("Yes") ?></span> -<?php } ?> -</span></span></td> -</tr> -</table> -</div></div> + <p> + <?php print str_replace("\n", "<br />\n", htmlspecialchars($row['Agenda'])) ?> + </p> -<?php -if (!$isrunning) { ?> -<div class="pgbox"> - <div class="pgboxtitle"> - <span class="f3"><?php echo __('Voters'); ?></span> - </div> - <div class="pgboxbody"> + <table> + <tr> + <th><?php print __("Yes") ?></th> + <th><?php print __("No") ?></th> + <th><?php print __("Abstain") ?></th> + <th><?php print __("Total") ?></th> + <th><?php print __('Voted') ?></th> + </tr> + <tr> + <td><?php print $row['Yes'] ?></td> + <td><?php print $row['No'] ?></td> + <td><?php print $row['Abstain'] ?></td> + <td><?php print ($row['Yes'] + $row['No'] + $row['Abstain']) ?></td> + <td> + <?php if ($hasvoted == 0): ?> + <span style="color: red; font-weight: bold"><?php print __("No") ?></span> + <?php else: ?> + <span style="color: green; font-weight: bold"><?php print __("Yes") ?></span> + <?php endif; ?> + </td> + </tr> + </table> +</div> + +<?php if (!$isrunning): ?> +<div class="box"> + <h2><?php echo __("Voters"); ?></h2> <?php echo $whovoted; ?> - </div> </div> -<?php -} ?> +<?php endif; ?> -<div class='pgbox'> -<div class='pgboxbody'> -<?php if ($canvote == 1) { ?> -<form action='tu.php?id=<?php print $row['ID'] ?>' method='post'> -<fieldset> -<input type='submit' class='button' name='voteYes' value='<?php print __("Yes") ?>' /> -<input type='submit' class='button' name='voteNo' value='<?php print __("No") ?>' /> -<input type='submit' class='button' name='voteAbstain' value='<?php print __("Abstain") ?>' /> -<input type='hidden' name='doVote' value='1' /> -<input type='hidden' name='token' value='<?php print htmlspecialchars($_COOKIE['AURSID']) ?>' /> -</fieldset> -</form> -<?php } else { ?> -<?php print $errorvote ?> -<?php } ?> -</div></div> +<div class="box"> + +<?php if ($canvote == 1): ?> + <form action="tu.php?id=<?php print $row['ID'] ?>" method="post"> + <fieldset> + <input type="submit" class="button" name="voteYes" value="<?php print __("Yes") ?>" /> + <input type="submit" class="button" name="voteNo" value="<?php print __("No") ?>" /> + <input type="submit" class="button" name="voteAbstain" value="<?php print __("Abstain") ?>" /> + <input type="hidden" name="doVote" value="1" /> + <input type="hidden" name="token" value="<?php echo htmlspecialchars($_COOKIE['AURSID']) ?>" /> + </fieldset> + </form> +<?php else: + print $errorvote ?> +<?php endif; ?> +</div> diff --git a/web/template/tu_list.php b/web/template/tu_list.php index 75d9414e..ce19da3c 100644 --- a/web/template/tu_list.php +++ b/web/template/tu_list.php @@ -1,62 +1,56 @@ -<div class="pgbox"> - <div class="pgboxtitle" style="text-align:right;"> - <span class='f3'><?php print $type ?></span> - </div> - <table width='100%' cellspacing='0' cellpadding='2'> - <tr> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("Proposal") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'> - <a href='?off=<?php print $off ?>&by=<?php print $by_next ?>'><?php print __("Start") ?></a> - </span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("End") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("User") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("Yes") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __("No") ?></span></th> - <th style='border-bottom: #666 1px solid; vertical-align: bottom'><span class='f2'><?php print __('Voted') ?></span></th> - </tr> - <?php if (mysql_num_rows($result) == 0) { ?> - <tr><td align='center' colspan='0'><?php print __("No results found.") ?></td></tr> - <?php } else { for ($i = 0; $row = mysql_fetch_assoc($result); $i++) { (($i % 2) == 0) ? $c = "data1" : $c = "data2"; ?> - <tr> - <td class='<?php print $c ?>'><span class='f4'><span class='blue'> - <?php - $row["Agenda"] = htmlspecialchars(substr($row["Agenda"], 0, $prev_Len)); - ?> - <a href='tu.php?id=<?php print $row['ID'] ?>'><?php print $row["Agenda"] ?></a></span></span> - </td> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'><?php print gmdate("j M y", $row["Submitted"]) ?></span></span></td> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'><?php print gmdate("j M y", $row["End"]) ?></span></span></td> - <td class='<?php print $c ?>'><span class='f6'><span class='blue'> - <?php - if (!empty($row['User'])) { - print "<a href='packages.php?K=" . $row['User'] . "&SeB=m'>" . $row['User'] . "</a>"; - } else { - print "N/A"; - } - ?> - </span></span></td> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'><?php print $row['Yes'] ?></span></span></td> - <td class='<?php print $c ?>'><span class='f5'><span class='blue'><?php print $row['No'] ?></span></span></td> - <td class='<?php print $c ?>'> - <?php - $q = "SELECT * FROM TU_Votes WHERE VoteID = " . $row['ID'] . " AND UserID = " . uid_from_sid($_COOKIE["AURSID"]); - $result_tulist = db_query($q, $dbh); - if ($result_tulist) { - $hasvoted = mysql_num_rows($result_tulist); - } - else { - $hasvoted = 0; - } - ?> - <span class='f5'><span class='blue'> - <?php if ($hasvoted == 0) { ?> - <span style='color: red; font-weight: bold'><?php print __("No") ?></span> - <?php } else { ?> - <span style='color: green; font-weight: bold'><?php print __("Yes") ?></span> - <?php } ?> - </span></span> - </td> - </tr> - <?php } } ?> - </table> +<div class="box"> + <h2><?php print $type ?></h2> + <table class="results"> + <thead> + <tr> + <th><?php print __("Proposal") ?></th> + <th><a href="?off=<?php print $off ?>&by=<?php print $by_next ?>"><?php print __("Start") ?></a></th> + <th><?php print __("End") ?></th> + <th><?php print __("User") ?></th> + <th><?php print __("Yes") ?></th> + <th><?php print __("No") ?></th> + <th><?php print __('Voted') ?></th> + </tr> + </thead> + + <tbody> + <?php if (empty($result)): ?> + <tr><td align="center" colspan="0"><?php print __("No results found.") ?></td></tr> + <?php else: while (list($indx, $row) = each($result)): + if ($indx % 2): + $c = "even"; + else: + $c = "odd"; + endif; + ?> + <tr class="<?php print $c ?>"> + <td><?php $row["Agenda"] = htmlspecialchars(substr($row["Agenda"], 0, $prev_Len)); ?> + <a href="tu.php?id=<?php print $row['ID'] ?>"><?php print $row["Agenda"] ?></a></span></span> + </td> + <td><?php print gmdate("Y-m-d", $row["Submitted"]) ?></td> + <td><?php print gmdate("Y-m-d", $row["End"]) ?></td> + <td> + <?php if (!empty($row['User'])): ?> + <a href="packages.php?K=<?php echo $row['User'] ?>&SeB=m"><?php echo $row['User'] ?></a> + <?php else: + print "N/A"; + endif; + ?> + </td> + <td><?php print $row['Yes'] ?></td> + <td><?php print $row['No'] ?></td> + <td> + <?php if (tu_voted($row['ID'], uid_from_sid($_COOKIE["AURSID"]))): ?> + <span style="color: green; font-weight: bold"><?php print __("Yes") ?></span> + <?php else: ?> + <span style="color: red; font-weight: bold"><?php print __("No") ?></span> + <?php endif; ?> + </td> + </tr> + <?php + endwhile; + endif; + ?> + </tbody> + </table> </div> |