commit
de87bdbb0d
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,6 +3,8 @@ data
|
|||||||
images
|
images
|
||||||
thumbs
|
thumbs
|
||||||
!lib/images
|
!lib/images
|
||||||
|
*.phar
|
||||||
|
*.sqlite
|
||||||
|
|
||||||
|
|
||||||
# Created by http://www.gitignore.io
|
# Created by http://www.gitignore.io
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
<FilesMatch "\.(sqlite|sdb|s3db|db)$">
|
<FilesMatch "\.(sqlite|sdb|s3db|db)$">
|
||||||
Deny from all
|
<IfModule mod_authz_host.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !mod_authz_host.c>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
<IfModule mod_rewrite.c>
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
imports:
|
imports:
|
||||||
- javascript
|
- javascript
|
||||||
- php
|
- php
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
excluded_paths: [lib/*,ext/tagger/script.js,ext/chatbox/*]
|
excluded_paths: [lib/*,ext/tagger/script.js,ext/chatbox/*]
|
||||||
|
|
||||||
|
tools:
|
||||||
|
external_code_coverage: true
|
||||||
|
59
.travis.yml
59
.travis.yml
@ -2,47 +2,42 @@ language: php
|
|||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
php:
|
php:
|
||||||
# Here is where we can list the versions of PHP you want to test against
|
- 5.4
|
||||||
# using major version aliases
|
- 5.5
|
||||||
- 5.4
|
- 5.6
|
||||||
- 5.5
|
- nightly
|
||||||
- 5.6
|
|
||||||
- nightly
|
|
||||||
|
|
||||||
# optionally specify a list of environments, for example to test different RDBMS
|
|
||||||
env:
|
env:
|
||||||
|
matrix:
|
||||||
- DB=mysql
|
- DB=mysql
|
||||||
- DB=pgsql
|
- DB=pgsql
|
||||||
- DB=sqlite
|
- DB=sqlite
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# Enable logging of all queries (for debugging) and create the database schema for shimmie.
|
- mkdir -p data/config
|
||||||
- mkdir -p data/config
|
- if [[ "$DB" == "pgsql" ]]; then psql -c "SELECT set_config('log_statement', 'all', false);" -U postgres; fi
|
||||||
- if [[ "$DB" == "pgsql" ]]; then psql -c "SELECT set_config('log_statement', 'all', false);" -U postgres; fi
|
- if [[ "$DB" == "pgsql" ]]; then psql -c "CREATE DATABASE shimmie;" -U postgres; fi
|
||||||
- if [[ "$DB" == "pgsql" ]]; then psql -c "CREATE DATABASE shimmie;" -U postgres; fi
|
- if [[ "$DB" == "pgsql" ]]; then echo '<?php define("DATABASE_DSN", "pgsql:user=postgres;password=;host=;dbname=shimmie");' > data/config/auto_install.conf.php ; fi
|
||||||
- if [[ "$DB" == "pgsql" ]]; then echo '<?php define("DATABASE_DSN", "pgsql:user=postgres;password=;host=;dbname=shimmie");' > data/config/auto_install.conf.php ; fi
|
- if [[ "$DB" == "mysql" ]]; then mysql -e "SET GLOBAL general_log = 'ON';" -uroot; fi
|
||||||
- if [[ "$DB" == "mysql" ]]; then mysql -e "SET GLOBAL general_log = 'ON';" -uroot; fi
|
- if [[ "$DB" == "mysql" ]]; then mysql -e "CREATE DATABASE shimmie;" -uroot; fi
|
||||||
- if [[ "$DB" == "mysql" ]]; then mysql -e "CREATE DATABASE shimmie;" -uroot; fi
|
- if [[ "$DB" == "mysql" ]]; then echo '<?php define("DATABASE_DSN", "mysql:user=root;password=;host=localhost;dbname=shimmie");' > data/config/auto_install.conf.php ; fi
|
||||||
- if [[ "$DB" == "mysql" ]]; then echo '<?php define("DATABASE_DSN", "mysql:user=root;password=;host=localhost;dbname=shimmie");' > data/config/auto_install.conf.php ; fi
|
- if [[ "$DB" == "sqlite" ]]; then echo '<?php define("DATABASE_DSN", "sqlite:shimmie.sqlite");' > data/config/auto_install.conf.php ; fi
|
||||||
- if [[ "$DB" == "sqlite" ]]; then echo '<?php define("DATABASE_DSN", "sqlite:shimmie.sqlite");' > data/config/auto_install.conf.php ; fi
|
- wget https://scrutinizer-ci.com/ocular.phar
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- php install.php
|
- php install.php
|
||||||
- phpunit --configuration tests/phpunit.xml
|
- phpunit --configuration tests/phpunit.xml --coverage-clover=data/coverage.clover
|
||||||
|
|
||||||
# If a failure occured then dump out a bunch of logs for debugging purposes.
|
|
||||||
after_failure:
|
after_failure:
|
||||||
- head -n 100 data/config/*
|
- head -n 100 data/config/*
|
||||||
- ls /var/run/mysql*
|
- ls /var/run/mysql*
|
||||||
- ls /var/log/*mysql*
|
- ls /var/log/*mysql*
|
||||||
- cat /var/log/mysql.err
|
- cat /var/log/mysql.err
|
||||||
- cat /var/log/mysql.log
|
- cat /var/log/mysql.log
|
||||||
- cat /var/log/mysql/error.log
|
- cat /var/log/mysql/error.log
|
||||||
- cat /var/log/mysql/slow.log
|
- cat /var/log/mysql/slow.log
|
||||||
- ls /var/log/postgresql
|
- ls /var/log/postgresql
|
||||||
- cat /var/log/postgresql/postgresql*
|
- cat /var/log/postgresql/postgresql*
|
||||||
|
|
||||||
# configure notifications (email, IRC, campfire etc)
|
after_script:
|
||||||
#notifications:
|
- php ocular.phar code-coverage:upload --format=php-clover data/coverage.clover
|
||||||
# irc: "irc.freenode.org#shimmie"
|
|
||||||
#
|
|
||||||
|
@ -96,7 +96,7 @@ class BaseThemelet {
|
|||||||
*
|
*
|
||||||
* @param string $base_url
|
* @param string $base_url
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @param int|string $page
|
* @param string $page
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -108,8 +108,8 @@ class BaseThemelet {
|
|||||||
/**
|
/**
|
||||||
* @param string $base_url
|
* @param string $base_url
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @param int|string $page
|
* @param string $page
|
||||||
* @param int|string $current_page
|
* @param int $current_page
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@ class Block {
|
|||||||
*/
|
*/
|
||||||
public $body;
|
public $body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where the block should be placed. The default theme supports
|
* Where the block should be placed. The default theme supports
|
||||||
* "main" and "left", other themes can add their own areas.
|
* "main" and "left", other themes can add their own areas.
|
||||||
*
|
*
|
||||||
@ -58,7 +58,7 @@ class Block {
|
|||||||
$this->body = $body;
|
$this->body = $body;
|
||||||
$this->section = $section;
|
$this->section = $section;
|
||||||
$this->position = $position;
|
$this->position = $position;
|
||||||
$this->id = str_replace(' ', '_', is_null($id) ? (is_null($header) ? md5($body) : $header) . $section : $id);
|
$this->id = preg_replace('/[^\w]/', '',str_replace(' ', '_', is_null($id) ? (is_null($header) ? md5($body) : $header) . $section : $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,4 +94,3 @@ class NavBlock extends Block {
|
|||||||
parent::__construct("Navigation", "<a href='".make_link()."'>Index</a>", "left", 0);
|
parent::__construct("Navigation", "<a href='".make_link()."'>Index</a>", "left", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ class Database {
|
|||||||
*
|
*
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @return mixed|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
public function get_row($query, $args=array()) {
|
public function get_row($query, $args=array()) {
|
||||||
$_start = microtime(true);
|
$_start = microtime(true);
|
||||||
@ -702,7 +702,7 @@ class Database {
|
|||||||
* Get the ID of the last inserted row.
|
* Get the ID of the last inserted row.
|
||||||
*
|
*
|
||||||
* @param string|null $seq
|
* @param string|null $seq
|
||||||
* @return string
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function get_last_insert_id($seq) {
|
public function get_last_insert_id($seq) {
|
||||||
if($this->engine->name == "pgsql") {
|
if($this->engine->name == "pgsql") {
|
||||||
|
@ -282,7 +282,7 @@ abstract class DataHandlerExtension extends Extension {
|
|||||||
abstract protected function supported_ext($ext);
|
abstract protected function supported_ext($ext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $tmpname
|
* @param string $tmpname
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
abstract protected function check_contents($tmpname);
|
abstract protected function check_contents($tmpname);
|
||||||
|
@ -63,7 +63,7 @@ class Image {
|
|||||||
public $tag_array;
|
public $tag_array;
|
||||||
|
|
||||||
public $owner_id, $owner_ip;
|
public $owner_id, $owner_ip;
|
||||||
public $posted, $posted_timestamp;
|
public $posted;
|
||||||
public $source;
|
public $source;
|
||||||
public $locked;
|
public $locked;
|
||||||
|
|
||||||
@ -82,7 +82,6 @@ class Image {
|
|||||||
$name = str_replace("images.", "", $name);
|
$name = str_replace("images.", "", $name);
|
||||||
$this->$name = $value; // hax, this is likely the cause of much scrutinizer-ci complaints.
|
$this->$name = $value; // hax, this is likely the cause of much scrutinizer-ci complaints.
|
||||||
}
|
}
|
||||||
$this->posted_timestamp = strtotime($this->posted); // pray
|
|
||||||
$this->locked = bool_escape($this->locked);
|
$this->locked = bool_escape($this->locked);
|
||||||
|
|
||||||
assert(is_numeric($this->id));
|
assert(is_numeric($this->id));
|
||||||
@ -192,6 +191,13 @@ class Image {
|
|||||||
return ($yays > 1 || $nays > 0);
|
return ($yays > 1 || $nays > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $tags
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return null|PDOStatement
|
||||||
|
* @throws SCoreException
|
||||||
|
*/
|
||||||
public function get_accelerated_result($tags, $offset, $limit) {
|
public function get_accelerated_result($tags, $offset, $limit) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
@ -244,7 +250,7 @@ class Image {
|
|||||||
* Count the number of image results for a given search
|
* Count the number of image results for a given search
|
||||||
*
|
*
|
||||||
* @param string[] $tags
|
* @param string[] $tags
|
||||||
* @return mixed
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function count_images($tags=array()) {
|
public static function count_images($tags=array()) {
|
||||||
assert('is_array($tags)');
|
assert('is_array($tags)');
|
||||||
@ -284,7 +290,6 @@ class Image {
|
|||||||
return ceil(Image::count_images($tags) / $config->get_int('index_images'));
|
return ceil(Image::count_images($tags) / $config->get_int('index_images'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessors & mutators
|
* Accessors & mutators
|
||||||
*/
|
*/
|
||||||
@ -401,9 +406,9 @@ class Image {
|
|||||||
/**
|
/**
|
||||||
* Check configured template for a link, then try nice URL, then plain URL
|
* Check configured template for a link, then try nice URL, then plain URL
|
||||||
*
|
*
|
||||||
* @param $template
|
* @param string $template
|
||||||
* @param $nice
|
* @param string $nice
|
||||||
* @param $plain
|
* @param string $plain
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function get_link($template, $nice, $plain) {
|
private function get_link($template, $nice, $plain) {
|
||||||
@ -532,6 +537,10 @@ class Image {
|
|||||||
return $this->locked;
|
return $this->locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $tf
|
||||||
|
* @throws SCoreException
|
||||||
|
*/
|
||||||
public function set_locked($tf) {
|
public function set_locked($tf) {
|
||||||
global $database;
|
global $database;
|
||||||
$ln = $tf ? "Y" : "N";
|
$ln = $tf ? "Y" : "N";
|
||||||
@ -551,9 +560,22 @@ class Image {
|
|||||||
*/
|
*/
|
||||||
public function delete_tags_from_image() {
|
public function delete_tags_from_image() {
|
||||||
global $database;
|
global $database;
|
||||||
$database->execute(
|
if($database->get_driver_name() == "mysql") {
|
||||||
"UPDATE tags SET count = count - 1 WHERE id IN ".
|
//mysql < 5.6 has terrible subquery optimization, using EXISTS / JOIN fixes this
|
||||||
"(SELECT tag_id FROM image_tags WHERE image_id = :id)", array("id"=>$this->id));
|
$database->execute("
|
||||||
|
UPDATE tags t
|
||||||
|
INNER JOIN image_tags it ON t.id = it.tag_id
|
||||||
|
SET count = count - 1
|
||||||
|
WHERE it.image_id = :id",
|
||||||
|
array("id"=>$this->id)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$database->execute("
|
||||||
|
UPDATE tags
|
||||||
|
SET count = count - 1
|
||||||
|
WHERE id IN (SELECT tag_id FROM image_tags WHERE image_id = :id)", array("id"=>$this->id)
|
||||||
|
);
|
||||||
|
}
|
||||||
$database->execute("DELETE FROM image_tags WHERE image_id=:id", array("id"=>$this->id));
|
$database->execute("DELETE FROM image_tags WHERE image_id=:id", array("id"=>$this->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,9 +589,6 @@ class Image {
|
|||||||
assert('is_array($tags) && count($tags) > 0', var_export($tags, true));
|
assert('is_array($tags) && count($tags) > 0', var_export($tags, true));
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$tags = array_map(array('Tag', 'sanitise'), $tags);
|
|
||||||
$tags = Tag::resolve_aliases($tags);
|
|
||||||
|
|
||||||
if(count($tags) <= 0) {
|
if(count($tags) <= 0) {
|
||||||
throw new SCoreException('Tried to set zero tags');
|
throw new SCoreException('Tried to set zero tags');
|
||||||
}
|
}
|
||||||
@ -579,12 +598,6 @@ class Image {
|
|||||||
$this->delete_tags_from_image();
|
$this->delete_tags_from_image();
|
||||||
// insert each new tags
|
// insert each new tags
|
||||||
foreach($tags as $tag) {
|
foreach($tags as $tag) {
|
||||||
$ttpe = new TagTermParseEvent($tag, $this->id);
|
|
||||||
send_event($ttpe);
|
|
||||||
if($ttpe->is_metatag()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mb_strlen($tag, 'UTF-8') > 255){
|
if(mb_strlen($tag, 'UTF-8') > 255){
|
||||||
flash_message("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n");
|
flash_message("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n");
|
||||||
continue;
|
continue;
|
||||||
@ -623,6 +636,19 @@ class Image {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send list of metatags to be parsed.
|
||||||
|
*
|
||||||
|
* @param [] $metatags
|
||||||
|
* @param int $image_id
|
||||||
|
*/
|
||||||
|
public function parse_metatags($metatags, $image_id) {
|
||||||
|
foreach($metatags as $tag) {
|
||||||
|
$ttpe = new TagTermParseEvent($tag, $image_id, TRUE);
|
||||||
|
send_event($ttpe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete this image from the database and disk
|
* Delete this image from the database and disk
|
||||||
*/
|
*/
|
||||||
@ -736,9 +762,58 @@ class Image {
|
|||||||
return Image::build_accurate_search_querylet($terms);
|
return Image::build_accurate_search_querylet($terms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $terms
|
||||||
|
* @return ImgQuerylet[]
|
||||||
|
*/
|
||||||
|
private static function parse_meta_terms($terms) {
|
||||||
|
$img_querylets = array();
|
||||||
|
$stpe = new SearchTermParseEvent(null, $terms);
|
||||||
|
send_event($stpe);
|
||||||
|
if ($stpe->is_querylet_set()) {
|
||||||
|
foreach ($stpe->get_querylets() as $querylet) {
|
||||||
|
$img_querylets[] = new ImgQuerylet($querylet, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $img_querylets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ImgQuerylet[] $img_querylets
|
||||||
|
* @return Querylet
|
||||||
|
*/
|
||||||
|
private static function build_img_search($img_querylets) {
|
||||||
|
// merge all the image metadata searches into one generic querylet
|
||||||
|
$n = 0;
|
||||||
|
$sql = "";
|
||||||
|
$terms = array();
|
||||||
|
foreach ($img_querylets as $iq) {
|
||||||
|
if ($n++ > 0) $sql .= " AND";
|
||||||
|
if (!$iq->positive) $sql .= " NOT";
|
||||||
|
$sql .= " (" . $iq->qlet->sql . ")";
|
||||||
|
$terms = array_merge($terms, $iq->qlet->variables);
|
||||||
|
}
|
||||||
|
return new Querylet($sql, $terms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Querylet $img_search
|
||||||
|
* @return Querylet
|
||||||
|
*/
|
||||||
|
private static function build_simple_query($img_search) {
|
||||||
|
$query = new Querylet("SELECT images.* FROM images ");
|
||||||
|
|
||||||
|
if (!empty($img_search->sql)) {
|
||||||
|
$query->append_sql(" WHERE ");
|
||||||
|
$query->append($img_search);
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: this description is no longer accurate, though it does get across
|
* WARNING: this description is no longer accurate, though it does get across
|
||||||
* the general idea - the actual method has a few extra optimisiations
|
* the general idea - the actual method has a few extra optimisations
|
||||||
*
|
*
|
||||||
* "foo bar -baz user=foo" becomes
|
* "foo bar -baz user=foo" becomes
|
||||||
*
|
*
|
||||||
@ -752,7 +827,7 @@ class Image {
|
|||||||
* A) Incredibly simple:
|
* A) Incredibly simple:
|
||||||
* Each search term maps to a list of image IDs
|
* Each search term maps to a list of image IDs
|
||||||
* B) Runs really fast on a good database:
|
* B) Runs really fast on a good database:
|
||||||
* These lists are calucalted once, and the set intersection taken
|
* These lists are calculated once, and the set intersection taken
|
||||||
* C) Runs really slow on bad databases:
|
* C) Runs really slow on bad databases:
|
||||||
* All the subqueries are executed every time for every row in the
|
* All the subqueries are executed every time for every row in the
|
||||||
* images table. Yes, MySQL does suck this much.
|
* images table. Yes, MySQL does suck this much.
|
||||||
@ -764,21 +839,12 @@ class Image {
|
|||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$tag_querylets = array();
|
$tag_querylets = array();
|
||||||
$img_querylets = array();
|
$img_querylets = self::parse_meta_terms($terms);
|
||||||
$positive_tag_count = 0;
|
$positive_tag_count = 0;
|
||||||
|
|
||||||
$stpe = new SearchTermParseEvent(null, $terms);
|
|
||||||
send_event($stpe);
|
|
||||||
if($stpe->is_querylet_set()) {
|
|
||||||
foreach($stpe->get_querylets() as $querylet) {
|
|
||||||
$img_querylets[] = new ImgQuerylet($querylet, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$terms = Tag::resolve_aliases($terms);
|
|
||||||
|
|
||||||
// parse the words that are searched for into
|
// parse the words that are searched for into
|
||||||
// various types of querylet
|
// various types of querylet
|
||||||
|
$terms = Tag::resolve_aliases($terms);
|
||||||
foreach($terms as $term) {
|
foreach($terms as $term) {
|
||||||
$positive = true;
|
$positive = true;
|
||||||
if(is_string($term) && !empty($term) && ($term[0] == '-')) {
|
if(is_string($term) && !empty($term) && ($term[0] == '-')) {
|
||||||
@ -804,41 +870,25 @@ class Image {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$img_search = self::build_img_search($img_querylets);
|
||||||
|
|
||||||
// merge all the image metadata searches into one generic querylet
|
|
||||||
$n = 0;
|
|
||||||
$sql = "";
|
|
||||||
$terms = array();
|
|
||||||
foreach($img_querylets as $iq) {
|
|
||||||
if($n++ > 0) $sql .= " AND";
|
|
||||||
if(!$iq->positive) $sql .= " NOT";
|
|
||||||
$sql .= " (" . $iq->qlet->sql . ")";
|
|
||||||
$terms = array_merge($terms, $iq->qlet->variables);
|
|
||||||
}
|
|
||||||
$img_search = new Querylet($sql, $terms);
|
|
||||||
|
|
||||||
// How many tag querylets are there?
|
// How many tag querylets are there?
|
||||||
$count_tag_querylets = count($tag_querylets);
|
$count_tag_querylets = count($tag_querylets);
|
||||||
|
|
||||||
// no tags, do a simple search (+image metadata if we have any)
|
// no tags, do a simple search (+image metadata if we have any)
|
||||||
if($count_tag_querylets === 0) {
|
if($count_tag_querylets === 0) {
|
||||||
$query = new Querylet("SELECT images.* FROM images ");
|
$query = self::build_simple_query($img_search);
|
||||||
|
|
||||||
if(!empty($img_search->sql)) {
|
|
||||||
$query->append_sql(" WHERE ");
|
|
||||||
$query->append($img_search);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// one positive tag (a common case), do an optimised search
|
// one positive tag (a common case), do an optimised search
|
||||||
else if($count_tag_querylets === 1 && $tag_querylets[0]->positive) {
|
else if($count_tag_querylets === 1 && $tag_querylets[0]->positive) {
|
||||||
$query = new Querylet($database->scoreql_to_sql("
|
$query = new Querylet($database->scoreql_to_sql("
|
||||||
SELECT images.* FROM images
|
SELECT images.*
|
||||||
|
FROM images
|
||||||
JOIN image_tags ON images.id=image_tags.image_id
|
JOIN image_tags ON images.id=image_tags.image_id
|
||||||
JOIN tags ON image_tags.tag_id=tags.id
|
JOIN tags ON image_tags.tag_id=tags.id
|
||||||
WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)
|
WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)
|
||||||
"), array("tag"=>$tag_querylets[0]->tag));
|
"), array("tag"=>$tag_querylets[0]->tag));
|
||||||
|
|
||||||
if(!empty($img_search->sql)) {
|
if(!empty($img_search->sql)) {
|
||||||
$query->append_sql(" AND ");
|
$query->append_sql(" AND ");
|
||||||
@ -854,10 +904,12 @@ class Image {
|
|||||||
|
|
||||||
foreach($tag_querylets as $tq) {
|
foreach($tag_querylets as $tq) {
|
||||||
$tag_ids = $database->get_col(
|
$tag_ids = $database->get_col(
|
||||||
$database->scoreql_to_sql(
|
$database->scoreql_to_sql("
|
||||||
"SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)"
|
SELECT id
|
||||||
),
|
FROM tags
|
||||||
array("tag"=>$tq->tag));
|
WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)
|
||||||
|
"), array("tag"=>$tq->tag)
|
||||||
|
);
|
||||||
if($tq->positive) {
|
if($tq->positive) {
|
||||||
$positive_tag_id_array = array_merge($positive_tag_id_array, $tag_ids);
|
$positive_tag_id_array = array_merge($positive_tag_id_array, $tag_ids);
|
||||||
$tags_ok = count($tag_ids) > 0;
|
$tags_ok = count($tag_ids) > 0;
|
||||||
@ -872,7 +924,7 @@ class Image {
|
|||||||
$have_pos = count($positive_tag_id_array) > 0;
|
$have_pos = count($positive_tag_id_array) > 0;
|
||||||
$have_neg = count($negative_tag_id_array) > 0;
|
$have_neg = count($negative_tag_id_array) > 0;
|
||||||
|
|
||||||
$sql = "SELECT images.* FROM images WHERE images.id IN (";
|
$sql = "";
|
||||||
if($have_pos) {
|
if($have_pos) {
|
||||||
$positive_tag_id_list = join(', ', $positive_tag_id_array);
|
$positive_tag_id_list = join(', ', $positive_tag_id_array);
|
||||||
$sql .= "
|
$sql .= "
|
||||||
@ -894,8 +946,11 @@ class Image {
|
|||||||
WHERE tag_id IN ($negative_tag_id_list)
|
WHERE tag_id IN ($negative_tag_id_list)
|
||||||
";
|
";
|
||||||
}
|
}
|
||||||
$sql .= ")";
|
$query = new Querylet("
|
||||||
$query = new Querylet($sql);
|
SELECT images.*
|
||||||
|
FROM images
|
||||||
|
WHERE images.id IN ($sql)
|
||||||
|
");
|
||||||
|
|
||||||
if(strlen($img_search->sql) > 0) {
|
if(strlen($img_search->sql) > 0) {
|
||||||
$query->append_sql(" AND ");
|
$query->append_sql(" AND ");
|
||||||
@ -921,23 +976,16 @@ class Image {
|
|||||||
* build_accurate_search_querylet() for a full explanation
|
* build_accurate_search_querylet() for a full explanation
|
||||||
*
|
*
|
||||||
* @param array $terms
|
* @param array $terms
|
||||||
|
* @return Querylet
|
||||||
*/
|
*/
|
||||||
private static function build_ugly_search_querylet($terms) {
|
private static function build_ugly_search_querylet($terms) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$tag_querylets = array();
|
$tag_querylets = array();
|
||||||
$img_querylets = array();
|
$img_querylets = self::parse_meta_terms($terms);
|
||||||
$positive_tag_count = 0;
|
$positive_tag_count = 0;
|
||||||
$negative_tag_count = 0;
|
$negative_tag_count = 0;
|
||||||
|
|
||||||
$stpe = new SearchTermParseEvent(null, $terms);
|
|
||||||
send_event($stpe);
|
|
||||||
if($stpe->is_querylet_set()) {
|
|
||||||
foreach($stpe->get_querylets() as $querylet) {
|
|
||||||
$img_querylets[] = new ImgQuerylet($querylet, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$terms = Tag::resolve_aliases($terms);
|
$terms = Tag::resolve_aliases($terms);
|
||||||
|
|
||||||
reset($terms); // rewind to first element in array.
|
reset($terms); // rewind to first element in array.
|
||||||
@ -979,44 +1027,24 @@ class Image {
|
|||||||
else $negative_tag_count++;
|
else $negative_tag_count++;
|
||||||
}
|
}
|
||||||
$tag_search = new Querylet($sql, $terms);
|
$tag_search = new Querylet($sql, $terms);
|
||||||
|
$img_search = self::build_img_search($img_querylets);
|
||||||
// merge all the image metadata searches into one generic querylet
|
|
||||||
$n = 0;
|
|
||||||
$sql = "";
|
|
||||||
$terms = array();
|
|
||||||
foreach($img_querylets as $iq) {
|
|
||||||
if($n++ > 0) $sql .= " AND";
|
|
||||||
if(!$iq->positive) $sql .= " NOT";
|
|
||||||
$sql .= " (" . $iq->qlet->sql . ")";
|
|
||||||
$terms = array_merge($terms, $iq->qlet->variables);
|
|
||||||
}
|
|
||||||
$img_search = new Querylet($sql, $terms);
|
|
||||||
|
|
||||||
|
|
||||||
// no tags, do a simple search (+image metadata if we have any)
|
// no tags, do a simple search (+image metadata if we have any)
|
||||||
if($positive_tag_count + $negative_tag_count == 0) {
|
if($positive_tag_count + $negative_tag_count == 0) {
|
||||||
$query = new Querylet("SELECT images.*,UNIX_TIMESTAMP(posted) AS posted_timestamp FROM images ");
|
$query = self::build_simple_query($img_search);
|
||||||
|
|
||||||
if(!empty($img_search->sql)) {
|
|
||||||
$query->append_sql(" WHERE ");
|
|
||||||
$query->append($img_search);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// one positive tag (a common case), do an optimised search
|
// one positive tag (a common case), do an optimised search
|
||||||
else if($positive_tag_count === 1 && $negative_tag_count === 0) {
|
else if($positive_tag_count === 1 && $negative_tag_count === 0) {
|
||||||
$query = new Querylet(
|
// MySQL is braindead, and does a full table scan on images, running the subquery once for each row -_-
|
||||||
// MySQL is braindead, and does a full table scan on images, running the subquery once for each row -_-
|
// "{$this->get_images} WHERE images.id IN (SELECT image_id FROM tags WHERE tag LIKE ?) ",
|
||||||
// "{$this->get_images} WHERE images.id IN (SELECT image_id FROM tags WHERE tag LIKE ?) ",
|
$query = new Querylet("
|
||||||
"
|
SELECT images.*
|
||||||
SELECT images.*, UNIX_TIMESTAMP(posted) AS posted_timestamp
|
FROM images
|
||||||
FROM tags, image_tags, images
|
JOIN image_tags ON images.id=image_tags.image_id
|
||||||
WHERE
|
JOIN tags ON image_tags.tag_id=tags.id
|
||||||
tag LIKE :tag0
|
WHERE tag LIKE :tag0
|
||||||
AND tags.id = image_tags.tag_id
|
", $tag_search->variables);
|
||||||
AND image_tags.image_id = images.id
|
|
||||||
",
|
|
||||||
$tag_search->variables);
|
|
||||||
|
|
||||||
if(!empty($img_search->sql)) {
|
if(!empty($img_search->sql)) {
|
||||||
$query->append_sql(" AND ");
|
$query->append_sql(" AND ");
|
||||||
@ -1031,7 +1059,10 @@ class Image {
|
|||||||
|
|
||||||
$x = 0;
|
$x = 0;
|
||||||
foreach($tag_search->variables as $tag) {
|
foreach($tag_search->variables as $tag) {
|
||||||
$tag_ids = $database->get_col("SELECT id FROM tags WHERE tag LIKE :tag", array("tag"=>$tag));
|
$tag_ids = $database->get_col(
|
||||||
|
"SELECT id FROM tags WHERE tag LIKE :tag",
|
||||||
|
array("tag"=>$tag)
|
||||||
|
);
|
||||||
$tag_id_array = array_merge($tag_id_array, $tag_ids);
|
$tag_id_array = array_merge($tag_id_array, $tag_ids);
|
||||||
|
|
||||||
$tags_ok = count($tag_ids) > 0 || !$tag_querylets[$x]->positive;
|
$tags_ok = count($tag_ids) > 0 || !$tag_querylets[$x]->positive;
|
||||||
@ -1057,7 +1088,7 @@ class Image {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
$query = new Querylet('
|
$query = new Querylet('
|
||||||
SELECT *, UNIX_TIMESTAMP(posted) AS posted_timestamp
|
SELECT *
|
||||||
FROM ('.$subquery->sql.') AS images ', $subquery->variables);
|
FROM ('.$subquery->sql.') AS images ', $subquery->variables);
|
||||||
|
|
||||||
if(!empty($img_search->sql)) {
|
if(!empty($img_search->sql)) {
|
||||||
@ -1102,7 +1133,7 @@ class Tag {
|
|||||||
* Remove any excess fluff from a user-input tag
|
* Remove any excess fluff from a user-input tag
|
||||||
*
|
*
|
||||||
* @param string $tag
|
* @param string $tag
|
||||||
* @return mixed
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function sanitise($tag) {
|
public static function sanitise($tag) {
|
||||||
assert('is_string($tag)');
|
assert('is_string($tag)');
|
||||||
@ -1118,7 +1149,7 @@ class Tag {
|
|||||||
*
|
*
|
||||||
* @param string|string[] $tags
|
* @param string|string[] $tags
|
||||||
* @param bool $tagme
|
* @param bool $tagme
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public static function explode($tags, $tagme=true) {
|
public static function explode($tags, $tagme=true) {
|
||||||
assert('is_string($tags) || is_array($tags)');
|
assert('is_string($tags) || is_array($tags)');
|
||||||
@ -1142,6 +1173,8 @@ class Tag {
|
|||||||
$tag_array = array("tagme");
|
$tag_array = array("tagme");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tag_array = array_iunique($tag_array); //remove duplicate tags
|
||||||
|
|
||||||
sort($tag_array);
|
sort($tag_array);
|
||||||
|
|
||||||
return $tag_array;
|
return $tag_array;
|
||||||
@ -1213,7 +1246,10 @@ class Tag {
|
|||||||
global $database;
|
global $database;
|
||||||
$db_wild_tag = str_replace("%", "\%", $tag);
|
$db_wild_tag = str_replace("%", "\%", $tag);
|
||||||
$db_wild_tag = str_replace("*", "%", $db_wild_tag);
|
$db_wild_tag = str_replace("*", "%", $db_wild_tag);
|
||||||
$newtags = $database->get_col($database->scoreql_to_sql("SELECT tag FROM tags WHERE SCORE_STRNORM(tag) LIKE SCORE_STRNORM(?)"), array($db_wild_tag));
|
$newtags = $database->get_col(
|
||||||
|
$database->scoreql_to_sql("SELECT tag FROM tags WHERE SCORE_STRNORM(tag) LIKE SCORE_STRNORM(?)"),
|
||||||
|
array($db_wild_tag)
|
||||||
|
);
|
||||||
if(count($newtags) > 0) {
|
if(count($newtags) > 0) {
|
||||||
$resolved = $newtags;
|
$resolved = $newtags;
|
||||||
} else {
|
} else {
|
||||||
@ -1237,7 +1273,7 @@ class Tag {
|
|||||||
$i = 0;
|
$i = 0;
|
||||||
$tag_count = count($tags);
|
$tag_count = count($tags);
|
||||||
while($i<$tag_count) {
|
while($i<$tag_count) {
|
||||||
$aliases = explode(' ', Tag::resolve_alias($tags[$i]));
|
$aliases = Tag::explode(Tag::resolve_alias($tags[$i]), FALSE);
|
||||||
foreach($aliases as $alias){
|
foreach($aliases as $alias){
|
||||||
if(!in_array($alias, $new)){
|
if(!in_array($alias, $new)){
|
||||||
if($tags[$i] == $alias){
|
if($tags[$i] == $alias){
|
||||||
@ -1284,7 +1320,7 @@ function move_upload_to_archive(DataUploadEvent $event) {
|
|||||||
* @param $base string
|
* @param $base string
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function add_dir(/*string*/ $base) {
|
function add_dir($base) {
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
foreach(list_files($base) as $full_path) {
|
foreach(list_files($base) as $full_path) {
|
||||||
@ -1307,12 +1343,12 @@ function add_dir(/*string*/ $base) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $tmpname
|
* @param string $tmpname
|
||||||
* @param $filename
|
* @param string $filename
|
||||||
* @param $tags
|
* @param string $tags
|
||||||
* @throws UploadException
|
* @throws UploadException
|
||||||
*/
|
*/
|
||||||
function add_image(/*string*/ $tmpname, /*string*/ $filename, /*string*/ $tags) {
|
function add_image($tmpname, $filename, $tags) {
|
||||||
assert(file_exists($tmpname));
|
assert(file_exists($tmpname));
|
||||||
|
|
||||||
$pathinfo = pathinfo($filename);
|
$pathinfo = pathinfo($filename);
|
||||||
@ -1337,7 +1373,7 @@ function add_image(/*string*/ $tmpname, /*string*/ $filename, /*string*/ $tags)
|
|||||||
*
|
*
|
||||||
* @param int $orig_width
|
* @param int $orig_width
|
||||||
* @param int $orig_height
|
* @param int $orig_height
|
||||||
* @return array
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
function get_thumbnail_size(/*int*/ $orig_width, /*int*/ $orig_height) {
|
function get_thumbnail_size(/*int*/ $orig_width, /*int*/ $orig_height) {
|
||||||
global $config;
|
global $config;
|
||||||
@ -1363,4 +1399,3 @@ function get_thumbnail_size(/*int*/ $orig_width, /*int*/ $orig_height) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,6 +205,10 @@ class Page {
|
|||||||
$this->cookies[] = array($full_name, $value, $time, $path);
|
$this->cookies[] = array($full_name, $value, $time, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
public function get_cookie(/*string*/ $name) {
|
public function get_cookie(/*string*/ $name) {
|
||||||
$full_name = COOKIE_PREFIX."_".$name;
|
$full_name = COOKIE_PREFIX."_".$name;
|
||||||
if(isset($_COOKIE[$full_name])) {
|
if(isset($_COOKIE[$full_name])) {
|
||||||
|
@ -36,7 +36,7 @@ _d("COMPILE_ELS", false); // boolean pre-build the list of event listeners
|
|||||||
_d("NICE_URLS", false); // boolean force niceurl mode
|
_d("NICE_URLS", false); // boolean force niceurl mode
|
||||||
_d("SEARCH_ACCEL", false); // boolean use search accelerator
|
_d("SEARCH_ACCEL", false); // boolean use search accelerator
|
||||||
_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse
|
_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse
|
||||||
_d("VERSION", '2.5.4+'); // string shimmie version
|
_d("VERSION", '2.5.5+'); // string shimmie version
|
||||||
_d("TIMEZONE", null); // string timezone
|
_d("TIMEZONE", null); // string timezone
|
||||||
_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,comment,tag_list,index,tag_edit,alias_editor"); // extensions to always enable
|
_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,comment,tag_list,index,tag_edit,alias_editor"); // extensions to always enable
|
||||||
_d("EXTRA_EXTS", ""); // optional extra extensions
|
_d("EXTRA_EXTS", ""); // optional extra extensions
|
||||||
|
@ -124,6 +124,25 @@ function no_escape($input) {
|
|||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $val
|
||||||
|
* @param int|null $min
|
||||||
|
* @param int|null $max
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function clamp($val, $min, $max) {
|
||||||
|
if(!is_numeric($val) || (!is_null($min) && $val < $min)) {
|
||||||
|
$val = $min;
|
||||||
|
}
|
||||||
|
if(!is_null($max) && $val > $max) {
|
||||||
|
$val = $max;
|
||||||
|
}
|
||||||
|
if(!is_null($min) && !is_null($max)) {
|
||||||
|
assert('$val >= $min && $val <= $max', "$min <= $val <= $max");
|
||||||
|
}
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $attrs
|
* @param array $attrs
|
||||||
@ -268,17 +287,22 @@ function validate_input($inputs) {
|
|||||||
|
|
||||||
foreach($inputs as $key => $validations) {
|
foreach($inputs as $key => $validations) {
|
||||||
$flags = explode(',', $validations);
|
$flags = explode(',', $validations);
|
||||||
|
|
||||||
|
if(in_array('bool', $flags) && !isset($_POST[$key])) {
|
||||||
|
$_POST[$key] = 'off';
|
||||||
|
}
|
||||||
|
|
||||||
if(in_array('optional', $flags)) {
|
if(in_array('optional', $flags)) {
|
||||||
if(!isset($_POST[$key])) {
|
if(!isset($_POST[$key]) || trim($_POST[$key]) == "") {
|
||||||
|
$outputs[$key] = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!isset($_POST[$key]) || trim($_POST[$key]) == "") {
|
||||||
if(!isset($_POST[$key])) {
|
|
||||||
throw new InvalidInput("Input '$key' not set");
|
throw new InvalidInput("Input '$key' not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = $_POST[$key];
|
$value = trim($_POST[$key]);
|
||||||
|
|
||||||
if(in_array('user_id', $flags)) {
|
if(in_array('user_id', $flags)) {
|
||||||
$id = int_escape($value);
|
$id = int_escape($value);
|
||||||
@ -308,11 +332,36 @@ function validate_input($inputs) {
|
|||||||
$outputs[$key] = $value;
|
$outputs[$key] = $value;
|
||||||
}
|
}
|
||||||
else if(in_array('email', $flags)) {
|
else if(in_array('email', $flags)) {
|
||||||
$outputs[$key] = $value;
|
$outputs[$key] = trim($value);
|
||||||
}
|
}
|
||||||
else if(in_array('password', $flags)) {
|
else if(in_array('password', $flags)) {
|
||||||
$outputs[$key] = $value;
|
$outputs[$key] = $value;
|
||||||
}
|
}
|
||||||
|
else if(in_array('int', $flags)) {
|
||||||
|
$value = trim($value);
|
||||||
|
if(empty($value) || !is_numeric($value)) {
|
||||||
|
throw new InvalidInput("Invalid int: ".html_escape($value));
|
||||||
|
}
|
||||||
|
$outputs[$key] = (int)$value;
|
||||||
|
}
|
||||||
|
else if(in_array('bool', $flags)) {
|
||||||
|
$outputs[$key] = bool_escape($value);
|
||||||
|
}
|
||||||
|
else if(in_array('string', $flags)) {
|
||||||
|
if(in_array('trim', $flags)) {
|
||||||
|
$value = trim($value);
|
||||||
|
}
|
||||||
|
if(in_array('lower', $flags)) {
|
||||||
|
$value = strtolower($value);
|
||||||
|
}
|
||||||
|
if(in_array('not-empty', $flags)) {
|
||||||
|
throw new InvalidInput("$key must not be blank");
|
||||||
|
}
|
||||||
|
if(in_array('nullify', $flags)) {
|
||||||
|
if(empty($value)) $value = null;
|
||||||
|
}
|
||||||
|
$outputs[$key] = $value;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw new InvalidInput("Unknown validation '$validations'");
|
throw new InvalidInput("Unknown validation '$validations'");
|
||||||
}
|
}
|
||||||
@ -910,21 +959,19 @@ function transload($url, $mfile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($config->get_string("transload_engine") === "fopen") {
|
if($config->get_string("transload_engine") === "fopen") {
|
||||||
$fp = @fopen($url, "r");
|
$fp_in = @fopen($url, "r");
|
||||||
if(!$fp) {
|
$fp_out = fopen($mfile, "w");
|
||||||
|
if(!$fp_in || !$fp_out) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$data = "";
|
|
||||||
$length = 0;
|
$length = 0;
|
||||||
while(!feof($fp) && $length <= $config->get_int('upload_size')) {
|
while(!feof($fp_in) && $length <= $config->get_int('upload_size')) {
|
||||||
$data .= fread($fp, 8192);
|
$data = fread($fp_in, 8192);
|
||||||
$length = strlen($data);
|
$length += strlen($data);
|
||||||
|
fwrite($fp_out, $data);
|
||||||
}
|
}
|
||||||
fclose($fp);
|
fclose($fp_in);
|
||||||
|
fclose($fp_out);
|
||||||
$fp = fopen($mfile, "w");
|
|
||||||
fwrite($fp, $data);
|
|
||||||
fclose($fp);
|
|
||||||
|
|
||||||
$headers = http_parse_headers(implode("\n", $http_response_header));
|
$headers = http_parse_headers(implode("\n", $http_response_header));
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class AdminPageTest extends ShimmiePHPUnitTestCase {
|
class AdminPageTest extends ShimmiePHPUnitTestCase {
|
||||||
function testAuth() {
|
public function testAuth() {
|
||||||
$this->get_page('admin');
|
$this->get_page('admin');
|
||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
$this->assert_title("Permission Denied");
|
$this->assert_title("Permission Denied");
|
||||||
@ -16,7 +16,7 @@ class AdminPageTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_title("Admin Tools");
|
$this->assert_title("Admin Tools");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testLowercase() {
|
public function testLowercase() {
|
||||||
$ts = time(); // we need a tag that hasn't been used before
|
$ts = time(); // we need a tag that hasn't been used before
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
@ -37,7 +37,7 @@ class AdminPageTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# FIXME: make sure the admin tools actually work
|
# FIXME: make sure the admin tools actually work
|
||||||
function testRecount() {
|
public function testRecount() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page('admin');
|
$this->get_page('admin');
|
||||||
$this->assert_title("Admin Tools");
|
$this->assert_title("Admin Tools");
|
||||||
@ -46,7 +46,7 @@ class AdminPageTest extends ShimmiePHPUnitTestCase {
|
|||||||
send_event(new AdminActionEvent('recount_tag_use'));
|
send_event(new AdminActionEvent('recount_tag_use'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDump() {
|
public function testDump() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page('admin');
|
$this->get_page('admin');
|
||||||
$this->assert_title("Admin Tools");
|
$this->assert_title("Admin Tools");
|
||||||
@ -57,7 +57,7 @@ class AdminPageTest extends ShimmiePHPUnitTestCase {
|
|||||||
//$this->assert_response(200);
|
//$this->assert_response(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDBQ() {
|
public function testDBQ() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
class AliasEditorTest extends ShimmiePHPUnitTestCase {
|
class AliasEditorTest extends ShimmiePHPUnitTestCase {
|
||||||
function testAliasList() {
|
public function testAliasList() {
|
||||||
$this->get_page('alias/list');
|
$this->get_page('alias/list');
|
||||||
$this->assert_response(200);
|
$this->assert_response(200);
|
||||||
$this->assert_title("Alias List");
|
$this->assert_title("Alias List");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAliasListReadOnly() {
|
public function testAliasListReadOnly() {
|
||||||
// Check that normal users can't add aliases.
|
// Check that normal users can't add aliases.
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$this->get_page('alias/list');
|
$this->get_page('alias/list');
|
||||||
@ -14,7 +14,7 @@ class AliasEditorTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_no_text("Add");
|
$this->assert_no_text("Add");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAliasEditor() {
|
public function testAliasEditor() {
|
||||||
/*
|
/*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* FIXME: TODO:
|
* FIXME: TODO:
|
||||||
@ -26,6 +26,8 @@ class AliasEditorTest extends ShimmiePHPUnitTestCase {
|
|||||||
* dig into this and determine exactly what is happening.
|
* dig into this and determine exactly what is happening.
|
||||||
*
|
*
|
||||||
*********************************************************************
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
@ -97,8 +99,6 @@ class AliasEditorTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->get_page('alias/list');
|
$this->get_page('alias/list');
|
||||||
$this->assert_title("Alias List");
|
$this->assert_title("Alias List");
|
||||||
$this->assert_no_text("Add");
|
$this->assert_no_text("Add");
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ArtistTest extends ShimmiePHPUnitTestCase {
|
class ArtistTest extends ShimmiePHPUnitTestCase {
|
||||||
function testSearch() {
|
public function testSearch() {
|
||||||
# FIXME: check that the results are there
|
# FIXME: check that the results are there
|
||||||
$this->get_page("post/list/author=bob/1");
|
$this->get_page("post/list/author=bob/1");
|
||||||
#$this->assert_response(200);
|
#$this->assert_response(200);
|
||||||
|
@ -23,7 +23,7 @@ class ArtistsTheme extends Themelet {
|
|||||||
* @param null|int $artistID
|
* @param null|int $artistID
|
||||||
* @param bool $is_admin
|
* @param bool $is_admin
|
||||||
*/
|
*/
|
||||||
public function sidebar_options(/*string*/ $mode, $artistID=NULL, $is_admin=FALSE){
|
public function sidebar_options(/*string*/ $mode, $artistID=NULL, $is_admin=FALSE) {
|
||||||
global $page, $user;
|
global $page, $user;
|
||||||
|
|
||||||
$html = "";
|
$html = "";
|
||||||
@ -77,49 +77,44 @@ class ArtistsTheme extends Themelet {
|
|||||||
if($html) $page->add_block(new Block("Manage Artists", $html, "left", 10));
|
if($html) $page->add_block(new Block("Manage Artists", $html, "left", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_artist_editor($artist, $aliases, $members, $urls)
|
public function show_artist_editor($artist, $aliases, $members, $urls) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$artistName = $artist['name'];
|
$artistName = $artist['name'];
|
||||||
$artistNotes = $artist['notes'];
|
$artistNotes = $artist['notes'];
|
||||||
$artistID = $artist['id'];
|
$artistID = $artist['id'];
|
||||||
|
|
||||||
// aliases
|
// aliases
|
||||||
$aliasesString = "";
|
$aliasesString = "";
|
||||||
$aliasesIDsString = "";
|
$aliasesIDsString = "";
|
||||||
foreach ($aliases as $alias)
|
foreach ($aliases as $alias) {
|
||||||
{
|
$aliasesString .= $alias["alias_name"]." ";
|
||||||
$aliasesString .= $alias["alias_name"]." ";
|
$aliasesIDsString .= $alias["alias_id"]." ";
|
||||||
$aliasesIDsString .= $alias["alias_id"]." ";
|
}
|
||||||
}
|
$aliasesString = rtrim($aliasesString);
|
||||||
$aliasesString = rtrim($aliasesString);
|
$aliasesIDsString = rtrim($aliasesIDsString);
|
||||||
$aliasesIDsString = rtrim($aliasesIDsString);
|
|
||||||
|
|
||||||
// members
|
// members
|
||||||
$membersString = "";
|
$membersString = "";
|
||||||
$membersIDsString = "";
|
$membersIDsString = "";
|
||||||
foreach ($members as $member)
|
foreach ($members as $member) {
|
||||||
{
|
$membersString .= $member["name"]." ";
|
||||||
$membersString .= $member["name"]." ";
|
$membersIDsString .= $member["id"]." ";
|
||||||
$membersIDsString .= $member["id"]." ";
|
}
|
||||||
}
|
$membersString = rtrim($membersString);
|
||||||
$membersString = rtrim($membersString);
|
$membersIDsString = rtrim($membersIDsString);
|
||||||
$membersIDsString = rtrim($membersIDsString);
|
|
||||||
|
|
||||||
// urls
|
// urls
|
||||||
$urlsString = "";
|
$urlsString = "";
|
||||||
$urlsIDsString = "";
|
$urlsIDsString = "";
|
||||||
foreach ($urls as $url)
|
foreach ($urls as $url) {
|
||||||
{
|
$urlsString .= $url["url"]."\n";
|
||||||
$urlsString .= $url["url"]."\n";
|
$urlsIDsString .= $url["id"]." ";
|
||||||
$urlsIDsString .= $url["id"]." ";
|
}
|
||||||
}
|
$urlsString = substr($urlsString, 0, strlen($urlsString) -1);
|
||||||
$urlsString = substr($urlsString, 0, strlen($urlsString) -1);
|
$urlsIDsString = rtrim($urlsIDsString);
|
||||||
$urlsIDsString = rtrim($urlsIDsString);
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
'
|
|
||||||
<form method="POST" action="'.make_link("artist/edited/".$artist['id']).'">
|
<form method="POST" action="'.make_link("artist/edited/".$artist['id']).'">
|
||||||
'.$user->get_auth_html().'
|
'.$user->get_auth_html().'
|
||||||
<table>
|
<table>
|
||||||
@ -135,113 +130,108 @@ class ArtistsTheme extends Themelet {
|
|||||||
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
|
';
|
||||||
';
|
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Edit artist", $html, "main", 10));
|
$page->add_block(new Block("Edit artist", $html, "main", 10));
|
||||||
}
|
|
||||||
|
|
||||||
public function new_artist_composer()
|
|
||||||
{
|
|
||||||
global $page, $user;
|
|
||||||
|
|
||||||
$html = "<form action=".make_link("artist/create")." method='POST'>
|
|
||||||
".$user->get_auth_html()."
|
|
||||||
<table>
|
|
||||||
<tr><td>Name:</td><td><input type='text' name='name' /></td></tr>
|
|
||||||
<tr><td>Aliases:</td><td><input type='text' name='aliases' /></td></tr>
|
|
||||||
<tr><td>Members:</td><td><input type='text' name='members' /></td></tr>
|
|
||||||
<tr><td>URLs:</td><td><textarea name='urls'></textarea></td></tr>
|
|
||||||
<tr><td>Notes:</td><td><textarea name='notes'></textarea></td></tr>
|
|
||||||
<tr><td colspan='2'><input type='submit' value='Submit' /></td></tr>
|
|
||||||
</table>
|
|
||||||
";
|
|
||||||
|
|
||||||
$page->set_title("Artists");
|
|
||||||
$page->set_heading("Artists");
|
|
||||||
$page->add_block(new Block("Artists", $html, "main", 10));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function list_artists($artists, $pageNumber, $totalPages)
|
public function new_artist_composer() {
|
||||||
{
|
global $page, $user;
|
||||||
global $user, $page;
|
|
||||||
|
|
||||||
$html = "<table id='poolsList' class='zebra'>".
|
$html = "<form action=".make_link("artist/create")." method='POST'>
|
||||||
"<thead><tr>".
|
".$user->get_auth_html()."
|
||||||
"<th>Name</th>".
|
<table>
|
||||||
"<th>Type</th>".
|
<tr><td>Name:</td><td><input type='text' name='name' /></td></tr>
|
||||||
"<th>Last updater</th>".
|
<tr><td>Aliases:</td><td><input type='text' name='aliases' /></td></tr>
|
||||||
"<th>Posts</th>";
|
<tr><td>Members:</td><td><input type='text' name='members' /></td></tr>
|
||||||
|
<tr><td>URLs:</td><td><textarea name='urls'></textarea></td></tr>
|
||||||
|
<tr><td>Notes:</td><td><textarea name='notes'></textarea></td></tr>
|
||||||
|
<tr><td colspan='2'><input type='submit' value='Submit' /></td></tr>
|
||||||
|
</table>
|
||||||
|
";
|
||||||
|
|
||||||
|
$page->set_title("Artists");
|
||||||
|
$page->set_heading("Artists");
|
||||||
|
$page->add_block(new Block("Artists", $html, "main", 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function list_artists($artists, $pageNumber, $totalPages) {
|
||||||
|
global $user, $page;
|
||||||
|
|
||||||
if(!$user->is_anonymous()) $html .= "<th colspan='2'>Action</th>"; // space for edit link
|
$html = "<table id='poolsList' class='zebra'>".
|
||||||
|
"<thead><tr>".
|
||||||
|
"<th>Name</th>".
|
||||||
|
"<th>Type</th>".
|
||||||
|
"<th>Last updater</th>".
|
||||||
|
"<th>Posts</th>";
|
||||||
|
|
||||||
|
if(!$user->is_anonymous()) $html .= "<th colspan='2'>Action</th>"; // space for edit link
|
||||||
|
|
||||||
$html .= "</tr></thead>";
|
$html .= "</tr></thead>";
|
||||||
|
|
||||||
$deletionLinkActionArray =
|
$deletionLinkActionArray = array(
|
||||||
array('artist' => 'artist/nuke/'
|
'artist' => 'artist/nuke/',
|
||||||
, 'alias' => 'artist/alias/delete/'
|
'alias' => 'artist/alias/delete/',
|
||||||
, 'member' => 'artist/member/delete/'
|
'member' => 'artist/member/delete/',
|
||||||
);
|
);
|
||||||
|
|
||||||
$editionLinkActionArray =
|
$editionLinkActionArray = array(
|
||||||
array('artist' => 'artist/edit/'
|
'artist' => 'artist/edit/',
|
||||||
, 'alias' => 'artist/alias/edit/'
|
'alias' => 'artist/alias/edit/',
|
||||||
, 'member' => 'artist/member/edit/'
|
'member' => 'artist/member/edit/',
|
||||||
);
|
);
|
||||||
|
|
||||||
$typeTextArray =
|
$typeTextArray = array(
|
||||||
array('artist' => 'Artist'
|
'artist' => 'Artist',
|
||||||
, 'alias' => 'Alias'
|
'alias' => 'Alias',
|
||||||
, 'member' => 'Member'
|
'member' => 'Member',
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($artists as $artist) {
|
foreach ($artists as $artist) {
|
||||||
if ($artist['type'] != 'artist')
|
if ($artist['type'] != 'artist')
|
||||||
$artist['name'] = str_replace("_", " ", $artist['name']);
|
$artist['name'] = str_replace("_", " ", $artist['name']);
|
||||||
|
|
||||||
$elementLink = "<a href='".make_link("artist/view/".$artist['artist_id'])."'>".str_replace("_", " ", $artist['name'])."</a>";
|
$elementLink = "<a href='".make_link("artist/view/".$artist['artist_id'])."'>".str_replace("_", " ", $artist['name'])."</a>";
|
||||||
//$artist_link = "<a href='".make_link("artist/view/".$artist['artist_id'])."'>".str_replace("_", " ", $artist['artist_name'])."</a>";
|
//$artist_link = "<a href='".make_link("artist/view/".$artist['artist_id'])."'>".str_replace("_", " ", $artist['artist_name'])."</a>";
|
||||||
$user_link = "<a href='".make_link("user/".$artist['user_name'])."'>".$artist['user_name']."</a>";
|
$user_link = "<a href='".make_link("user/".$artist['user_name'])."'>".$artist['user_name']."</a>";
|
||||||
$edit_link = "<a href='".make_link($editionLinkActionArray[$artist['type']].$artist['id'])."'>Edit</a>";
|
$edit_link = "<a href='".make_link($editionLinkActionArray[$artist['type']].$artist['id'])."'>Edit</a>";
|
||||||
$del_link = "<a href='".make_link($deletionLinkActionArray[$artist['type']].$artist['id'])."'>Delete</a>";
|
$del_link = "<a href='".make_link($deletionLinkActionArray[$artist['type']].$artist['id'])."'>Delete</a>";
|
||||||
|
|
||||||
$html .= "<tr>".
|
$html .= "<tr>".
|
||||||
"<td class='left'>".$elementLink;
|
"<td class='left'>".$elementLink;
|
||||||
|
|
||||||
//if ($artist['type'] == 'member')
|
//if ($artist['type'] == 'member')
|
||||||
// $html .= " (member of ".$artist_link.")";
|
// $html .= " (member of ".$artist_link.")";
|
||||||
|
|
||||||
//if ($artist['type'] == 'alias')
|
//if ($artist['type'] == 'alias')
|
||||||
// $html .= " (alias for ".$artist_link.")";
|
// $html .= " (alias for ".$artist_link.")";
|
||||||
|
|
||||||
$html .= "</td>".
|
$html .= "</td>".
|
||||||
"<td>".$typeTextArray[$artist['type']]."</td>".
|
"<td>".$typeTextArray[$artist['type']]."</td>".
|
||||||
"<td>".$user_link."</td>".
|
"<td>".$user_link."</td>".
|
||||||
"<td>".$artist['posts']."</td>";
|
"<td>".$artist['posts']."</td>";
|
||||||
|
|
||||||
if(!$user->is_anonymous()) $html .= "<td>".$edit_link."</td>";
|
if(!$user->is_anonymous()) $html .= "<td>".$edit_link."</td>";
|
||||||
if($user->is_admin()) $html .= "<td>".$del_link."</td>";
|
if($user->is_admin()) $html .= "<td>".$del_link."</td>";
|
||||||
|
|
||||||
$html .= "</tr>";
|
$html .= "</tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= "</tbody></table>";
|
$html .= "</tbody></table>";
|
||||||
|
|
||||||
$page->set_title("Artists");
|
$page->set_title("Artists");
|
||||||
$page->set_heading("Artists");
|
$page->set_heading("Artists");
|
||||||
$page->add_block(new Block("Artists", $html, "main", 10));
|
$page->add_block(new Block("Artists", $html, "main", 10));
|
||||||
|
|
||||||
$this->display_paginator($page, "artist/list", null, $pageNumber, $totalPages);
|
$this->display_paginator($page, "artist/list", null, $pageNumber, $totalPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_new_alias_composer($artistID)
|
public function show_new_alias_composer($artistID) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
'<form method="POST" action='.make_link("artist/alias/add").'>
|
<form method="POST" action='.make_link("artist/alias/add").'>
|
||||||
'.$user->get_auth_html().'
|
'.$user->get_auth_html().'
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Alias:</td><td><input type="text" name="aliases" />
|
<tr><td>Alias:</td><td><input type="text" name="aliases" />
|
||||||
@ -249,277 +239,290 @@ class ArtistsTheme extends Themelet {
|
|||||||
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
';
|
';
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Artist Aliases", $html, "main", 20));
|
$page->add_block(new Block("Artist Aliases", $html, "main", 20));
|
||||||
}
|
}
|
||||||
public function show_new_member_composer($artistID)
|
|
||||||
{
|
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
public function show_new_member_composer($artistID) {
|
||||||
' <form method="POST" action='.make_link("artist/member/add").'>
|
global $user;
|
||||||
|
|
||||||
|
$html = '
|
||||||
|
<form method="POST" action='.make_link("artist/member/add").'>
|
||||||
'.$user->get_auth_html().'
|
'.$user->get_auth_html().'
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Members:</td><td><input type="text" name="members" />
|
<tr><td>Members:</td><td><input type="text" name="members" />
|
||||||
<input type="hidden" name="artistID" value='.$artistID.' /></td></tr>
|
<input type="hidden" name="artistID" value='.$artistID.' /></td></tr>
|
||||||
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
';
|
';
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Artist members", $html, "main", 30));
|
$page->add_block(new Block("Artist members", $html, "main", 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_new_url_composer($artistID)
|
public function show_new_url_composer($artistID) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
' <form method="POST" action='.make_link("artist/url/add").'>
|
<form method="POST" action='.make_link("artist/url/add").'>
|
||||||
'.$user->get_auth_html().'
|
'.$user->get_auth_html().'
|
||||||
<table>
|
<table>
|
||||||
<tr><td>URL:</td><td><textarea name="urls"></textarea>
|
<tr><td>URL:</td><td><textarea name="urls"></textarea>
|
||||||
<input type="hidden" name="artistID" value='.$artistID.' /></td></tr>
|
<input type="hidden" name="artistID" value='.$artistID.' /></td></tr>
|
||||||
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
';
|
';
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Artist URLs", $html, "main", 40));
|
$page->add_block(new Block("Artist URLs", $html, "main", 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_alias_editor($alias)
|
public function show_alias_editor($alias) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
'
|
<form method="POST" action="'.make_link("artist/alias/edited/".$alias['id']).'">
|
||||||
<form method="POST" action="'.make_link("artist/alias/edited/".$alias['id']).'">
|
'.$user->get_auth_html().'
|
||||||
'.$user->get_auth_html().'
|
<label for="alias">Alias:</label>
|
||||||
<label for="alias">Alias:</label>
|
<input type="text" name="alias" value="'.$alias['alias'].'" />
|
||||||
<input type="text" name="alias" value="'.$alias['alias'].'" />
|
<input type="hidden" name="aliasID" value="'.$alias['id'].'" />
|
||||||
<input type="hidden" name="aliasID" value="'.$alias['id'].'" />
|
<input type="submit" value="Submit" />
|
||||||
<input type="submit" value="Submit" />
|
</form>
|
||||||
</form>
|
';
|
||||||
';
|
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Edit Alias", $html, "main", 10));
|
$page->add_block(new Block("Edit Alias", $html, "main", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_url_editor($url)
|
public function show_url_editor($url) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
'
|
<form method="POST" action="'.make_link("artist/url/edited/".$url['id']).'">
|
||||||
<form method="POST" action="'.make_link("artist/url/edited/".$url['id']).'">
|
'.$user->get_auth_html().'
|
||||||
'.$user->get_auth_html().'
|
<label for="url">URL:</label>
|
||||||
<label for="url">URL:</label>
|
<input type="text" name="url" value="'.$url['url'].'" />
|
||||||
<input type="text" name="url" value="'.$url['url'].'" />
|
<input type="hidden" name="urlID" value="'.$url['id'].'" />
|
||||||
<input type="hidden" name="urlID" value="'.$url['id'].'" />
|
<input type="submit" value="Submit" />
|
||||||
<input type="submit" value="Submit" />
|
</form>
|
||||||
</form>
|
';
|
||||||
';
|
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Edit URL", $html, "main", 10));
|
$page->add_block(new Block("Edit URL", $html, "main", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_member_editor($member)
|
public function show_member_editor($member) {
|
||||||
{
|
global $user;
|
||||||
global $user;
|
|
||||||
|
|
||||||
$html =
|
$html = '
|
||||||
'
|
<form method="POST" action="'.make_link("artist/member/edited/".$member['id']).'">
|
||||||
<form method="POST" action="'.make_link("artist/member/edited/".$member['id']).'">
|
'.$user->get_auth_html().'
|
||||||
'.$user->get_auth_html().'
|
<label for="member">Member name:</label>
|
||||||
<label for="member">Member name:</label>
|
<input type="text" name="name" value="'.$member['name'].'" />
|
||||||
<input type="text" name="name" value="'.$member['name'].'" />
|
<input type="hidden" name="memberID" value="'.$member['id'].'" />
|
||||||
<input type="hidden" name="memberID" value="'.$member['id'].'" />
|
<input type="submit" value="Submit" />
|
||||||
<input type="submit" value="Submit" />
|
</form>
|
||||||
</form>
|
';
|
||||||
';
|
|
||||||
|
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("Edit Member", $html, "main", 10));
|
$page->add_block(new Block("Edit Member", $html, "main", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin)
|
public function show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin) {
|
||||||
{
|
global $page;
|
||||||
global $page;
|
|
||||||
|
|
||||||
$artist_link = "<a href='".make_link("post/list/".$artist['name']."/1")."'>".str_replace("_", " ", $artist['name'])."</a>";
|
$artist_link = "<a href='".make_link("post/list/".$artist['name']."/1")."'>".str_replace("_", " ", $artist['name'])."</a>";
|
||||||
|
|
||||||
$html = "<table id='poolsList' class='zebra'>
|
$html = "<table id='poolsList' class='zebra'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>";
|
<th></th>";
|
||||||
|
|
||||||
if ($userIsLogged)
|
if ($userIsLogged) $html .= "<th></th>";
|
||||||
$html .= "<th></th>";
|
if ($userIsAdmin) $html .= "<th></th>";
|
||||||
|
|
||||||
if ($userIsAdmin)
|
$html .= " <tr>
|
||||||
$html .= "<th></th>";
|
|
||||||
|
|
||||||
$html .= " <tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class='left'>Name:</td>
|
<td class='left'>Name:</td>
|
||||||
<td class='left'>".$artist_link."</td>";
|
<td class='left'>".$artist_link."</td>";
|
||||||
if ($userIsLogged) $html .= "<td></td>";
|
if ($userIsLogged) $html .= "<td></td>";
|
||||||
if ($userIsAdmin) $html .= "<td></td>";
|
if ($userIsAdmin) $html .= "<td></td>";
|
||||||
$html .= "</tr>";
|
$html .= "</tr>";
|
||||||
|
|
||||||
if (count($aliases) > 0)
|
$html .= $this->render_aliases($aliases, $userIsLogged, $userIsAdmin);
|
||||||
{
|
$html .= $this->render_members($members, $userIsLogged, $userIsAdmin);
|
||||||
$aliasViewLink = str_replace("_", " ", $aliases[0]['alias_name']); // no link anymore
|
$html .= $this->render_urls($urls, $userIsLogged, $userIsAdmin);
|
||||||
$aliasEditLink = "<a href='".make_link("artist/alias/edit/".$aliases[0]['alias_id'])."'>Edit</a>";
|
|
||||||
$aliasDeleteLink = "<a href='".make_link("artist/alias/delete/".$aliases[0]['alias_id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'>Aliases:</td>
|
|
||||||
<td class='left'>".$aliasViewLink."</td>";
|
|
||||||
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$aliasEditLink."</td>";
|
|
||||||
|
|
||||||
if ($userIsAdmin)
|
$html .= "<tr>
|
||||||
$html .= "<td class='left'>".$aliasDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
|
|
||||||
if (count($aliases) > 1)
|
|
||||||
{
|
|
||||||
for ($i = 1; $i < count($aliases); $i++)
|
|
||||||
{
|
|
||||||
$aliasViewLink = str_replace("_", " ", $aliases[$i]['alias_name']); // no link anymore
|
|
||||||
$aliasEditLink = "<a href='".make_link("artist/alias/edit/".$aliases[$i]['alias_id'])."'>Edit</a>";
|
|
||||||
$aliasDeleteLink = "<a href='".make_link("artist/alias/delete/".$aliases[$i]['alias_id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'> </td>
|
|
||||||
<td class='left'>".$aliasViewLink."</td>";
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$aliasEditLink."</td>";
|
|
||||||
if ($userIsAdmin)
|
|
||||||
$html .= "<td class='left'>".$aliasDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($members) > 0)
|
|
||||||
{
|
|
||||||
$memberViewLink = str_replace("_", " ", $members[0]['name']); // no link anymore
|
|
||||||
$memberEditLink = "<a href='".make_link("artist/member/edit/".$members[0]['id'])."'>Edit</a>";
|
|
||||||
$memberDeleteLink = "<a href='".make_link("artist/member/delete/".$members[0]['id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'>Members:</td>
|
|
||||||
<td class='left'>".$memberViewLink."</td>";
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$memberEditLink."</td>";
|
|
||||||
if ($userIsAdmin)
|
|
||||||
$html .= "<td class='left'>".$memberDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
|
|
||||||
if (count($members) > 1)
|
|
||||||
{
|
|
||||||
for ($i = 1; $i < count($members); $i++)
|
|
||||||
{
|
|
||||||
$memberViewLink = str_replace("_", " ", $members[$i]['name']); // no link anymore
|
|
||||||
$memberEditLink = "<a href='".make_link("artist/member/edit/".$members[$i]['id'])."'>Edit</a>";
|
|
||||||
$memberDeleteLink = "<a href='".make_link("artist/member/delete/".$members[$i]['id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'> </td>
|
|
||||||
<td class='left'>".$memberViewLink."</td>";
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$memberEditLink."</td>";
|
|
||||||
if ($userIsAdmin)
|
|
||||||
$html .= "<td class='left'>".$memberDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($urls) > 0)
|
|
||||||
{
|
|
||||||
$urlViewLink = "<a href='".str_replace("_", " ", $urls[0]['url'])."' target='_blank'>".str_replace("_", " ", $urls[0]['url'])."</a>";
|
|
||||||
$urlEditLink = "<a href='".make_link("artist/url/edit/".$urls[0]['id'])."'>Edit</a>";
|
|
||||||
$urlDeleteLink = "<a href='".make_link("artist/url/delete/".$urls[0]['id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'>URLs:</td>
|
|
||||||
<td class='left'>".$urlViewLink."</td>";
|
|
||||||
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$urlEditLink."</td>";
|
|
||||||
|
|
||||||
if ($userIsAdmin)
|
|
||||||
$html .= "<td class='left'>".$urlDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
|
|
||||||
if (count($urls) > 1)
|
|
||||||
{
|
|
||||||
for ($i = 1; $i < count($urls); $i++)
|
|
||||||
{
|
|
||||||
$urlViewLink = "<a href='".str_replace("_", " ", $urls[$i]['url'])."' target='_blank'>".str_replace("_", " ", $urls[$i]['url'])."</a>";
|
|
||||||
$urlEditLink = "<a href='".make_link("artist/url/edit/".$urls[$i]['id'])."'>Edit</a>";
|
|
||||||
$urlDeleteLink = "<a href='".make_link("artist/url/delete/".$urls[$i]['id'])."'>Delete</a>";
|
|
||||||
|
|
||||||
$html .= "<tr>
|
|
||||||
<td class='left'> </td>
|
|
||||||
<td class='left'>".$urlViewLink."</td>";
|
|
||||||
if ($userIsLogged)
|
|
||||||
$html .= "<td class='left'>".$urlEditLink."</td>";
|
|
||||||
|
|
||||||
if ($userIsAdmin)
|
|
||||||
$html .= "<td class='left'>".$urlDeleteLink."</td>";
|
|
||||||
|
|
||||||
$html .= "</tr>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$html .=
|
|
||||||
"<tr>
|
|
||||||
<td class='left'>Notes:</td>
|
<td class='left'>Notes:</td>
|
||||||
<td class='left'>".$artist["notes"]."</td>";
|
<td class='left'>".$artist["notes"]."</td>";
|
||||||
if ($userIsLogged) $html .= "<td></td>";
|
if ($userIsLogged) $html .= "<td></td>";
|
||||||
if ($userIsAdmin) $html .= "<td></td>";
|
if ($userIsAdmin) $html .= "<td></td>";
|
||||||
//TODO how will notes be edited? On edit artist? (should there be an editartist?) or on a editnotes?
|
//TODO how will notes be edited? On edit artist? (should there be an editartist?) or on a editnotes?
|
||||||
//same question for deletion
|
//same question for deletion
|
||||||
$html .= "</tr>
|
$html .= "</tr>
|
||||||
</table>";
|
</table>";
|
||||||
|
|
||||||
$page->set_title("Artist");
|
$page->set_title("Artist");
|
||||||
$page->set_heading("Artist");
|
$page->set_heading("Artist");
|
||||||
$page->add_block(new Block("Artist", $html, "main", 10));
|
$page->add_block(new Block("Artist", $html, "main", 10));
|
||||||
|
|
||||||
//we show the images for the artist
|
//we show the images for the artist
|
||||||
$artist_images = "";
|
$artist_images = "";
|
||||||
foreach($images as $image) {
|
foreach($images as $image) {
|
||||||
|
$thumb_html = $this->build_thumb_html($image);
|
||||||
$thumb_html = $this->build_thumb_html($image);
|
|
||||||
|
|
||||||
$artist_images .= '<span class="thumb">'.
|
$artist_images .= '<span class="thumb">'.
|
||||||
'<a href="$image_link">'.$thumb_html.'</a>'.
|
'<a href="$image_link">'.$thumb_html.'</a>'.
|
||||||
'</span>';
|
'</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$page->add_block(new Block("Artist Images", $artist_images, "main", 20));
|
$page->add_block(new Block("Artist Images", $artist_images, "main", 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $aliases
|
||||||
|
* @param $userIsLogged
|
||||||
|
* @param $userIsAdmin
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function render_aliases($aliases, $userIsLogged, $userIsAdmin) {
|
||||||
|
$html = "";
|
||||||
|
if(count($aliases) > 0) {
|
||||||
|
$aliasViewLink = str_replace("_", " ", $aliases[0]['alias_name']); // no link anymore
|
||||||
|
$aliasEditLink = "<a href='" . make_link("artist/alias/edit/" . $aliases[0]['alias_id']) . "'>Edit</a>";
|
||||||
|
$aliasDeleteLink = "<a href='" . make_link("artist/alias/delete/" . $aliases[0]['alias_id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'>Aliases:</td>
|
||||||
|
<td class='left'>" . $aliasViewLink . "</td>";
|
||||||
|
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $aliasEditLink . "</td>";
|
||||||
|
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $aliasDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
|
||||||
|
if (count($aliases) > 1) {
|
||||||
|
for ($i = 1; $i < count($aliases); $i++) {
|
||||||
|
$aliasViewLink = str_replace("_", " ", $aliases[$i]['alias_name']); // no link anymore
|
||||||
|
$aliasEditLink = "<a href='" . make_link("artist/alias/edit/" . $aliases[$i]['alias_id']) . "'>Edit</a>";
|
||||||
|
$aliasDeleteLink = "<a href='" . make_link("artist/alias/delete/" . $aliases[$i]['alias_id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'> </td>
|
||||||
|
<td class='left'>" . $aliasViewLink . "</td>";
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $aliasEditLink . "</td>";
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $aliasDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $members
|
||||||
|
* @param $userIsLogged
|
||||||
|
* @param $userIsAdmin
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function render_members($members, $userIsLogged, $userIsAdmin) {
|
||||||
|
$html = "";
|
||||||
|
if(count($members) > 0) {
|
||||||
|
$memberViewLink = str_replace("_", " ", $members[0]['name']); // no link anymore
|
||||||
|
$memberEditLink = "<a href='" . make_link("artist/member/edit/" . $members[0]['id']) . "'>Edit</a>";
|
||||||
|
$memberDeleteLink = "<a href='" . make_link("artist/member/delete/" . $members[0]['id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'>Members:</td>
|
||||||
|
<td class='left'>" . $memberViewLink . "</td>";
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $memberEditLink . "</td>";
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $memberDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
|
||||||
|
if (count($members) > 1) {
|
||||||
|
for ($i = 1; $i < count($members); $i++) {
|
||||||
|
$memberViewLink = str_replace("_", " ", $members[$i]['name']); // no link anymore
|
||||||
|
$memberEditLink = "<a href='" . make_link("artist/member/edit/" . $members[$i]['id']) . "'>Edit</a>";
|
||||||
|
$memberDeleteLink = "<a href='" . make_link("artist/member/delete/" . $members[$i]['id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'> </td>
|
||||||
|
<td class='left'>" . $memberViewLink . "</td>";
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $memberEditLink . "</td>";
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $memberDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $urls
|
||||||
|
* @param $userIsLogged
|
||||||
|
* @param $userIsAdmin
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function render_urls($urls, $userIsLogged, $userIsAdmin) {
|
||||||
|
$html = "";
|
||||||
|
if(count($urls) > 0) {
|
||||||
|
$urlViewLink = "<a href='" . str_replace("_", " ", $urls[0]['url']) . "' target='_blank'>" . str_replace("_", " ", $urls[0]['url']) . "</a>";
|
||||||
|
$urlEditLink = "<a href='" . make_link("artist/url/edit/" . $urls[0]['id']) . "'>Edit</a>";
|
||||||
|
$urlDeleteLink = "<a href='" . make_link("artist/url/delete/" . $urls[0]['id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'>URLs:</td>
|
||||||
|
<td class='left'>" . $urlViewLink . "</td>";
|
||||||
|
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $urlEditLink . "</td>";
|
||||||
|
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $urlDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
|
||||||
|
if (count($urls) > 1) {
|
||||||
|
for ($i = 1; $i < count($urls); $i++) {
|
||||||
|
$urlViewLink = "<a href='" . str_replace("_", " ", $urls[$i]['url']) . "' target='_blank'>" . str_replace("_", " ", $urls[$i]['url']) . "</a>";
|
||||||
|
$urlEditLink = "<a href='" . make_link("artist/url/edit/" . $urls[$i]['id']) . "'>Edit</a>";
|
||||||
|
$urlDeleteLink = "<a href='" . make_link("artist/url/delete/" . $urls[$i]['id']) . "'>Delete</a>";
|
||||||
|
|
||||||
|
$html .= "<tr>
|
||||||
|
<td class='left'> </td>
|
||||||
|
<td class='left'>" . $urlViewLink . "</td>";
|
||||||
|
if ($userIsLogged)
|
||||||
|
$html .= "<td class='left'>" . $urlEditLink . "</td>";
|
||||||
|
|
||||||
|
if ($userIsAdmin)
|
||||||
|
$html .= "<td class='left'>" . $urlDeleteLink . "</td>";
|
||||||
|
|
||||||
|
$html .= "</tr>";
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class BanWordsTest extends ShimmiePHPUnitTestCase {
|
class BanWordsTest extends ShimmiePHPUnitTestCase {
|
||||||
function check_blocked($image_id, $words) {
|
public function check_blocked($image_id, $words) {
|
||||||
global $user;
|
global $user;
|
||||||
try {
|
try {
|
||||||
send_event(new CommentPostingEvent($image_id, $user, $words));
|
send_event(new CommentPostingEvent($image_id, $user, $words));
|
||||||
@ -11,7 +11,7 @@ class BanWordsTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testWordBan() {
|
public function testWordBan() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_string("banned_words", "viagra\nporn\n\n/http:.*\.cn\//");
|
$config->set_string("banned_words", "viagra\nporn\n\n/http:.*\.cn\//");
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class BBCode extends FormatterExtension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* @return mixed
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function filter_spoiler(/*string*/ $text) {
|
private function filter_spoiler(/*string*/ $text) {
|
||||||
return str_replace(
|
return str_replace(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class BlocksTest extends ShimmiePHPUnitTestCase {
|
class BlocksTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBlocks() {
|
public function testBlocks() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("blocks/list");
|
$this->get_page("blocks/list");
|
||||||
$this->assert_response(200);
|
$this->assert_response(200);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
class BlotterTest extends ShimmiePHPUnitTestCase {
|
class BlotterTest extends ShimmiePHPUnitTestCase {
|
||||||
function testLogin() {
|
public function testLogin() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
//$this->assert_text("Blotter Editor");
|
//$this->assert_text("Blotter Editor");
|
||||||
//$this->click("Blotter Editor");
|
//$this->click("Blotter Editor");
|
||||||
//$this->log_out();
|
//$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDenial() {
|
public function testDenial() {
|
||||||
$this->get_page("blotter/editor");
|
$this->get_page("blotter/editor");
|
||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
$this->get_page("blotter/add");
|
$this->get_page("blotter/add");
|
||||||
@ -16,7 +16,7 @@ class BlotterTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAddViewRemove() {
|
public function testAddViewRemove() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$this->get_page("blotter/editor");
|
$this->get_page("blotter/editor");
|
||||||
|
@ -62,7 +62,7 @@ class BlotterTheme extends Themelet {
|
|||||||
if($entries[$i]['important'] == 'Y') { $important = 'Y'; } else { $important = 'N'; }
|
if($entries[$i]['important'] == 'Y') { $important = 'Y'; } else { $important = 'N'; }
|
||||||
|
|
||||||
// Add the new table row(s)
|
// Add the new table row(s)
|
||||||
$table_rows .=
|
$table_rows .=
|
||||||
"<tr>
|
"<tr>
|
||||||
<td>$entry_date</td>
|
<td>$entry_date</td>
|
||||||
<td>$entry_text</td>
|
<td>$entry_text</td>
|
||||||
@ -114,7 +114,7 @@ class BlotterTheme extends Themelet {
|
|||||||
$i_open = "<font color='#{$i_color}'>";
|
$i_open = "<font color='#{$i_color}'>";
|
||||||
$i_close="</font>";
|
$i_close="</font>";
|
||||||
}
|
}
|
||||||
$html .= "{$i_open}{$clean_date} - {$entry_text}{$i_close}<br /><br />";
|
$html .= "{$i_open}{$clean_date} - {$entry_text}{$i_close}<br /><br />";
|
||||||
}
|
}
|
||||||
$html .= "</pre>";
|
$html .= "</pre>";
|
||||||
return $html;
|
return $html;
|
||||||
@ -139,9 +139,9 @@ class BlotterTheme extends Themelet {
|
|||||||
$entry_text = $entries[$i]['entry_text'];
|
$entry_text = $entries[$i]['entry_text'];
|
||||||
if($entries[$i]['important'] == 'Y') {
|
if($entries[$i]['important'] == 'Y') {
|
||||||
$i_open = "<font color='#{$i_color}'>";
|
$i_open = "<font color='#{$i_color}'>";
|
||||||
$i_close="</font>";
|
$i_close="</font>";
|
||||||
}
|
}
|
||||||
$entries_list .= "<li>{$i_open}{$clean_date} - {$entry_text}{$i_close}</li>";
|
$entries_list .= "<li>{$i_open}{$clean_date} - {$entry_text}{$i_close}</li>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$pos_break = "";
|
$pos_break = "";
|
||||||
@ -149,7 +149,7 @@ class BlotterTheme extends Themelet {
|
|||||||
|
|
||||||
if($position === "left") {
|
if($position === "left") {
|
||||||
$pos_break = "<br />";
|
$pos_break = "<br />";
|
||||||
$pos_align = "";
|
$pos_align = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count($entries) === 0) {
|
if(count($entries) === 0) {
|
||||||
@ -176,4 +176,3 @@ class BlotterTheme extends Themelet {
|
|||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class BookmarksTest extends ShimmiePHPUnitTestCase {
|
class BookmarksTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBookmarks() {
|
public function testBookmarks() {
|
||||||
$this->get_page("bookmark/add");
|
$this->get_page("bookmark/add");
|
||||||
$this->get_page("bookmark/remove");
|
$this->get_page("bookmark/remove");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class BrowserSearchTest extends ShimmiePHPUnitTestCase {
|
class BrowserSearchTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBasic() {
|
public function testBasic() {
|
||||||
$this->get_page("browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml");
|
$this->get_page("browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml");
|
||||||
$this->get_page("browser_search/test");
|
$this->get_page("browser_search/test");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class BulkAddTest extends ShimmiePHPUnitTestCase {
|
class BulkAddTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBulkAdd() {
|
public function testBulkAdd() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$this->get_page('admin');
|
$this->get_page('admin');
|
||||||
@ -11,7 +11,8 @@ class BulkAddTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assertContains("Error, asdf is not a readable directory",
|
$this->assertContains("Error, asdf is not a readable directory",
|
||||||
$bae->results, implode("\n", $bae->results));
|
$bae->results, implode("\n", $bae->results));
|
||||||
|
|
||||||
return; // FIXME: have BAE return a list of successes as well as errors?
|
// FIXME: have BAE return a list of successes as well as errors?
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->get_page('admin');
|
$this->get_page('admin');
|
||||||
$this->assert_title("Admin Tools");
|
$this->assert_title("Admin Tools");
|
||||||
|
@ -54,6 +54,14 @@ class BulkAddCSV extends Extension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the necessary DataUploadEvent for a given image and tags.
|
* Generate the necessary DataUploadEvent for a given image and tags.
|
||||||
|
*
|
||||||
|
* @param string $tmpname
|
||||||
|
* @param string $filename
|
||||||
|
* @param string $tags
|
||||||
|
* @param string $source
|
||||||
|
* @param string $rating
|
||||||
|
* @param string $thumbfile
|
||||||
|
* @throws UploadException
|
||||||
*/
|
*/
|
||||||
private function add_image($tmpname, $filename, $tags, $source, $rating, $thumbfile) {
|
private function add_image($tmpname, $filename, $tags, $source, $rating, $thumbfile) {
|
||||||
assert(file_exists($tmpname));
|
assert(file_exists($tmpname));
|
||||||
|
@ -71,12 +71,16 @@ class Comment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \User $user
|
* @param User $user
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function count_comments_by_user($user) {
|
public static function count_comments_by_user($user) {
|
||||||
global $database;
|
global $database;
|
||||||
return $database->get_one("SELECT COUNT(*) AS count FROM comments WHERE owner_id=:owner_id", array("owner_id"=>$user->id));
|
return $database->get_one("
|
||||||
|
SELECT COUNT(*) AS count
|
||||||
|
FROM comments
|
||||||
|
WHERE owner_id=:owner_id
|
||||||
|
", array("owner_id"=>$user->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,6 +93,9 @@ class Comment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CommentList extends Extension {
|
class CommentList extends Extension {
|
||||||
|
/** @var CommentListTheme $theme */
|
||||||
|
var $theme;
|
||||||
|
|
||||||
public function onInitExt(InitExtEvent $event) {
|
public function onInitExt(InitExtEvent $event) {
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
$config->set_default_int('comment_window', 5);
|
$config->set_default_int('comment_window', 5);
|
||||||
@ -147,78 +154,92 @@ class CommentList extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onPageRequest(PageRequestEvent $event) {
|
public function onPageRequest(PageRequestEvent $event) {
|
||||||
global $page, $user, $database;
|
|
||||||
if($event->page_matches("comment")) {
|
if($event->page_matches("comment")) {
|
||||||
if($event->get_arg(0) === "add") {
|
switch($event->get_arg(0)) {
|
||||||
if(isset($_POST['image_id']) && isset($_POST['comment'])) {
|
case "add": $this->onPageRequest_add(); break;
|
||||||
try {
|
case "delete": $this->onPageRequest_delete($event); break;
|
||||||
$i_iid = int_escape($_POST['image_id']);
|
case "bulk_delete": $this->onPageRequest_bulk_delete(); break;
|
||||||
$cpe = new CommentPostingEvent($_POST['image_id'], $user, $_POST['comment']);
|
case "list": $this->onPageRequest_list($event); break;
|
||||||
send_event($cpe);
|
case "beta-search": $this->onPageRequest_beta_search($event); break;
|
||||||
$page->set_mode("redirect");
|
|
||||||
$page->set_redirect(make_link("post/view/$i_iid#comment_on_$i_iid"));
|
|
||||||
}
|
|
||||||
catch(CommentPostingException $ex) {
|
|
||||||
$this->theme->display_error(403, "Comment Blocked", $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($event->get_arg(0) === "delete") {
|
|
||||||
if($user->can("delete_comment")) {
|
|
||||||
// FIXME: post, not args
|
|
||||||
if($event->count_args() === 3) {
|
|
||||||
send_event(new CommentDeletionEvent($event->get_arg(1)));
|
|
||||||
flash_message("Deleted comment");
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
if(!empty($_SERVER['HTTP_REFERER'])) {
|
|
||||||
$page->set_redirect($_SERVER['HTTP_REFERER']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$page->set_redirect(make_link("post/view/".$event->get_arg(2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->theme->display_permission_denied();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($event->get_arg(0) === "bulk_delete") {
|
|
||||||
if($user->can("delete_comment") && !empty($_POST["ip"])) {
|
|
||||||
$ip = $_POST['ip'];
|
|
||||||
|
|
||||||
$cids = $database->get_col("SELECT id FROM comments WHERE owner_ip=:ip", array("ip"=>$ip));
|
|
||||||
$num = count($cids);
|
|
||||||
log_warning("comment", "Deleting $num comments from $ip");
|
|
||||||
foreach($cids as $cid) {
|
|
||||||
send_event(new CommentDeletionEvent($cid));
|
|
||||||
}
|
|
||||||
flash_message("Deleted $num comments");
|
|
||||||
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
$page->set_redirect(make_link("admin"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->theme->display_permission_denied();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($event->get_arg(0) === "list") {
|
|
||||||
$page_num = int_escape($event->get_arg(1));
|
|
||||||
$this->build_page($page_num);
|
|
||||||
}
|
|
||||||
else if($event->get_arg(0) === "beta-search") {
|
|
||||||
$search = $event->get_arg(1);
|
|
||||||
$page_num = int_escape($event->get_arg(2));
|
|
||||||
$duser = User::by_name($search);
|
|
||||||
$i_comment_count = Comment::count_comments_by_user($duser);
|
|
||||||
$com_per_page = 50;
|
|
||||||
$total_pages = ceil($i_comment_count/$com_per_page);
|
|
||||||
$page_num = $this->sanity_check_pagenumber($page_num, $total_pages);
|
|
||||||
$comments = $this->get_user_comments($duser->id, $com_per_page, ($page_num-1) * $com_per_page);
|
|
||||||
$this->theme->display_all_user_comments($comments, $page_num, $total_pages, $duser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function onPageRequest_add() {
|
||||||
|
global $user, $page;
|
||||||
|
if (isset($_POST['image_id']) && isset($_POST['comment'])) {
|
||||||
|
try {
|
||||||
|
$i_iid = int_escape($_POST['image_id']);
|
||||||
|
$cpe = new CommentPostingEvent($_POST['image_id'], $user, $_POST['comment']);
|
||||||
|
send_event($cpe);
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
$page->set_redirect(make_link("post/view/$i_iid#comment_on_$i_iid"));
|
||||||
|
} catch (CommentPostingException $ex) {
|
||||||
|
$this->theme->display_error(403, "Comment Blocked", $ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onPageRequest_delete(PageRequestEvent $event) {
|
||||||
|
global $user, $page;
|
||||||
|
if ($user->can("delete_comment")) {
|
||||||
|
// FIXME: post, not args
|
||||||
|
if ($event->count_args() === 3) {
|
||||||
|
send_event(new CommentDeletionEvent($event->get_arg(1)));
|
||||||
|
flash_message("Deleted comment");
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
if (!empty($_SERVER['HTTP_REFERER'])) {
|
||||||
|
$page->set_redirect($_SERVER['HTTP_REFERER']);
|
||||||
|
} else {
|
||||||
|
$page->set_redirect(make_link("post/view/" . $event->get_arg(2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->theme->display_permission_denied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onPageRequest_bulk_delete() {
|
||||||
|
global $user, $database, $page;
|
||||||
|
if ($user->can("delete_comment") && !empty($_POST["ip"])) {
|
||||||
|
$ip = $_POST['ip'];
|
||||||
|
|
||||||
|
$comment_ids = $database->get_col("
|
||||||
|
SELECT id
|
||||||
|
FROM comments
|
||||||
|
WHERE owner_ip=:ip
|
||||||
|
", array("ip" => $ip));
|
||||||
|
$num = count($comment_ids);
|
||||||
|
log_warning("comment", "Deleting $num comments from $ip");
|
||||||
|
foreach($comment_ids as $cid) {
|
||||||
|
send_event(new CommentDeletionEvent($cid));
|
||||||
|
}
|
||||||
|
flash_message("Deleted $num comments");
|
||||||
|
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
$page->set_redirect(make_link("admin"));
|
||||||
|
} else {
|
||||||
|
$this->theme->display_permission_denied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onPageRequest_list(PageRequestEvent $event) {
|
||||||
|
$page_num = int_escape($event->get_arg(1));
|
||||||
|
$this->build_page($page_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onPageRequest_beta_search(PageRequestEvent $event) {
|
||||||
|
$search = $event->get_arg(1);
|
||||||
|
$page_num = int_escape($event->get_arg(2));
|
||||||
|
$duser = User::by_name($search);
|
||||||
|
$i_comment_count = Comment::count_comments_by_user($duser);
|
||||||
|
$com_per_page = 50;
|
||||||
|
$total_pages = ceil($i_comment_count / $com_per_page);
|
||||||
|
$page_num = clamp($page_num, 1, $total_pages);
|
||||||
|
$comments = $this->get_user_comments($duser->id, $com_per_page, ($page_num - 1) * $com_per_page);
|
||||||
|
$this->theme->display_all_user_comments($comments, $page_num, $total_pages, $duser);
|
||||||
|
}
|
||||||
|
|
||||||
public function onAdminBuilding(AdminBuildingEvent $event) {
|
public function onAdminBuilding(AdminBuildingEvent $event) {
|
||||||
$this->theme->display_admin_block();
|
$this->theme->display_admin_block();
|
||||||
}
|
}
|
||||||
@ -264,7 +285,10 @@ class CommentList extends Extension {
|
|||||||
|
|
||||||
public function onCommentDeletion(CommentDeletionEvent $event) {
|
public function onCommentDeletion(CommentDeletionEvent $event) {
|
||||||
global $database;
|
global $database;
|
||||||
$database->Execute("DELETE FROM comments WHERE id=:comment_id", array("comment_id"=>$event->comment_id));
|
$database->Execute("
|
||||||
|
DELETE FROM comments
|
||||||
|
WHERE id=:comment_id
|
||||||
|
", array("comment_id"=>$event->comment_id));
|
||||||
log_info("comment", "Deleting Comment #{$event->comment_id}");
|
log_info("comment", "Deleting Comment #{$event->comment_id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,38 +352,32 @@ class CommentList extends Extension {
|
|||||||
") / 10);
|
") / 10);
|
||||||
$database->cache->set("comment_pages", $total_pages, 600);
|
$database->cache->set("comment_pages", $total_pages, 600);
|
||||||
}
|
}
|
||||||
|
$total_pages = max($total_pages, 1);
|
||||||
if(is_null($current_page) || $current_page <= 0) {
|
|
||||||
$current_page = 1;
|
$current_page = clamp($current_page, 1, $total_pages);
|
||||||
}
|
|
||||||
$current_page = $this->sanity_check_pagenumber($current_page, $total_pages);
|
|
||||||
|
|
||||||
$threads_per_page = 10;
|
$threads_per_page = 10;
|
||||||
$start = $threads_per_page * ($current_page - 1);
|
$start = $threads_per_page * ($current_page - 1);
|
||||||
|
|
||||||
$get_threads = "
|
$result = $database->Execute("
|
||||||
SELECT image_id,MAX(posted) AS latest
|
SELECT image_id,MAX(posted) AS latest
|
||||||
FROM comments
|
FROM comments
|
||||||
$where
|
$where
|
||||||
GROUP BY image_id
|
GROUP BY image_id
|
||||||
ORDER BY latest DESC
|
ORDER BY latest DESC
|
||||||
LIMIT :limit OFFSET :offset
|
LIMIT :limit OFFSET :offset
|
||||||
";
|
", array("limit"=>$threads_per_page, "offset"=>$start));
|
||||||
$result = $database->Execute($get_threads, array("limit"=>$threads_per_page, "offset"=>$start));
|
|
||||||
|
|
||||||
if(ext_is_live("Ratings")) {
|
$user_ratings = ext_is_live("Ratings") ? Ratings::get_user_privs($user) : "";
|
||||||
$user_ratings = Ratings::get_user_privs($user);
|
|
||||||
} else {
|
|
||||||
$user_ratings = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$images = array();
|
$images = array();
|
||||||
while($row = $result->fetch()) {
|
while($row = $result->fetch()) {
|
||||||
$image = Image::by_id($row["image_id"]);
|
$image = Image::by_id($row["image_id"]);
|
||||||
if(ext_is_live("Ratings") && !is_null($image)) {
|
if(
|
||||||
if(strpos($user_ratings, $image->rating) === FALSE) {
|
ext_is_live("Ratings") && !is_null($image) &&
|
||||||
$image = null; // this is "clever", I may live to regret it
|
strpos($user_ratings, $image->rating) === FALSE
|
||||||
}
|
) {
|
||||||
|
$image = null; // this is "clever", I may live to regret it
|
||||||
}
|
}
|
||||||
if(!is_null($image)) {
|
if(!is_null($image)) {
|
||||||
$comments = $this->get_comments($image->id);
|
$comments = $this->get_comments($image->id);
|
||||||
@ -373,22 +391,13 @@ class CommentList extends Extension {
|
|||||||
|
|
||||||
// get comments {{{
|
// get comments {{{
|
||||||
/**
|
/**
|
||||||
* @param int $count
|
* @param string $query
|
||||||
* @return array
|
* @param array $args
|
||||||
|
* @return Comment[]
|
||||||
*/
|
*/
|
||||||
private function get_recent_comments($count) {
|
private function get_generic_comments($query, $args) {
|
||||||
global $database;
|
global $database;
|
||||||
$rows = $database->get_all("
|
$rows = $database->get_all($query, $args);
|
||||||
SELECT
|
|
||||||
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
|
||||||
comments.comment as comment, comments.id as comment_id,
|
|
||||||
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
|
||||||
comments.posted as posted
|
|
||||||
FROM comments
|
|
||||||
LEFT JOIN users ON comments.owner_id=users.id
|
|
||||||
ORDER BY comments.id DESC
|
|
||||||
LIMIT :limit
|
|
||||||
", array("limit"=>$count));
|
|
||||||
$comments = array();
|
$comments = array();
|
||||||
foreach($rows as $row) {
|
foreach($rows as $row) {
|
||||||
$comments[] = new Comment($row);
|
$comments[] = new Comment($row);
|
||||||
@ -396,60 +405,68 @@ class CommentList extends Extension {
|
|||||||
return $comments;
|
return $comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $count
|
||||||
|
* @return Comment[]
|
||||||
|
*/
|
||||||
|
private function get_recent_comments($count) {
|
||||||
|
return $this->get_generic_comments("
|
||||||
|
SELECT
|
||||||
|
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
||||||
|
comments.comment as comment, comments.id as comment_id,
|
||||||
|
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
||||||
|
comments.posted as posted
|
||||||
|
FROM comments
|
||||||
|
LEFT JOIN users ON comments.owner_id=users.id
|
||||||
|
ORDER BY comments.id DESC
|
||||||
|
LIMIT :limit
|
||||||
|
", array("limit"=>$count));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $user_id
|
* @param int $user_id
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @return array
|
* @return Comment[]
|
||||||
*/
|
*/
|
||||||
private function get_user_comments(/*int*/ $user_id, /*int*/ $count, /*int*/ $offset=0) {
|
private function get_user_comments(/*int*/ $user_id, /*int*/ $count, /*int*/ $offset=0) {
|
||||||
global $database;
|
return $this->get_generic_comments("
|
||||||
$rows = $database->get_all("
|
SELECT
|
||||||
SELECT
|
|
||||||
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
||||||
comments.comment as comment, comments.id as comment_id,
|
comments.comment as comment, comments.id as comment_id,
|
||||||
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
||||||
comments.posted as posted
|
comments.posted as posted
|
||||||
FROM comments
|
FROM comments
|
||||||
LEFT JOIN users ON comments.owner_id=users.id
|
LEFT JOIN users ON comments.owner_id=users.id
|
||||||
WHERE users.id = :user_id
|
WHERE users.id = :user_id
|
||||||
ORDER BY comments.id DESC
|
ORDER BY comments.id DESC
|
||||||
LIMIT :limit OFFSET :offset
|
LIMIT :limit OFFSET :offset
|
||||||
", array("user_id"=>$user_id, "offset"=>$offset, "limit"=>$count));
|
", array("user_id"=>$user_id, "offset"=>$offset, "limit"=>$count));
|
||||||
$comments = array();
|
|
||||||
foreach($rows as $row) {
|
|
||||||
$comments[] = new Comment($row);
|
|
||||||
}
|
|
||||||
return $comments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $image_id
|
* @param int $image_id
|
||||||
* @return array
|
* @return Comment[]
|
||||||
*/
|
*/
|
||||||
private function get_comments(/*int*/ $image_id) {
|
private function get_comments(/*int*/ $image_id) {
|
||||||
global $database;
|
return $this->get_generic_comments("
|
||||||
$i_image_id = int_escape($image_id);
|
SELECT
|
||||||
$rows = $database->get_all("
|
|
||||||
SELECT
|
|
||||||
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
||||||
comments.comment as comment, comments.id as comment_id,
|
comments.comment as comment, comments.id as comment_id,
|
||||||
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
||||||
comments.posted as posted
|
comments.posted as posted
|
||||||
FROM comments
|
FROM comments
|
||||||
LEFT JOIN users ON comments.owner_id=users.id
|
LEFT JOIN users ON comments.owner_id=users.id
|
||||||
WHERE comments.image_id=:image_id
|
WHERE comments.image_id=:image_id
|
||||||
ORDER BY comments.id ASC
|
ORDER BY comments.id ASC
|
||||||
", array("image_id"=>$i_image_id));
|
", array("image_id"=>$image_id));
|
||||||
$comments = array();
|
|
||||||
foreach($rows as $row) {
|
|
||||||
$comments[] = new Comment($row);
|
|
||||||
}
|
|
||||||
return $comments;
|
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// add / remove / edit comments {{{
|
// add / remove / edit comments {{{
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
private function is_comment_limit_hit() {
|
private function is_comment_limit_hit() {
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
|
|
||||||
@ -463,9 +480,11 @@ class CommentList extends Extension {
|
|||||||
else $window_sql = "interval '$window minute'";
|
else $window_sql = "interval '$window minute'";
|
||||||
|
|
||||||
// window doesn't work as an SQL param because it's inside quotes >_<
|
// window doesn't work as an SQL param because it's inside quotes >_<
|
||||||
$result = $database->get_all("SELECT * FROM comments WHERE owner_ip = :remote_ip ".
|
$result = $database->get_all("
|
||||||
"AND posted > now() - $window_sql",
|
SELECT *
|
||||||
Array("remote_ip"=>$_SERVER['REMOTE_ADDR']));
|
FROM comments
|
||||||
|
WHERE owner_ip = :remote_ip AND posted > now() - $window_sql
|
||||||
|
", array("remote_ip"=>$_SERVER['REMOTE_ADDR']));
|
||||||
|
|
||||||
return (count($result) >= $max);
|
return (count($result) >= $max);
|
||||||
}
|
}
|
||||||
@ -483,6 +502,8 @@ class CommentList extends Extension {
|
|||||||
* many times.
|
* many times.
|
||||||
*
|
*
|
||||||
* FIXME: assumes comments are posted via HTTP...
|
* FIXME: assumes comments are posted via HTTP...
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function get_hash() {
|
public static function get_hash() {
|
||||||
return md5($_SERVER['REMOTE_ADDR'] . date("%Y%m%d"));
|
return md5($_SERVER['REMOTE_ADDR'] . date("%Y%m%d"));
|
||||||
@ -537,28 +558,14 @@ class CommentList extends Extension {
|
|||||||
*/
|
*/
|
||||||
private function is_dupe(/*int*/ $image_id, /*string*/ $comment) {
|
private function is_dupe(/*int*/ $image_id, /*string*/ $comment) {
|
||||||
global $database;
|
global $database;
|
||||||
return ($database->get_row("SELECT * FROM comments WHERE image_id=:image_id AND comment=:comment", array("image_id"=>$image_id, "comment"=>$comment)));
|
return $database->get_row("
|
||||||
|
SELECT *
|
||||||
|
FROM comments
|
||||||
|
WHERE image_id=:image_id AND comment=:comment
|
||||||
|
", array("image_id"=>$image_id, "comment"=>$comment));
|
||||||
}
|
}
|
||||||
// do some checks
|
// do some checks
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $pagenum
|
|
||||||
* @param int $maxpage
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private function sanity_check_pagenumber(/*int*/ $pagenum, /*int*/ $maxpage){
|
|
||||||
if (!is_numeric($pagenum)){
|
|
||||||
$pagenum=1;
|
|
||||||
}
|
|
||||||
if ($pagenum>$maxpage){
|
|
||||||
$pagenum=$maxpage;
|
|
||||||
}
|
|
||||||
if ($pagenum<=0){
|
|
||||||
$pagenum=1;
|
|
||||||
}
|
|
||||||
return $pagenum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $image_id
|
* @param int $image_id
|
||||||
* @param User $user
|
* @param User $user
|
||||||
@ -588,6 +595,12 @@ class CommentList extends Extension {
|
|||||||
log_info("comment", "Comment #$cid added to Image #$image_id: $snippet", false, array("image_id"=>$image_id, "comment_id"=>$cid));
|
log_info("comment", "Comment #$cid added to Image #$image_id: $snippet", false, array("image_id"=>$image_id, "comment_id"=>$cid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $image_id
|
||||||
|
* @param User $user
|
||||||
|
* @param string $comment
|
||||||
|
* @throws CommentPostingException
|
||||||
|
*/
|
||||||
private function comment_checks(/*int*/ $image_id, User $user, /*string*/ $comment) {
|
private function comment_checks(/*int*/ $image_id, User $user, /*string*/ $comment) {
|
||||||
global $config, $page;
|
global $config, $page;
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
class CommentListTest extends ShimmiePHPUnitTestCase {
|
class CommentListTest extends ShimmiePHPUnitTestCase {
|
||||||
function setUp() {
|
public function setUp() {
|
||||||
global $config;
|
global $config;
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$config->set_int("comment_limit", 100);
|
$config->set_int("comment_limit", 100);
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function tearDown() {
|
public function tearDown() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_int("comment_limit", 10);
|
$config->set_int("comment_limit", 10);
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCommentsPage() {
|
public function testCommentsPage() {
|
||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
@ -85,8 +85,9 @@ class CommentListTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_no_text('ASDFASDF');
|
$this->assert_no_text('ASDFASDF');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public function testSingleDel() {
|
||||||
function testSingleDel() {
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
|
|
||||||
@ -106,5 +107,4 @@ class CommentListTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->delete_image($image_id);
|
$this->delete_image($image_id);
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
@ -55,360 +55,46 @@ class DanbooruApi extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Danbooru API
|
// Danbooru API
|
||||||
private function api_danbooru(PageRequestEvent $event)
|
private function api_danbooru(PageRequestEvent $event) {
|
||||||
{
|
|
||||||
global $page;
|
global $page;
|
||||||
global $config;
|
|
||||||
global $database;
|
|
||||||
global $user;
|
|
||||||
$page->set_mode("data");
|
$page->set_mode("data");
|
||||||
$page->set_type("application/xml");
|
|
||||||
//debug
|
|
||||||
//$page->set_type("text/plain");
|
|
||||||
|
|
||||||
$results = array();
|
if(($event->get_arg(1) == 'add_post') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'create.xml'))) {
|
||||||
|
|
||||||
$danboorup_kludge=1; // danboorup for firefox makes broken links out of location: /path
|
|
||||||
|
|
||||||
/*
|
|
||||||
add_post()
|
|
||||||
Adds a post to the database.
|
|
||||||
Parameters
|
|
||||||
* login: login
|
|
||||||
* password: password
|
|
||||||
* file: file as a multipart form
|
|
||||||
* source: source url
|
|
||||||
* title: title **IGNORED**
|
|
||||||
* tags: list of tags as a string, delimited by whitespace
|
|
||||||
* md5: MD5 hash of upload in hexadecimal format
|
|
||||||
* rating: rating of the post. can be explicit, questionable, or safe. **IGNORED**
|
|
||||||
Notes
|
|
||||||
* The only necessary parameter is tags and either file or source.
|
|
||||||
* If you want to sign your post, you need a way to authenticate your account, either by supplying login and password, or by supplying a cookie.
|
|
||||||
* If an account is not supplied or if it doesnt authenticate, he post will be added anonymously.
|
|
||||||
* If the md5 parameter is supplied and does not match the hash of whats on the server, the post is rejected.
|
|
||||||
Response
|
|
||||||
The response depends on the method used:
|
|
||||||
Post
|
|
||||||
* X-Danbooru-Location set to the URL for newly uploaded post.
|
|
||||||
Get
|
|
||||||
* Redirected to the newly uploaded post.
|
|
||||||
*/
|
|
||||||
if(($event->get_arg(1) == 'add_post') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'create.xml')))
|
|
||||||
{
|
|
||||||
// No XML data is returned from this function
|
// No XML data is returned from this function
|
||||||
$page->set_type("text/plain");
|
$page->set_type("text/plain");
|
||||||
// Check first if a login was supplied, if it wasn't check if the user is logged in via cookie
|
$this->api_add_post();
|
||||||
// If all that fails, it's an anonymous upload
|
|
||||||
$this->authenticate_user();
|
|
||||||
// Now we check if a file was uploaded or a url was provided to transload
|
|
||||||
// Much of this code is borrowed from /ext/upload
|
|
||||||
|
|
||||||
if($user->can("create_image"))
|
|
||||||
{
|
|
||||||
if(isset($_FILES['file']))
|
|
||||||
{ // A file was POST'd in
|
|
||||||
$file = $_FILES['file']['tmp_name'];
|
|
||||||
$filename = $_FILES['file']['name'];
|
|
||||||
// If both a file is posted and a source provided, I'm assuming source is the source of the file
|
|
||||||
if(isset($_REQUEST['source']) && !empty($_REQUEST['source']))
|
|
||||||
{
|
|
||||||
$source = $_REQUEST['source'];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
$source = null;
|
|
||||||
}
|
|
||||||
} elseif(isset($_FILES['post']))
|
|
||||||
{
|
|
||||||
$file = $_FILES['post']['tmp_name']['file'];
|
|
||||||
$filename = $_FILES['post']['name']['file'];
|
|
||||||
if(isset($_REQUEST['post']['source']) && !empty($_REQUEST['post']['source']))
|
|
||||||
{
|
|
||||||
$source = $_REQUEST['post']['source'];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
$source = null;
|
|
||||||
}
|
|
||||||
} elseif(isset($_REQUEST['source']) || isset($_REQUEST['post']['source']))
|
|
||||||
{ // A url was provided
|
|
||||||
$url = isset($_REQUEST['source']) ? $_REQUEST['source'] : $_REQUEST['post']['source'];
|
|
||||||
$source = $url;
|
|
||||||
$tmp_filename = tempnam("/tmp", "shimmie_transload");
|
|
||||||
|
|
||||||
// Are we using fopen wrappers or curl?
|
|
||||||
if($config->get_string("transload_engine") == "fopen")
|
|
||||||
{
|
|
||||||
$fp = fopen($url, "r");
|
|
||||||
if(!$fp) {
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: fopen read error");
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = "";
|
|
||||||
$length = 0;
|
|
||||||
while(!feof($fp) && $length <= $config->get_int('upload_size'))
|
|
||||||
{
|
|
||||||
$data .= fread($fp, 8192);
|
|
||||||
$length = strlen($data);
|
|
||||||
}
|
|
||||||
fclose($fp);
|
|
||||||
|
|
||||||
$fp = fopen($tmp_filename, "w");
|
|
||||||
fwrite($fp, $data);
|
|
||||||
fclose($fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($config->get_string("transload_engine") == "curl")
|
|
||||||
{
|
|
||||||
$ch = curl_init($url);
|
|
||||||
$fp = fopen($tmp_filename, "w");
|
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
|
||||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
|
||||||
|
|
||||||
curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
fclose($fp);
|
|
||||||
}
|
|
||||||
$file = $tmp_filename;
|
|
||||||
$filename = basename($url);
|
|
||||||
} else
|
|
||||||
{ // Nothing was specified at all
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: no input files");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get tags out of url
|
|
||||||
$posttags = Tag::explode(isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']);
|
|
||||||
$hash = md5_file($file);
|
|
||||||
// Was an md5 supplied? Does it match the file hash?
|
|
||||||
if(isset($_REQUEST['md5']))
|
|
||||||
{
|
|
||||||
if(strtolower($_REQUEST['md5']) != $hash)
|
|
||||||
{
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: md5 mismatch");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Upload size checking is now performed in the upload extension
|
|
||||||
// It is also currently broken due to some confusion over file variable ($tmp_filename?)
|
|
||||||
|
|
||||||
// Does it exist already?
|
|
||||||
$existing = Image::by_hash($hash);
|
|
||||||
if(!is_null($existing)) {
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: duplicate");
|
|
||||||
$existinglink = make_link("post/view/" . $existing->id);
|
|
||||||
if($danboorup_kludge) $existinglink=make_http($existinglink);
|
|
||||||
$page->add_http_header("X-Danbooru-Location: $existinglink");
|
|
||||||
return; // wut!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire off an event which should process the new file and add it to the db
|
|
||||||
$fileinfo = pathinfo($filename);
|
|
||||||
$metadata = array();
|
|
||||||
$metadata['filename'] = $fileinfo['basename'];
|
|
||||||
$metadata['extension'] = $fileinfo['extension'];
|
|
||||||
$metadata['tags'] = $posttags;
|
|
||||||
$metadata['source'] = $source;
|
|
||||||
//log_debug("danbooru_api","========== NEW($filename) =========");
|
|
||||||
//log_debug("danbooru_api", "upload($filename): fileinfo(".var_export($fileinfo,TRUE)."), metadata(".var_export($metadata,TRUE).")...");
|
|
||||||
|
|
||||||
try {
|
|
||||||
$nevent = new DataUploadEvent($file, $metadata);
|
|
||||||
//log_debug("danbooru_api", "send_event(".var_export($nevent,TRUE).")");
|
|
||||||
send_event($nevent);
|
|
||||||
// If it went ok, grab the id for the newly uploaded image and pass it in the header
|
|
||||||
$newimg = Image::by_hash($hash); // FIXME: Unsupported file doesn't throw an error?
|
|
||||||
$newid = make_link("post/view/" . $newimg->id);
|
|
||||||
if($danboorup_kludge) $newid=make_http($newid);
|
|
||||||
|
|
||||||
// Did we POST or GET this call?
|
|
||||||
if($_SERVER['REQUEST_METHOD'] == 'POST')
|
|
||||||
{
|
|
||||||
$page->add_http_header("X-Danbooru-Location: $newid");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$page->add_http_header("Location: $newid");
|
|
||||||
}
|
|
||||||
catch(UploadException $ex) {
|
|
||||||
// Did something screw up?
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: exception - " . $ex->getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
$page->set_code(409);
|
|
||||||
$page->add_http_header("X-Danbooru-Errors: authentication error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
elseif(($event->get_arg(1) == 'find_posts') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'index.xml'))) {
|
||||||
find_posts()
|
$page->set_type("application/xml");
|
||||||
Find all posts that match the search criteria. Posts will be ordered by id descending.
|
$page->set_data($this->api_find_posts());
|
||||||
Parameters
|
|
||||||
* md5: md5 hash to search for (comma delimited)
|
|
||||||
* id: id to search for (comma delimited)
|
|
||||||
* tags: what tags to search for
|
|
||||||
* limit: limit
|
|
||||||
* page: page number
|
|
||||||
* after_id: limit results to posts added after this id
|
|
||||||
*/
|
|
||||||
if(($event->get_arg(1) == 'find_posts') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'index.xml')))
|
|
||||||
{
|
|
||||||
$this->authenticate_user();
|
|
||||||
$start = 0;
|
|
||||||
|
|
||||||
if(isset($_GET['md5']))
|
|
||||||
{
|
|
||||||
$md5list = explode(",",$_GET['md5']);
|
|
||||||
foreach($md5list as $md5)
|
|
||||||
{
|
|
||||||
$results[] = Image::by_hash($md5);
|
|
||||||
}
|
|
||||||
$count = count($results);
|
|
||||||
} elseif(isset($_GET['id']))
|
|
||||||
{
|
|
||||||
$idlist = explode(",",$_GET['id']);
|
|
||||||
foreach($idlist as $id)
|
|
||||||
{
|
|
||||||
$results[] = Image::by_id($id);
|
|
||||||
}
|
|
||||||
$count = count($results);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
$limit = isset($_GET['limit']) ? int_escape($_GET['limit']) : 100;
|
|
||||||
|
|
||||||
// Calculate start offset.
|
|
||||||
if (isset($_GET['page'])) // Danbooru API uses 'page' >= 1
|
|
||||||
$start = (int_escape($_GET['page'])-1) * $limit;
|
|
||||||
else if (isset($_GET['pid'])) // Gelbooru API uses 'pid' >= 0
|
|
||||||
$start = int_escape($_GET['pid']) * $limit;
|
|
||||||
else
|
|
||||||
$start = 0;
|
|
||||||
|
|
||||||
$tags = isset($_GET['tags']) ? Tag::explode($_GET['tags']) : array();
|
|
||||||
$count = Image::count_images($tags);
|
|
||||||
$results = Image::find_images(max($start, 0), min($limit, 100), $tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we have the array $results filled with Image objects
|
|
||||||
// Let's display them
|
|
||||||
$xml = "<posts count=\"{$count}\" offset=\"{$start}\">\n";
|
|
||||||
foreach($results as $img)
|
|
||||||
{
|
|
||||||
// Sanity check to see if $img is really an image object
|
|
||||||
// If it isn't (e.g. someone requested an invalid md5 or id), break out of the this
|
|
||||||
if(!is_object($img))
|
|
||||||
continue;
|
|
||||||
$taglist = $img->get_tag_list();
|
|
||||||
$owner = $img->get_owner();
|
|
||||||
$previewsize = get_thumbnail_size($img->width, $img->height);
|
|
||||||
$xml .= xml_tag("post", array(
|
|
||||||
"id" => $img->id,
|
|
||||||
"md5" => $img->hash,
|
|
||||||
"file_name" => $img->filename,
|
|
||||||
"file_url" => $img->get_image_link(),
|
|
||||||
"height" => $img->height,
|
|
||||||
"width" => $img->width,
|
|
||||||
"preview_url" => $img->get_thumb_link(),
|
|
||||||
"preview_height" => $previewsize[1],
|
|
||||||
"preview_width" => $previewsize[0],
|
|
||||||
"rating" => "u",
|
|
||||||
"date" => $img->posted,
|
|
||||||
"is_warehoused" => false,
|
|
||||||
"tags" => $taglist,
|
|
||||||
"source" => $img->source,
|
|
||||||
"score" => 0,
|
|
||||||
"author" => $owner->name
|
|
||||||
));
|
|
||||||
}
|
|
||||||
$xml .= "</posts>";
|
|
||||||
$page->set_data($xml);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
elseif($event->get_arg(1) == 'find_tags') {
|
||||||
find_tags() Find all tags that match the search criteria.
|
$page->set_type("application/xml");
|
||||||
Parameters
|
$page->set_data($this->api_find_tags());
|
||||||
* id: A comma delimited list of tag id numbers.
|
|
||||||
* name: A comma delimited list of tag names.
|
|
||||||
* tags: any typical tag query. See Tag#parse_query for details.
|
|
||||||
* after_id: limit results to tags with an id number after after_id. Useful if you only want to refresh
|
|
||||||
*/
|
|
||||||
if($event->get_arg(1) == 'find_tags') {
|
|
||||||
if(isset($_GET['id'])) {
|
|
||||||
$idlist = explode(",",$_GET['id']);
|
|
||||||
foreach($idlist as $id) {
|
|
||||||
$sqlresult = $database->get_all(
|
|
||||||
"SELECT id,tag,count FROM tags WHERE id = ?",
|
|
||||||
array($id));
|
|
||||||
foreach($sqlresult as $row) {
|
|
||||||
$results[] = array($row['count'], $row['tag'], $row['id']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif(isset($_GET['name'])) {
|
|
||||||
$namelist = explode(",",$_GET['name']);
|
|
||||||
foreach($namelist as $name) {
|
|
||||||
$sqlresult = $database->get_all(
|
|
||||||
"SELECT id,tag,count FROM tags WHERE tag = ?",
|
|
||||||
array($name));
|
|
||||||
foreach($sqlresult as $row) {
|
|
||||||
$results[] = array($row['count'], $row['tag'], $row['id']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Currently disabled to maintain identical functionality to danbooru 1.0's own "broken" find_tags
|
|
||||||
elseif(isset($_GET['tags'])) {
|
|
||||||
$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0;
|
|
||||||
$tags = Tag::explode($_GET['tags']);
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0;
|
|
||||||
$sqlresult = $database->get_all(
|
|
||||||
"SELECT id,tag,count FROM tags WHERE count > 0 AND id >= ? ORDER BY id DESC",
|
|
||||||
array($start));
|
|
||||||
foreach($sqlresult as $row) {
|
|
||||||
$results[] = array($row['count'], $row['tag'], $row['id']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tag results collected, build XML output
|
|
||||||
$xml = "<tags>\n";
|
|
||||||
foreach($results as $tag) {
|
|
||||||
$xml .= "<tag type=\"0\" count=\"$tag[0]\" name=\"" . $this->xmlspecialchars($tag[1]) . "\" id=\"$tag[2]\"/>\n";
|
|
||||||
}
|
|
||||||
$xml .= "</tags>";
|
|
||||||
$page->set_data($xml);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hackery for danbooruup 0.3.2 providing the wrong view url. This simply redirects to the proper
|
// Hackery for danbooruup 0.3.2 providing the wrong view url. This simply redirects to the proper
|
||||||
// Shimmie view page
|
// Shimmie view page
|
||||||
// Example: danbooruup says the url is http://shimmie/api/danbooru/post/show/123
|
// Example: danbooruup says the url is http://shimmie/api/danbooru/post/show/123
|
||||||
// This redirects that to http://shimmie/post/view/123
|
// This redirects that to http://shimmie/post/view/123
|
||||||
if(($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'show')) {
|
elseif(($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'show')) {
|
||||||
$fixedlocation = make_link("post/view/" . $event->get_arg(3));
|
$fixedlocation = make_link("post/view/" . $event->get_arg(3));
|
||||||
$page->set_mode("redirect");
|
$page->set_mode("redirect");
|
||||||
$page->set_redirect($fixedlocation);
|
$page->set_redirect($fixedlocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turns out I use this a couple times so let's make it a utility function
|
/**
|
||||||
// Authenticates a user based on the contents of the login and password parameters
|
* Turns out I use this a couple times so let's make it a utility function
|
||||||
// or makes them anonymous. Does not set any cookies or anything permanent.
|
* Authenticates a user based on the contents of the login and password parameters
|
||||||
private function authenticate_user()
|
* or makes them anonymous. Does not set any cookies or anything permanent.
|
||||||
{
|
*/
|
||||||
global $config;
|
private function authenticate_user() {
|
||||||
global $user;
|
global $config, $user;
|
||||||
|
|
||||||
if(isset($_REQUEST['login']) && isset($_REQUEST['password']))
|
if(isset($_REQUEST['login']) && isset($_REQUEST['password'])) {
|
||||||
{
|
|
||||||
// Get this user from the db, if it fails the user becomes anonymous
|
// Get this user from the db, if it fails the user becomes anonymous
|
||||||
// Code borrowed from /ext/user
|
// Code borrowed from /ext/user
|
||||||
$name = $_REQUEST['login'];
|
$name = $_REQUEST['login'];
|
||||||
@ -416,18 +102,294 @@ class DanbooruApi extends Extension {
|
|||||||
$duser = User::by_name_and_pass($name, $pass);
|
$duser = User::by_name_and_pass($name, $pass);
|
||||||
if(!is_null($duser)) {
|
if(!is_null($duser)) {
|
||||||
$user = $duser;
|
$user = $duser;
|
||||||
} else
|
}
|
||||||
{
|
else {
|
||||||
$user = User::by_id($config->get_int("anon_id", 0));
|
$user = User::by_id($config->get_int("anon_id", 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// From htmlspecialchars man page on php.net comments
|
/**
|
||||||
// If tags contain quotes they need to be htmlified
|
* find_tags()
|
||||||
private function xmlspecialchars($text)
|
* Find all tags that match the search criteria.
|
||||||
{
|
*
|
||||||
return str_replace(''', ''', htmlspecialchars($text, ENT_QUOTES));
|
* Parameters
|
||||||
|
* - id: A comma delimited list of tag id numbers.
|
||||||
|
* - name: A comma delimited list of tag names.
|
||||||
|
* - tags: any typical tag query. See Tag#parse_query for details.
|
||||||
|
* - after_id: limit results to tags with an id number after after_id. Useful if you only want to refresh
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function api_find_tags() {
|
||||||
|
global $database;
|
||||||
|
$results = array();
|
||||||
|
if(isset($_GET['id'])) {
|
||||||
|
$idlist = explode(",", $_GET['id']);
|
||||||
|
foreach ($idlist as $id) {
|
||||||
|
$sqlresult = $database->get_all(
|
||||||
|
"SELECT id,tag,count FROM tags WHERE id = ?",
|
||||||
|
array($id));
|
||||||
|
foreach ($sqlresult as $row) {
|
||||||
|
$results[] = array($row['count'], $row['tag'], $row['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif(isset($_GET['name'])) {
|
||||||
|
$namelist = explode(",", $_GET['name']);
|
||||||
|
foreach ($namelist as $name) {
|
||||||
|
$sqlresult = $database->get_all(
|
||||||
|
"SELECT id,tag,count FROM tags WHERE tag = ?",
|
||||||
|
array($name));
|
||||||
|
foreach ($sqlresult as $row) {
|
||||||
|
$results[] = array($row['count'], $row['tag'], $row['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Currently disabled to maintain identical functionality to danbooru 1.0's own "broken" find_tags
|
||||||
|
elseif(false && isset($_GET['tags'])) {
|
||||||
|
$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0;
|
||||||
|
$tags = Tag::explode($_GET['tags']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0;
|
||||||
|
$sqlresult = $database->get_all(
|
||||||
|
"SELECT id,tag,count FROM tags WHERE count > 0 AND id >= ? ORDER BY id DESC",
|
||||||
|
array($start));
|
||||||
|
foreach ($sqlresult as $row) {
|
||||||
|
$results[] = array($row['count'], $row['tag'], $row['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag results collected, build XML output
|
||||||
|
$xml = "<tags>\n";
|
||||||
|
foreach ($results as $tag) {
|
||||||
|
$xml .= xml_tag("tag", array(
|
||||||
|
"type" => "0",
|
||||||
|
"counts" => $tag[0],
|
||||||
|
"name" => $tag[1],
|
||||||
|
"id" => $tag[2],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$xml .= "</tags>";
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_posts()
|
||||||
|
* Find all posts that match the search criteria. Posts will be ordered by id descending.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - md5: md5 hash to search for (comma delimited)
|
||||||
|
* - id: id to search for (comma delimited)
|
||||||
|
* - tags: what tags to search for
|
||||||
|
* - limit: limit
|
||||||
|
* - page: page number
|
||||||
|
* - after_id: limit results to posts added after this id
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws SCoreException
|
||||||
|
*/
|
||||||
|
private function api_find_posts() {
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
$this->authenticate_user();
|
||||||
|
$start = 0;
|
||||||
|
|
||||||
|
if(isset($_GET['md5'])) {
|
||||||
|
$md5list = explode(",", $_GET['md5']);
|
||||||
|
foreach ($md5list as $md5) {
|
||||||
|
$results[] = Image::by_hash($md5);
|
||||||
|
}
|
||||||
|
$count = count($results);
|
||||||
|
}
|
||||||
|
elseif(isset($_GET['id'])) {
|
||||||
|
$idlist = explode(",", $_GET['id']);
|
||||||
|
foreach ($idlist as $id) {
|
||||||
|
$results[] = Image::by_id($id);
|
||||||
|
}
|
||||||
|
$count = count($results);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$limit = isset($_GET['limit']) ? int_escape($_GET['limit']) : 100;
|
||||||
|
|
||||||
|
// Calculate start offset.
|
||||||
|
if (isset($_GET['page'])) // Danbooru API uses 'page' >= 1
|
||||||
|
$start = (int_escape($_GET['page']) - 1) * $limit;
|
||||||
|
else if (isset($_GET['pid'])) // Gelbooru API uses 'pid' >= 0
|
||||||
|
$start = int_escape($_GET['pid']) * $limit;
|
||||||
|
else
|
||||||
|
$start = 0;
|
||||||
|
|
||||||
|
$tags = isset($_GET['tags']) ? Tag::explode($_GET['tags']) : array();
|
||||||
|
$count = Image::count_images($tags);
|
||||||
|
$results = Image::find_images(max($start, 0), min($limit, 100), $tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we have the array $results filled with Image objects
|
||||||
|
// Let's display them
|
||||||
|
$xml = "<posts count=\"{$count}\" offset=\"{$start}\">\n";
|
||||||
|
foreach ($results as $img) {
|
||||||
|
// Sanity check to see if $img is really an image object
|
||||||
|
// If it isn't (e.g. someone requested an invalid md5 or id), break out of the this
|
||||||
|
if (!is_object($img))
|
||||||
|
continue;
|
||||||
|
$taglist = $img->get_tag_list();
|
||||||
|
$owner = $img->get_owner();
|
||||||
|
$previewsize = get_thumbnail_size($img->width, $img->height);
|
||||||
|
$xml .= xml_tag("post", array(
|
||||||
|
"id" => $img->id,
|
||||||
|
"md5" => $img->hash,
|
||||||
|
"file_name" => $img->filename,
|
||||||
|
"file_url" => $img->get_image_link(),
|
||||||
|
"height" => $img->height,
|
||||||
|
"width" => $img->width,
|
||||||
|
"preview_url" => $img->get_thumb_link(),
|
||||||
|
"preview_height" => $previewsize[1],
|
||||||
|
"preview_width" => $previewsize[0],
|
||||||
|
"rating" => "u",
|
||||||
|
"date" => $img->posted,
|
||||||
|
"is_warehoused" => false,
|
||||||
|
"tags" => $taglist,
|
||||||
|
"source" => $img->source,
|
||||||
|
"score" => 0,
|
||||||
|
"author" => $owner->name
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$xml .= "</posts>";
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add_post()
|
||||||
|
* Adds a post to the database.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - login: login
|
||||||
|
* - password: password
|
||||||
|
* - file: file as a multipart form
|
||||||
|
* - source: source url
|
||||||
|
* - title: title **IGNORED**
|
||||||
|
* - tags: list of tags as a string, delimited by whitespace
|
||||||
|
* - md5: MD5 hash of upload in hexadecimal format
|
||||||
|
* - rating: rating of the post. can be explicit, questionable, or safe. **IGNORED**
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
* - The only necessary parameter is tags and either file or source.
|
||||||
|
* - If you want to sign your post, you need a way to authenticate your account, either by supplying login and password, or by supplying a cookie.
|
||||||
|
* - If an account is not supplied or if it doesnt authenticate, he post will be added anonymously.
|
||||||
|
* - If the md5 parameter is supplied and does not match the hash of whats on the server, the post is rejected.
|
||||||
|
*
|
||||||
|
* Response
|
||||||
|
* The response depends on the method used:
|
||||||
|
* Post:
|
||||||
|
* - X-Danbooru-Location set to the URL for newly uploaded post.
|
||||||
|
* Get:
|
||||||
|
* - Redirected to the newly uploaded post.
|
||||||
|
*/
|
||||||
|
private function api_add_post() {
|
||||||
|
global $user, $config, $page;
|
||||||
|
$danboorup_kludge = 1; // danboorup for firefox makes broken links out of location: /path
|
||||||
|
|
||||||
|
// Check first if a login was supplied, if it wasn't check if the user is logged in via cookie
|
||||||
|
// If all that fails, it's an anonymous upload
|
||||||
|
$this->authenticate_user();
|
||||||
|
// Now we check if a file was uploaded or a url was provided to transload
|
||||||
|
// Much of this code is borrowed from /ext/upload
|
||||||
|
|
||||||
|
if (!$user->can("create_image")) {
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: authentication error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_FILES['file'])) { // A file was POST'd in
|
||||||
|
$file = $_FILES['file']['tmp_name'];
|
||||||
|
$filename = $_FILES['file']['name'];
|
||||||
|
// If both a file is posted and a source provided, I'm assuming source is the source of the file
|
||||||
|
if (isset($_REQUEST['source']) && !empty($_REQUEST['source'])) {
|
||||||
|
$source = $_REQUEST['source'];
|
||||||
|
} else {
|
||||||
|
$source = null;
|
||||||
|
}
|
||||||
|
} elseif (isset($_FILES['post'])) {
|
||||||
|
$file = $_FILES['post']['tmp_name']['file'];
|
||||||
|
$filename = $_FILES['post']['name']['file'];
|
||||||
|
if (isset($_REQUEST['post']['source']) && !empty($_REQUEST['post']['source'])) {
|
||||||
|
$source = $_REQUEST['post']['source'];
|
||||||
|
} else {
|
||||||
|
$source = null;
|
||||||
|
}
|
||||||
|
} elseif (isset($_REQUEST['source']) || isset($_REQUEST['post']['source'])) { // A url was provided
|
||||||
|
$source = isset($_REQUEST['source']) ? $_REQUEST['source'] : $_REQUEST['post']['source'];
|
||||||
|
$file = tempnam("/tmp", "shimmie_transload");
|
||||||
|
$ok = transload($source, $file);
|
||||||
|
if (!$ok) {
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: fopen read error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$filename = basename($source);
|
||||||
|
} else { // Nothing was specified at all
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: no input files");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tags out of url
|
||||||
|
$posttags = Tag::explode(isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']);
|
||||||
|
|
||||||
|
// Was an md5 supplied? Does it match the file hash?
|
||||||
|
$hash = md5_file($file);
|
||||||
|
if (isset($_REQUEST['md5']) && strtolower($_REQUEST['md5']) != $hash) {
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: md5 mismatch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Upload size checking is now performed in the upload extension
|
||||||
|
// It is also currently broken due to some confusion over file variable ($tmp_filename?)
|
||||||
|
|
||||||
|
// Does it exist already?
|
||||||
|
$existing = Image::by_hash($hash);
|
||||||
|
if (!is_null($existing)) {
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: duplicate");
|
||||||
|
$existinglink = make_link("post/view/" . $existing->id);
|
||||||
|
if ($danboorup_kludge) $existinglink = make_http($existinglink);
|
||||||
|
$page->add_http_header("X-Danbooru-Location: $existinglink");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire off an event which should process the new file and add it to the db
|
||||||
|
$fileinfo = pathinfo($filename);
|
||||||
|
$metadata = array();
|
||||||
|
$metadata['filename'] = $fileinfo['basename'];
|
||||||
|
$metadata['extension'] = $fileinfo['extension'];
|
||||||
|
$metadata['tags'] = $posttags;
|
||||||
|
$metadata['source'] = $source;
|
||||||
|
//log_debug("danbooru_api","========== NEW($filename) =========");
|
||||||
|
//log_debug("danbooru_api", "upload($filename): fileinfo(".var_export($fileinfo,TRUE)."), metadata(".var_export($metadata,TRUE).")...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
$nevent = new DataUploadEvent($file, $metadata);
|
||||||
|
//log_debug("danbooru_api", "send_event(".var_export($nevent,TRUE).")");
|
||||||
|
send_event($nevent);
|
||||||
|
// If it went ok, grab the id for the newly uploaded image and pass it in the header
|
||||||
|
$newimg = Image::by_hash($hash); // FIXME: Unsupported file doesn't throw an error?
|
||||||
|
$newid = make_link("post/view/" . $newimg->id);
|
||||||
|
if ($danboorup_kludge) $newid = make_http($newid);
|
||||||
|
|
||||||
|
// Did we POST or GET this call?
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$page->add_http_header("X-Danbooru-Location: $newid");
|
||||||
|
} else {
|
||||||
|
$page->add_http_header("Location: $newid");
|
||||||
|
}
|
||||||
|
} catch (UploadException $ex) {
|
||||||
|
// Did something screw up?
|
||||||
|
$page->set_code(409);
|
||||||
|
$page->add_http_header("X-Danbooru-Errors: exception - " . $ex->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class DanbooruApiTest extends ShimmiePHPUnitTestCase {
|
class DanbooruApiTest extends ShimmiePHPUnitTestCase {
|
||||||
function testSearch() {
|
public function testSearch() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$image_id = $this->post_image("tests/bedroom_workshop.jpg", "data");
|
$image_id = $this->post_image("tests/bedroom_workshop.jpg", "data");
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
class DowntimeTest extends ShimmiePHPUnitTestCase {
|
class DowntimeTest extends ShimmiePHPUnitTestCase {
|
||||||
function tearDown() {
|
public function tearDown() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_bool("downtime", false);
|
$config->set_bool("downtime", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDowntime() {
|
public function testDowntime() {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
$config->set_string("downtime_message", "brb, unit testing");
|
$config->set_string("downtime_message", "brb, unit testing");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class EmoticonTest extends ShimmiePHPUnitTestCase {
|
class EmoticonTest extends ShimmiePHPUnitTestCase {
|
||||||
function testEmoticons() {
|
public function testEmoticons() {
|
||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ETTest extends ShimmiePHPUnitTestCase {
|
class ETTest extends ShimmiePHPUnitTestCase {
|
||||||
function testET() {
|
public function testET() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("system_info");
|
$this->get_page("system_info");
|
||||||
$this->assert_title("System Info");
|
$this->assert_title("System Info");
|
||||||
|
@ -23,7 +23,7 @@ class ExtensionInfo {
|
|||||||
var $description, $documentation, $version, $visibility;
|
var $description, $documentation, $version, $visibility;
|
||||||
var $enabled;
|
var $enabled;
|
||||||
|
|
||||||
function __construct($main) {
|
public function __construct($main) {
|
||||||
$matches = array();
|
$matches = array();
|
||||||
$lines = file($main);
|
$lines = file($main);
|
||||||
$number_of_lines = count($lines);
|
$number_of_lines = count($lines);
|
||||||
@ -37,26 +37,26 @@ class ExtensionInfo {
|
|||||||
if(preg_match("/Name: (.*)/", $line, $matches)) {
|
if(preg_match("/Name: (.*)/", $line, $matches)) {
|
||||||
$this->name = $matches[1];
|
$this->name = $matches[1];
|
||||||
}
|
}
|
||||||
if(preg_match("/Visibility: (.*)/", $line, $matches)) {
|
else if(preg_match("/Visibility: (.*)/", $line, $matches)) {
|
||||||
$this->visibility = $matches[1];
|
$this->visibility = $matches[1];
|
||||||
}
|
}
|
||||||
if(preg_match("/Link: (.*)/", $line, $matches)) {
|
else if(preg_match("/Link: (.*)/", $line, $matches)) {
|
||||||
$this->link = $matches[1];
|
$this->link = $matches[1];
|
||||||
if($this->link[0] == "/") {
|
if($this->link[0] == "/") {
|
||||||
$this->link = make_link(substr($this->link, 1));
|
$this->link = make_link(substr($this->link, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(preg_match("/Version: (.*)/", $line, $matches)) {
|
else if(preg_match("/Version: (.*)/", $line, $matches)) {
|
||||||
$this->version = $matches[1];
|
$this->version = $matches[1];
|
||||||
}
|
}
|
||||||
if(preg_match("/Author: (.*) [<\(](.*@.*)[>\)]/", $line, $matches)) {
|
else if(preg_match("/Author: (.*) [<\(](.*@.*)[>\)]/", $line, $matches)) {
|
||||||
$this->author = $matches[1];
|
$this->author = $matches[1];
|
||||||
$this->email = $matches[2];
|
$this->email = $matches[2];
|
||||||
}
|
}
|
||||||
else if(preg_match("/Author: (.*)/", $line, $matches)) {
|
else if(preg_match("/Author: (.*)/", $line, $matches)) {
|
||||||
$this->author = $matches[1];
|
$this->author = $matches[1];
|
||||||
}
|
}
|
||||||
if(preg_match("/(.*)Description: ?(.*)/", $line, $matches)) {
|
else if(preg_match("/(.*)Description: ?(.*)/", $line, $matches)) {
|
||||||
$this->description = $matches[2];
|
$this->description = $matches[2];
|
||||||
$start = $matches[1]." ";
|
$start = $matches[1]." ";
|
||||||
$start_len = strlen($start);
|
$start_len = strlen($start);
|
||||||
@ -65,7 +65,7 @@ class ExtensionInfo {
|
|||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(preg_match("/(.*)Documentation: ?(.*)/", $line, $matches)) {
|
else if(preg_match("/(.*)Documentation: ?(.*)/", $line, $matches)) {
|
||||||
$this->documentation = $matches[2];
|
$this->documentation = $matches[2];
|
||||||
$start = $matches[1]." ";
|
$start = $matches[1]." ";
|
||||||
$start_len = strlen($start);
|
$start_len = strlen($start);
|
||||||
@ -75,7 +75,7 @@ class ExtensionInfo {
|
|||||||
}
|
}
|
||||||
$this->documentation = str_replace('$site', make_http(get_base_href()), $this->documentation);
|
$this->documentation = str_replace('$site', make_http(get_base_href()), $this->documentation);
|
||||||
}
|
}
|
||||||
if(preg_match("/\*\//", $line, $matches)) {
|
else if(preg_match("/\*\//", $line, $matches)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ class ExtManager extends Extension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $all
|
* @param bool $all
|
||||||
* @return array
|
* @return ExtensionInfo[]
|
||||||
*/
|
*/
|
||||||
private function get_extensions(/*bool*/ $all) {
|
private function get_extensions(/*bool*/ $all) {
|
||||||
$extensions = array();
|
$extensions = array();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ExtManagerTest extends ShimmiePHPUnitTestCase {
|
class ExtManagerTest extends ShimmiePHPUnitTestCase {
|
||||||
function testAuth() {
|
public function testAuth() {
|
||||||
$this->get_page('ext_manager');
|
$this->get_page('ext_manager');
|
||||||
$this->assert_title("Extensions");
|
$this->assert_title("Extensions");
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ class Favorites extends Extension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Image $image
|
* @param Image $image
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function list_persons_who_have_favorited(Image $image) {
|
private function list_persons_who_have_favorited(Image $image) {
|
||||||
global $database;
|
global $database;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class FavoritesTest extends ShimmiePHPUnitTestCase {
|
class FavoritesTest extends ShimmiePHPUnitTestCase {
|
||||||
function testFavorites() {
|
public function testFavorites() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class FeaturedTest extends ShimmiePHPUnitTestCase {
|
class FeaturedTest extends ShimmiePHPUnitTestCase {
|
||||||
function testFeatured() {
|
public function testFeatured() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class Handle404Test extends ShimmiePHPUnitTestCase {
|
class Handle404Test extends ShimmiePHPUnitTestCase {
|
||||||
function test404Handler() {
|
public function test404Handler() {
|
||||||
$this->get_page('not/a/page');
|
$this->get_page('not/a/page');
|
||||||
// most descriptive error first
|
// most descriptive error first
|
||||||
$this->assert_text("No handler could be found for the page 'not/a/page'");
|
$this->assert_text("No handler could be found for the page 'not/a/page'");
|
||||||
|
@ -44,7 +44,7 @@ class ArchiveFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $ext
|
* @param string $ext
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function supported_ext($ext) {
|
private function supported_ext($ext) {
|
||||||
|
@ -50,7 +50,7 @@ class FlashFileHandler extends DataHandlerExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $file
|
* @param string $file
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function check_contents(/*string*/ $file) {
|
protected function check_contents(/*string*/ $file) {
|
||||||
|
@ -50,7 +50,7 @@ class IcoFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $ext
|
* @param string $ext
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function supported_ext($ext) {
|
private function supported_ext($ext) {
|
||||||
@ -59,8 +59,8 @@ class IcoFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $filename
|
* @param string $filename
|
||||||
* @param $metadata
|
* @param mixed[] $metadata
|
||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
private function create_image_from_data($filename, $metadata) {
|
private function create_image_from_data($filename, $metadata) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class IcoHandlerTest extends ShimmiePHPUnitTestCase {
|
class IcoHandlerTest extends ShimmiePHPUnitTestCase {
|
||||||
function testIcoHander() {
|
public function testIcoHander() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("lib/static/favicon.ico", "shimmie favicon");
|
$image_id = $this->post_image("lib/static/favicon.ico", "shimmie favicon");
|
||||||
$this->get_page("post/view/$image_id"); // test for no crash
|
$this->get_page("post/view/$image_id"); // test for no crash
|
||||||
|
@ -26,7 +26,7 @@ class MP3FileHandler extends DataHandlerExtension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @param array $metadata
|
* @param mixed[] $metadata
|
||||||
* @return Image|null
|
* @return Image|null
|
||||||
*/
|
*/
|
||||||
protected function create_image_from_data($filename, $metadata) {
|
protected function create_image_from_data($filename, $metadata) {
|
||||||
|
@ -67,7 +67,7 @@ class PixelFileHandler extends DataHandlerExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $hash
|
* @param string $hash
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function create_thumb_force(/*string*/ $hash) {
|
protected function create_thumb_force(/*string*/ $hash) {
|
||||||
@ -91,9 +91,6 @@ class PixelFileHandler extends DataHandlerExtension {
|
|||||||
return $ok;
|
return $ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ImageAdminBlockBuildingEvent $event
|
|
||||||
*/
|
|
||||||
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) {
|
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) {
|
||||||
$event->add_part("
|
$event->add_part("
|
||||||
<form>
|
<form>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class PixelHandlerTest extends ShimmiePHPUnitTestCase {
|
class PixelHandlerTest extends ShimmiePHPUnitTestCase {
|
||||||
function testPixelHander() {
|
public function testPixelHander() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
//$this->assert_response(302);
|
//$this->assert_response(302);
|
||||||
|
@ -51,7 +51,7 @@ class SVGFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $ext
|
* @param string $ext
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function supported_ext($ext) {
|
private function supported_ext($ext) {
|
||||||
@ -60,8 +60,8 @@ class SVGFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $filename
|
* @param string $filename
|
||||||
* @param $metadata
|
* @param mixed[] $metadata
|
||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
private function create_image_from_data($filename, $metadata) {
|
private function create_image_from_data($filename, $metadata) {
|
||||||
@ -82,7 +82,7 @@ class SVGFileHandler extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $file
|
* @param string $file
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function check_contents($file) {
|
private function check_contents($file) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class SVGHandlerTest extends ShimmiePHPUnitTestCase {
|
class SVGHandlerTest extends ShimmiePHPUnitTestCase {
|
||||||
function testSVGHander() {
|
public function testSVGHander() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/test.svg", "something");
|
$image_id = $this->post_image("tests/test.svg", "something");
|
||||||
$this->get_page("post/view/$image_id"); // test for no crash
|
$this->get_page("post/view/$image_id"); // test for no crash
|
||||||
|
@ -118,7 +118,7 @@ class VideoFileHandler extends DataHandlerExtension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @param array $metadata
|
* @param mixed[] $metadata
|
||||||
* @return Image|null
|
* @return Image|null
|
||||||
*/
|
*/
|
||||||
protected function create_image_from_data($filename, $metadata) {
|
protected function create_image_from_data($filename, $metadata) {
|
||||||
@ -162,7 +162,7 @@ class VideoFileHandler extends DataHandlerExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $file
|
* @param string $file
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function check_contents($file) {
|
protected function check_contents($file) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class HomeTest extends ShimmiePHPUnitTestCase {
|
class HomeTest extends ShimmiePHPUnitTestCase {
|
||||||
function testHomePage() {
|
public function testHomePage() {
|
||||||
$this->get_page('home');
|
$this->get_page('home');
|
||||||
|
|
||||||
// FIXME: this page doesn't use blocks; need assert_data_contains
|
// FIXME: this page doesn't use blocks; need assert_data_contains
|
||||||
|
@ -32,6 +32,9 @@ class ImageAdditionEvent extends Event {
|
|||||||
class ImageAdditionException extends SCoreException {
|
class ImageAdditionException extends SCoreException {
|
||||||
var $error;
|
var $error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $error
|
||||||
|
*/
|
||||||
public function __construct($error) {
|
public function __construct($error) {
|
||||||
$this->error = $error;
|
$this->error = $error;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
class RemoveImageHashBanEvent extends Event {
|
class RemoveImageHashBanEvent extends Event {
|
||||||
var $hash;
|
var $hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hash
|
||||||
|
*/
|
||||||
public function __construct($hash) {
|
public function __construct($hash) {
|
||||||
$this->hash = $hash;
|
$this->hash = $hash;
|
||||||
}
|
}
|
||||||
@ -23,6 +26,10 @@ class AddImageHashBanEvent extends Event {
|
|||||||
var $hash;
|
var $hash;
|
||||||
var $reason;
|
var $reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hash
|
||||||
|
* @param string $reason
|
||||||
|
*/
|
||||||
public function __construct($hash, $reason) {
|
public function __construct($hash, $reason) {
|
||||||
$this->hash = $hash;
|
$this->hash = $hash;
|
||||||
$this->reason = $reason;
|
$this->reason = $reason;
|
||||||
@ -126,6 +133,11 @@ class ImageBan extends Extension {
|
|||||||
|
|
||||||
// DB funness
|
// DB funness
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $page
|
||||||
|
* @param int $size
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function get_image_hash_bans($page, $size=100) {
|
public function get_image_hash_bans($page, $size=100) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class HashBanTest extends ShimmiePHPUnitTestCase {
|
class HashBanTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBan() {
|
public function testBan() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
|
@ -253,9 +253,9 @@ class Index extends Extension {
|
|||||||
$search_terms = $event->get_search_terms();
|
$search_terms = $event->get_search_terms();
|
||||||
$page_number = $event->get_page_number();
|
$page_number = $event->get_page_number();
|
||||||
$page_size = $event->get_page_size();
|
$page_size = $event->get_page_size();
|
||||||
|
|
||||||
$count_search_terms = count($search_terms);
|
$count_search_terms = count($search_terms);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
#log_debug("index", "Search for ".implode(" ", $search_terms), false, array("terms"=>$search_terms));
|
#log_debug("index", "Search for ".implode(" ", $search_terms), false, array("terms"=>$search_terms));
|
||||||
$total_pages = Image::count_pages($search_terms);
|
$total_pages = Image::count_pages($search_terms);
|
||||||
@ -277,7 +277,7 @@ class Index extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$count_images = count($images);
|
$count_images = count($images);
|
||||||
|
|
||||||
if($count_search_terms === 0 && $count_images === 0 && $page_number === 1) {
|
if($count_search_terms === 0 && $count_images === 0 && $page_number === 1) {
|
||||||
$this->theme->display_intro($page);
|
$this->theme->display_intro($page);
|
||||||
send_event(new PostListBuildingEvent($search_terms));
|
send_event(new PostListBuildingEvent($search_terms));
|
||||||
@ -322,8 +322,17 @@ class Index extends Extension {
|
|||||||
// check for tags first as tag based searches are more common.
|
// check for tags first as tag based searches are more common.
|
||||||
if(preg_match("/^tags([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) {
|
if(preg_match("/^tags([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) {
|
||||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||||
$tags = $matches[2];
|
$count = $matches[2];
|
||||||
$event->add_querylet(new Querylet('images.id IN (SELECT DISTINCT image_id FROM image_tags GROUP BY image_id HAVING count(image_id) '.$cmp.' '.$tags.')'));
|
$event->add_querylet(
|
||||||
|
new Querylet("EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM image_tags it
|
||||||
|
LEFT JOIN tags t ON it.tag_id = t.id
|
||||||
|
WHERE images.id = it.image_id
|
||||||
|
GROUP BY image_id
|
||||||
|
HAVING COUNT(*) $cmp $count
|
||||||
|
)")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if(preg_match("/^ratio([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+):(\d+)$/i", $event->term, $matches)) {
|
else if(preg_match("/^ratio([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+):(\d+)$/i", $event->term, $matches)) {
|
||||||
$cmp = preg_replace('/^:/', '=', $matches[1]);
|
$cmp = preg_replace('/^:/', '=', $matches[1]);
|
||||||
@ -394,4 +403,3 @@ class Index extends Extension {
|
|||||||
$this->stpen++;
|
$this->stpen++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class IndexTest extends ShimmiePHPUnitTestCase {
|
class IndexTest extends ShimmiePHPUnitTestCase {
|
||||||
function testIndexPage() {
|
public function testIndexPage() {
|
||||||
$this->get_page('post/list');
|
$this->get_page('post/list');
|
||||||
$this->assert_title("Welcome to Shimmie ".VERSION);
|
$this->assert_title("Welcome to Shimmie ".VERSION);
|
||||||
$this->assert_no_text("Prev | Index | Next");
|
$this->assert_no_text("Prev | Index | Next");
|
||||||
@ -29,7 +29,7 @@ class IndexTest extends ShimmiePHPUnitTestCase {
|
|||||||
# FIXME: test search box
|
# FIXME: test search box
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSearches() {
|
public function testSearches() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "computer bedroom workshop");
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "computer bedroom workshop");
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
class IndexTheme extends Themelet {
|
class IndexTheme extends Themelet {
|
||||||
var $page_number, $total_pages, $search_terms;
|
var $page_number, $total_pages, $search_terms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $page_number
|
||||||
|
* @param int $total_pages
|
||||||
|
* @param string[] $search_terms
|
||||||
|
*/
|
||||||
public function set_page($page_number, $total_pages, $search_terms) {
|
public function set_page($page_number, $total_pages, $search_terms) {
|
||||||
$this->page_number = $page_number;
|
$this->page_number = $page_number;
|
||||||
$this->total_pages = $total_pages;
|
$this->total_pages = $total_pages;
|
||||||
@ -27,6 +32,10 @@ and of course start organising your images :-)
|
|||||||
$page->add_block(new Block("Installation Succeeded!", $text, "main", 0));
|
$page->add_block(new Block("Installation Succeeded!", $text, "main", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Page $page
|
||||||
|
* @param Image[] $images
|
||||||
|
*/
|
||||||
public function display_page(Page $page, $images) {
|
public function display_page(Page $page, $images) {
|
||||||
$this->display_page_header($page, $images);
|
$this->display_page_header($page, $images);
|
||||||
|
|
||||||
@ -41,12 +50,21 @@ and of course start organising your images :-)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function display_admin_block(/*array(string)*/ $parts) {
|
/**
|
||||||
|
* @param string[] $parts
|
||||||
|
*/
|
||||||
|
public function display_admin_block($parts) {
|
||||||
global $page;
|
global $page;
|
||||||
$page->add_block(new Block("List Controls", join("<br>", $parts), "left", 50));
|
$page->add_block(new Block("List Controls", join("<br>", $parts), "left", 50));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $page_number
|
||||||
|
* @param int $total_pages
|
||||||
|
* @param string[] $search_terms
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function build_navigation($page_number, $total_pages, $search_terms) {
|
protected function build_navigation($page_number, $total_pages, $search_terms) {
|
||||||
$prev = $page_number - 1;
|
$prev = $page_number - 1;
|
||||||
$next = $page_number + 1;
|
$next = $page_number + 1;
|
||||||
@ -72,6 +90,11 @@ and of course start organising your images :-)
|
|||||||
return $h_prev.' | '.$h_index.' | '.$h_next.'<br>'.$h_search;
|
return $h_prev.' | '.$h_index.' | '.$h_next.'<br>'.$h_search;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Image[] $images
|
||||||
|
* @param string $query
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function build_table($images, $query) {
|
protected function build_table($images, $query) {
|
||||||
$h_query = html_escape($query);
|
$h_query = html_escape($query);
|
||||||
$table = "<div class='shm-image-list' data-query='$h_query'>";
|
$table = "<div class='shm-image-list' data-query='$h_query'>";
|
||||||
@ -82,6 +105,10 @@ and of course start organising your images :-)
|
|||||||
return $table;
|
return $table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Page $page
|
||||||
|
* @param Image[] $images
|
||||||
|
*/
|
||||||
protected function display_page_header(Page $page, $images) {
|
protected function display_page_header(Page $page, $images) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
@ -102,6 +129,10 @@ and of course start organising your images :-)
|
|||||||
$page->set_heading($page_title);
|
$page->set_heading($page_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Page $page
|
||||||
|
* @param Image[] $images
|
||||||
|
*/
|
||||||
protected function display_page_images(Page $page, $images) {
|
protected function display_page_images(Page $page, $images) {
|
||||||
if (count($this->search_terms) > 0) {
|
if (count($this->search_terms) > 0) {
|
||||||
$query = url_escape(implode(' ', $this->search_terms));
|
$query = url_escape(implode(' ', $this->search_terms));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class IPBanTest extends ShimmiePHPUnitTestCase {
|
class IPBanTest extends ShimmiePHPUnitTestCase {
|
||||||
function testIPBan() {
|
public function testIPBan() {
|
||||||
$this->get_page('ip_ban/list');
|
$this->get_page('ip_ban/list');
|
||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
$this->assert_title("Permission Denied");
|
$this->assert_title("Permission Denied");
|
||||||
@ -9,7 +9,9 @@ class IPBanTest extends ShimmiePHPUnitTestCase {
|
|||||||
|
|
||||||
$this->get_page('ip_ban/list');
|
$this->get_page('ip_ban/list');
|
||||||
$this->assert_no_text("42.42.42.42");
|
$this->assert_no_text("42.42.42.42");
|
||||||
/*
|
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->set_field('ip', '42.42.42.42');
|
$this->set_field('ip', '42.42.42.42');
|
||||||
$this->set_field('reason', 'unit testing');
|
$this->set_field('reason', 'unit testing');
|
||||||
$this->set_field('end', '1 week');
|
$this->set_field('end', '1 week');
|
||||||
@ -18,7 +20,6 @@ class IPBanTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_text("42.42.42.42");
|
$this->assert_text("42.42.42.42");
|
||||||
$this->click("Remove"); // FIXME: remove which ban? :S
|
$this->click("Remove"); // FIXME: remove which ban? :S
|
||||||
$this->assert_no_text("42.42.42.42");
|
$this->assert_no_text("42.42.42.42");
|
||||||
*/
|
|
||||||
|
|
||||||
$this->get_page('ip_ban/list?all=on'); // just test it doesn't crash for now
|
$this->get_page('ip_ban/list?all=on'); // just test it doesn't crash for now
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class LinkImageTest extends ShimmiePHPUnitTestCase {
|
class LinkImageTest extends ShimmiePHPUnitTestCase {
|
||||||
function testLinkImage() {
|
public function testLinkImage() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pie");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pie");
|
||||||
|
|
||||||
@ -9,7 +9,8 @@ class LinkImageTest extends ShimmiePHPUnitTestCase {
|
|||||||
# in there, see if it takes us to the right page
|
# in there, see if it takes us to the right page
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
|
|
||||||
/*
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
$matches = array();
|
$matches = array();
|
||||||
preg_match("#value='(http://.*(/|%2F)post(/|%2F)view(/|%2F)[0-9]+)'#", $raw, $matches);
|
preg_match("#value='(http://.*(/|%2F)post(/|%2F)view(/|%2F)[0-9]+)'#", $raw, $matches);
|
||||||
@ -18,7 +19,6 @@ class LinkImageTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->get($matches[1]);
|
$this->get($matches[1]);
|
||||||
$this->assert_title("Image $image_id: pie");
|
$this->assert_title("Image $image_id: pie");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class LogDatabaseTest extends ShimmiePHPUnitTestCase {
|
class LogDatabaseTest extends ShimmiePHPUnitTestCase {
|
||||||
function testLog() {
|
public function testLog() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("log/view");
|
$this->get_page("log/view");
|
||||||
$this->get_page("log/view?module=core-image");
|
$this->get_page("log/view?module=core-image");
|
||||||
|
@ -16,62 +16,54 @@ class MassTagger extends Extension {
|
|||||||
public function onPostListBuilding(PostListBuildingEvent $event) {
|
public function onPostListBuilding(PostListBuildingEvent $event) {
|
||||||
global $config, $page, $user;
|
global $config, $page, $user;
|
||||||
|
|
||||||
if( !$user->is_admin() ) return;
|
if($user->is_admin()) {
|
||||||
|
$this->theme->display_mass_tagger( $page, $event, $config );
|
||||||
$this->theme->display_mass_tagger( $page, $event, $config );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPageRequest(PageRequestEvent $event) {
|
public function onPageRequest(PageRequestEvent $event) {
|
||||||
global $config, $page, $user;
|
global $page, $user;
|
||||||
if( !$event->page_matches("mass_tagger") ) return;
|
if($event->page_matches("mass_tagger/tag") && $user->is_admin()) {
|
||||||
if( !$user->is_admin() ) return;
|
if( !isset($_POST['ids']) or !isset($_POST['tag']) ) return;
|
||||||
|
|
||||||
if($event->get_arg(0) == "tag") $this->_apply_mass_tags( $config, $page, $user, $event );
|
$tag = $_POST['tag'];
|
||||||
}
|
|
||||||
|
$tag_array = explode(" ",$tag);
|
||||||
private function _apply_mass_tags( $config, Page $page, $user, $event ) {
|
$pos_tag_array = array();
|
||||||
if( !isset($_POST['ids']) or !isset($_POST['tag']) ) return;
|
$neg_tag_array = array();
|
||||||
|
foreach($tag_array as $new_tag) {
|
||||||
$tag = $_POST['tag'];
|
if (strpos($new_tag, '-') === 0)
|
||||||
|
$neg_tag_array[] = substr($new_tag,1);
|
||||||
$tag_array = explode(" ",$tag);
|
|
||||||
$pos_tag_array = array();
|
|
||||||
$neg_tag_array = array();
|
|
||||||
foreach($tag_array as $new_tag) {
|
|
||||||
if (strpos($new_tag, '-') === 0)
|
|
||||||
$neg_tag_array[] = substr($new_tag,1);
|
|
||||||
else
|
|
||||||
$pos_tag_array[] = $new_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ids = explode( ':', $_POST['ids'] );
|
|
||||||
$ids = array_filter ( $ids , 'is_numeric' );
|
|
||||||
|
|
||||||
$images = array_map( "Image::by_id", $ids );
|
|
||||||
|
|
||||||
if(isset($_POST['setadd']) &&
|
|
||||||
$_POST['setadd'] == 'set')
|
|
||||||
{
|
|
||||||
foreach($images as $image) {
|
|
||||||
$image->set_tags(Tag::explode($tag));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($images as $image) {
|
|
||||||
if (!empty($neg_tag_array)) {
|
|
||||||
$img_tags = array_merge($pos_tag_array, explode(" ",$image->get_tag_list()));
|
|
||||||
$img_tags = array_diff($img_tags, $neg_tag_array);
|
|
||||||
$image->set_tags(Tag::explode($img_tags));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
$image->set_tags(Tag::explode($tag . " " . $image->get_tag_list()));
|
$pos_tag_array[] = $new_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ids = explode( ':', $_POST['ids'] );
|
||||||
|
$ids = array_filter ( $ids , 'is_numeric' );
|
||||||
|
|
||||||
|
$images = array_map( "Image::by_id", $ids );
|
||||||
|
|
||||||
|
if(isset($_POST['setadd']) && $_POST['setadd'] == 'set') {
|
||||||
|
foreach($images as $image) {
|
||||||
|
$image->set_tags(Tag::explode($tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach($images as $image) {
|
||||||
|
if (!empty($neg_tag_array)) {
|
||||||
|
$img_tags = array_merge($pos_tag_array, explode(" ",$image->get_tag_list()));
|
||||||
|
$img_tags = array_diff($img_tags, $neg_tag_array);
|
||||||
|
$image->set_tags(Tag::explode($img_tags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$image->set_tags(Tag::explode($tag . " " . $image->get_tag_list()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
if(!isset($_SERVER['HTTP_REFERER'])) $_SERVER['HTTP_REFERER'] = make_link();
|
||||||
|
$page->set_redirect($_SERVER['HTTP_REFERER']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
if(!isset($_SERVER['HTTP_REFERER'])) $_SERVER['HTTP_REFERER'] = make_link();
|
|
||||||
$page->set_redirect($_SERVER['HTTP_REFERER']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,10 @@ class NotATag extends Extension {
|
|||||||
$this->scan($event->tags);
|
$this->scan($event->tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function scan(/*array*/ $tags_mixed) {
|
/**
|
||||||
|
* @param string[] $tags_mixed
|
||||||
|
*/
|
||||||
|
private function scan($tags_mixed) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$tags = array();
|
$tags = array();
|
||||||
@ -90,6 +93,11 @@ class NotATag extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $page
|
||||||
|
* @param int $size
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function get_untags($page, $size=100) {
|
public function get_untags($page, $size=100) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
|
@ -276,8 +276,7 @@ class Notes extends Extension {
|
|||||||
(?, ?, ?, ?, now(), ?, ?, ?, ?, ?)",
|
(?, ?, ?, ?, now(), ?, ?, ?, ?, ?)",
|
||||||
array(1, $imageID, $user_id, $_SERVER['REMOTE_ADDR'], $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText));
|
array(1, $imageID, $user_id, $_SERVER['REMOTE_ADDR'], $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText));
|
||||||
|
|
||||||
$result = $database->get_row("SELECT LAST_INSERT_ID() AS noteID", array());
|
$noteID = $database->get_last_insert_id('notes_id_seq');
|
||||||
$noteID = $result["noteID"];
|
|
||||||
|
|
||||||
log_info("notes", "Note added {$noteID} by {$user->name}");
|
log_info("notes", "Note added {$noteID} by {$user->name}");
|
||||||
|
|
||||||
@ -304,9 +303,9 @@ class Notes extends Extension {
|
|||||||
(?, ?, now())",
|
(?, ?, now())",
|
||||||
array($image_id, $user_id));
|
array($image_id, $user_id));
|
||||||
|
|
||||||
$result = $database->get_row("SELECT LAST_INSERT_ID() AS requestID", array());
|
$resultID = $database->get_last_insert_id('note_request_id_seq');
|
||||||
|
|
||||||
log_info("notes", "Note requested {$result["requestID"]} by {$user->name}");
|
log_info("notes", "Note requested {$requestID} by {$user->name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
class NumericScoreSetEvent extends Event {
|
class NumericScoreSetEvent extends Event {
|
||||||
var $image_id, $user, $score;
|
var $image_id, $user, $score;
|
||||||
|
|
||||||
public function __construct(/*int*/ $image_id, User $user, /*int*/ $score) {
|
/**
|
||||||
|
* @param int $image_id
|
||||||
|
* @param User $user
|
||||||
|
* @param int $score
|
||||||
|
*/
|
||||||
|
public function __construct($image_id, User $user, $score) {
|
||||||
$this->image_id = $image_id;
|
$this->image_id = $image_id;
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->score = $score;
|
$this->score = $score;
|
||||||
@ -102,15 +107,15 @@ class NumericScore extends Extension {
|
|||||||
|
|
||||||
if(!empty($_GET['day'])){
|
if(!empty($_GET['day'])){
|
||||||
$D = (int) $_GET['day'];
|
$D = (int) $_GET['day'];
|
||||||
if($D >= 1 && $D <= 31) $day = $D;
|
$day = clamp($D, 1, 31);
|
||||||
}
|
}
|
||||||
if(!empty($_GET['month'])){
|
if(!empty($_GET['month'])){
|
||||||
$M = (int) $_GET['month'];
|
$M = (int) $_GET['month'];
|
||||||
if($M >= 1 && $M <= 12) $month = $M;
|
$month = clamp($M, 1 ,12);
|
||||||
}
|
}
|
||||||
if(!empty($_GET['year'])){
|
if(!empty($_GET['year'])){
|
||||||
$Y = (int) $_GET['year'];
|
$Y = (int) $_GET['year'];
|
||||||
if($Y >= 1970 && $Y < 2100) $year = $Y;
|
$year = clamp($Y, 1970, 2100);
|
||||||
}
|
}
|
||||||
|
|
||||||
$totaldate = $year."/".$month."/".$day;
|
$totaldate = $year."/".$month."/".$day;
|
||||||
@ -168,7 +173,10 @@ class NumericScore extends Extension {
|
|||||||
$this->delete_votes_by($event->id);
|
$this->delete_votes_by($event->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete_votes_by(/*int*/ $user_id) {
|
/**
|
||||||
|
* @param int $user_id
|
||||||
|
*/
|
||||||
|
public function delete_votes_by($user_id) {
|
||||||
global $database;
|
global $database;
|
||||||
|
|
||||||
$image_ids = $database->get_col("SELECT image_id FROM numeric_score_votes WHERE user_id=?", array($user_id));
|
$image_ids = $database->get_col("SELECT image_id FROM numeric_score_votes WHERE user_id=?", array($user_id));
|
||||||
@ -239,9 +247,9 @@ class NumericScore extends Extension {
|
|||||||
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
|
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
|
||||||
array("ns_user_id"=>$iid)));
|
array("ns_user_id"=>$iid)));
|
||||||
}
|
}
|
||||||
else if(preg_match("/^order[=|:](numeric_)?(score)[_]?(desc|asc)?$/i", $event->term, $matches)){
|
else if(preg_match("/^order[=|:](?:numeric_)?(score)(?:_(desc|asc))?$/i", $event->term, $matches)){
|
||||||
$default_order_for_column = "DESC";
|
$default_order_for_column = "DESC";
|
||||||
$sort = isset($matches[3]) ? strtoupper($matches[3]) : $default_order_for_column;
|
$sort = isset($matches[2]) ? strtoupper($matches[2]) : $default_order_for_column;
|
||||||
Image::$order_sql = "images.numeric_score $sort";
|
Image::$order_sql = "images.numeric_score $sort";
|
||||||
$event->add_querylet(new Querylet("1=1")); //small hack to avoid metatag being treated as normal tag
|
$event->add_querylet(new Querylet("1=1")); //small hack to avoid metatag being treated as normal tag
|
||||||
}
|
}
|
||||||
@ -250,7 +258,7 @@ class NumericScore extends Extension {
|
|||||||
public function onTagTermParse(TagTermParseEvent $event) {
|
public function onTagTermParse(TagTermParseEvent $event) {
|
||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
if(preg_match("/^vote[=|:](up|down|remove)$/", $event->term, $matches)) {
|
if(preg_match("/^vote[=|:](up|down|remove)$/", $event->term, $matches) && $event->parse) {
|
||||||
global $user;
|
global $user;
|
||||||
$score = ($matches[1] == "up" ? 1 : ($matches[1] == "down" ? -1 : 0));
|
$score = ($matches[1] == "up" ? 1 : ($matches[1] == "down" ? -1 : 0));
|
||||||
if(!$user->is_anonymous()) {
|
if(!$user->is_anonymous()) {
|
||||||
@ -290,7 +298,7 @@ class NumericScore extends Extension {
|
|||||||
* @param int $user_id
|
* @param int $user_id
|
||||||
* @param int $score
|
* @param int $score
|
||||||
*/
|
*/
|
||||||
private function add_vote(/*int*/ $image_id, /*int*/ $user_id, /*int*/ $score) {
|
private function add_vote($image_id, $user_id, $score) {
|
||||||
global $database;
|
global $database;
|
||||||
$database->execute(
|
$database->execute(
|
||||||
"DELETE FROM numeric_score_votes WHERE image_id=:imageid AND user_id=:userid",
|
"DELETE FROM numeric_score_votes WHERE image_id=:imageid AND user_id=:userid",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class NumericScoreTest extends ShimmiePHPUnitTestCase {
|
class NumericScoreTest extends ShimmiePHPUnitTestCase {
|
||||||
function testNumericScore() {
|
public function testNumericScore() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class OekakiTest extends ShimmiePHPUnitTestCase {
|
class OekakiTest extends ShimmiePHPUnitTestCase {
|
||||||
function testLog() {
|
public function testLog() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$this->get_page("oekaki/create");
|
$this->get_page("oekaki/create");
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ class _SafeOuroborosImage
|
|||||||
// meta
|
// meta
|
||||||
$this->change = intval($img->id); //DaFug is this even supposed to do? ChangeID?
|
$this->change = intval($img->id); //DaFug is this even supposed to do? ChangeID?
|
||||||
// Should be JSON specific, just strip this when converting to XML
|
// Should be JSON specific, just strip this when converting to XML
|
||||||
$this->created_at = array('n' => 123456789, 's' => $img->posted_timestamp, 'json_class' => 'Time');
|
$this->created_at = array('n' => 123456789, 's' => strtotime($img->posted), 'json_class' => 'Time');
|
||||||
$this->id = intval($img->id);
|
$this->id = intval($img->id);
|
||||||
$this->parent_id = null;
|
$this->parent_id = null;
|
||||||
if (defined('ENABLED_EXTS')) {
|
if (defined('ENABLED_EXTS')) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class PrivMsgTest extends ShimmiePHPUnitTestCase {
|
class PrivMsgTest extends ShimmiePHPUnitTestCase {
|
||||||
function testPM() {
|
public function testPM() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("user/test");
|
$this->get_page("user/test");
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class PrivMsgTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAdminAccess() {
|
public function testAdminAccess() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("user/test");
|
$this->get_page("user/test");
|
||||||
|
|
||||||
|
@ -252,19 +252,21 @@ class Pools extends Extension {
|
|||||||
* When displaying an image, optionally list all the pools that the
|
* When displaying an image, optionally list all the pools that the
|
||||||
* image is currently a member of on a side panel, as well as a link
|
* image is currently a member of on a side panel, as well as a link
|
||||||
* to the Next image in the pool.
|
* to the Next image in the pool.
|
||||||
|
*
|
||||||
|
* @var DisplayingImageEvent $event
|
||||||
*/
|
*/
|
||||||
public function onDisplayingImage(DisplayingImageEvent $event) {
|
public function onDisplayingImage(DisplayingImageEvent $event) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
if($config->get_bool("poolsInfoOnViewImage")) {
|
if($config->get_bool("poolsInfoOnViewImage")) {
|
||||||
$imageID = $event->image->id;
|
$imageID = $event->image->id;
|
||||||
$poolsIDs = $this->get_pool_id($imageID);
|
$poolsIDs = $this->get_pool_ids($imageID);
|
||||||
|
|
||||||
$show_nav = $config->get_bool("poolsShowNavLinks", false);
|
$show_nav = $config->get_bool("poolsShowNavLinks", false);
|
||||||
|
|
||||||
$navInfo = array();
|
$navInfo = array();
|
||||||
foreach($poolsIDs as $poolID) {
|
foreach($poolsIDs as $poolID) {
|
||||||
$pool = $this->get_single_pool($poolID['pool_id']);
|
$pool = $this->get_single_pool($poolID);
|
||||||
|
|
||||||
$navInfo[$pool['id']] = array();
|
$navInfo[$pool['id']] = array();
|
||||||
$navInfo[$pool['id']]['info'] = $pool;
|
$navInfo[$pool['id']]['info'] = $pool;
|
||||||
@ -374,16 +376,10 @@ class Pools extends Extension {
|
|||||||
private function list_pools(Page $page, /*int*/ $pageNumber) {
|
private function list_pools(Page $page, /*int*/ $pageNumber) {
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
|
|
||||||
if(is_null($pageNumber) || !is_numeric($pageNumber))
|
$pageNumber = clamp($pageNumber, 1, null) - 1;
|
||||||
$pageNumber = 0;
|
|
||||||
else if ($pageNumber <= 0)
|
|
||||||
$pageNumber = 0;
|
|
||||||
else
|
|
||||||
$pageNumber--;
|
|
||||||
|
|
||||||
$poolsPerPage = $config->get_int("poolsListsPerPage");
|
$poolsPerPage = $config->get_int("poolsListsPerPage");
|
||||||
|
|
||||||
|
|
||||||
$order_by = "";
|
$order_by = "";
|
||||||
$order = $page->get_cookie("ui-order-pool");
|
$order = $page->get_cookie("ui-order-pool");
|
||||||
if($order == "created" || is_null($order)){
|
if($order == "created" || is_null($order)){
|
||||||
@ -397,15 +393,14 @@ class Pools extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$pools = $database->get_all("
|
$pools = $database->get_all("
|
||||||
SELECT p.id, p.user_id, p.public, p.title, p.description,
|
SELECT p.id, p.user_id, p.public, p.title, p.description,
|
||||||
p.posts, u.name as user_name
|
p.posts, u.name as user_name
|
||||||
FROM pools AS p
|
FROM pools AS p
|
||||||
INNER JOIN users AS u
|
INNER JOIN users AS u
|
||||||
ON p.user_id = u.id
|
ON p.user_id = u.id
|
||||||
$order_by
|
$order_by
|
||||||
LIMIT :l OFFSET :o
|
LIMIT :l OFFSET :o
|
||||||
", array("l"=>$poolsPerPage, "o"=>$pageNumber * $poolsPerPage)
|
", array("l"=>$poolsPerPage, "o"=>$pageNumber * $poolsPerPage));
|
||||||
);
|
|
||||||
|
|
||||||
$totalPages = ceil($database->get_one("SELECT COUNT(*) FROM pools") / $poolsPerPage);
|
$totalPages = ceil($database->get_one("SELECT COUNT(*) FROM pools") / $poolsPerPage);
|
||||||
|
|
||||||
@ -416,7 +411,7 @@ class Pools extends Extension {
|
|||||||
/**
|
/**
|
||||||
* HERE WE CREATE A NEW POOL
|
* HERE WE CREATE A NEW POOL
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return int
|
||||||
* @throws PoolCreationException
|
* @throws PoolCreationException
|
||||||
*/
|
*/
|
||||||
private function add_pool() {
|
private function add_pool() {
|
||||||
@ -438,12 +433,9 @@ class Pools extends Extension {
|
|||||||
VALUES (:uid, :public, :title, :desc, now())",
|
VALUES (:uid, :public, :title, :desc, now())",
|
||||||
array("uid"=>$user->id, "public"=>$public, "title"=>$_POST["title"], "desc"=>$_POST["description"]));
|
array("uid"=>$user->id, "public"=>$public, "title"=>$_POST["title"], "desc"=>$_POST["description"]));
|
||||||
|
|
||||||
$result = array();
|
$poolID = $database->get_last_insert_id('pools_id_seq');
|
||||||
$result['poolID'] = $database->get_last_insert_id('pools_id_seq');
|
log_info("pools", "Pool {$poolID} created by {$user->name}");
|
||||||
|
return $poolID;
|
||||||
log_info("pools", "Pool {$result["poolID"]} created by {$user->name}");
|
|
||||||
|
|
||||||
return $result["poolID"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -482,11 +474,11 @@ class Pools extends Extension {
|
|||||||
/**
|
/**
|
||||||
* Get all of the pool IDs that an image is in, given an image ID.
|
* Get all of the pool IDs that an image is in, given an image ID.
|
||||||
* @param int $imageID Integer ID for the image
|
* @param int $imageID Integer ID for the image
|
||||||
* @return array
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
private function get_pool_id(/*int*/ $imageID) {
|
private function get_pool_ids(/*int*/ $imageID) {
|
||||||
global $database;
|
global $database;
|
||||||
return $database->get_all("SELECT pool_id FROM pool_images WHERE image_id=:iid", array("iid"=>$imageID));
|
return $database->get_col("SELECT pool_id FROM pool_images WHERE image_id=:iid", array("iid"=>$imageID));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class PoolsTest extends ShimmiePHPUnitTestCase {
|
class PoolsTest extends ShimmiePHPUnitTestCase {
|
||||||
function testPools() {
|
public function testPools() {
|
||||||
$this->get_page('pool/list');
|
$this->get_page('pool/list');
|
||||||
$this->assert_title("Pools");
|
$this->assert_title("Pools");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class RandomTest extends ShimmiePHPUnitTestCase {
|
class RandomTest extends ShimmiePHPUnitTestCase {
|
||||||
function testRandom() {
|
public function testRandom() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
@ -15,7 +15,7 @@ class RandomTest extends ShimmiePHPUnitTestCase {
|
|||||||
# FIXME: assert($raw == file(blah.jpg))
|
# FIXME: assert($raw == file(blah.jpg))
|
||||||
}
|
}
|
||||||
|
|
||||||
function testPostListBlock() {
|
public function testPostListBlock() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("setup");
|
$this->get_page("setup");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class RatingTest extends ShimmiePHPUnitTestCase {
|
class RatingTest extends ShimmiePHPUnitTestCase {
|
||||||
function testRating() {
|
public function testRating() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class RegenThumbTest extends ShimmiePHPUnitTestCase {
|
class RegenThumbTest extends ShimmiePHPUnitTestCase {
|
||||||
function testRegenThumb() {
|
public function testRegenThumb() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
|
@ -58,7 +58,7 @@ class Relationships extends Extension {
|
|||||||
public function onTagTermParse(TagTermParseEvent $event) {
|
public function onTagTermParse(TagTermParseEvent $event) {
|
||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
if(preg_match("/^parent[=|:]([0-9]+|none)$/", $event->term, $matches)) {
|
if(preg_match("/^parent[=|:]([0-9]+|none)$/", $event->term, $matches) && $event->parse) {
|
||||||
$parentID = $matches[1];
|
$parentID = $matches[1];
|
||||||
|
|
||||||
if($parentID == "none" || $parentID == "0"){
|
if($parentID == "none" || $parentID == "0"){
|
||||||
@ -67,7 +67,7 @@ class Relationships extends Extension {
|
|||||||
$this->set_parent($event->id, $parentID);
|
$this->set_parent($event->id, $parentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(preg_match("/^child[=|:]([0-9]+)$/", $event->term, $matches)) {
|
else if(preg_match("/^child[=|:]([0-9]+)$/", $event->term, $matches) && $event->parse) {
|
||||||
$childID = $matches[1];
|
$childID = $matches[1];
|
||||||
|
|
||||||
$this->set_child($event->id, $childID);
|
$this->set_child($event->id, $childID);
|
||||||
|
@ -141,7 +141,10 @@ class ReportImage extends Extension {
|
|||||||
$this->delete_reports_by($event->id);
|
$this->delete_reports_by($event->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete_reports_by(/*int*/ $user_id) {
|
/**
|
||||||
|
* @param int $user_id
|
||||||
|
*/
|
||||||
|
public function delete_reports_by($user_id) {
|
||||||
global $database;
|
global $database;
|
||||||
$database->execute("DELETE FROM image_reports WHERE reporter_id=?", array($user_id));
|
$database->execute("DELETE FROM image_reports WHERE reporter_id=?", array($user_id));
|
||||||
$database->cache->delete("image-report-count");
|
$database->cache->delete("image-report-count");
|
||||||
@ -165,7 +168,7 @@ class ReportImage extends Extension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Image $image
|
* @param Image $image
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function get_reporters(Image $image) {
|
public function get_reporters(Image $image) {
|
||||||
global $database;
|
global $database;
|
||||||
@ -206,7 +209,7 @@ class ReportImage extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function count_reported_images() {
|
public function count_reported_images() {
|
||||||
global $database;
|
global $database;
|
||||||
@ -220,13 +223,3 @@ class ReportImage extends Extension {
|
|||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ===== Changelog =====
|
|
||||||
// * Version 0.3a / 0.3a_rc - 11/06/07 - I can no longer use the same theme.php file for both SVN and RCx. Sorry.
|
|
||||||
// * Same deal with theme.php as it is with main.php
|
|
||||||
// * Version 0.3 / 0.3_rc - 11/06/07 - Added the option to display thumbnails, moved the reported image list to it's
|
|
||||||
// own page, and checked to make sure the user is an admin before letting them delete / view reported images.
|
|
||||||
// * Version 0.2c_rc2 - 10/27/07 - Now (really!) supports Shimmie2 RC2!
|
|
||||||
// * Version 0.2b - 10/27/07 - Now supports Shimmie2 RC2!
|
|
||||||
// * Version 0.2a - 10/24/07 - Fixed some SQL issues. I will make sure to test before commiting :)
|
|
||||||
// * Version 0.2 - 10/24/07 - First public release.
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ReportImageTest extends ShimmiePHPUnitTestCase {
|
class ReportImageTest extends ShimmiePHPUnitTestCase {
|
||||||
function testReportImage() {
|
public function testReportImage() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ResLimitTest extends ShimmiePHPUnitTestCase {
|
class ResLimitTest extends ShimmiePHPUnitTestCase {
|
||||||
function testResLimitOK() {
|
public function testResLimitOK() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_int("upload_min_height", 0);
|
$config->set_int("upload_min_height", 0);
|
||||||
$config->set_int("upload_min_width", 0);
|
$config->set_int("upload_min_width", 0);
|
||||||
@ -16,7 +16,7 @@ class ResLimitTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_no_text("ratio");
|
$this->assert_no_text("ratio");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testResLimitSmall() {
|
public function testResLimitSmall() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_int("upload_min_height", 900);
|
$config->set_int("upload_min_height", 900);
|
||||||
$config->set_int("upload_min_width", 900);
|
$config->set_int("upload_min_width", 900);
|
||||||
@ -33,7 +33,7 @@ class ResLimitTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testResLimitLarge() {
|
public function testResLimitLarge() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_int("upload_min_height", 0);
|
$config->set_int("upload_min_height", 0);
|
||||||
$config->set_int("upload_min_width", 0);
|
$config->set_int("upload_min_width", 0);
|
||||||
@ -50,7 +50,7 @@ class ResLimitTest extends ShimmiePHPUnitTestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testResLimitRatio() {
|
public function testResLimitRatio() {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_int("upload_min_height", -1);
|
$config->set_int("upload_min_height", -1);
|
||||||
$config->set_int("upload_min_width", -1);
|
$config->set_int("upload_min_width", -1);
|
||||||
|
@ -75,12 +75,12 @@ class ResizeImage extends Extension {
|
|||||||
$isanigif = 0;
|
$isanigif = 0;
|
||||||
if($image_obj->ext == "gif"){
|
if($image_obj->ext == "gif"){
|
||||||
$image_filename = warehouse_path("images", $image_obj->hash);
|
$image_filename = warehouse_path("images", $image_obj->hash);
|
||||||
if(!($fh = @fopen($image_filename, 'rb'))){ //check if gif is animated (via http://www.php.net/manual/en/function.imagecreatefromgif.php#104473)
|
if(($fh = @fopen($image_filename, 'rb'))) {
|
||||||
return false;
|
//check if gif is animated (via http://www.php.net/manual/en/function.imagecreatefromgif.php#104473)
|
||||||
}
|
while(!feof($fh) && $isanigif < 2) {
|
||||||
while(!feof($fh) && $isanigif < 2) {
|
$chunk = fread($fh, 1024 * 100);
|
||||||
$chunk = fread($fh, 1024 * 100);
|
$isanigif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
|
||||||
$isanigif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($isanigif == 0){
|
if($isanigif == 0){
|
||||||
@ -180,51 +180,15 @@ class ResizeImage extends Extension {
|
|||||||
if (($image_obj->width != $info[0] ) || ($image_obj->height != $info[1])) {
|
if (($image_obj->width != $info[0] ) || ($image_obj->height != $info[1])) {
|
||||||
throw new ImageResizeException("The current image size does not match what is set in the database! - Aborting Resize.");
|
throw new ImageResizeException("The current image size does not match what is set in the database! - Aborting Resize.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
$memory_use = $this->calc_memory_use($info);
|
||||||
Check Memory usage limits
|
|
||||||
|
|
||||||
Old check: $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024);
|
|
||||||
New check: memory_use = width * height * (bits per channel) * channels * 2.5
|
|
||||||
|
|
||||||
It didn't make sense to compute the memory usage based on the NEW size for the image. ($width*$height*4)
|
|
||||||
We need to consider the size that we are GOING TO instead.
|
|
||||||
|
|
||||||
The factor of 2.5 is simply a rough guideline.
|
|
||||||
http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (isset($info['bits']) && isset($info['channels']))
|
|
||||||
{
|
|
||||||
$memory_use = ($info[0] * $info[1] * ($info['bits'] / 8) * $info['channels'] * 2.5) / 1024;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// If we don't have bits and channel info from the image then assume default values
|
|
||||||
// of 8 bits per color and 4 channels (R,G,B,A) -- ie: regular 24-bit color
|
|
||||||
//
|
|
||||||
$memory_use = ($info[0] * $info[1] * 1 * 4 * 2.5) / 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
$memory_limit = get_memory_limit();
|
$memory_limit = get_memory_limit();
|
||||||
|
|
||||||
if ($memory_use > $memory_limit) {
|
if ($memory_use > $memory_limit) {
|
||||||
throw new ImageResizeException("The image is too large to resize given the memory limits. ($memory_use > $memory_limit)");
|
throw new ImageResizeException("The image is too large to resize given the memory limits. ($memory_use > $memory_limit)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the new size of the image */
|
|
||||||
if ( $height > 0 && $width > 0 ) {
|
|
||||||
$new_height = $height;
|
|
||||||
$new_width = $width;
|
|
||||||
} else {
|
|
||||||
// Scale the new image
|
|
||||||
if ($width == 0) $factor = $height/$image_obj->height;
|
|
||||||
elseif ($height == 0) $factor = $width/$image_obj->width;
|
|
||||||
else $factor = min( $width / $image_obj->width, $height / $image_obj->height );
|
|
||||||
|
|
||||||
$new_width = round( $image_obj->width * $factor );
|
list($new_height, $new_width) = $this->calc_new_size($image_obj, $width, $height);
|
||||||
$new_height = round( $image_obj->height * $factor );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attempt to load the image */
|
/* Attempt to load the image */
|
||||||
switch ( $info[2] ) {
|
switch ( $info[2] ) {
|
||||||
case IMAGETYPE_GIF: $image = imagecreatefromgif($image_filename); break;
|
case IMAGETYPE_GIF: $image = imagecreatefromgif($image_filename); break;
|
||||||
@ -303,19 +267,65 @@ class ResizeImage extends Extension {
|
|||||||
send_event(new ThumbnailGenerationEvent($new_hash, $filetype));
|
send_event(new ThumbnailGenerationEvent($new_hash, $filetype));
|
||||||
|
|
||||||
/* Update the database */
|
/* Update the database */
|
||||||
$database->Execute(
|
$database->Execute("
|
||||||
"UPDATE images SET
|
UPDATE images SET filename = :filename, filesize = :filesize, hash = :hash, width = :width, height = :height
|
||||||
filename = :filename, filesize = :filesize, hash = :hash, width = :width, height = :height
|
WHERE id = :id
|
||||||
WHERE
|
", array(
|
||||||
id = :id
|
"filename"=>$new_filename, "filesize"=>$new_size, "hash"=>$new_hash,
|
||||||
",
|
"width"=>$new_width, "height"=>$new_height, "id"=>$image_obj->id
|
||||||
array(
|
));
|
||||||
"filename"=>$new_filename, "filesize"=>$new_size, "hash"=>$new_hash,
|
|
||||||
"width"=>$new_width, "height"=>$new_height, "id"=>$image_obj->id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
log_info("resize", "Resized Image #{$image_obj->id} - New hash: {$new_hash}");
|
log_info("resize", "Resized Image #{$image_obj->id} - New hash: {$new_hash}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Memory usage limits
|
||||||
|
*
|
||||||
|
* Old check: $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024);
|
||||||
|
* New check: memory_use = width * height * (bits per channel) * channels * 2.5
|
||||||
|
*
|
||||||
|
* It didn't make sense to compute the memory usage based on the NEW size for the image. ($width*$height*4)
|
||||||
|
* We need to consider the size that we are GOING TO instead.
|
||||||
|
*
|
||||||
|
* The factor of 2.5 is simply a rough guideline.
|
||||||
|
* http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize
|
||||||
|
*
|
||||||
|
* @param $info
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function calc_memory_use($info) {
|
||||||
|
if (isset($info['bits']) && isset($info['channels'])) {
|
||||||
|
return $memory_use = ($info[0] * $info[1] * ($info['bits'] / 8) * $info['channels'] * 2.5) / 1024;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If we don't have bits and channel info from the image then assume default values
|
||||||
|
// of 8 bits per color and 4 channels (R,G,B,A) -- ie: regular 24-bit color
|
||||||
|
return $memory_use = ($info[0] * $info[1] * 1 * 4 * 2.5) / 1024;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Image $image_obj
|
||||||
|
* @param $width
|
||||||
|
* @param $height
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
private function calc_new_size(Image $image_obj, $width, $height) {
|
||||||
|
/* Calculate the new size of the image */
|
||||||
|
if ($height > 0 && $width > 0) {
|
||||||
|
$new_height = $height;
|
||||||
|
$new_width = $width;
|
||||||
|
return array($new_height, $new_width);
|
||||||
|
} else {
|
||||||
|
// Scale the new image
|
||||||
|
if ($width == 0) $factor = $height / $image_obj->height;
|
||||||
|
elseif ($height == 0) $factor = $width / $image_obj->width;
|
||||||
|
else $factor = min($width / $image_obj->width, $height / $image_obj->height);
|
||||||
|
|
||||||
|
$new_width = round($image_obj->width * $factor);
|
||||||
|
$new_height = round($image_obj->height * $factor);
|
||||||
|
return array($new_height, $new_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,16 +25,16 @@ class RSS_Comments extends Extension {
|
|||||||
$page->set_type("application/rss+xml");
|
$page->set_type("application/rss+xml");
|
||||||
|
|
||||||
$comments = $database->get_all("
|
$comments = $database->get_all("
|
||||||
SELECT
|
SELECT
|
||||||
users.id as user_id, users.name as user_name,
|
users.id as user_id, users.name as user_name,
|
||||||
comments.comment as comment, comments.id as comment_id,
|
comments.comment as comment, comments.id as comment_id,
|
||||||
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
comments.image_id as image_id, comments.owner_ip as poster_ip,
|
||||||
UNIX_TIMESTAMP(posted) AS posted_timestamp
|
comments.posted as posted
|
||||||
FROM comments
|
FROM comments
|
||||||
LEFT JOIN users ON comments.owner_id=users.id
|
LEFT JOIN users ON comments.owner_id=users.id
|
||||||
ORDER BY comments.id DESC
|
ORDER BY comments.id DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
");
|
");
|
||||||
|
|
||||||
$data = "";
|
$data = "";
|
||||||
foreach($comments as $comment) {
|
foreach($comments as $comment) {
|
||||||
@ -42,7 +42,7 @@ class RSS_Comments extends Extension {
|
|||||||
$comment_id = $comment['comment_id'];
|
$comment_id = $comment['comment_id'];
|
||||||
$link = make_http(make_link("post/view/$image_id"));
|
$link = make_http(make_link("post/view/$image_id"));
|
||||||
$owner = html_escape($comment['user_name']);
|
$owner = html_escape($comment['user_name']);
|
||||||
$posted = date(DATE_RSS, $comment['posted_timestamp']);
|
$posted = date(DATE_RSS, strtotime($comment['posted']));
|
||||||
$comment = html_escape($comment['comment']);
|
$comment = html_escape($comment['comment']);
|
||||||
$content = html_escape("$owner: $comment");
|
$content = html_escape("$owner: $comment");
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ class RSS_Images extends Extension {
|
|||||||
$owner = $image->get_owner();
|
$owner = $image->get_owner();
|
||||||
$thumb_url = $image->get_thumb_link();
|
$thumb_url = $image->get_thumb_link();
|
||||||
$image_url = $image->get_image_link();
|
$image_url = $image->get_image_link();
|
||||||
$posted = date(DATE_RSS, $image->posted_timestamp);
|
$posted = date(DATE_RSS, strtotime($image->posted));
|
||||||
$content = html_escape(
|
$content = html_escape(
|
||||||
"<p>" . $this->theme->build_thumb_html($image) . "</p>" .
|
"<p>" . $this->theme->build_thumb_html($image) . "</p>" .
|
||||||
"<p>Uploaded by " . html_escape($owner->name) . "</p>"
|
"<p>Uploaded by " . html_escape($owner->name) . "</p>"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class SetupTest extends ShimmiePHPUnitTestCase {
|
class SetupTest extends ShimmiePHPUnitTestCase {
|
||||||
function testNiceUrlsTest() {
|
public function testNiceUrlsTest() {
|
||||||
# XXX: this only checks that the text is "ok", to check
|
# XXX: this only checks that the text is "ok", to check
|
||||||
# for a bug where it was coming out as "\nok"; it doesn't
|
# for a bug where it was coming out as "\nok"; it doesn't
|
||||||
# check that niceurls actually work
|
# check that niceurls actually work
|
||||||
@ -9,27 +9,27 @@ class SetupTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_no_content("\n");
|
$this->assert_no_content("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAuthAnon() {
|
public function testAuthAnon() {
|
||||||
$this->get_page('setup');
|
$this->get_page('setup');
|
||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
$this->assert_title("Permission Denied");
|
$this->assert_title("Permission Denied");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAuthUser() {
|
public function testAuthUser() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$this->get_page('setup');
|
$this->get_page('setup');
|
||||||
$this->assert_response(403);
|
$this->assert_response(403);
|
||||||
$this->assert_title("Permission Denied");
|
$this->assert_title("Permission Denied");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAuthAdmin() {
|
public function testAuthAdmin() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page('setup');
|
$this->get_page('setup');
|
||||||
$this->assert_title("Shimmie Setup");
|
$this->assert_title("Shimmie Setup");
|
||||||
$this->assert_text("General");
|
$this->assert_text("General");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAdvanced() {
|
public function testAdvanced() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page('setup/advanced');
|
$this->get_page('setup/advanced');
|
||||||
$this->assert_title("Shimmie Setup");
|
$this->assert_title("Shimmie Setup");
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
|
|
||||||
class _SafeImage {
|
class _SafeImage {
|
||||||
#{"id":"2","height":"768","width":"1024","hash":"71cdfaabbcdad3f777e0b60418532e94","filesize":"439561","filename":"HeilAmu.png","ext":"png","owner_ip":"0.0.0.0","posted":"0000-00-00 00:00:00","source":null,"locked":"N","owner_id":"0","rating":"u","numeric_score":"0","text_score":"0","notes":"0","favorites":"0","posted_timestamp":-62169955200,"tag_array":["cat","kunimitsu"]}
|
|
||||||
|
|
||||||
public $id;
|
public $id;
|
||||||
public $height;
|
public $height;
|
||||||
public $width;
|
public $width;
|
||||||
@ -39,7 +37,7 @@ class _SafeImage {
|
|||||||
$this->hash = $img->hash;
|
$this->hash = $img->hash;
|
||||||
$this->filesize = $img->filesize;
|
$this->filesize = $img->filesize;
|
||||||
$this->ext = $img->ext;
|
$this->ext = $img->ext;
|
||||||
$this->posted = $img->posted_timestamp;
|
$this->posted = strtotime($img->posted);
|
||||||
$this->source = $img->source;
|
$this->source = $img->source;
|
||||||
$this->owner_id = $img->owner_id;
|
$this->owner_id = $img->owner_id;
|
||||||
$this->tags = $img->get_tag_array();
|
$this->tags = $img->get_tag_array();
|
||||||
@ -48,52 +46,30 @@ class _SafeImage {
|
|||||||
|
|
||||||
class ShimmieApi extends Extension {
|
class ShimmieApi extends Extension {
|
||||||
public function onPageRequest(PageRequestEvent $event) {
|
public function onPageRequest(PageRequestEvent $event) {
|
||||||
global $database, $page, $user;
|
global $page, $user;
|
||||||
|
|
||||||
if($event->page_matches("api/shimmie")) {
|
if($event->page_matches("api/shimmie")) {
|
||||||
$page->set_mode("data");
|
$page->set_mode("data");
|
||||||
$page->set_type("text/plain");
|
$page->set_type("text/plain");
|
||||||
if(!$event->page_matches("api/shimmie/get_tags") && !$event->page_matches("api/shimmie/get_image") && !$event->page_matches("api/shimmie/find_images") && !$event->page_matches("api/shimmie/get_user")){
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
$page->set_redirect(make_link("ext_doc/shimmie_api"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($event->page_matches("api/shimmie/get_tags")){
|
if($event->page_matches("api/shimmie/get_tags")){
|
||||||
$arg = $event->get_arg(0);
|
$tag = $event->get_arg(0);
|
||||||
|
if(empty($tag) && isset($_GET['tag'])) $tag = $_GET['tag'];
|
||||||
if(!empty($arg)){
|
$res = $this->api_get_tags($tag);
|
||||||
$all = $database->get_all(
|
|
||||||
"SELECT tag FROM tags WHERE tag LIKE ?",
|
|
||||||
array($arg."%"));
|
|
||||||
}
|
|
||||||
elseif(isset($_GET['tag'])){
|
|
||||||
$all = $database->get_all(
|
|
||||||
"SELECT tag FROM tags WHERE tag LIKE ?",
|
|
||||||
array($_GET['tag']."%"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$all = $database->get_all("SELECT tag FROM tags");
|
|
||||||
}
|
|
||||||
$res = array();
|
|
||||||
foreach($all as $row) {$res[] = $row["tag"];}
|
|
||||||
$page->set_data(json_encode($res));
|
$page->set_data(json_encode($res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($event->page_matches("api/shimmie/get_image")) {
|
elseif($event->page_matches("api/shimmie/get_image")) {
|
||||||
$arg = $event->get_arg(0);
|
$arg = $event->get_arg(0);
|
||||||
if(!empty($arg)){
|
if(empty($arg) && isset($_GET['id'])) $arg = $_GET['id'];
|
||||||
$image = Image::by_id(int_escape($event->get_arg(0)));
|
$image = Image::by_id(int_escape($arg));
|
||||||
}
|
|
||||||
elseif(isset($_GET['id'])){
|
|
||||||
$image = Image::by_id(int_escape($_GET['id']));
|
|
||||||
}
|
|
||||||
// FIXME: handle null image
|
// FIXME: handle null image
|
||||||
$image->get_tag_array(); // tag data isn't loaded into the object until necessary
|
$image->get_tag_array(); // tag data isn't loaded into the object until necessary
|
||||||
$safe_image = new _SafeImage($image);
|
$safe_image = new _SafeImage($image);
|
||||||
$page->set_data(json_encode($safe_image));
|
$page->set_data(json_encode($safe_image));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($event->page_matches("api/shimmie/find_images")) {
|
elseif($event->page_matches("api/shimmie/find_images")) {
|
||||||
$search_terms = $event->get_search_terms();
|
$search_terms = $event->get_search_terms();
|
||||||
$page_number = $event->get_page_number();
|
$page_number = $event->get_page_number();
|
||||||
$page_size = $event->get_page_size();
|
$page_size = $event->get_page_size();
|
||||||
@ -106,7 +82,7 @@ class ShimmieApi extends Extension {
|
|||||||
$page->set_data(json_encode($safe_images));
|
$page->set_data(json_encode($safe_images));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($event->page_matches("api/shimmie/get_user")) {
|
elseif($event->page_matches("api/shimmie/get_user")) {
|
||||||
$query = $user->id;
|
$query = $user->id;
|
||||||
$type = "id";
|
$type = "id";
|
||||||
if($event->count_args() == 1) {
|
if($event->count_args() == 1) {
|
||||||
@ -121,41 +97,77 @@ class ShimmieApi extends Extension {
|
|||||||
$type = "name";
|
$type = "name";
|
||||||
}
|
}
|
||||||
|
|
||||||
$all = $database->get_row(
|
$all = $this->api_get_user($type, $query);
|
||||||
"SELECT id,name,joindate,class FROM users WHERE $type=?",
|
|
||||||
array($query));
|
|
||||||
|
|
||||||
if(!empty($all)){
|
|
||||||
//FIXME?: For some weird reason, get_all seems to return twice. Unsetting second value to make things look nice..
|
|
||||||
// - it returns data as eg array(0=>1234, 'id'=>1234, 1=>'bob', 'name'=>bob, ...);
|
|
||||||
for($i=0; $i<4; $i++) unset($all[$i]);
|
|
||||||
$all['uploadcount'] = Image::count_images(array("user_id=".$all['id']));
|
|
||||||
$all['commentcount'] = $database->get_one(
|
|
||||||
"SELECT COUNT(*) AS count FROM comments WHERE owner_id=:owner_id",
|
|
||||||
array("owner_id"=>$all['id']));
|
|
||||||
|
|
||||||
if(isset($_GET['recent'])){
|
|
||||||
$recent = $database->get_all(
|
|
||||||
"SELECT * FROM images WHERE owner_id=? ORDER BY id DESC LIMIT 0, 5",
|
|
||||||
array($all['id']));
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach($recent as $all['recentposts'][$i]){
|
|
||||||
unset($all['recentposts'][$i]['owner_id']); //We already know the owners id..
|
|
||||||
unset($all['recentposts'][$i]['owner_ip']);
|
|
||||||
|
|
||||||
for($x=0; $x<14; $x++) unset($all['recentposts'][$i][$x]);
|
|
||||||
if(empty($all['recentposts'][$i]['author'])) unset($all['recentposts'][$i]['author']);
|
|
||||||
if($all['recentposts'][$i]['notes'] > 0) $all['recentposts'][$i]['has_notes'] = "Y";
|
|
||||||
else $all['recentposts'][$i]['has_notes'] = "N";
|
|
||||||
unset($all['recentposts'][$i]['notes']);
|
|
||||||
$i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$page->set_data(json_encode($all));
|
$page->set_data(json_encode($all));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
$page->set_redirect(make_link("ext_doc/shimmie_api"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $arg
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function api_get_tags($arg) {
|
||||||
|
global $database;
|
||||||
|
if (!empty($arg)) {
|
||||||
|
$all = $database->get_all("SELECT tag FROM tags WHERE tag LIKE ?", array($arg . "%"));
|
||||||
|
} else {
|
||||||
|
$all = $database->get_all("SELECT tag FROM tags");
|
||||||
|
}
|
||||||
|
$res = array();
|
||||||
|
foreach ($all as $row) {
|
||||||
|
$res[] = $row["tag"];
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $type
|
||||||
|
* @param $query
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function api_get_user($type, $query) {
|
||||||
|
global $database;
|
||||||
|
$all = $database->get_row(
|
||||||
|
"SELECT id, name, joindate, class FROM users WHERE $type=?",
|
||||||
|
array($query)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($all)) {
|
||||||
|
//FIXME?: For some weird reason, get_all seems to return twice. Unsetting second value to make things look nice..
|
||||||
|
// - it returns data as eg array(0=>1234, 'id'=>1234, 1=>'bob', 'name'=>bob, ...);
|
||||||
|
for ($i = 0; $i < 4; $i++) unset($all[$i]);
|
||||||
|
$all['uploadcount'] = Image::count_images(array("user_id=" . $all['id']));
|
||||||
|
$all['commentcount'] = $database->get_one(
|
||||||
|
"SELECT COUNT(*) AS count FROM comments WHERE owner_id=:owner_id",
|
||||||
|
array("owner_id" => $all['id']));
|
||||||
|
|
||||||
|
if (isset($_GET['recent'])) {
|
||||||
|
$recent = $database->get_all(
|
||||||
|
"SELECT * FROM images WHERE owner_id=? ORDER BY id DESC LIMIT 0, 5",
|
||||||
|
array($all['id']));
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($recent as $all['recentposts'][$i]) {
|
||||||
|
unset($all['recentposts'][$i]['owner_id']); //We already know the owners id..
|
||||||
|
unset($all['recentposts'][$i]['owner_ip']);
|
||||||
|
|
||||||
|
for ($x = 0; $x < 14; $x++) unset($all['recentposts'][$i][$x]);
|
||||||
|
if (empty($all['recentposts'][$i]['author'])) unset($all['recentposts'][$i]['author']);
|
||||||
|
if ($all['recentposts'][$i]['notes'] > 0) $all['recentposts'][$i]['has_notes'] = "Y";
|
||||||
|
else $all['recentposts'][$i]['has_notes'] = "N";
|
||||||
|
unset($all['recentposts'][$i]['notes']);
|
||||||
|
$i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $all;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ShimmieApiTest extends ShimmiePHPUnitTestCase {
|
class ShimmieApiTest extends ShimmiePHPUnitTestCase {
|
||||||
function testAPI() {
|
public function testAPI() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class SiteDescriptionTest extends ShimmiePHPUnitTestCase {
|
class SiteDescriptionTest extends ShimmiePHPUnitTestCase {
|
||||||
function testSiteDescription() {
|
public function testSiteDescription() {
|
||||||
global $config, $page;
|
global $config, $page;
|
||||||
$config->set_string("site_description", "A Shimmie testbed");
|
$config->set_string("site_description", "A Shimmie testbed");
|
||||||
$this->get_page("post/list");
|
$this->get_page("post/list");
|
||||||
@ -10,7 +10,7 @@ class SiteDescriptionTest extends ShimmiePHPUnitTestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSiteKeywords() {
|
public function testSiteKeywords() {
|
||||||
global $config, $page;
|
global $config, $page;
|
||||||
$config->set_string("site_keywords", "foo,bar,baz");
|
$config->set_string("site_keywords", "foo,bar,baz");
|
||||||
$this->get_page("post/list");
|
$this->get_page("post/list");
|
||||||
|
@ -56,7 +56,7 @@ class XMLSitemap extends Extension
|
|||||||
$latestimages_urllist[$arrayid] = "post/view/$image->id";
|
$latestimages_urllist[$arrayid] = "post/view/$image->id";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", $image->posted_timestamp));
|
$this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", strtotime($image->posted)));
|
||||||
|
|
||||||
/* --- Display page --- */
|
/* --- Display page --- */
|
||||||
// when sitemap is ok, display it from the file
|
// when sitemap is ok, display it from the file
|
||||||
@ -88,7 +88,7 @@ class XMLSitemap extends Extension
|
|||||||
// create url from image id's
|
// create url from image id's
|
||||||
$latestimages_urllist[$arrayid] = "post/view/$image->id";
|
$latestimages_urllist[$arrayid] = "post/view/$image->id";
|
||||||
}
|
}
|
||||||
$this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", $image->posted_timestamp));
|
$this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", strtotime($image->posted)));
|
||||||
|
|
||||||
/* --- Add other tags --- */
|
/* --- Add other tags --- */
|
||||||
$other_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 21,10000000");
|
$other_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 21,10000000");
|
||||||
@ -106,7 +106,7 @@ class XMLSitemap extends Extension
|
|||||||
// create url from image id's
|
// create url from image id's
|
||||||
$otherimages[$arrayid] = "post/view/$image->id";
|
$otherimages[$arrayid] = "post/view/$image->id";
|
||||||
}
|
}
|
||||||
$this->add_sitemap_queue($otherimages, "monthly", "0.6", date("Y-m-d", $image->posted_timestamp));
|
$this->add_sitemap_queue($otherimages, "monthly", "0.6", date("Y-m-d", strtotime($image->posted)));
|
||||||
|
|
||||||
|
|
||||||
/* --- Display page --- */
|
/* --- Display page --- */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class XMLSitemapTest extends ShimmiePHPUnitTestCase {
|
class XMLSitemapTest extends ShimmiePHPUnitTestCase {
|
||||||
function testBasic() {
|
public function testBasic() {
|
||||||
# this will implicitly check that there are no
|
# this will implicitly check that there are no
|
||||||
# PHP-level error messages
|
# PHP-level error messages
|
||||||
$this->get_page('sitemap.xml');
|
$this->get_page('sitemap.xml');
|
||||||
|
@ -95,11 +95,38 @@ class SourceSetEvent extends Event {
|
|||||||
class TagSetEvent extends Event {
|
class TagSetEvent extends Event {
|
||||||
/** @var \Image */
|
/** @var \Image */
|
||||||
public $image;
|
public $image;
|
||||||
var $tags;
|
public $tags;
|
||||||
|
public $metatags;
|
||||||
|
|
||||||
public function __construct(Image $image, $tags) {
|
public function __construct(Image $image, $tags) {
|
||||||
$this->image = $image;
|
$this->image = $image;
|
||||||
$this->tags = Tag::explode($tags);
|
|
||||||
|
$this->tags = array();
|
||||||
|
$this->metatags = array();
|
||||||
|
|
||||||
|
//tags need to be sanitised, alias checked & have metatags removed before being passed to onTagSet
|
||||||
|
$tag_array = Tag::explode($tags);
|
||||||
|
$tag_array = array_map(array('Tag', 'sanitise'), $tag_array);
|
||||||
|
$tag_array = Tag::resolve_aliases($tag_array);
|
||||||
|
|
||||||
|
foreach($tag_array as $tag) {
|
||||||
|
if((strpos($tag, ':') === FALSE) && (strpos($tag, '=') === FALSE)) {
|
||||||
|
//Tag doesn't contain : or =, meaning it can't possibly be a metatag.
|
||||||
|
//This should help speed wise, as it avoids running every single tag through a bunch of preg_match instead.
|
||||||
|
array_push($this->tags, $tag);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ttpe = new TagTermParseEvent($tag, $this->image->id, FALSE); //Only check for metatags, don't parse. Parsing is done after set_tags.
|
||||||
|
send_event($ttpe);
|
||||||
|
|
||||||
|
//seperate tags from metatags
|
||||||
|
if(!$ttpe->is_metatag()) {
|
||||||
|
array_push($this->tags, $tag);
|
||||||
|
}else{
|
||||||
|
array_push($this->metatags, $tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,14 +158,17 @@ class LockSetEvent extends Event {
|
|||||||
* Signal that a tag term needs parsing
|
* Signal that a tag term needs parsing
|
||||||
*/
|
*/
|
||||||
class TagTermParseEvent extends Event {
|
class TagTermParseEvent extends Event {
|
||||||
var $term = null;
|
public $term = NULL; //tag
|
||||||
var $id = null;
|
public $id = NULL; //image_id
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
public $metatag = false;
|
public $metatag = FALSE;
|
||||||
|
/** @var bool */
|
||||||
|
public $parse = TRUE; //marks the tag to be parsed, and not just checked if valid metatag
|
||||||
|
|
||||||
public function __construct($term, $id) {
|
public function __construct($term, $id, $parse) {
|
||||||
$this->term = $term;
|
$this->term = $term;
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
$this->parse = $parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,6 +245,7 @@ class TagEdit extends Extension {
|
|||||||
if($user->can("edit_image_tag") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) {
|
if($user->can("edit_image_tag") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) {
|
||||||
$event->image->set_tags($event->tags);
|
$event->image->set_tags($event->tags);
|
||||||
}
|
}
|
||||||
|
$event->image->parse_metatags($event->metatags, $event->image->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSourceSet(SourceSetEvent $event) {
|
public function onSourceSet(SourceSetEvent $event) {
|
||||||
@ -257,7 +288,7 @@ class TagEdit extends Extension {
|
|||||||
public function onTagTermParse(TagTermParseEvent $event) {
|
public function onTagTermParse(TagTermParseEvent $event) {
|
||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
if(preg_match("/^source[=|:](.*)$/i", $event->term, $matches)) {
|
if(preg_match("/^source[=|:](.*)$/i", $event->term, $matches) && $event->parse) {
|
||||||
$source = ($matches[1] !== "none" ? $matches[1] : null);
|
$source = ($matches[1] !== "none" ? $matches[1] : null);
|
||||||
send_event(new SourceSetEvent(Image::by_id($event->id), $source));
|
send_event(new SourceSetEvent(Image::by_id($event->id), $source));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class TagEditTest extends ShimmiePHPUnitTestCase {
|
class TagEditTest extends ShimmiePHPUnitTestCase {
|
||||||
function testTagEdit() {
|
public function testTagEdit() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
@ -21,7 +21,7 @@ class TagEditTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSourceEdit() {
|
public function testSourceEdit() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
@ -48,10 +48,12 @@ class TagEditTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Mass Tagger seems to be broken, and this test case always fails.
|
* FIXME: Mass Tagger seems to be broken, and this test case always fails.
|
||||||
*
|
*/
|
||||||
function testMassEdit() {
|
public function testMassEdit() {
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
@ -71,6 +73,5 @@ class TagEditTest extends ShimmiePHPUnitTestCase {
|
|||||||
|
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class TagEditCloud extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onInitExt(InitExtEvent $event) {
|
public function onInitExt(InitExtEvent $event) {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_default_bool("tageditcloud_disable", false);
|
$config->set_default_bool("tageditcloud_disable", false);
|
||||||
@ -74,16 +74,14 @@ class TagEditCloud extends Extension {
|
|||||||
|
|
||||||
$ignore_tags = Tag::explode($config->get_string("tageditcloud_ignoretags"));
|
$ignore_tags = Tag::explode($config->get_string("tageditcloud_ignoretags"));
|
||||||
|
|
||||||
if(class_exists("TagCategories")){
|
if(ext_is_live("TagCategories")) {
|
||||||
$categories = $database->get_all("SELECT category, color FROM image_tag_categories");
|
$categories = $database->get_all("SELECT category, color FROM image_tag_categories");
|
||||||
$cat_color = array();
|
$cat_color = array();
|
||||||
foreach($categories as $row){
|
foreach($categories as $row) {
|
||||||
$cat_color[$row['category']] = $row['color'];
|
$cat_color[$row['category']] = $row['color'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag_data = null;
|
|
||||||
|
|
||||||
switch($sort_method) {
|
switch($sort_method) {
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -99,31 +97,29 @@ class TagEditCloud extends Extension {
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
$relevant_tags = array_diff($image->get_tag_array(),$ignore_tags);
|
$relevant_tags = array_diff($image->get_tag_array(),$ignore_tags);
|
||||||
if(count($relevant_tags) > 0) {
|
if(count($relevant_tags) == 0) {
|
||||||
$relevant_tags = implode(",",array_map(array($database,"escape"),$relevant_tags));
|
return null;
|
||||||
$tag_data = $database->get_all("
|
|
||||||
SELECT t2.tag AS tag, COUNT(image_id) AS count, FLOOR(LN(LN(COUNT(image_id) - :tag_min1 + 1)+1)*150)/200 AS scaled
|
|
||||||
FROM image_tags it1
|
|
||||||
JOIN image_tags it2 USING(image_id)
|
|
||||||
JOIN tags t1 ON it1.tag_id = t1.id
|
|
||||||
JOIN tags t2 ON it2.tag_id = t2.id
|
|
||||||
WHERE t1.count >= :tag_min2 AND t1.tag IN($relevant_tags)
|
|
||||||
GROUP BY t2.tag
|
|
||||||
ORDER BY count DESC
|
|
||||||
LIMIT :limit",
|
|
||||||
array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count));
|
|
||||||
}
|
}
|
||||||
|
$relevant_tags = implode(",",array_map(array($database,"escape"),$relevant_tags));
|
||||||
|
$tag_data = $database->get_all("
|
||||||
|
SELECT t2.tag AS tag, COUNT(image_id) AS count, FLOOR(LN(LN(COUNT(image_id) - :tag_min1 + 1)+1)*150)/200 AS scaled
|
||||||
|
FROM image_tags it1
|
||||||
|
JOIN image_tags it2 USING(image_id)
|
||||||
|
JOIN tags t1 ON it1.tag_id = t1.id
|
||||||
|
JOIN tags t2 ON it2.tag_id = t2.id
|
||||||
|
WHERE t1.count >= :tag_min2 AND t1.tag IN($relevant_tags)
|
||||||
|
GROUP BY t2.tag
|
||||||
|
ORDER BY count DESC
|
||||||
|
LIMIT :limit",
|
||||||
|
array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(is_null($tag_data)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$counter = 1;
|
$counter = 1;
|
||||||
foreach($tag_data as $row) {
|
foreach($tag_data as $row) {
|
||||||
$full_tag = $row['tag'];
|
$full_tag = $row['tag'];
|
||||||
|
|
||||||
if(class_exists("TagCategories")){
|
if(ext_is_live("TagCategories")){
|
||||||
$tc = explode(':',$row['tag']);
|
$tc = explode(':',$row['tag']);
|
||||||
if(isset($tc[1]) && isset($cat_color[$tc[0]])){
|
if(isset($tc[1]) && isset($cat_color[$tc[0]])){
|
||||||
$h_tag = html_escape($tc[1]);
|
$h_tag = html_escape($tc[1]);
|
||||||
|
@ -329,7 +329,8 @@ class Tag_History extends Extension {
|
|||||||
|
|
||||||
$image = Image::by_id($stored_image_id);
|
$image = Image::by_id($stored_image_id);
|
||||||
if ( ! $image instanceof Image) {
|
if ( ! $image instanceof Image) {
|
||||||
throw new ImageDoesNotExist("Error: cannot find any image with the ID = ". $stored_image_id);
|
continue;
|
||||||
|
//throw new ImageDoesNotExist("Error: cannot find any image with the ID = ". $stored_image_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("tag_history", 'Reverting tags of Image #'.$stored_image_id.' to ['.$stored_tags.']');
|
log_debug("tag_history", 'Reverting tags of Image #'.$stored_image_id.' to ['.$stored_tags.']');
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
class TagHistoryTest extends ShimmiePHPUnitTestCase {
|
class TagHistoryTest extends ShimmiePHPUnitTestCase {
|
||||||
function testTagHistory() {
|
public function testTagHistory() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||||
$this->get_page("post/view/$image_id");
|
$this->get_page("post/view/$image_id");
|
||||||
$this->assert_title("Image $image_id: pbx");
|
$this->assert_title("Image $image_id: pbx");
|
||||||
|
|
||||||
/*
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
$this->set_field("tag_edit__tags", "new");
|
$this->set_field("tag_edit__tags", "new");
|
||||||
$this->click("Set");
|
$this->click("Set");
|
||||||
@ -15,7 +16,6 @@ class TagHistoryTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_text("new (Set by demo");
|
$this->assert_text("new (Set by demo");
|
||||||
$this->click("Revert To");
|
$this->click("Revert To");
|
||||||
$this->assert_title("Image $image_id: pbx");
|
$this->assert_title("Image $image_id: pbx");
|
||||||
*/
|
|
||||||
|
|
||||||
$this->get_page("tag_history/all/1");
|
$this->get_page("tag_history/all/1");
|
||||||
$this->assert_title("Global Tag History");
|
$this->assert_title("Global Tag History");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
class TagListTest extends ShimmiePHPUnitTestCase {
|
class TagListTest extends ShimmiePHPUnitTestCase {
|
||||||
var $pages = array("map", "alphabetic", "popularity", "categories");
|
var $pages = array("map", "alphabetic", "popularity", "categories");
|
||||||
|
|
||||||
function testTagList() {
|
public function testTagList() {
|
||||||
$this->get_page('tags/map');
|
$this->get_page('tags/map');
|
||||||
$this->assert_title('Tag List');
|
$this->assert_title('Tag List');
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ class TagListTest extends ShimmiePHPUnitTestCase {
|
|||||||
# FIXME: test that these show the right stuff
|
# FIXME: test that these show the right stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
function testMinCount() {
|
public function testMinCount() {
|
||||||
foreach($this->pages as $page) {
|
foreach($this->pages as $page) {
|
||||||
$this->get_page("tags/$page?mincount=999999");
|
$this->get_page("tags/$page?mincount=999999");
|
||||||
$this->assert_title("Tag List");
|
$this->assert_title("Tag List");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class TipsTest extends ShimmiePHPUnitTestCase {
|
class TipsTest extends ShimmiePHPUnitTestCase {
|
||||||
function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
@ -15,7 +15,7 @@ class TipsTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testImageless() {
|
public function testImageless() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$this->get_page("tips/list");
|
$this->get_page("tips/list");
|
||||||
@ -37,7 +37,7 @@ class TipsTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testImaged() {
|
public function testImaged() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$this->get_page("tips/list");
|
$this->get_page("tips/list");
|
||||||
@ -59,7 +59,7 @@ class TipsTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDisabled() {
|
public function testDisabled() {
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
|
|
||||||
$this->get_page("tips/list");
|
$this->get_page("tips/list");
|
||||||
|
@ -234,8 +234,8 @@ class Upload extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|int $id
|
* @param int $id
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function tags_for_upload_slot($id) {
|
private function tags_for_upload_slot($id) {
|
||||||
if(isset($_POST["tags$id"])) {
|
if(isset($_POST["tags$id"])) {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
class UploadTest extends ShimmiePHPUnitTestCase {
|
class UploadTest extends ShimmiePHPUnitTestCase {
|
||||||
function testUploadPage() {
|
public function testUploadPage() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
|
|
||||||
$this->get_page("upload");
|
$this->get_page("upload");
|
||||||
$this->assert_title("Upload");
|
$this->assert_title("Upload");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUpload() {
|
public function testUpload() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRejectDupe() {
|
public function testRejectDupe() {
|
||||||
$this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -23,7 +23,7 @@ class UploadTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRejectUnknownFiletype() {
|
public function testRejectUnknownFiletype() {
|
||||||
try {
|
try {
|
||||||
$this->post_image("index.php", "test");
|
$this->post_image("index.php", "test");
|
||||||
}
|
}
|
||||||
@ -32,16 +32,16 @@ class UploadTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRejectHuge() {
|
public function testRejectHuge() {
|
||||||
/*
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
// FIXME: huge.dat is rejected for other reasons; manual testing shows that this works
|
// FIXME: huge.dat is rejected for other reasons; manual testing shows that this works
|
||||||
file_put_contents("huge.dat", file_get_contents("tests/pbx_screenshot.jpg") . str_repeat("U", 1024*1024*3));
|
file_put_contents("huge.dat", file_get_contents("tests/pbx_screenshot.jpg") . str_repeat("U", 1024*1024*3));
|
||||||
$image_id_4 = $this->post_image("index.php", "test");
|
$this->post_image("index.php", "test");
|
||||||
$this->assert_response(200);
|
$this->assert_response(200);
|
||||||
$this->assert_title("Upload Status");
|
$this->assert_title("Upload Status");
|
||||||
$this->assert_text("File too large");
|
$this->assert_text("File too large");
|
||||||
unlink("huge.dat");
|
unlink("huge.dat");
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,9 @@ class UserCreationException extends SCoreException {}
|
|||||||
class NullUserException extends SCoreException {}
|
class NullUserException extends SCoreException {}
|
||||||
|
|
||||||
class UserPage extends Extension {
|
class UserPage extends Extension {
|
||||||
|
/** @var UserPageTheme $theme */
|
||||||
|
var $theme;
|
||||||
|
|
||||||
public function onInitExt(InitExtEvent $event) {
|
public function onInitExt(InitExtEvent $event) {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_default_bool("login_signup_enabled", true);
|
$config->set_default_bool("login_signup_enabled", true);
|
||||||
@ -94,64 +97,22 @@ class UserPage extends Extension {
|
|||||||
public function onPageRequest(PageRequestEvent $event) {
|
public function onPageRequest(PageRequestEvent $event) {
|
||||||
global $config, $page, $user;
|
global $config, $page, $user;
|
||||||
|
|
||||||
// user info is shown on all pages
|
$this->show_user_info();
|
||||||
if($user->is_anonymous()) {
|
|
||||||
$this->theme->display_login_block($page);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$ubbe = new UserBlockBuildingEvent();
|
|
||||||
send_event($ubbe);
|
|
||||||
ksort($ubbe->parts);
|
|
||||||
$this->theme->display_user_block($page, $user, $ubbe->parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($event->page_matches("user_admin")) {
|
if($event->page_matches("user_admin")) {
|
||||||
if($event->get_arg(0) == "login") {
|
if($event->get_arg(0) == "login") {
|
||||||
if(isset($_POST['user']) && isset($_POST['pass'])) {
|
if(isset($_POST['user']) && isset($_POST['pass'])) {
|
||||||
$this->login($page);
|
$this->page_login($_POST['user'], $_POST['pass']);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->theme->display_login_page($page);
|
$this->theme->display_login_page($page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if($event->get_arg(0) == "recover") {
|
else if($event->get_arg(0) == "recover") {
|
||||||
$user = User::by_name($_POST['username']);
|
$this->page_recover($_POST['username']);
|
||||||
if(is_null($user)) {
|
|
||||||
$this->theme->display_error(404, "Error", "There's no user with that name");
|
|
||||||
}
|
|
||||||
else if(is_null($user->email)) {
|
|
||||||
$this->theme->display_error(400, "Error", "That user has no registered email address");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// send email
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if($event->get_arg(0) == "create") {
|
else if($event->get_arg(0) == "create") {
|
||||||
if(!$config->get_bool("login_signup_enabled")) {
|
$this->page_create();
|
||||||
$this->theme->display_signups_disabled($page);
|
|
||||||
}
|
|
||||||
else if(!isset($_POST['name'])) {
|
|
||||||
$this->theme->display_signup_page($page);
|
|
||||||
}
|
|
||||||
else if($_POST['pass1'] != $_POST['pass2']) {
|
|
||||||
$this->theme->display_error(400, "Password Mismatch", "Passwords don't match");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
if(!captcha_check()) {
|
|
||||||
throw new UserCreationException("Error in captcha");
|
|
||||||
}
|
|
||||||
|
|
||||||
$uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email']);
|
|
||||||
send_event($uce);
|
|
||||||
$this->set_login_cookie($uce->username, $uce->password);
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
$page->set_redirect(make_link("user"));
|
|
||||||
}
|
|
||||||
catch(UserCreationException $ex) {
|
|
||||||
$this->theme->display_error(400, "User Creation Error", $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if($event->get_arg(0) == "list") {
|
else if($event->get_arg(0) == "list") {
|
||||||
// select users.id,name,joindate,admin,
|
// select users.id,name,joindate,admin,
|
||||||
@ -165,24 +126,7 @@ class UserPage extends Extension {
|
|||||||
$this->theme->display_user_list($page, User::by_list(0), $user);
|
$this->theme->display_user_list($page, User::by_list(0), $user);
|
||||||
}
|
}
|
||||||
else if($event->get_arg(0) == "logout") {
|
else if($event->get_arg(0) == "logout") {
|
||||||
$page->add_cookie("session", "", time()+60*60*24*$config->get_int('login_memory'), "/");
|
$this->page_logout();
|
||||||
if(CACHE_HTTP || SPEED_HAX) {
|
|
||||||
# to keep as few versions of content as possible,
|
|
||||||
# make cookies all-or-nothing
|
|
||||||
$page->add_cookie("user", "", time()+60*60*24*$config->get_int('login_memory'), "/");
|
|
||||||
}
|
|
||||||
log_info("user", "Logged out");
|
|
||||||
$page->set_mode("redirect");
|
|
||||||
|
|
||||||
// Try forwarding to same page on logout unless user comes from registration page
|
|
||||||
if ($config->get_int("user_loginshowprofile",0) == 0 &&
|
|
||||||
isset($_SERVER['HTTP_REFERER']) &&
|
|
||||||
strstr($_SERVER['HTTP_REFERER'], "post/"))
|
|
||||||
{
|
|
||||||
$page->set_redirect ($_SERVER['HTTP_REFERER']);
|
|
||||||
} else {
|
|
||||||
$page->set_redirect(make_link());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$user->check_auth_token()) {
|
if(!$user->check_auth_token()) {
|
||||||
@ -369,8 +313,8 @@ class UserPage extends Extension {
|
|||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
$matches = array();
|
$matches = array();
|
||||||
if(preg_match("/^(poster|user)[=|:](.*)$/i", $event->term, $matches)) {
|
if(preg_match("/^(?:poster|user)[=|:](.*)$/i", $event->term, $matches)) {
|
||||||
$duser = User::by_name($matches[2]);
|
$duser = User::by_name($matches[1]);
|
||||||
if(!is_null($duser)) {
|
if(!is_null($duser)) {
|
||||||
$user_id = $duser->id;
|
$user_id = $duser->id;
|
||||||
}
|
}
|
||||||
@ -379,25 +323,33 @@ class UserPage extends Extension {
|
|||||||
}
|
}
|
||||||
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
||||||
}
|
}
|
||||||
else if(preg_match("/^(poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) {
|
else if(preg_match("/^(?:poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) {
|
||||||
$user_id = int_escape($matches[2]);
|
$user_id = int_escape($matches[1]);
|
||||||
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
||||||
}
|
}
|
||||||
else if($user->can("view_ip") && preg_match("/^(poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) {
|
else if($user->can("view_ip") && preg_match("/^(?:poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) {
|
||||||
$user_ip = $matches[2]; // FIXME: ip_escape?
|
$user_ip = $matches[1]; // FIXME: ip_escape?
|
||||||
$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
|
$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function show_user_info() {
|
||||||
|
global $user, $page;
|
||||||
|
// user info is shown on all pages
|
||||||
|
if ($user->is_anonymous()) {
|
||||||
|
$this->theme->display_login_block($page);
|
||||||
|
} else {
|
||||||
|
$ubbe = new UserBlockBuildingEvent();
|
||||||
|
send_event($ubbe);
|
||||||
|
ksort($ubbe->parts);
|
||||||
|
$this->theme->display_user_block($page, $user, $ubbe->parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// Things done *with* the user {{{
|
// Things done *with* the user {{{
|
||||||
/**
|
private function page_login($name, $pass) {
|
||||||
* @param Page $page
|
global $config, $user, $page;
|
||||||
*/
|
|
||||||
private function login(Page $page) {
|
|
||||||
global $config, $user;
|
|
||||||
|
|
||||||
$name = $_POST['user'];
|
|
||||||
$pass = $_POST['pass'];
|
|
||||||
|
|
||||||
if(empty($name) || empty($pass)) {
|
if(empty($name) || empty($pass)) {
|
||||||
$this->theme->display_error(400, "Error", "Username or password left blank");
|
$this->theme->display_error(400, "Error", "Username or password left blank");
|
||||||
@ -427,12 +379,72 @@ class UserPage extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function page_logout() {
|
||||||
|
global $page, $config;
|
||||||
|
$page->add_cookie("session", "", time() + 60 * 60 * 24 * $config->get_int('login_memory'), "/");
|
||||||
|
if (CACHE_HTTP || SPEED_HAX) {
|
||||||
|
# to keep as few versions of content as possible,
|
||||||
|
# make cookies all-or-nothing
|
||||||
|
$page->add_cookie("user", "", time() + 60 * 60 * 24 * $config->get_int('login_memory'), "/");
|
||||||
|
}
|
||||||
|
log_info("user", "Logged out");
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
|
||||||
|
// Try forwarding to same page on logout unless user comes from registration page
|
||||||
|
if ($config->get_int("user_loginshowprofile", 0) == 0 &&
|
||||||
|
isset($_SERVER['HTTP_REFERER']) &&
|
||||||
|
strstr($_SERVER['HTTP_REFERER'], "post/")
|
||||||
|
) {
|
||||||
|
$page->set_redirect($_SERVER['HTTP_REFERER']);
|
||||||
|
} else {
|
||||||
|
$page->set_redirect(make_link());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
private function page_recover($username) {
|
||||||
|
$user = User::by_name($username);
|
||||||
|
if (is_null($user)) {
|
||||||
|
$this->theme->display_error(404, "Error", "There's no user with that name");
|
||||||
|
} else if (is_null($user->email)) {
|
||||||
|
$this->theme->display_error(400, "Error", "That user has no registered email address");
|
||||||
|
} else {
|
||||||
|
// send email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function page_create() {
|
||||||
|
global $config, $page;
|
||||||
|
if (!$config->get_bool("login_signup_enabled")) {
|
||||||
|
$this->theme->display_signups_disabled($page);
|
||||||
|
} else if (!isset($_POST['name'])) {
|
||||||
|
$this->theme->display_signup_page($page);
|
||||||
|
} else if ($_POST['pass1'] != $_POST['pass2']) {
|
||||||
|
$this->theme->display_error(400, "Password Mismatch", "Passwords don't match");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (!captcha_check()) {
|
||||||
|
throw new UserCreationException("Error in captcha");
|
||||||
|
}
|
||||||
|
|
||||||
|
$uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email']);
|
||||||
|
send_event($uce);
|
||||||
|
$this->set_login_cookie($uce->username, $uce->password);
|
||||||
|
$page->set_mode("redirect");
|
||||||
|
$page->set_redirect(make_link("user"));
|
||||||
|
} catch (UserCreationException $ex) {
|
||||||
|
$this->theme->display_error(400, "User Creation Error", $ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param UserCreationEvent $event
|
* @param UserCreationEvent $event
|
||||||
* @throws UserCreationException
|
* @throws UserCreationException
|
||||||
*/
|
*/
|
||||||
private function check_user_creation(UserCreationEvent $event)
|
private function check_user_creation(UserCreationEvent $event) {
|
||||||
{
|
|
||||||
$name = $event->username;
|
$name = $event->username;
|
||||||
//$pass = $event->password;
|
//$pass = $event->password;
|
||||||
//$email = $event->email;
|
//$email = $event->email;
|
||||||
@ -450,8 +462,7 @@ class UserPage extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function create_user(UserCreationEvent $event)
|
private function create_user(UserCreationEvent $event) {
|
||||||
{
|
|
||||||
global $database, $user;
|
global $database, $user;
|
||||||
|
|
||||||
$email = (!empty($event->email)) ? $event->email : null;
|
$email = (!empty($event->email)) ? $event->email : null;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class UserPageTest extends ShimmiePHPUnitTestCase {
|
class UserPageTest extends ShimmiePHPUnitTestCase {
|
||||||
function testUserPage() {
|
public function testUserPage() {
|
||||||
$this->get_page('user');
|
$this->get_page('user');
|
||||||
$this->assert_title("Not Logged In");
|
$this->assert_title("Not Logged In");
|
||||||
$this->assert_no_text("Options");
|
$this->assert_no_text("Options");
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
class ViewTest extends ShimmiePHPUnitTestCase {
|
class ViewTest extends ShimmiePHPUnitTestCase {
|
||||||
function testViewPage() {
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
// FIXME: upload images
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testViewPage() {
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
||||||
@ -9,8 +14,16 @@ class ViewTest extends ShimmiePHPUnitTestCase {
|
|||||||
|
|
||||||
$this->get_page("post/view/$image_id_1");
|
$this->get_page("post/view/$image_id_1");
|
||||||
$this->assert_title("Image $image_id_1: test");
|
$this->assert_title("Image $image_id_1: test");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPrevNext() {
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
|
$this->log_in_as_user();
|
||||||
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
||||||
|
$image_id_3 = $this->post_image("tests/favicon.png", "test");
|
||||||
|
|
||||||
/*
|
|
||||||
$this->click("Prev");
|
$this->click("Prev");
|
||||||
$this->assert_title("Image $image_id_2: test2");
|
$this->assert_title("Image $image_id_2: test2");
|
||||||
|
|
||||||
@ -19,22 +32,35 @@ class ViewTest extends ShimmiePHPUnitTestCase {
|
|||||||
|
|
||||||
$this->click("Next");
|
$this->click("Next");
|
||||||
$this->assert_title("Image not found");
|
$this->assert_title("Image not found");
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
public function testView404() {
|
||||||
|
$this->log_in_as_user();
|
||||||
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
||||||
|
$image_id_3 = $this->post_image("tests/favicon.png", "test");
|
||||||
|
$idp1 = $image_id_3 + 1;
|
||||||
|
|
||||||
$this->get_page("post/view/$idp1");
|
$this->get_page("post/view/$idp1");
|
||||||
$this->assert_title('Image not found');
|
$this->assert_title('Image not found');
|
||||||
|
|
||||||
$this->get_page('post/view/-1');
|
$this->get_page('post/view/-1');
|
||||||
$this->assert_title('Image not found');
|
$this->assert_title('Image not found');
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
public function testNextSearchResult() {
|
||||||
* FIXME: this assumes Nice URLs.
|
$this->markTestIncomplete();
|
||||||
*
|
|
||||||
|
$this->log_in_as_user();
|
||||||
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "test");
|
||||||
|
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "test2");
|
||||||
|
$image_id_3 = $this->post_image("tests/favicon.png", "test");
|
||||||
|
|
||||||
|
// FIXME: this assumes Nice URLs.
|
||||||
# note: skips image #2
|
# note: skips image #2
|
||||||
$this->get_page("post/view/$image_id_1?search=test"); // FIXME: assumes niceurls
|
$this->get_page("post/view/$image_id_1?search=test"); // FIXME: assumes niceurls
|
||||||
$this->click("Prev");
|
$this->click("Prev");
|
||||||
$this->assert_title("Image $image_id_3: test");
|
$this->assert_title("Image $image_id_3: test");
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
class WikiTest extends ShimmiePHPUnitTestCase {
|
class WikiTest extends ShimmiePHPUnitTestCase {
|
||||||
function testIndex() {
|
public function testIndex() {
|
||||||
$this->get_page("wiki");
|
$this->get_page("wiki");
|
||||||
$this->assert_title("Index");
|
$this->assert_title("Index");
|
||||||
$this->assert_text("This is a default page");
|
$this->assert_text("This is a default page");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public function testAccess() {
|
||||||
function testAccess() {
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
global $config;
|
global $config;
|
||||||
foreach(array("anon", "user", "admin") as $user) {
|
foreach(array("anon", "user", "admin") as $user) {
|
||||||
foreach(array(false, true) as $allowed) {
|
foreach(array(false, true) as $allowed) {
|
||||||
@ -39,7 +40,9 @@ class WikiTest extends ShimmiePHPUnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testLock() {
|
public function testLock() {
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_bool("wiki_edit_anon", true);
|
$config->set_bool("wiki_edit_anon", true);
|
||||||
$config->set_bool("wiki_edit_user", false);
|
$config->set_bool("wiki_edit_user", false);
|
||||||
@ -73,7 +76,9 @@ class WikiTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDefault() {
|
public function testDefault() {
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("wiki/wiki:default");
|
$this->get_page("wiki/wiki:default");
|
||||||
$this->assert_title("wiki:default");
|
$this->assert_title("wiki:default");
|
||||||
@ -90,7 +95,9 @@ class WikiTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRevisions() {
|
public function testRevisions() {
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
$this->log_in_as_admin();
|
$this->log_in_as_admin();
|
||||||
$this->get_page("wiki/test");
|
$this->get_page("wiki/test");
|
||||||
$this->assert_title("test");
|
$this->assert_title("test");
|
||||||
@ -111,6 +118,5 @@ class WikiTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->click("Delete All");
|
$this->click("Delete All");
|
||||||
$this->log_out();
|
$this->log_out();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
class WordFilterTest extends ShimmiePHPUnitTestCase {
|
class WordFilterTest extends ShimmiePHPUnitTestCase {
|
||||||
function setUp() {
|
public function setUp() {
|
||||||
global $config;
|
global $config;
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$config->set_string("word_filter", "whore,nice lady\na duck,a kitten\n white ,\tspace\ninvalid");
|
$config->set_string("word_filter", "whore,nice lady\na duck,a kitten\n white ,\tspace\ninvalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
function _doThings($in, $out) {
|
public function _doThings($in, $out) {
|
||||||
global $user;
|
global $user;
|
||||||
$this->log_in_as_user();
|
$this->log_in_as_user();
|
||||||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx computer screenshot");
|
||||||
@ -15,49 +15,49 @@ class WordFilterTest extends ShimmiePHPUnitTestCase {
|
|||||||
$this->assert_text($out);
|
$this->assert_text($out);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRegular() {
|
public function testRegular() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"posted by a whore",
|
"posted by a whore",
|
||||||
"posted by a nice lady"
|
"posted by a nice lady"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testReplaceAll() {
|
public function testReplaceAll() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"a whore is a whore is a whore",
|
"a whore is a whore is a whore",
|
||||||
"a nice lady is a nice lady is a nice lady"
|
"a nice lady is a nice lady is a nice lady"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testMixedCase() {
|
public function testMixedCase() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"monkey WhorE",
|
"monkey WhorE",
|
||||||
"monkey nice lady"
|
"monkey nice lady"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testOnlyWholeWords() {
|
public function testOnlyWholeWords() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"my name is whoretta",
|
"my name is whoretta",
|
||||||
"my name is whoretta"
|
"my name is whoretta"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testMultipleWords() {
|
public function testMultipleWords() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"I would like a duck",
|
"I would like a duck",
|
||||||
"I would like a kitten"
|
"I would like a kitten"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testWhitespace() {
|
public function testWhitespace() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"A colour is white",
|
"A colour is white",
|
||||||
"A colour is space"
|
"A colour is space"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testIgnoreInvalid() {
|
public function testIgnoreInvalid() {
|
||||||
$this->_doThings(
|
$this->_doThings(
|
||||||
"The word was invalid",
|
"The word was invalid",
|
||||||
"The word was invalid"
|
"The word was invalid"
|
||||||
|
9
tests/test-deep.sh
Executable file
9
tests/test-deep.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
php \
|
||||||
|
-d extension.dir=/usr/lib/php/extensions/no-debug-non-zts-20121212/ \
|
||||||
|
-d extension=xdebug.so \
|
||||||
|
-d xdebug.profiler_output_dir=./data/prof/ \
|
||||||
|
-d xdebug.profiler_enable=1 \
|
||||||
|
./phpunit.phar \
|
||||||
|
--config tests/phpunit.xml \
|
||||||
|
--coverage-clover data/coverage.clover
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user