Merge pull request #418 from jgen/develop

Even more linting and cleaning!
This commit is contained in:
Daku 2014-05-23 23:24:32 +01:00
commit 36713803e3
108 changed files with 3144 additions and 1809 deletions

149
README.markdown Normal file
View File

@ -0,0 +1,149 @@
```
_________.__ .__ .__ ________
/ _____/| |__ |__| _____ _____ |__| ____ \_____ \
\_____ \ | | \ | | / \ / \ | |_/ __ \ / ____/
/ \| Y \| || Y Y \| Y Y \| |\ ___/ / \
/_______ /|___| /|__||__|_| /|__|_| /|__| \___ >\_______ \
\/ \/ \/ \/ \/ \/
```
# Shimmie
[![Build Status](https://travis-ci.org/shish/shimmie2.svg?branch=master)](https://travis-ci.org/shish/shimmie2)
This is the main branch of Shimmie, if you know anything at all about running
websites, this is the version to use.
Alternatively if you want a version that will never have significant changes,
check out one of the versioned branches.
# Requirements
- MySQL/MariaDB 5.1+ (with experimental support for PostgreSQL 8+ and SQLite 3)
- PHP 5.3+
- GD or ImageMagick
# Installation
1. Create a blank database
2. Unzip shimmie into a folder on the web host
3. Visit the folder with a web browser
4. Enter the location of the database
5. Click "install". Hopefully you'll end up at the welcome screen; if
not, you should be given instructions on how to fix any errors~
## Upgrade from 2.3.X
1. Backup your current files and database!
2. Unzip into a clean folder
3. Copy across the images, thumbs, and data folders
4. Move `old/config.php` to `new/data/config/shimmie.conf.php`
5. Edit `shimmie.conf.php` to use the new database connection format:
OLD Format:
```php
$database_dsn = "<proto>://<username>:<password>@<host>/<database>";
```
NEW Format:
```php
define("DATABASE_DSN", "<proto>:user=<username>;password=<password>;host=<host>;dbname=<database>");
```
The rest should be automatic~
If there are any errors with the upgrade process, `in_upgrade=true` will
be left in the config table and the process will be paused for the admin
to investigate.
Deleting this config entry and refreshing the page should continue the upgrade from where it left off.
### Upgrade from earlier versions
I very much recommend going via each major release in turn (eg, 2.0.6
-> 2.1.3 -> 2.2.4 -> 2.3.0 rather than 2.0.6 -> 2.3.0).
While the basic database and file formats haven't changed *completely*, it's different
enough to be a pain.
## Custom Configuration
Various aspects of Shimmie can be configured to suit your site specific needs
via the file `data/config/shimmie.conf.php` (created after installation).
Take a look at `core/sys_config.inc.php` for the available options that can
be used.
#### Custom User Classes
User classes can be added to or altered by placing them in
`data/config/user-classes.conf.php`.
For example, one can override the default anonymous "allow nothing" permissions like so:
```php
new UserClass("anonymous", "base", array(
"create_comment" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"create_image_report" => True,
));
```
For a moderator class, being a regular user who can delete images and comments:
```php
new UserClass("moderator", "user", array(
"delete_image" => True,
"delete_comment" => True,
));
```
For a list of permissions, see `core/userclass.class.php`
# Development Info
ui-* cookies are for the client-side scripts only; in some configurations
(eg with varnish cache) they will be stripped before they reach the server
shm-* CSS classes are for javascript to hook into; if you're customising
themes, be careful with these, and avoid styling them, eg:
- shm-thumb = outermost element of a thumbnail
* data-tags
* data-post-id
- shm-toggler = click this to toggle elements that match the selector
* data-toggle-sel
- shm-unlocker = click this to unlock elements that match the selector
* data-unlock-sel
- shm-clink = a link to a comment, flash the target element when clicked
* data-clink-sel
Documentation: http://shimmie.shishnet.org/doc/
Please tell me if those docs are lacking in any way, so that they can be
improved for the next person who uses them
# Contact
IRC: `#shimmie` on [Freenode](irc.freenode.net)
Email: webmaster at shishnet.org
Issue/Bug tracker: http://github.com/shish/shimmie2/issues
# Licence
All code is released under the [GNU GPL Version 2](http://www.gnu.org/licenses/gpl-2.0.html) unless mentioned otherwise.
If you give shimmie to someone else, you have to give them the source (which should be easy, as PHP
is an interpreted language...). If you want to add customisations to your own
site, then those customisations belong to you, and you can do what you want
with them.

View File

@ -1,133 +0,0 @@
_________.__ .__ .__ ________
/ _____/| |__ |__| _____ _____ |__| ____ \_____ \
\_____ \ | | \ | | / \ / \ | |_/ __ \ / ____/
/ \| Y \| || Y Y \| Y Y \| |\ ___/ / \
/_______ /|___| /|__||__|_| /|__|_| /|__| \___ >\_______ \
\/ \/ \/ \/ \/ \/
_________________________________________________________________________
Shimmie Development
~~~~~~~~~~~~~~~~~~~
This is the main branch of Shimmie, if you know anything at all about
running websites, this is the version to use. Alternatively if you want
a version that will never have significant changes, check out one of the
versioned branches.
Requirements
~~~~~~~~~~~~
MySQL/MariaDB 5.1+ (with experimental support for PostgreSQL 8+ and SQLite 3)
PHP 5.3+
GD or ImageMagick
Installation
~~~~~~~~~~~~
1) Create a blank database
2) Unzip shimmie into a folder on the web host
3) Visit the folder with a web browser
4) Enter the location of the database
5) Click "install". Hopefully you'll end up at the welcome screen; if
not, you should be given instructions on how to fix any errors~
Upgrade from 2.3.X
~~~~~~~~~~~~~~~~~~
- Backup your current files and database!
- Unzip into a clean folder
- Copy across the images, thumbs, and data folders
- Move old/config.php to new/data/config/shimmie.conf.php
- Edit shimmie.conf.php to use the new database connection format:
OLD: $database_dsn = "<proto>://<username>:<password>@<host>/<database>";
NEW: define("DATABASE_DSN", "<proto>:user=<username>;password=<password>;host=<host>;dbname=<database>");
The rest should be automatic~
If there are any errors with the upgrade process, "in_upgrade=true" will
be left in the config table and the process will be paused for the admin
to investigate. Deleting this config entry and refreshing the page should
continue the upgrade from where it left off.
Upgrade from earlier versions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I very much recommend going via each major release in turn (eg, 2.0.6
-> 2.1.3 -> 2.2.4 -> 2.3.0 rather than 2.0.6 -> 2.3.0). While the basic
database and file formats haven't changed *completely*, it's different
enough to be a pain.
Custom Configuration
~~~~~~~~~~~~~~~~~~~~
Various aspects of Shimmie can be configured to suit your site specific needs
via the file "data/config/shimmie.conf.php" (created after installation).
Take a look at "core/sys_config.inc.php" for the available options that can
be used.
Custom User Classes
~~~~~~~~~~~~~~~~~~~
User classes can be added to or altered by placing them in
`data/config/user-classes.conf.php`. For example, one can override the
default anonymous "allow nothing" permissions like so:
new UserClass("anonymous", "base", array(
"create_comment" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"create_image_report" => True,
));
For a moderator class, being a regular user who can delete images and
comments:
new UserClass("moderator", "user", array(
"delete_image" => True,
"delete_comment" => True,
));
For a list of permissions, see core/userclass.class.php
Development Info
~~~~~~~~~~~~~~~~
ui-* cookies are for the client-side scripts only; in some configurations
(eg with varnish cache) they will be stripped before they reach the server
shm-* CSS classes are for javascript to hook into; if you're customising
themes, be careful with these, and avoid styling them, eg:
- shm-thumb = outermost element of a thumbnail
- data-tags
- data-post-id
- shm-toggler = click this to toggle elements that match the selector
- data-toggle-sel
- shm-unlocker = click this to unlock elements that match the selector
- data-unlock-sel
- shm-clink = a link to a comment, flash the target element when clicked
- data-clink-sel
http://shimmie.shishnet.org/doc/
Please tell me if those docs are lacking in any way, so that they can be
improved for the next person who uses them
Contact
~~~~~~~
#shimmie on Freenode -- IRC
webmaster at shishnet.org -- email
https://github.com/shish/shimmie2/issues -- bug tracker
Licence
~~~~~~~
All code is GPLv2 unless mentioned otherwise; ie, if you give shimmie to
someone else, you have to give them the source (which should be easy, as PHP
is an interpreted language...). If you want to add customisations to your own
site, then those customisations belong to you, and you can do what you want
with them.

View File

@ -1,17 +1,20 @@
<?php <?php
/** /**
* A basic chunk of a page * Class Block
*
* A basic chunk of a page.
*/ */
class Block { class Block {
/** /**
* The block's title * The block's title.
* *
* @var string * @var string
*/ */
public $header; public $header;
/** /**
* The content * The content of the block.
* *
* @var string * @var string
*/ */
@ -19,7 +22,7 @@ class Block {
/** /**
* 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.
* *
* @var string * @var string
*/ */
@ -35,7 +38,9 @@ class Block {
public $position; public $position;
/** /**
* @var int * A unique ID for the block.
*
* @var string
*/ */
public $id; public $id;
@ -46,7 +51,7 @@ class Block {
* @param string $body * @param string $body
* @param string $section * @param string $section
* @param int $position * @param int $position
* @param null|int $id * @param null|int $id A unique ID for the block (generated automatically if null).
*/ */
public function __construct($header, $body, /*string*/ $section="main", /*int*/ $position=50, $id=null) { public function __construct($header, $body, /*string*/ $section="main", /*int*/ $position=50, $id=null) {
$this->header = $header; $this->header = $header;
@ -77,9 +82,12 @@ class Block {
/** /**
* Class NavBlock
*
* A generic navigation block with a link to the main page. * A generic navigation block with a link to the main page.
* *
* Used because "new NavBlock()" is easier than "new Block('Navigation', ..." * Used because "new NavBlock()" is easier than "new Block('Navigation', ..."
*
*/ */
class NavBlock extends Block { class NavBlock extends Block {
public function __construct() { public function __construct() {

View File

@ -1,94 +1,237 @@
<?php <?php
/** /**
* an abstract interface for altering a name:value pair list * Interface Config
*
* An abstract interface for altering a name:value pair list.
*/ */
interface Config { interface Config {
/** /**
* Save the list of name:value pairs to wherever they came from, * Save the list of name:value pairs to wherever they came from,
* so that the next time a page is loaded it will use the new * so that the next time a page is loaded it will use the new
* configuration * configuration.
*
* @param null|string $name
* @return mixed|void
*/ */
public function save(/*string*/ $name=null); public function save(/*string*/ $name=null);
/** @name set_* //@{ /*--------------------------------- SET ------------------------------------------------------*/
* Set a configuration option to a new value, regardless /**
* of what the value is at the moment * Set a configuration option to a new value, regardless of what the value is at the moment.
* @param string $name
* @param null|int $value
* @return void
*/ */
//@{
public function set_int(/*string*/ $name, $value); public function set_int(/*string*/ $name, $value);
/**
* Set a configuration option to a new value, regardless of what the value is at the moment.
* @param string $name
* @param null|string $value
* @return void
*/
public function set_string(/*string*/ $name, $value); public function set_string(/*string*/ $name, $value);
/**
* Set a configuration option to a new value, regardless of what the value is at the moment.
* @param string $name
* @param null|bool|string $value
* @return void
*/
public function set_bool(/*string*/ $name, $value); public function set_bool(/*string*/ $name, $value);
/**
* Set a configuration option to a new value, regardless of what the value is at the moment.
* @param string $name
* @param array $value
* @return void
*/
public function set_array(/*string*/ $name, $value); public function set_array(/*string*/ $name, $value);
//@} //@} /*--------------------------------------------------------------------------------------------*/
/** @name set_default_* //@{ /*-------------------------------- SET DEFAULT -----------------------------------------------*/
* Set a configuration option to a new value, if there is no /**
* value currently. Extensions should generally call these * Set a configuration option to a new value, if there is no value currently.
* from their InitExtEvent handlers. This has the advantage *
* that the values will show up in the "advanced" setup page * Extensions should generally call these from their InitExtEvent handlers.
* where they can be modified, while calling get_* with a * This has the advantage that the values will show up in the "advanced" setup
* "default" paramater won't show up. * page where they can be modified, while calling get_* with a "default"
* parameter won't show up.
*
* @param string $name
* @param int $value
* @return void
*/ */
//@{
public function set_default_int(/*string*/ $name, $value); public function set_default_int(/*string*/ $name, $value);
public function set_default_string(/*string*/ $name, $value);
public function set_default_bool(/*string*/ $name, $value);
public function set_default_array(/*string*/ $name, $value);
//@}
/** @name get_* /**
* pick a value out of the table by name, cast to the * Set a configuration option to a new value, if there is no value currently.
* appropritate data type *
* Extensions should generally call these from their InitExtEvent handlers.
* This has the advantage that the values will show up in the "advanced" setup
* page where they can be modified, while calling get_* with a "default"
* parameter won't show up.
*
* @param string $name
* @param string|null $value
* @return void
*/
public function set_default_string(/*string*/ $name, $value);
/**
* Set a configuration option to a new value, if there is no value currently.
*
* Extensions should generally call these from their InitExtEvent handlers.
* This has the advantage that the values will show up in the "advanced" setup
* page where they can be modified, while calling get_* with a "default"
* parameter won't show up.
*
* @param string $name
* @param bool|string|null $value
* @return void
*/
public function set_default_bool(/*string*/ $name, $value);
/**
* Set a configuration option to a new value, if there is no value currently.
*
* Extensions should generally call these from their InitExtEvent handlers.
* This has the advantage that the values will show up in the "advanced" setup
* page where they can be modified, while calling get_* with a "default"
* parameter won't show up.
*
* @param string $name
* @param array $value
* @return void
*/
public function set_default_array(/*string*/ $name, $value);
//@} /*--------------------------------------------------------------------------------------------*/
//@{ /*--------------------------------- GET ------------------------------------------------------*/
/**
* Pick a value out of the table by name, cast to the appropriate data type.
* @param string $name
* @param null|int $default
* @return int
*/ */
//@{
public function get_int(/*string*/ $name, $default=null); public function get_int(/*string*/ $name, $default=null);
/**
* Pick a value out of the table by name, cast to the appropriate data type.
* @param string $name
* @param null|string $default
* @return string
*/
public function get_string(/*string*/ $name, $default=null); public function get_string(/*string*/ $name, $default=null);
/**
* Pick a value out of the table by name, cast to the appropriate data type.
* @param string $name
* @param null|bool|string $default
* @return bool
*/
public function get_bool(/*string*/ $name, $default=null); public function get_bool(/*string*/ $name, $default=null);
/**
* Pick a value out of the table by name, cast to the appropriate data type.
* @param string $name
* @param array|null $default
* @return array
*/
public function get_array(/*string*/ $name, $default=array()); public function get_array(/*string*/ $name, $default=array());
//@} //@} /*--------------------------------------------------------------------------------------------*/
} }
/** /**
* Class BaseConfig
*
* Common methods for manipulating the list, loading and saving is * Common methods for manipulating the list, loading and saving is
* left to the concrete implementation * left to the concrete implementation
*/ */
abstract class BaseConfig implements Config { abstract class BaseConfig implements Config {
var $values = array(); var $values = array();
/**
* @param string $name
* @param int|null $value
* @return void
*/
public function set_int(/*string*/ $name, $value) { public function set_int(/*string*/ $name, $value) {
$this->values[$name] = parse_shorthand_int($value); $this->values[$name] = parse_shorthand_int($value);
$this->save($name); $this->save($name);
} }
/**
* @param string $name
* @param null|string $value
* @return void
*/
public function set_string(/*string*/ $name, $value) { public function set_string(/*string*/ $name, $value) {
$this->values[$name] = $value; $this->values[$name] = $value;
$this->save($name); $this->save($name);
} }
/**
* @param string $name
* @param bool|null|string $value
* @return void
*/
public function set_bool(/*string*/ $name, $value) { public function set_bool(/*string*/ $name, $value) {
$this->values[$name] = (($value == 'on' || $value === true) ? 'Y' : 'N'); $this->values[$name] = (($value == 'on' || $value === true) ? 'Y' : 'N');
$this->save($name); $this->save($name);
} }
/**
* @param string $name
* @param array $value
* @return void
*/
public function set_array(/*string*/ $name, $value) { public function set_array(/*string*/ $name, $value) {
assert(isset($value) && is_array($value)); assert(isset($value) && is_array($value));
$this->values[$name] = implode(",", $value); $this->values[$name] = implode(",", $value);
$this->save($name); $this->save($name);
} }
/**
* @param string $name
* @param int $value
* @return void
*/
public function set_default_int(/*string*/ $name, $value) { public function set_default_int(/*string*/ $name, $value) {
if(is_null($this->get($name))) { if(is_null($this->get($name))) {
$this->values[$name] = parse_shorthand_int($value); $this->values[$name] = parse_shorthand_int($value);
} }
} }
/**
* @param string $name
* @param null|string $value
* @return void
*/
public function set_default_string(/*string*/ $name, $value) { public function set_default_string(/*string*/ $name, $value) {
if(is_null($this->get($name))) { if(is_null($this->get($name))) {
$this->values[$name] = $value; $this->values[$name] = $value;
} }
} }
/**
* @param string $name
* @param bool|null|string $value
* @return void
*/
public function set_default_bool(/*string*/ $name, $value) { public function set_default_bool(/*string*/ $name, $value) {
if(is_null($this->get($name))) { if(is_null($this->get($name))) {
$this->values[$name] = (($value == 'on' || $value === true) ? 'Y' : 'N'); $this->values[$name] = (($value == 'on' || $value === true) ? 'Y' : 'N');
} }
} }
/**
* @param string $name
* @param array $value
* @return void
*/
public function set_default_array(/*string*/ $name, $value) { public function set_default_array(/*string*/ $name, $value) {
assert(isset($value) && is_array($value)); assert(isset($value) && is_array($value));
if(is_null($this->get($name))) { if(is_null($this->get($name))) {
@ -96,19 +239,47 @@ abstract class BaseConfig implements Config {
} }
} }
/**
* @param string $name
* @param null|int $default
* @return int
*/
public function get_int(/*string*/ $name, $default=null) { public function get_int(/*string*/ $name, $default=null) {
return (int)($this->get($name, $default)); return (int)($this->get($name, $default));
} }
/**
* @param string $name
* @param null|string $default
* @return null|string
*/
public function get_string(/*string*/ $name, $default=null) { public function get_string(/*string*/ $name, $default=null) {
return $this->get($name, $default); return $this->get($name, $default);
} }
/**
* @param string $name
* @param null|bool|string $default
* @return bool
*/
public function get_bool(/*string*/ $name, $default=null) { public function get_bool(/*string*/ $name, $default=null) {
return bool_escape($this->get($name, $default)); return bool_escape($this->get($name, $default));
} }
/**
* @param string $name
* @param array $default
* @return array
*/
public function get_array(/*string*/ $name, $default=array()) { public function get_array(/*string*/ $name, $default=array()) {
return explode(",", $this->get($name, "")); return explode(",", $this->get($name, ""));
} }
/**
* @param string $name
* @param null|mixed $default
* @return null|mixed
*/
private function get(/*string*/ $name, $default=null) { private function get(/*string*/ $name, $default=null) {
if(isset($this->values[$name])) { if(isset($this->values[$name])) {
return $this->values[$name]; return $this->values[$name];
@ -121,13 +292,19 @@ abstract class BaseConfig implements Config {
/** /**
* For testing, mostly * Class HardcodeConfig
*
* For testing, mostly.
*/ */
class HardcodeConfig extends BaseConfig { class HardcodeConfig extends BaseConfig {
public function __construct($dict) { public function __construct($dict) {
$this->values = $dict; $this->values = $dict;
} }
/**
* @param null|string $name
* @return mixed|void
*/
public function save(/*string*/ $name=null) { public function save(/*string*/ $name=null) {
// static config is static // static config is static
} }
@ -135,6 +312,8 @@ class HardcodeConfig extends BaseConfig {
/** /**
* Class StaticConfig
*
* Loads the config list from a PHP file; the file should be in the format: * Loads the config list from a PHP file; the file should be in the format:
* *
* <?php * <?php
@ -143,6 +322,10 @@ class HardcodeConfig extends BaseConfig {
* ?> * ?>
*/ */
class StaticConfig extends BaseConfig { class StaticConfig extends BaseConfig {
/**
* @param string $filename
* @throws Exception
*/
public function __construct($filename) { public function __construct($filename) {
if(file_exists($filename)) { if(file_exists($filename)) {
require_once $filename; require_once $filename;
@ -158,6 +341,10 @@ class StaticConfig extends BaseConfig {
} }
} }
/**
* @param null|string $name
* @return mixed|void
*/
public function save(/*string*/ $name=null) { public function save(/*string*/ $name=null) {
// static config is static // static config is static
} }
@ -165,6 +352,8 @@ class StaticConfig extends BaseConfig {
/** /**
* Class DatabaseConfig
*
* Loads the config list from a table in a given database, the table should * Loads the config list from a table in a given database, the table should
* be called config and have the schema: * be called config and have the schema:
* *
@ -176,10 +365,13 @@ class StaticConfig extends BaseConfig {
* \endcode * \endcode
*/ */
class DatabaseConfig extends BaseConfig { class DatabaseConfig extends BaseConfig {
/** @var \Database|null */
var $database = null; var $database = null;
/* /**
* Load the config table from a database * Load the config table from a database.
*
* @param Database $database
*/ */
public function __construct(Database $database) { public function __construct(Database $database) {
$this->database = $database; $this->database = $database;
@ -197,8 +389,11 @@ class DatabaseConfig extends BaseConfig {
} }
} }
/* /**
* Save the current values as the new config table * Save the current values as the new config table.
*
* @param null|string $name
* @return mixed|void
*/ */
public function save(/*string*/ $name=null) { public function save(/*string*/ $name=null) {
if(is_null($name)) { if(is_null($name)) {
@ -217,7 +412,13 @@ class DatabaseConfig extends BaseConfig {
} }
} }
/**
* Class MockConfig
*/
class MockConfig extends HardcodeConfig { class MockConfig extends HardcodeConfig {
/**
* @param array $config
*/
public function __construct($config=array()) { public function __construct($config=array()) {
$config["db_version"] = "999"; $config["db_version"] = "999";
$config["anon_id"] = "0"; $config["anon_id"] = "0";

View File

@ -2,41 +2,70 @@
/** @privatesection */ /** @privatesection */
// Querylet {{{ // Querylet {{{
class Querylet { class Querylet {
var $sql; /** @var string */
var $variables; public $sql;
/** @var array */
public $variables;
/**
* @param string $sql
* @param array $variables
*/
public function __construct($sql, $variables=array()) { public function __construct($sql, $variables=array()) {
$this->sql = $sql; $this->sql = $sql;
$this->variables = $variables; $this->variables = $variables;
} }
/**
* @param \Querylet $querylet
*/
public function append($querylet) { public function append($querylet) {
assert(!is_null($querylet)); assert(!is_null($querylet));
$this->sql .= $querylet->sql; $this->sql .= $querylet->sql;
$this->variables = array_merge($this->variables, $querylet->variables); $this->variables = array_merge($this->variables, $querylet->variables);
} }
/**
* @param string $sql
*/
public function append_sql($sql) { public function append_sql($sql) {
$this->sql .= $sql; $this->sql .= $sql;
} }
/**
* @param mixed $var
*/
public function add_variable($var) { public function add_variable($var) {
$this->variables[] = $var; $this->variables[] = $var;
} }
} }
class TagQuerylet {
var $tag;
var $positive;
class TagQuerylet {
/** @var string */
public $tag;
/** @var bool */
public $positive;
/**
* @param string $tag
* @param bool $positive
*/
public function __construct($tag, $positive) { public function __construct($tag, $positive) {
$this->tag = $tag; $this->tag = $tag;
$this->positive = $positive; $this->positive = $positive;
} }
} }
class ImgQuerylet {
var $qlet;
var $positive;
class ImgQuerylet {
/** @var \Querylet */
public $qlet;
/** @var bool */
public $positive;
/**
* @param \Querylet $qlet
* @param bool $positive
*/
public function __construct($qlet, $positive) { public function __construct($qlet, $positive) {
$this->qlet = $qlet; $this->qlet = $qlet;
$this->positive = $positive; $this->positive = $positive;
@ -45,25 +74,46 @@ class ImgQuerylet {
// }}} // }}}
// {{{ db engines // {{{ db engines
class DBEngine { class DBEngine {
/** @var null|string */
public $name = null; public $name = null;
/**
* @param \PDO $db
*/
public function init($db) {} public function init($db) {}
/**
* @param string $scoreql
* @return string
*/
public function scoreql_to_sql($scoreql) { public function scoreql_to_sql($scoreql) {
return $scoreql; return $scoreql;
} }
/**
* @param string $name
* @param string $data
* @return string
*/
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
return 'CREATE TABLE '.$name.' ('.$data.')'; return 'CREATE TABLE '.$name.' ('.$data.')';
} }
} }
class MySQL extends DBEngine { class MySQL extends DBEngine {
/** @var string */
public $name = "mysql"; public $name = "mysql";
/**
* @param \PDO $db
*/
public function init($db) { public function init($db) {
$db->exec("SET NAMES utf8;"); $db->exec("SET NAMES utf8;");
} }
/**
* @param string $data
* @return string
*/
public function scoreql_to_sql($data) { public function scoreql_to_sql($data) {
$data = str_replace("SCORE_AIPK", "INTEGER PRIMARY KEY auto_increment", $data); $data = str_replace("SCORE_AIPK", "INTEGER PRIMARY KEY auto_increment", $data);
$data = str_replace("SCORE_INET", "VARCHAR(45)", $data); $data = str_replace("SCORE_INET", "VARCHAR(45)", $data);
@ -77,6 +127,11 @@ class MySQL extends DBEngine {
return $data; return $data;
} }
/**
* @param string $name
* @param string $data
* @return string
*/
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data); $data = $this->scoreql_to_sql($data);
$ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'"; $ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'";
@ -84,12 +139,20 @@ class MySQL extends DBEngine {
} }
} }
class PostgreSQL extends DBEngine { class PostgreSQL extends DBEngine {
/** @var string */
public $name = "pgsql"; public $name = "pgsql";
/**
* @param \PDO $db
*/
public function init($db) { public function init($db) {
$db->exec("SET application_name TO 'shimmie [{$_SERVER['REMOTE_ADDR']}]';"); $db->exec("SET application_name TO 'shimmie [{$_SERVER['REMOTE_ADDR']}]';");
} }
/**
* @param string $data
* @return string
*/
public function scoreql_to_sql($data) { public function scoreql_to_sql($data) {
$data = str_replace("SCORE_AIPK", "SERIAL PRIMARY KEY", $data); $data = str_replace("SCORE_AIPK", "SERIAL PRIMARY KEY", $data);
$data = str_replace("SCORE_INET", "INET", $data); $data = str_replace("SCORE_INET", "INET", $data);
@ -103,6 +166,11 @@ class PostgreSQL extends DBEngine {
return $data; return $data;
} }
/**
* @param string $name
* @param string $data
* @return string
*/
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data); $data = $this->scoreql_to_sql($data);
return 'CREATE TABLE '.$name.' ('.$data.')'; return 'CREATE TABLE '.$name.' ('.$data.')';
@ -123,8 +191,12 @@ function _concat($a, $b) { return $a . $b; }
function _lower($a) { return strtolower($a); } function _lower($a) { return strtolower($a); }
class SQLite extends DBEngine { class SQLite extends DBEngine {
/** @var string */
public $name = "sqlite"; public $name = "sqlite";
/**
* @param \PDO $db
*/
public function init($db) { public function init($db) {
ini_set('sqlite.assoc_case', 0); ini_set('sqlite.assoc_case', 0);
$db->exec("PRAGMA foreign_keys = ON;"); $db->exec("PRAGMA foreign_keys = ON;");
@ -138,6 +210,10 @@ class SQLite extends DBEngine {
$db->sqliteCreateFunction('lower', '_lower', 1); $db->sqliteCreateFunction('lower', '_lower', 1);
} }
/**
* @param string $data
* @return string
*/
public function scoreql_to_sql($data) { public function scoreql_to_sql($data) {
$data = str_replace("SCORE_AIPK", "INTEGER PRIMARY KEY", $data); $data = str_replace("SCORE_AIPK", "INTEGER PRIMARY KEY", $data);
$data = str_replace("SCORE_INET", "VARCHAR(45)", $data); $data = str_replace("SCORE_INET", "VARCHAR(45)", $data);
@ -150,6 +226,11 @@ class SQLite extends DBEngine {
return $data; return $data;
} }
/**
* @param string $name
* @param string $data
* @return string
*/
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data); $data = $this->scoreql_to_sql($data);
$cols = array(); $cols = array();
@ -187,8 +268,16 @@ class NoCache implements CacheEngine {
public function get_misses() {return 0;} public function get_misses() {return 0;}
} }
class MemcacheCache implements CacheEngine { class MemcacheCache implements CacheEngine {
var $memcache=null, $hits=0, $misses=0; /** @var \Memcache|null */
public $memcache=null;
/** @var int */
private $hits=0;
/** @var int */
private $misses=0;
/**
* @param string $args
*/
public function __construct($args) { public function __construct($args) {
$hp = explode(":", $args); $hp = explode(":", $args);
if(class_exists("Memcache")) { if(class_exists("Memcache")) {
@ -197,6 +286,10 @@ class MemcacheCache implements CacheEngine {
} }
} }
/**
* @param string $key
* @return array|bool|string
*/
public function get($key) { public function get($key) {
assert(!is_null($key)); assert(!is_null($key));
if((DEBUG_CACHE === true) || (is_null(DEBUG_CACHE) && @$_GET['DEBUG_CACHE'])) { if((DEBUG_CACHE === true) || (is_null(DEBUG_CACHE) && @$_GET['DEBUG_CACHE'])) {
@ -213,19 +306,35 @@ class MemcacheCache implements CacheEngine {
} }
} }
/**
* @param string $key
* @param mixed $val
* @param int $time
*/
public function set($key, $val, $time=0) { public function set($key, $val, $time=0) {
assert(!is_null($key)); assert(!is_null($key));
$this->memcache->set($key, $val, false, $time); $this->memcache->set($key, $val, false, $time);
} }
/**
* @param string $key
*/
public function delete($key) { public function delete($key) {
assert(!is_null($key)); assert(!is_null($key));
$this->memcache->delete($key); $this->memcache->delete($key);
} }
/**
* @return int
*/
public function get_hits() {return $this->hits;} public function get_hits() {return $this->hits;}
/**
* @return int
*/
public function get_misses() {return $this->misses;} public function get_misses() {return $this->misses;}
} }
class APCCache implements CacheEngine { class APCCache implements CacheEngine {
var $hits=0, $misses=0; var $hits=0, $misses=0;
@ -267,25 +376,28 @@ class APCCache implements CacheEngine {
*/ */
class Database { class Database {
/** /**
* The PDO database connection object, for anyone who wants direct access * The PDO database connection object, for anyone who wants direct access.
* @var null|PDO
*/ */
private $db = null; private $db = null;
/** /**
* Meta info about the database engine * Meta info about the database engine.
* @var DBEngine * @var DBEngine|null
*/ */
private $engine = null; private $engine = null;
/** /**
* The currently active cache engine * The currently active cache engine.
* @var CacheEngine * @var CacheEngine|null
*/ */
public $cache = null; public $cache = null;
/** /**
* A boolean flag to track if we already have an active transaction. * A boolean flag to track if we already have an active transaction.
* (ie: True if beginTransaction() already called) * (ie: True if beginTransaction() already called)
*
* @var bool
*/ */
public $transaction = false; public $transaction = false;
@ -364,6 +476,10 @@ class Database {
} }
} }
/**
* @return bool
* @throws SCoreException
*/
public function commit() { public function commit() {
if(!is_null($this->db)) { if(!is_null($this->db)) {
if ($this->transaction === true) { if ($this->transaction === true) {
@ -376,6 +492,10 @@ class Database {
} }
} }
/**
* @return bool
* @throws SCoreException
*/
public function rollback() { public function rollback() {
if(!is_null($this->db)) { if(!is_null($this->db)) {
if ($this->transaction === true) { if ($this->transaction === true) {
@ -388,23 +508,39 @@ class Database {
} }
} }
/**
* @param string $input
* @return string
*/
public function escape($input) { public function escape($input) {
if(is_null($this->db)) $this->connect_db(); if(is_null($this->db)) $this->connect_db();
return $this->db->Quote($input); return $this->db->Quote($input);
} }
/**
* @param string $input
* @return string
*/
public function scoreql_to_sql($input) { public function scoreql_to_sql($input) {
if(is_null($this->engine)) $this->connect_engine(); if(is_null($this->engine)) $this->connect_engine();
return $this->engine->scoreql_to_sql($input); return $this->engine->scoreql_to_sql($input);
} }
/**
* @return null|string
*/
public function get_driver_name() { public function get_driver_name() {
if(is_null($this->engine)) $this->connect_engine(); if(is_null($this->engine)) $this->connect_engine();
return $this->engine->name; return $this->engine->name;
} }
/** /**
* Execute an SQL query and return an PDO resultset * Execute an SQL query and return an PDO result-set.
*
* @param string $query
* @param array $args
* @return PDOStatement
* @throws SCoreException
*/ */
public function execute($query, $args=array()) { public function execute($query, $args=array()) {
try { try {
@ -433,14 +569,22 @@ class Database {
} }
/** /**
* Execute an SQL query and return a 2D array * Execute an SQL query and return a 2D array.
*
* @param string $query
* @param array $args
* @return array
*/ */
public function get_all($query, $args=array()) { public function get_all($query, $args=array()) {
return $this->execute($query, $args)->fetchAll(); return $this->execute($query, $args)->fetchAll();
} }
/** /**
* Execute an SQL query and return a single row * Execute an SQL query and return a single row.
*
* @param string $query
* @param array $args
* @return mixed|null
*/ */
public function get_row($query, $args=array()) { public function get_row($query, $args=array()) {
$row = $this->execute($query, $args)->fetch(); $row = $this->execute($query, $args)->fetch();
@ -448,7 +592,11 @@ class Database {
} }
/** /**
* Execute an SQL query and return the first column of each row * Execute an SQL query and return the first column of each row.
*
* @param string $query
* @param array $args
* @return array
*/ */
public function get_col($query, $args=array()) { public function get_col($query, $args=array()) {
$stmt = $this->execute($query, $args); $stmt = $this->execute($query, $args);
@ -460,7 +608,11 @@ class Database {
} }
/** /**
* Execute an SQL query and return the the first row => the second rown * Execute an SQL query and return the the first row => the second rown.
*
* @param string $query
* @param array $args
* @return array
*/ */
public function get_pairs($query, $args=array()) { public function get_pairs($query, $args=array()) {
$stmt = $this->execute($query, $args); $stmt = $this->execute($query, $args);
@ -472,7 +624,11 @@ class Database {
} }
/** /**
* Execute an SQL query and return a single value * Execute an SQL query and return a single value.
*
* @param string $query
* @param array $args
* @return mixed
*/ */
public function get_one($query, $args=array()) { public function get_one($query, $args=array()) {
$row = $this->execute($query, $args)->fetch(); $row = $this->execute($query, $args)->fetch();
@ -480,7 +636,10 @@ class Database {
} }
/** /**
* get the ID of the last inserted row * Get the ID of the last inserted row.
*
* @param string|null $seq
* @return string
*/ */
public function get_last_insert_id($seq) { public function get_last_insert_id($seq) {
if($this->engine->name == "pgsql") { if($this->engine->name == "pgsql") {
@ -492,15 +651,20 @@ class Database {
} }
/** /**
* Create a table from pseudo-SQL * Create a table from pseudo-SQL.
*
* @param string $name
* @param string $data
*/ */
public function create_table($name, $data) { public function create_table($name, $data) {
if(is_null($this->engine)) $this->connect_engine(); if(is_null($this->engine)) { $this->connect_engine(); }
$this->execute($this->engine->create_table_sql($name, $data)); $this->execute($this->engine->create_table_sql($name, $data));
} }
/** /**
* Returns the number of tables present in the current database. * Returns the number of tables present in the current database.
*
* @return int|null
*/ */
public function count_tables() { public function count_tables() {
if(is_null($this->db) || is_null($this->engine)) $this->connect_db(); if(is_null($this->db) || is_null($this->engine)) $this->connect_db();
@ -525,14 +689,26 @@ class Database {
} }
class MockDatabase extends Database { class MockDatabase extends Database {
/** @var int */
var $query_id = 0; var $query_id = 0;
/** @var array */
var $responses = array(); var $responses = array();
/** @var \NoCache|null */
var $cache = null; var $cache = null;
/**
* @param array $responses
*/
public function __construct($responses = array()) { public function __construct($responses = array()) {
$this->cache = new NoCache(); $this->cache = new NoCache();
$this->responses = $responses; $this->responses = $responses;
} }
/**
* @param string $query
* @param array $params
* @return PDOStatement
*/
public function execute($query, $params=array()) { public function execute($query, $params=array()) {
log_debug("mock-database", log_debug("mock-database",
"QUERY: " . $query . "QUERY: " . $query .
@ -542,13 +718,51 @@ class MockDatabase extends Database {
return $this->responses[$this->query_id++]; return $this->responses[$this->query_id++];
} }
/**
* @param string $query
* @param array $args
* @return array|PDOStatement
*/
public function get_all($query, $args=array()) {return $this->execute($query, $args);} public function get_all($query, $args=array()) {return $this->execute($query, $args);}
/**
* @param string $query
* @param array $args
* @return mixed|null|PDOStatement
*/
public function get_row($query, $args=array()) {return $this->execute($query, $args);} public function get_row($query, $args=array()) {return $this->execute($query, $args);}
/**
* @param string $query
* @param array $args
* @return array|PDOStatement
*/
public function get_col($query, $args=array()) {return $this->execute($query, $args);} public function get_col($query, $args=array()) {return $this->execute($query, $args);}
/**
* @param string $query
* @param array $args
* @return array|PDOStatement
*/
public function get_pairs($query, $args=array()) {return $this->execute($query, $args);} public function get_pairs($query, $args=array()) {return $this->execute($query, $args);}
/**
* @param string $query
* @param array $args
* @return mixed|PDOStatement
*/
public function get_one($query, $args=array()) {return $this->execute($query, $args);} public function get_one($query, $args=array()) {return $this->execute($query, $args);}
/**
* @param null|string $seq
* @return int|string
*/
public function get_last_insert_id($seq) {return $this->query_id;} public function get_last_insert_id($seq) {return $this->query_id;}
/**
* @param string $sql
* @return string
*/
public function scoreql_to_sql($sql) {return $sql;} public function scoreql_to_sql($sql) {return $sql;}
public function create_table($name, $def) {} public function create_table($name, $def) {}
public function connect_engine() {} public function connect_engine() {}

View File

@ -1,21 +1,40 @@
<?php <?php
/**
* Class Email
*
* A generic email.
*/
class Email { class Email {
/** /** @var string */
* A generic email.
*/
public $to; public $to;
/** @var string */
public $subject; public $subject;
/** @var string */
public $header; public $header;
/** @var null|string */
public $style; public $style;
/** @var null|string */
public $header_img; public $header_img;
/** @var null|string */
public $sitename; public $sitename;
/** @var null|string */
public $sitedomain; public $sitedomain;
/** @var null|string */
public $siteemail; public $siteemail;
/** @var string */
public $date; public $date;
/** @var string */
public $body; public $body;
/** @var null|string */
public $footer; public $footer;
/**
* @param string $to
* @param string $subject
* @param string $header
* @param string $body
*/
public function __construct($to, $subject, $header, $body) { public function __construct($to, $subject, $header, $body) {
global $config; global $config;
$this->to = $to; $this->to = $to;

View File

@ -26,8 +26,19 @@ class InitExtEvent extends Event {}
* $event->get_arg(0) = "42" * $event->get_arg(0) = "42"
*/ */
class PageRequestEvent extends Event { class PageRequestEvent extends Event {
/**
* @var array
*/
public $args; public $args;
/**
* @var int
*/
public $arg_count; public $arg_count;
/**
* @var int
*/
public $part_count; public $part_count;
/** /**
@ -90,7 +101,7 @@ class PageRequestEvent extends Event {
* Get the n th argument of the page request (if it exists.) * Get the n th argument of the page request (if it exists.)
* *
* @param int $n * @param int $n
* @return string|null The argmuent (string) or NULL * @return string|null The argument (string) or NULL
*/ */
public function get_arg(/*int*/ $n) { public function get_arg(/*int*/ $n) {
$offset = $this->part_count + $n; $offset = $this->part_count + $n;
@ -154,9 +165,19 @@ class PageRequestEvent extends Event {
* Sent when index.php is called from the command line * Sent when index.php is called from the command line
*/ */
class CommandEvent extends Event { class CommandEvent extends Event {
/**
* @var string
*/
public $cmd = "help"; public $cmd = "help";
/**
* @var array
*/
public $args = array(); public $args = array();
/**
* @param string[] $args
*/
public function __construct(/*array(string)*/ $args) { public function __construct(/*array(string)*/ $args) {
global $user; global $user;
@ -215,19 +236,28 @@ class CommandEvent extends Event {
class TextFormattingEvent extends Event { class TextFormattingEvent extends Event {
/** /**
* For reference * For reference
*
* @var string
*/ */
var $original; public $original;
/** /**
* with formatting applied * with formatting applied
*
* @var string
*/ */
var $formatted; public $formatted;
/** /**
* with formatting removed * with formatting removed
*
* @var string
*/ */
var $stripped; public $stripped;
/**
* @param string $text
*/
public function __construct(/*string*/ $text) { public function __construct(/*string*/ $text) {
$h_text = html_escape(trim($text)); $h_text = html_escape(trim($text));
$this->original = $h_text; $this->original = $h_text;
@ -244,36 +274,44 @@ class LogEvent extends Event {
/** /**
* a category, normally the extension name * a category, normally the extension name
* *
* @return string * @var string
*/ */
var $section; public $section;
/** /**
* See python... * See python...
* *
* @return int * @var int
*/ */
var $priority = 0; public $priority = 0;
/** /**
* Free text to be logged * Free text to be logged
* *
* @return text * @var string
*/ */
var $message; public $message;
/** /**
* The time that the event was created * The time that the event was created
* *
* @return int * @var int
*/ */
var $time; public $time;
/** /**
* Extra data to be held separate * Extra data to be held separate
*
* @var array
*/ */
var $args; public $args;
/**
* @param string $section
* @param int $priority
* @param string $message
* @param array $args
*/
public function __construct($section, $priority, $message, $args) { public function __construct($section, $priority, $message, $args) {
$this->section = $section; $this->section = $section;
$this->priority = $priority; $this->priority = $priority;

View File

@ -1,11 +1,16 @@
<?php <?php
/** /**
* A base exception to be caught by the upper levels * Class SCoreException
*
* A base exception to be caught by the upper levels.
*/ */
class SCoreException extends Exception {} class SCoreException extends Exception {}
/** /**
* A fairly common, generic exception * Class PermissionDeniedException
*
* A fairly common, generic exception.
*/ */
class PermissionDeniedException extends SCoreException {} class PermissionDeniedException extends SCoreException {}

View File

@ -70,6 +70,8 @@
*/ */
/** /**
* Class Extension
*
* send_event(BlahEvent()) -> onBlah($event) * send_event(BlahEvent()) -> onBlah($event)
* *
* Also loads the theme object into $this->theme if available * Also loads the theme object into $this->theme if available
@ -96,7 +98,11 @@ abstract class Extension {
} }
/** /**
* Find the theme object for a given extension * Find the theme object for a given extension.
*
* @param Extension $class
* @param bool $fatal
* @return bool
*/ */
private function get_theme_object(Extension $class, $fatal=true) { private function get_theme_object(Extension $class, $fatal=true) {
$base = get_class($class); $base = get_class($class);
@ -114,7 +120,9 @@ abstract class Extension {
/** /**
* Override this to change the priority of the extension, * Override this to change the priority of the extension,
* lower numbered ones will recieve events first * lower numbered ones will recieve events first.
*
* @return int
*/ */
public function get_priority() { public function get_priority() {
return 50; return 50;
@ -122,23 +130,43 @@ abstract class Extension {
} }
/** /**
* Several extensions have this in common, make a common API * Class FormatterExtension
*
* Several extensions have this in common, make a common API.
*/ */
abstract class FormatterExtension extends Extension { abstract class FormatterExtension extends Extension {
/**
* @param TextFormattingEvent $event
*/
public function onTextFormatting(TextFormattingEvent $event) { public function onTextFormatting(TextFormattingEvent $event) {
$event->formatted = $this->format($event->formatted); $event->formatted = $this->format($event->formatted);
$event->stripped = $this->strip($event->stripped); $event->stripped = $this->strip($event->stripped);
} }
/**
* @param string $text
* @return string
*/
abstract public function format(/*string*/ $text); abstract public function format(/*string*/ $text);
/**
* @param string $text
* @return string
*/
abstract public function strip(/*string*/ $text); abstract public function strip(/*string*/ $text);
} }
/** /**
* Class DataHandlerExtension
*
* This too is a common class of extension with many methods in common, * This too is a common class of extension with many methods in common,
* so we have a base class to extend from * so we have a base class to extend from.
*/ */
abstract class DataHandlerExtension extends Extension { abstract class DataHandlerExtension extends Extension {
/**
* @param DataUploadEvent $event
* @throws UploadException
*/
public function onDataUpload(DataUploadEvent $event) { public function onDataUpload(DataUploadEvent $event) {
$supported_ext = $this->supported_ext($event->type); $supported_ext = $this->supported_ext($event->type);
$check_contents = $this->check_contents($event->tmpname); $check_contents = $this->check_contents($event->tmpname);
@ -202,6 +230,9 @@ abstract class DataHandlerExtension extends Extension {
} }
} }
/**
* @param ThumbnailGenerationEvent $event
*/
public function onThumbnailGeneration(ThumbnailGenerationEvent $event) { public function onThumbnailGeneration(ThumbnailGenerationEvent $event) {
if($this->supported_ext($event->type)) { if($this->supported_ext($event->type)) {
if (method_exists($this, 'create_thumb_force') && $event->force == true) { if (method_exists($this, 'create_thumb_force') && $event->force == true) {
@ -213,6 +244,9 @@ abstract class DataHandlerExtension extends Extension {
} }
} }
/**
* @param DisplayingImageEvent $event
*/
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
global $page; global $page;
if($this->supported_ext($event->image->ext)) { if($this->supported_ext($event->image->ext)) {
@ -229,9 +263,29 @@ abstract class DataHandlerExtension extends Extension {
protected function setup() {} protected function setup() {}
*/ */
/**
* @param string $ext
* @return bool
*/
abstract protected function supported_ext($ext); abstract protected function supported_ext($ext);
/**
* @param $tmpname
* @return bool
*/
abstract protected function check_contents($tmpname); abstract protected function check_contents($tmpname);
/**
* @param string $filename
* @param array $metadata
* @return Image|null
*/
abstract protected function create_image_from_data($filename, $metadata); abstract protected function create_image_from_data($filename, $metadata);
/**
* @param string $hash
* @return bool
*/
abstract protected function create_thumb($hash); abstract protected function create_thumb($hash);
} }

View File

@ -31,15 +31,38 @@ $order_sql = null; // this feels ugly
require_once "lib/flexihash.php"; require_once "lib/flexihash.php";
/** /**
* An object representing an entry in the images table. As of 2.2, this no * Class Image
* longer necessarily represents an image per se, but could be a video, *
* sound file, or any other supported upload type. * An object representing an entry in the images table.
*
* As of 2.2, this no longer necessarily represents an
* image per se, but could be a video, sound file, or any
* other supported upload type.
*/ */
class Image { class Image {
/** @var null|int */
public $id = null; public $id = null;
public $height, $width;
public $hash, $filesize; /** @var int */
public $filename, $ext; public $height;
/** @var int */
public $width;
/** @var string */
public $hash;
public $filesize;
/** @var string */
public $filename;
/** @var string */
public $ext;
/** @var string[]|null */
public $tag_array;
public $owner_id, $owner_ip; public $owner_id, $owner_ip;
public $posted, $posted_timestamp; public $posted, $posted_timestamp;
public $source; public $source;
@ -47,7 +70,9 @@ class Image {
/** /**
* One will very rarely construct an image directly, more common * One will very rarely construct an image directly, more common
* would be to use Image::by_id, Image::by_hash, etc * would be to use Image::by_id, Image::by_hash, etc.
*
* @param null|mixed $row
*/ */
public function __construct($row=null) { public function __construct($row=null) {
if(!is_null($row)) { if(!is_null($row)) {
@ -66,7 +91,7 @@ class Image {
} }
/** /**
* Find an image by ID * Find an image by ID.
* *
* @param int $id * @param int $id
* @return Image * @return Image
@ -79,7 +104,7 @@ class Image {
} }
/** /**
* Find an image by hash * Find an image by hash.
* *
* @param string $hash * @param string $hash
* @return Image * @return Image
@ -92,9 +117,9 @@ class Image {
} }
/** /**
* Pick a random image out of a set * Pick a random image out of a set.
* *
* @param array $tags * @param string[] $tags
* @return Image * @return Image
*/ */
public static function by_random($tags=array()) { public static function by_random($tags=array()) {
@ -112,9 +137,9 @@ class Image {
* *
* @param int $start * @param int $start
* @param int $limit * @param int $limit
* @param array $tags * @param string[] $tags
* @throws SCoreException * @throws SCoreException
* @return Array * @return Image[]
*/ */
public static function find_images(/*int*/ $start, /*int*/ $limit, $tags=array()) { public static function find_images(/*int*/ $start, /*int*/ $limit, $tags=array()) {
assert(is_numeric($start)); assert(is_numeric($start));
@ -153,7 +178,7 @@ class Image {
/** /**
* Count the number of image results for a given search * Count the number of image results for a given search
* *
* @param array $tags * @param string[] $tags
* @return mixed * @return mixed
*/ */
public static function count_images($tags=array()) { public static function count_images($tags=array()) {
@ -185,7 +210,7 @@ class Image {
/** /**
* Count the number of pages for a given search * Count the number of pages for a given search
* *
* @param array $tags * @param string[] $tags
* @return float * @return float
*/ */
public static function count_pages($tags=array()) { public static function count_pages($tags=array()) {
@ -205,7 +230,7 @@ class Image {
* Rather than simply $this_id + 1, one must take into account * Rather than simply $this_id + 1, one must take into account
* deleted images and search queries * deleted images and search queries
* *
* @param array $tags * @param string[] $tags
* @param bool $next * @param bool $next
* @return Image * @return Image
*/ */
@ -239,7 +264,7 @@ class Image {
/** /**
* The reverse of get_next * The reverse of get_next
* *
* @param array $tags * @param string[] $tags
* @return Image * @return Image
*/ */
public function get_prev($tags=array()) { public function get_prev($tags=array()) {
@ -269,7 +294,9 @@ class Image {
} }
/** /**
* Get this image's tags as an array * Get this image's tags as an array.
*
* @return string[]
*/ */
public function get_tag_array() { public function get_tag_array() {
global $database; global $database;
@ -349,7 +376,7 @@ class Image {
/** /**
* Get the tooltip for this image, formatted according to the * Get the tooltip for this image, formatted according to the
* configured template * configured template.
* *
* @return string * @return string
*/ */
@ -378,7 +405,7 @@ class Image {
} }
/** /**
* Figure out where the full size image is on disk * Figure out where the full size image is on disk.
* *
* @return string * @return string
*/ */
@ -387,7 +414,7 @@ class Image {
} }
/** /**
* Figure out where the thumbnail is on disk * Figure out where the thumbnail is on disk.
* *
* @return string * @return string
*/ */
@ -396,7 +423,7 @@ class Image {
} }
/** /**
* Get the original filename * Get the original filename.
* *
* @return string * @return string
*/ */
@ -405,7 +432,7 @@ class Image {
} }
/** /**
* Get the image's mime type * Get the image's mime type.
* *
* @return string * @return string
*/ */
@ -480,7 +507,9 @@ class Image {
} }
/** /**
* Set the tags for this image * Set the tags for this image.
*
* @param string[] $tags
*/ */
public function set_tags($tags) { public function set_tags($tags) {
global $database; global $database;
@ -564,7 +593,7 @@ class Image {
/** /**
* Someone please explain this * Someone please explain this
* *
* @param $tmpl * @param string $tmpl
* @param string $_escape * @param string $_escape
* @return string * @return string
*/ */
@ -637,6 +666,10 @@ class Image {
return $tmpl; return $tmpl;
} }
/**
* @param string[] $terms
* @return \Querylet
*/
private static function build_search_querylet($terms) { private static function build_search_querylet($terms) {
assert(is_array($terms)); assert(is_array($terms));
global $database; global $database;
@ -666,6 +699,9 @@ class Image {
* 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.
*
* @param string[] $terms
* @return \Querylet
*/ */
private static function build_accurate_search_querylet($terms) { private static function build_accurate_search_querylet($terms) {
global $database; global $database;
@ -983,9 +1019,12 @@ class Image {
} }
/** /**
* Class Tag
*
* A class for organising the tag related functions. * A class for organising the tag related functions.
* *
* All the methods are static, one should never actually use a tag object. * All the methods are static, one should never actually use a tag object.
*
*/ */
class Tag { class Tag {
/** /**
@ -1003,7 +1042,11 @@ class Tag {
} }
/** /**
* Turn any string or array into a valid tag array * Turn any string or array into a valid tag array.
*
* @param string|string[] $tags
* @param bool $tagme
* @return array
*/ */
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));
@ -1033,7 +1076,7 @@ class Tag {
} }
/** /**
* @param $tags * @param string|string[] $tags
* @return string * @return string
*/ */
public static function implode($tags) { public static function implode($tags) {
@ -1073,6 +1116,10 @@ class Tag {
return $negative ? "-$newtag" : $newtag; return $negative ? "-$newtag" : $newtag;
} }
/**
* @param string $tag
* @return array
*/
public static function resolve_wildcard($tag) { public static function resolve_wildcard($tag) {
// if there is no wildcard, return the tag // if there is no wildcard, return the tag
if(strpos($tag, "*") === false) { if(strpos($tag, "*") === false) {
@ -1102,8 +1149,8 @@ class Tag {
/** /**
* This function takes a list (array) of tags and changes any tags that have aliases * This function takes a list (array) of tags and changes any tags that have aliases
* *
* @param array $tags Array of tags * @param string[] $tags Array of tags
* @return array of tags * @return array
*/ */
public static function resolve_aliases($tags) { public static function resolve_aliases($tags) {
assert(is_array($tags)); assert(is_array($tags));
@ -1139,7 +1186,11 @@ class Tag {
/** /**
* Move a file from PHP's temporary area into shimmie's image storage * Move a file from PHP's temporary area into shimmie's image storage
* hierarchy, or throw an exception trying * hierarchy, or throw an exception trying.
*
* @param DataUploadEvent $event
* @return bool
* @throws UploadException
*/ */
function move_upload_to_archive(DataUploadEvent $event) { function move_upload_to_archive(DataUploadEvent $event) {
$target = warehouse_path("images", $event->hash); $target = warehouse_path("images", $event->hash);

View File

@ -28,28 +28,32 @@
/** /**
* Class Page
*
* A data structure for holding all the bits of data that make up a page. * A data structure for holding all the bits of data that make up a page.
* *
* The various extensions all add whatever they want to this structure, * The various extensions all add whatever they want to this structure,
* then Layout turns it into HTML * then Layout turns it into HTML.
*/ */
class Page { class Page {
/** @name Overall */ /** @name Overall */
//@{ //@{
/** @private */ /** @var string */
var $mode = "page"; public $mode = "page";
/** @private */ /** @var string */
var $type = "text/html; charset=utf-8"; public $type = "text/html; charset=utf-8";
/** /**
* Set what this page should do; "page", "data", or "redirect". * Set what this page should do; "page", "data", or "redirect".
* @param string $mode
*/ */
public function set_mode($mode) { public function set_mode($mode) {
$this->mode = $mode; $this->mode = $mode;
} }
/** /**
* Set the page's MIME type * Set the page's MIME type.
* @param string $type
*/ */
public function set_type($type) { public function set_type($type) {
$this->type = $type; $this->type = $type;
@ -61,20 +65,23 @@ class Page {
/** @name "data" mode */ /** @name "data" mode */
//@{ //@{
/** @private */ /** @var string */
var $data = ""; private $data = "";
/** @private */
var $filename = null; /** @var string */
private $filename = null;
/** /**
* Set the raw data to be sent * Set the raw data to be sent.
* @param string $data
*/ */
public function set_data($data) { public function set_data($data) {
$this->data = $data; $this->data = $data;
} }
/** /**
* Set the recommended download filename * Set the recommended download filename.
* @param string $filename
*/ */
public function set_filename($filename) { public function set_filename($filename) {
$this->filename = $filename; $this->filename = $filename;
@ -86,12 +93,13 @@ class Page {
/** @name "redirect" mode */ /** @name "redirect" mode */
//@{ //@{
/** @private */ /** @var string */
var $redirect = ""; private $redirect = "";
/** /**
* Set the URL to redirect to (remember to use make_link() if linking * Set the URL to redirect to (remember to use make_link() if linking
* to a page in the same site) * to a page in the same site).
* @param string $redirect
*/ */
public function set_redirect($redirect) { public function set_redirect($redirect) {
$this->redirect = $redirect; $this->redirect = $redirect;
@ -103,39 +111,56 @@ class Page {
/** @name "page" mode */ /** @name "page" mode */
//@{ //@{
/** @privatesection */ /** @var string */
var $title = ""; public $title = "";
var $heading = "";
var $subheading = ""; /** @var string */
var $quicknav = ""; public $heading = "";
var $html_headers = array();
var $http_headers = array(); /** @var string */
var $blocks = array(); public $subheading = "";
/** @publicsection */
/** @var string */
public $quicknav = "";
/** @var string[] */
public $html_headers = array();
/** @var string[] */
public $http_headers = array();
/** @var Block[] */
public $blocks = array();
/** /**
* Set the window title * Set the window title.
* @param string $title
*/ */
public function set_title($title) { public function set_title($title) {
$this->title = $title; $this->title = $title;
} }
/** /**
* Set the main heading * Set the main heading.
* @param string $heading
*/ */
public function set_heading($heading) { public function set_heading($heading) {
$this->heading = $heading; $this->heading = $heading;
} }
/** /**
* Set the sub heading * Set the sub heading.
* @param string $subheading
*/ */
public function set_subheading($subheading) { public function set_subheading($subheading) {
$this->subheading = $subheading; $this->subheading = $subheading;
} }
/** /**
* Add a line to the HTML head section * Add a line to the HTML head section.
* @param string $line
* @param int $position
*/ */
public function add_html_header($line, $position=50) { public function add_html_header($line, $position=50) {
while(isset($this->html_headers[$position])) $position++; while(isset($this->html_headers[$position])) $position++;
@ -144,6 +169,8 @@ class Page {
/** /**
* Add a http header to be sent to the client. * Add a http header to be sent to the client.
* @param string $line
* @param int $position
*/ */
public function add_http_header($line, $position=50) { public function add_http_header($line, $position=50) {
while(isset($this->http_headers[$position])) $position++; while(isset($this->http_headers[$position])) $position++;
@ -152,6 +179,7 @@ class Page {
/** /**
* Get all the HTML headers that are currently set and return as a string. * Get all the HTML headers that are currently set and return as a string.
* @return string
*/ */
public function get_all_html_headers() { public function get_all_html_headers() {
$data = ''; $data = '';
@ -162,14 +190,15 @@ class Page {
} }
/** /**
* Removes all currently set HTML headers. (Be careful..) * Removes all currently set HTML headers (Be careful..).
*/ */
public function delete_all_html_headers() { public function delete_all_html_headers() {
$this->html_headers = array(); $this->html_headers = array();
} }
/** /**
* Add a Block of data * Add a Block of data to the page.
* @param Block $block
*/ */
public function add_block(Block $block) { public function add_block(Block $block) {
$this->blocks[] = $block; $this->blocks[] = $block;
@ -180,7 +209,7 @@ class Page {
// ============================================== // ==============================================
/** /**
* Display the page according to the mode and data given * Display the page according to the mode and data given.
*/ */
public function display() { public function display() {
global $page, $user; global $page, $user;

View File

@ -6,9 +6,11 @@ function _new_user($row) {
/** /**
* Class User
*
* An object representing a row in the "users" table. * An object representing a row in the "users" table.
* *
* The currently logged in user will always be accessible via the global variable $user * The currently logged in user will always be accessible via the global variable $user.
*/ */
class User { class User {
/** @var int */ /** @var int */
@ -22,10 +24,11 @@ class User {
public $join_date; public $join_date;
/** @var string */
public $passhash; public $passhash;
/** @var UserClass */ /** @var UserClass */
var $class; public $class;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Initialisation * * Initialisation *
@ -38,7 +41,9 @@ class User {
/** /**
* One will very rarely construct a user directly, more common * One will very rarely construct a user directly, more common
* would be to use User::by_id, User::by_session, etc * would be to use User::by_id, User::by_session, etc.
*
* @param mixed $row
*/ */
public function __construct($row) { public function __construct($row) {
global $_user_classes; global $_user_classes;
@ -145,7 +150,7 @@ class User {
/** /**
* Test if this user is anonymous (not logged in) * Test if this user is anonymous (not logged in).
* *
* @return bool * @return bool
*/ */
@ -155,7 +160,7 @@ class User {
} }
/** /**
* Test if this user is logged in * Test if this user is logged in.
* *
* @return bool * @return bool
*/ */
@ -165,7 +170,7 @@ class User {
} }
/** /**
* Test if this user is an administrator * Test if this user is an administrator.
* *
* @return bool * @return bool
*/ */
@ -193,6 +198,9 @@ class User {
log_info("core-user", 'Set password for '.$this->name); log_info("core-user", 'Set password for '.$this->name);
} }
/**
* @param string $address
*/
public function set_email(/*string*/ $address) { public function set_email(/*string*/ $address) {
global $database; global $database;
$database->Execute("UPDATE users SET email=:email WHERE id=:id", array("email"=>$address, "id"=>$this->id)); $database->Execute("UPDATE users SET email=:email WHERE id=:id", array("email"=>$address, "id"=>$this->id));
@ -201,7 +209,8 @@ class User {
/** /**
* Get a snippet of HTML which will render the user's avatar, be that * Get a snippet of HTML which will render the user's avatar, be that
* a local file, a remote file, a gravatar, a something else, etc * a local file, a remote file, a gravatar, a something else, etc.
*
* @return String of HTML * @return String of HTML
*/ */
public function get_avatar_html() { public function get_avatar_html() {
@ -231,7 +240,7 @@ class User {
* the form was generated within the session. Salted and re-hashed so that * the form was generated within the session. Salted and re-hashed so that
* reading a web page from the user's cache doesn't give access to the session key * reading a web page from the user's cache doesn't give access to the session key
* *
* @return String containing auth token (MD5sum) * @return string A string containing auth token (MD5sum)
*/ */
public function get_auth_token() { public function get_auth_token() {
global $config; global $config;

View File

@ -1,11 +1,34 @@
<?php <?php
/**
* @global UserClass[] $_user_classes
*/
$_user_classes = array(); $_user_classes = array();
/**
* Class UserClass
*/
class UserClass { class UserClass {
/**
* @var null|string
*/
public $name = null; public $name = null;
/**
* @var \UserClass|null
*/
public $parent = null; public $parent = null;
/**
* @var array
*/
public $abilities = array(); public $abilities = array();
/**
* @param string $name
* @param null|string $parent
* @param array $abilities
*/
public function __construct($name, $parent=null, $abilities=array()) { public function __construct($name, $parent=null, $abilities=array()) {
global $_user_classes; global $_user_classes;

View File

@ -124,6 +124,12 @@ function no_escape($input) {
return $input; return $input;
} }
/**
* @param string $name
* @param array $attrs
* @param array $children
* @return string
*/
function xml_tag($name, $attrs=array(), $children=array()) { function xml_tag($name, $attrs=array(), $children=array()) {
$xml = "<$name "; $xml = "<$name ";
foreach($attrs as $k => $v) { foreach($attrs as $k => $v) {
@ -427,6 +433,10 @@ function make_form($target, $method="POST", $multipart=False, $form_id="", $onsu
return '<form action="'.$target.'" method="'.$method.'" '.$extra.'>'.$auth; return '<form action="'.$target.'" method="'.$method.'" '.$extra.'>'.$auth;
} }
/**
* @param string $file The filename
* @return string
*/
function mtimefile($file) { function mtimefile($file) {
$data_href = get_base_href(); $data_href = get_base_href();
$mtime = filemtime($file); $mtime = filemtime($file);
@ -445,8 +455,11 @@ function get_theme() {
return $theme; return $theme;
} }
/* /**
* like glob, with support for matching very long patterns with braces * Like glob, with support for matching very long patterns with braces.
*
* @param string $pattern
* @return array
*/ */
function zglob($pattern) { function zglob($pattern) {
$results = array(); $results = array();
@ -470,6 +483,9 @@ function zglob($pattern) {
* CAPTCHA abstraction * * CAPTCHA abstraction *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @return string
*/
function captcha_get_html() { function captcha_get_html() {
global $config, $user; global $config, $user;
@ -492,6 +508,9 @@ function captcha_get_html() {
return $captcha; return $captcha;
} }
/**
* @return bool
*/
function captcha_check() { function captcha_check() {
global $config, $user; global $config, $user;
@ -593,7 +612,10 @@ function getMimeType($file, $ext="", $list=false) {
return 'application/octet-stream'; return 'application/octet-stream';
} }
/**
* @param string $mime_type
* @return bool|string
*/
function getExtension ($mime_type){ function getExtension ($mime_type){
if(empty($mime_type)){ if(empty($mime_type)){
return false; return false;
@ -762,6 +784,11 @@ function get_prefixed_cookie(/*string*/ $name) {
* The counterpart for get_prefixed_cookie, this works like php's * The counterpart for get_prefixed_cookie, this works like php's
* setcookie method, but prepends the site-wide cookie prefix to * setcookie method, but prepends the site-wide cookie prefix to
* the $name argument before doing anything. * the $name argument before doing anything.
*
* @param string $name
* @param string $value
* @param int $time
* @param string $path
*/ */
function set_prefixed_cookie($name, $value, $time, $path) { function set_prefixed_cookie($name, $value, $time, $path) {
global $config; global $config;
@ -770,13 +797,16 @@ function set_prefixed_cookie($name, $value, $time, $path) {
} }
/** /**
* Set (or extend) a flash-message cookie * Set (or extend) a flash-message cookie.
* *
* This can optionally be done at the same time as saving a log message with log_*() * This can optionally be done at the same time as saving a log message with log_*()
* *
* Generally one should flash a message in onPageRequest and log a message wherever * Generally one should flash a message in onPageRequest and log a message wherever
* the action actually takes place (eg onWhateverElse) - but much of the time, actions * the action actually takes place (eg onWhateverElse) - but much of the time, actions
* are taken from within onPageRequest... * are taken from within onPageRequest...
*
* @param string $text
* @param string $type
*/ */
function flash_message(/*string*/ $text, /*string*/ $type="info") { function flash_message(/*string*/ $text, /*string*/ $type="info") {
$current = get_prefixed_cookie("flash_message"); $current = get_prefixed_cookie("flash_message");
@ -816,10 +846,9 @@ function get_base_href() {
} }
/** /**
* A shorthand way to send a TextFormattingEvent and get the * A shorthand way to send a TextFormattingEvent and get the results.
* results
* *
* @param $string * @param string $string
* @return string * @return string
*/ */
function format_text(/*string*/ $string) { function format_text(/*string*/ $string) {
@ -828,6 +857,12 @@ function format_text(/*string*/ $string) {
return $tfe->formatted; return $tfe->formatted;
} }
/**
* @param string $base
* @param string $hash
* @param bool $create
* @return string
*/
function warehouse_path(/*string*/ $base, /*string*/ $hash, /*bool*/ $create=true) { function warehouse_path(/*string*/ $base, /*string*/ $hash, /*bool*/ $create=true) {
$ab = substr($hash, 0, 2); $ab = substr($hash, 0, 2);
$cd = substr($hash, 2, 2); $cd = substr($hash, 2, 2);
@ -841,12 +876,21 @@ function warehouse_path(/*string*/ $base, /*string*/ $hash, /*bool*/ $create=tru
return $pa; return $pa;
} }
/**
* @param string $filename
* @return string
*/
function data_path($filename) { function data_path($filename) {
$filename = "data/" . $filename; $filename = "data/" . $filename;
if(!file_exists(dirname($filename))) mkdir(dirname($filename), 0755, true); if(!file_exists(dirname($filename))) mkdir(dirname($filename), 0755, true);
return $filename; return $filename;
} }
/**
* @param string $url
* @param string $mfile
* @return array|bool
*/
function transload($url, $mfile) { function transload($url, $mfile) {
global $config; global $config;
@ -955,12 +999,17 @@ function findHeader ($headers, $name){
$_included = array(); $_included = array();
/** /**
* Get the active contents of a .php file * Get the active contents of a .php file
*
* @param string $fname
* @return string|null
*/ */
function manual_include($fname) { function manual_include($fname) {
if(!file_exists($fname)) return;
global $_included; global $_included;
if(in_array($fname, $_included)) return;
if(!file_exists($fname)) return null;
if(in_array($fname, $_included)) return null;
$_included[] = $fname; $_included[] = $fname;
print "$fname\n"; print "$fname\n";
@ -1007,6 +1056,12 @@ define("SCORE_LOG_NOTSET", 0);
* $flash = null (default) - log to server only, no flash message * $flash = null (default) - log to server only, no flash message
* $flash = true - show the message to the user as well * $flash = true - show the message to the user as well
* $flash = "some string" - log the message, flash the string * $flash = "some string" - log the message, flash the string
*
* @param string $section
* @param int $priority
* @param string $message
* @param null|bool|string $flash
* @param array $args
*/ */
function log_msg(/*string*/ $section, /*int*/ $priority, /*string*/ $message, $flash=null, $args=array()) { function log_msg(/*string*/ $section, /*int*/ $priority, /*string*/ $message, $flash=null, $args=array()) {
send_event(new LogEvent($section, $priority, $message, $args)); send_event(new LogEvent($section, $priority, $message, $args));
@ -1029,10 +1084,13 @@ function log_warning( /*string*/ $section, /*string*/ $message, $flash=null, $ar
function log_error( /*string*/ $section, /*string*/ $message, $flash=null, $args=array()) {log_msg($section, SCORE_LOG_ERROR, $message, $flash, $args);} function log_error( /*string*/ $section, /*string*/ $message, $flash=null, $args=array()) {log_msg($section, SCORE_LOG_ERROR, $message, $flash, $args);}
function log_critical(/*string*/ $section, /*string*/ $message, $flash=null, $args=array()) {log_msg($section, SCORE_LOG_CRITICAL, $message, $flash, $args);} function log_critical(/*string*/ $section, /*string*/ $message, $flash=null, $args=array()) {log_msg($section, SCORE_LOG_CRITICAL, $message, $flash, $args);}
/**
* Get a unique ID for this request, useful for grouping log messages
*/
$_request_id = null; $_request_id = null;
/**
* Get a unique ID for this request, useful for grouping log messages.
*
* @return null|string
*/
function get_request_id() { function get_request_id() {
global $_request_id; global $_request_id;
if(!$_request_id) { if(!$_request_id) {
@ -1214,7 +1272,11 @@ function full_copy($source, $target) {
$_event_listeners = array(); $_event_listeners = array();
/** /**
* Register an Extension * Register an Extension.
*
* @param Extension $extension
* @param int $pos
* @param array $events
*/ */
function add_event_listener(Extension $extension, $pos=50, $events=array()) { function add_event_listener(Extension $extension, $pos=50, $events=array()) {
global $_event_listeners; global $_event_listeners;
@ -1231,7 +1293,9 @@ function add_event_listener(Extension $extension, $pos=50, $events=array()) {
$_event_count = 0; $_event_count = 0;
/** /**
* Send an event to all registered Extensions * Send an event to all registered Extensions.
*
* @param Event $event
*/ */
function send_event(Event $event) { function send_event(Event $event) {
global $_event_listeners, $_event_count; global $_event_listeners, $_event_count;
@ -1265,7 +1329,7 @@ $_load_start = microtime(true);
* Collects some debug information (execution time, memory usage, queries, etc) * Collects some debug information (execution time, memory usage, queries, etc)
* and formats it to stick in the footer of the page. * and formats it to stick in the footer of the page.
* *
* @return String of debug info to add to the page. * @return string debug info to add to the page.
*/ */
function get_debug_info() { function get_debug_info() {
global $config, $_event_count, $database, $_execs, $_load_start; global $config, $_event_count, $database, $_execs, $_load_start;
@ -1299,6 +1363,10 @@ function get_debug_info() {
/** @privatesection */ /** @privatesection */
/**
* @param array|string $arr
* @return array|string
*/
function _stripslashes_r($arr) { function _stripslashes_r($arr) {
return is_array($arr) ? array_map('_stripslashes_r', $arr) : stripslashes($arr); return is_array($arr) ? array_map('_stripslashes_r', $arr) : stripslashes($arr);
} }
@ -1342,6 +1410,10 @@ function _sanitise_environment() {
} }
} }
/**
* @param string $_theme
* @return array
*/
function _get_themelet_files($_theme) { function _get_themelet_files($_theme) {
$base_themelets = array(); $base_themelets = array();
if(file_exists('themes/'.$_theme.'/custompage.class.php')) $base_themelets[] = 'themes/'.$_theme.'/custompage.class.php'; if(file_exists('themes/'.$_theme.'/custompage.class.php')) $base_themelets[] = 'themes/'.$_theme.'/custompage.class.php';
@ -1424,6 +1496,7 @@ function _load_extensions() {
/** /**
* Used to display fatal errors to the web user. * Used to display fatal errors to the web user.
* @param Exception $e
*/ */
function _fatal_error(Exception $e) { function _fatal_error(Exception $e) {
$version = VERSION; $version = VERSION;
@ -1455,6 +1528,9 @@ function _fatal_error(Exception $e) {
* *
* Necessary because various servers and various clients * Necessary because various servers and various clients
* think that / is special... * think that / is special...
*
* @param string $str
* @return string
*/ */
function _decaret($str) { function _decaret($str) {
$out = ""; $out = "";
@ -1473,6 +1549,9 @@ function _decaret($str) {
return $out; return $out;
} }
/**
* @return User
*/
function _get_user() { function _get_user() {
global $config; global $config;
$user = null; $user = null;

View File

@ -24,15 +24,26 @@
* Sent when the admin page is ready to be added to * Sent when the admin page is ready to be added to
*/ */
class AdminBuildingEvent extends Event { class AdminBuildingEvent extends Event {
var $page; /** @var \Page */
public $page;
/**
* @param Page $page
*/
public function __construct(Page $page) { public function __construct(Page $page) {
$this->page = $page; $this->page = $page;
} }
} }
class AdminActionEvent extends Event { class AdminActionEvent extends Event {
var $action; /** @var string */
var $redirect = true; public $action;
/** @var bool */
public $redirect = true;
/**
* @param string $action
*/
public function __construct(/*string*/ $action) { public function __construct(/*string*/ $action) {
$this->action = $action; $this->action = $action;
} }

View File

@ -12,6 +12,12 @@ class AdminPageTheme extends Themelet {
$page->add_block(new NavBlock()); $page->add_block(new NavBlock());
} }
/**
* @param string $name
* @param string $action
* @param bool $protected
* @return string
*/
protected function button(/*string*/ $name, /*string*/ $action, /*boolean*/ $protected=false) { protected function button(/*string*/ $name, /*string*/ $action, /*boolean*/ $protected=false) {
$c_protected = $protected ? " protected" : ""; $c_protected = $protected ? " protected" : "";
$html = make_form(make_link("admin/$action"), "POST", false, null, null, "admin$c_protected"); $html = make_form(make_link("admin/$action"), "POST", false, null, null, "admin$c_protected");

View File

@ -11,9 +11,15 @@
*/ */
class AddAliasEvent extends Event { class AddAliasEvent extends Event {
var $oldtag; /** @var string */
var $newtag; public $oldtag;
/** @var string */
public $newtag;
/**
* @param string $oldtag
* @param string $newtag
*/
public function __construct($oldtag, $newtag) { public function __construct($oldtag, $newtag) {
$this->oldtag = trim($oldtag); $this->oldtag = trim($oldtag);
$this->newtag = trim($newtag); $this->newtag = trim($newtag);
@ -124,6 +130,10 @@ class AliasEditor extends Extension {
} }
} }
/**
* @param Database $database
* @return string
*/
private function get_alias_csv(Database $database) { private function get_alias_csv(Database $database) {
$csv = ""; $csv = "";
$aliases = $database->get_pairs("SELECT oldtag, newtag FROM aliases ORDER BY newtag"); $aliases = $database->get_pairs("SELECT oldtag, newtag FROM aliases ORDER BY newtag");
@ -133,6 +143,10 @@ class AliasEditor extends Extension {
return $csv; return $csv;
} }
/**
* @param Database $database
* @param string $csv
*/
private function add_alias_csv(Database $database, /*string*/ $csv) { private function add_alias_csv(Database $database, /*string*/ $csv) {
$csv = str_replace("\r", "\n", $csv); $csv = str_replace("\r", "\n", $csv);
foreach(explode("\n", $csv) as $line) { foreach(explode("\n", $csv) as $line) {
@ -148,9 +162,15 @@ class AliasEditor extends Extension {
} }
} }
// add alias *after* mass tag editing, else the MTE will /**
// search for the images and be redirected to the alias, * Get the priority for this extension.
// missing out the images tagged with the oldtag *
* Add alias *after* mass tag editing, else the MTE will
* search for the images and be redirected to the alias,
* missing out the images tagged with the old tag.
*
* @return int
*/
public function get_priority() {return 60;} public function get_priority() {return 60;}
} }

View File

@ -1,11 +1,14 @@
<?php <?php
class AliasEditorTheme extends Themelet { class AliasEditorTheme extends Themelet {
/* /**
* Show a page of aliases: * Show a page of aliases.
* *
* $aliases = an array of ($old_tag => $new_tag) * Note: $can_manage = whether things like "add new alias" should be shown
* $can_manage = whether things like "add new alias" should be shown *
* @param array $aliases An array of ($old_tag => $new_tag)
* @param int $pageNumber
* @param int $totalPages
*/ */
public function display_aliases($aliases, $pageNumber, $totalPages) { public function display_aliases($aliases, $pageNumber, $totalPages) {
global $page, $user; global $page, $user;

View File

@ -9,14 +9,22 @@
* Simply enable this extention in the extention manager to enable arrow key navigation. * Simply enable this extention in the extention manager to enable arrow key navigation.
*/ */
class ArrowkeyNavigation extends Extension { class ArrowkeyNavigation extends Extension {
# Adds functionality for post/view on images /**
* Adds functionality for post/view on images.
*
* @param DisplayingImageEvent $event
*/
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
$prev_url = make_http(make_link("post/prev/".$event->image->id)); $prev_url = make_http(make_link("post/prev/".$event->image->id));
$next_url = make_http(make_link("post/next/".$event->image->id)); $next_url = make_http(make_link("post/next/".$event->image->id));
$this->add_arrowkeys_code($prev_url, $next_url); $this->add_arrowkeys_code($prev_url, $next_url);
} }
# Adds functionality for post/list /**
* Adds functionality for post/list.
*
* @param PageRequestEvent $event
*/
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
if($event->page_matches("post/list")) { if($event->page_matches("post/list")) {
$pageinfo = $this->get_list_pageinfo($event); $pageinfo = $this->get_list_pageinfo($event);
@ -26,7 +34,12 @@ class ArrowkeyNavigation extends Extension {
} }
} }
# adds the javascript to the page with the given urls /**
* Adds the javascript to the page with the given urls.
*
* @param string $prev_url
* @param string $next_url
*/
private function add_arrowkeys_code($prev_url, $next_url) { private function add_arrowkeys_code($prev_url, $next_url) {
global $page; global $page;
@ -41,8 +54,13 @@ class ArrowkeyNavigation extends Extension {
</script>", 60); </script>", 60);
} }
# returns info about the current page number /**
private function get_list_pageinfo($event) { * Returns info about the current page number.
*
* @param PageRequestEvent $event
* @return array
*/
private function get_list_pageinfo(PageRequestEvent $event) {
global $config, $database; global $config, $database;
// get the amount of images per page // get the amount of images per page

View File

@ -9,9 +9,19 @@
* *
*/ */
class AuthorSetEvent extends Event { class AuthorSetEvent extends Event {
var $image, $user, $author; /** @var \Image */
public $image;
/** @var \User */
public $user;
/** @var string */
public $author;
public function __construct(Image $image, User $user, /*string*/ $author) /**
* @param Image $image
* @param User $user
* @param string $author
*/
public function __construct(Image $image, User $user, /*string*/ $author)
{ {
$this->image = $image; $this->image = $image;
$this->user = $user; $this->user = $user;
@ -937,9 +947,12 @@ class Artists extends Extension {
return $result; return $result;
} }
/* /**
* HERE WE GET THE ID OF THE ARTIST * HERE WE GET THE ID OF THE ARTIST.
*/ *
* @param string $name
* @return string|int
*/
private function get_artist_id($name){ private function get_artist_id($name){
global $database; global $database;
$artistID = $database->get_row("SELECT id FROM artists WHERE name = ?" $artistID = $database->get_row("SELECT id FROM artists WHERE name = ?"
@ -1203,7 +1216,8 @@ class Artists extends Extension {
/* /*
* HERE WE GET THE INFO OF THE ALIAS * HERE WE GET THE INFO OF THE ALIAS
*/ */
private function get_alias($artistID){ private function get_alias($artistID)
{
if (!is_numeric($artistID)) return; if (!is_numeric($artistID)) return;
global $database; global $database;

View File

@ -1,6 +1,10 @@
<?php <?php
class ArtistsTheme extends Themelet { class ArtistsTheme extends Themelet {
/**
* @param string $author
* @return string
*/
public function get_author_editor_html(/*string*/ $author) { public function get_author_editor_html(/*string*/ $author) {
$h_author = html_escape($author); $h_author = html_escape($author);
return " return "
@ -14,6 +18,11 @@ class ArtistsTheme extends Themelet {
"; ";
} }
/**
* @param string $mode
* @param null|int $artistID
* @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;

View File

@ -26,6 +26,10 @@
*/ */
class BBCode extends FormatterExtension { class BBCode extends FormatterExtension {
/**
* @param string $text
* @return string
*/
public function format(/*string*/ $text) { public function format(/*string*/ $text) {
$text = $this->extract_code($text); $text = $this->extract_code($text);
foreach(array( foreach(array(
@ -62,6 +66,10 @@ class BBCode extends FormatterExtension {
return $text; return $text;
} }
/**
* @param string $text
* @return string
*/
public function strip(/*string*/ $text) { public function strip(/*string*/ $text) {
foreach(array( foreach(array(
"b", "i", "u", "s", "sup", "sub", "h1", "h2", "h3", "h4", "b", "i", "u", "s", "sup", "sub", "h1", "h2", "h3", "h4",
@ -81,7 +89,10 @@ class BBCode extends FormatterExtension {
return $text; return $text;
} }
/**
* @param string $text
* @return mixed
*/
private function filter_spoiler(/*string*/ $text) { private function filter_spoiler(/*string*/ $text) {
return str_replace( return str_replace(
array("[spoiler]","[/spoiler]"), array("[spoiler]","[/spoiler]"),
@ -89,6 +100,10 @@ class BBCode extends FormatterExtension {
$text); $text);
} }
/**
* @param string $text
* @return string
*/
private function strip_spoiler(/*string*/ $text) { private function strip_spoiler(/*string*/ $text) {
$l1 = strlen("[spoiler]"); $l1 = strlen("[spoiler]");
$l2 = strlen("[/spoiler]"); $l2 = strlen("[/spoiler]");
@ -110,6 +125,10 @@ class BBCode extends FormatterExtension {
return $text; return $text;
} }
/**
* @param string $text
* @return string
*/
private function extract_code(/*string*/ $text) { private function extract_code(/*string*/ $text) {
# at the end of this function, the only code! blocks should be # at the end of this function, the only code! blocks should be
# the ones we've added -- others may contain malicious content, # the ones we've added -- others may contain malicious content,
@ -137,6 +156,10 @@ class BBCode extends FormatterExtension {
return $text; return $text;
} }
/**
* @param string $text
* @return string
*/
private function insert_code(/*string*/ $text) { private function insert_code(/*string*/ $text) {
$l1 = strlen("[code!]"); $l1 = strlen("[code!]");
$l2 = strlen("[/code!]"); $l2 = strlen("[/code!]");

View File

@ -32,7 +32,7 @@ class Blocks extends Extension {
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $database, $page, $user;
$blocks = $database->cache->get("blocks"); $blocks = $database->cache->get("blocks");
if($blocks === false) { if($blocks === false) {

View File

@ -4,7 +4,6 @@ $kioskMode = false;
include '../php/filestorage.class.php'; include '../php/filestorage.class.php';
include '../preferences.php'; include '../preferences.php';
include '../php/json.class.php';
include '../php/functions.php'; include '../php/functions.php';
include '../php/yshout.class.php'; include '../php/yshout.class.php';
include '../php/ajaxcall.class.php'; include '../php/ajaxcall.class.php';
@ -41,7 +40,7 @@ function doLogin() {
'html' => cp() 'html' => cp()
); );
echo jsonEncode($result); echo json_encode($result);
return; return;
} }
@ -53,7 +52,7 @@ function doLogin() {
} else } else
$result['error'] = 'invalid'; $result['error'] = 'invalid';
echo jsonEncode($result); echo json_encode($result);
} }
function doLogout() { function doLogout() {
@ -63,7 +62,7 @@ function doLogout() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
} }
function doUnban() { function doUnban() {
@ -74,7 +73,7 @@ function doUnban() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
return; return;
} }
@ -92,7 +91,7 @@ function doUnban() {
$result['error'] = 'notbanned'; $result['error'] = 'notbanned';
echo jsonEncode($result); echo json_encode($result);
} }
function doUnbanAll() { function doUnbanAll() {
@ -103,7 +102,7 @@ function doUnbanAll() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
return; return;
} }
@ -116,7 +115,7 @@ function doUnbanAll() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
} }
@ -128,7 +127,7 @@ function doSetPreference() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
return; return;
} }
@ -150,7 +149,7 @@ function doSetPreference() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
} }
@ -162,7 +161,7 @@ function doResetPreferences() {
'error' => false 'error' => false
); );
echo jsonEncode($result); echo json_encode($result);
return; return;
} }
@ -177,7 +176,7 @@ function doResetPreferences() {
'prefs' => $prefs 'prefs' => $prefs
); );
echo jsonEncode($result); echo json_encode($result);
} }
/* CP Display */ /* CP Display */
@ -456,4 +455,3 @@ function about() {
return $html; return $html;
} }
?>

View File

@ -3,7 +3,6 @@
include '../php/filestorage.class.php'; include '../php/filestorage.class.php';
include '../preferences.php'; include '../preferences.php';
include '../php/json.class.php';
include '../php/functions.php'; include '../php/functions.php';
include '../php/yshout.class.php'; include '../php/yshout.class.php';

View File

@ -2,9 +2,7 @@
$null = null; $null = null;
include 'php/filestorage.class.php'; include 'php/filestorage.class.php';
include 'preferences.php'; include 'preferences.php';
include 'php/json.class.php';
include 'php/functions.php'; include 'php/functions.php';
include 'php/yshout.class.php'; include 'php/yshout.class.php';
include 'php/ajaxcall.class.php'; include 'php/ajaxcall.class.php';
?>

View File

@ -95,7 +95,7 @@
$send['error'] = false; $send['error'] = false;
} }
echo jsonEncode($send); echo json_encode($send);
} }
function doUnban() { function doUnban() {
@ -115,7 +115,7 @@
$send['error'] = false; $send['error'] = false;
} }
echo jsonEncode($send); echo json_encode($send);
} }
function doDelete() { function doDelete() {
@ -132,7 +132,7 @@
$send['error'] = false; $send['error'] = false;
} }
echo jsonEncode($send); echo json_encode($send);
} }
function banSelf() { function banSelf() {
@ -143,7 +143,7 @@
$send = array(); $send = array();
$send['error'] = false; $send['error'] = false;
echo jsonEncode($send); echo json_encode($send);
} }
function unbanSelf() { function unbanSelf() {
@ -158,7 +158,7 @@
$send['error'] = 'admin'; $send['error'] = 'admin';
} }
echo jsonEncode($send); echo json_encode($send);
} }
function reload() { function reload() {
@ -168,7 +168,7 @@
$posts = $ys->latestPosts($prefs['truncate']); $posts = $ys->latestPosts($prefs['truncate']);
$this->setSessTimestamp($posts); $this->setSessTimestamp($posts);
$this->updates['posts'] = $posts; $this->updates['posts'] = $posts;
echo jsonEncode($this->updates); echo json_encode($this->updates);
} }
function initSession() { function initSession() {
@ -186,7 +186,7 @@
'banned' => true 'banned' => true
); );
echo jsonEncode($this->updates); echo json_encode($this->updates);
} }
function sendUpdates() { function sendUpdates() {
@ -199,7 +199,7 @@
$this->updates['posts'] = $posts; $this->updates['posts'] = $posts;
echo jsonEncode($this->updates); echo json_encode($this->updates);
} }
function setSessTimestamp(&$posts) { function setSessTimestamp(&$posts) {
@ -231,7 +231,7 @@
if ($ys->banned(ip())) if ($ys->banned(ip()))
$this->updates['banned'] = true; $this->updates['banned'] = true;
echo jsonEncode($this->updates); echo json_encode($this->updates);
} }
function cleanPrefs($prefs) { function cleanPrefs($prefs) {
@ -253,7 +253,7 @@
$send['error'] = false; $send['error'] = false;
} }
echo jsonEncode($send); echo json_encode($send);
} }
function clearLogs() { function clearLogs() {
@ -277,7 +277,7 @@
$send['error'] = false; $send['error'] = false;
} }
echo jsonEncode($send); echo json_encode($send);
} }
} }

View File

@ -45,19 +45,6 @@
return false; return false;
} }
function jsonEncode(&$array) {
if ($array) {
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
return $json->encode($array);
} else
return 'ar';
}
function jsonDecode($encoded) {
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
return $json->decode($encoded);
}
function validIP($ip) { function validIP($ip) {
if ($ip == long2ip(ip2long($ip))) if ($ip == long2ip(ip2long($ip)))
return true; return true;

View File

@ -1,805 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Converts to and from JSON format.
*
* JSON (JavaScript Object Notation) is a lightweight data-interchange
* format. It is easy for humans to read and write. It is easy for machines
* to parse and generate. It is based on a subset of the JavaScript
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
* This feature can also be found in Python. JSON is a text format that is
* completely language independent but uses conventions that are familiar
* to programmers of the C-family of languages, including C, C++, C#, Java,
* JavaScript, Perl, TCL, and many others. These properties make JSON an
* ideal data-interchange language.
*
* This package provides a simple encoder and decoder for JSON notation. It
* is intended for use with client-side Javascript applications that make
* use of HTTPRequest to perform server communication functions - data can
* be encoded into JSON notation for use in a client-side javascript, or
* decoded from incoming Javascript requests. JSON format is native to
* Javascript, and can be directly eval()'ed with no further parsing
* overhead
*
* All strings should be in ASCII or UTF-8 format!
*
* LICENSE: Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met: Redistributions of source code must retain the
* above copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* @category
* @package Services_JSON
* @author Michal Migurski <mike-json@teczno.com>
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
* @copyright 2005 Michal Migurski
* @version CVS: $Id: JSON.php,v 1.30 2006/03/08 16:10:20 migurski Exp $
* @license http://www.opensource.org/licenses/bsd-license.php
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
*/
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
define('SERVICES_JSON_SLICE', 1);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
define('SERVICES_JSON_IN_STR', 2);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
define('SERVICES_JSON_IN_ARR', 3);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
define('SERVICES_JSON_IN_OBJ', 4);
/**
* Marker constant for Services_JSON::decode(), used to flag stack state
*/
define('SERVICES_JSON_IN_CMT', 5);
/**
* Behavior switch for Services_JSON::decode()
*/
define('SERVICES_JSON_LOOSE_TYPE', 16);
/**
* Behavior switch for Services_JSON::decode()
*/
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
/**
* Converts to and from JSON format.
*
* Brief example of use:
*
* <code>
* // create a new instance of Services_JSON
* $json = new Services_JSON();
*
* // convert a complexe value to JSON notation, and send it to the browser
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
* $output = $json->encode($value);
*
* print($output);
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
*
* // accept incoming POST data, assumed to be in JSON notation
* $input = file_get_contents('php://input', 1000000);
* $value = $json->decode($input);
* </code>
*/
class Services_JSON
{
/**
* constructs a new JSON instance
*
* @param int $use object behavior flags; combine with boolean-OR
*
* possible values:
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
* "{...}" syntax creates associative arrays
* instead of objects in decode().
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
* Values which can't be encoded (e.g. resources)
* appear as NULL instead of throwing errors.
* By default, a deeply-nested resource will
* bubble up with an error, so all return values
* from encode() should be checked with isError()
*/
function Services_JSON($use = 0)
{
$this->use = $use;
}
/**
* convert a string from one UTF-16 char to one UTF-8 char
*
* Normally should be handled by mb_convert_encoding, but
* provides a slower PHP-only method for installations
* that lack the multibye string extension.
*
* @param string $utf16 UTF-16 character
* @return string UTF-8 character
* @access private
*/
function utf162utf8($utf16)
{
// oh please oh please oh please oh please oh please
if(function_exists('mb_convert_encoding')) {
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
}
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
switch(true) {
case ((0x7F & $bytes) == $bytes):
// this case should never be reached, because we are in ASCII range
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0x7F & $bytes);
case (0x07FF & $bytes) == $bytes:
// return a 2-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0xC0 | (($bytes >> 6) & 0x1F))
. chr(0x80 | ($bytes & 0x3F));
case (0xFFFF & $bytes) == $bytes:
// return a 3-byte UTF-8 character
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0xE0 | (($bytes >> 12) & 0x0F))
. chr(0x80 | (($bytes >> 6) & 0x3F))
. chr(0x80 | ($bytes & 0x3F));
}
// ignoring UTF-32 for now, sorry
return '';
}
/**
* convert a string from one UTF-8 char to one UTF-16 char
*
* Normally should be handled by mb_convert_encoding, but
* provides a slower PHP-only method for installations
* that lack the multibye string extension.
*
* @param string $utf8 UTF-8 character
* @return string UTF-16 character
* @access private
*/
function utf82utf16($utf8)
{
// oh please oh please oh please oh please oh please
if(function_exists('mb_convert_encoding')) {
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
}
switch(strlen($utf8)) {
case 1:
// this case should never be reached, because we are in ASCII range
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return $utf8;
case 2:
// return a UTF-16 character from a 2-byte UTF-8 char
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr(0x07 & (ord($utf8{0}) >> 2))
. chr((0xC0 & (ord($utf8{0}) << 6))
| (0x3F & ord($utf8{1})));
case 3:
// return a UTF-16 character from a 3-byte UTF-8 char
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
return chr((0xF0 & (ord($utf8{0}) << 4))
| (0x0F & (ord($utf8{1}) >> 2)))
. chr((0xC0 & (ord($utf8{1}) << 6))
| (0x7F & ord($utf8{2})));
}
// ignoring UTF-32 for now, sorry
return '';
}
/**
* encodes an arbitrary variable into JSON format
*
* @param mixed $var any number, boolean, string, array, or object to be encoded.
* see argument 1 to Services_JSON() above for array-parsing behavior.
* if var is a strng, note that encode() always expects it
* to be in ASCII or UTF-8 format!
*
* @return mixed JSON string representation of input var or an error if a problem occurs
* @access public
*/
function encode($var)
{
switch (gettype($var)) {
case 'boolean':
return $var ? 'true' : 'false';
case 'NULL':
return 'null';
case 'integer':
return (int) $var;
case 'double':
case 'float':
return (float) $var;
case 'string':
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
$ascii = '';
$strlen_var = strlen($var);
/*
* Iterate over every character in the string,
* escaping with a slash or encoding to UTF-8 where necessary
*/
for ($c = 0; $c < $strlen_var; ++$c) {
$ord_var_c = ord($var{$c});
switch (true) {
case $ord_var_c == 0x08:
$ascii .= '\b';
break;
case $ord_var_c == 0x09:
$ascii .= '\t';
break;
case $ord_var_c == 0x0A:
$ascii .= '\n';
break;
case $ord_var_c == 0x0C:
$ascii .= '\f';
break;
case $ord_var_c == 0x0D:
$ascii .= '\r';
break;
case $ord_var_c == 0x22:
case $ord_var_c == 0x2F:
case $ord_var_c == 0x5C:
// double quote, slash, slosh
$ascii .= '\\'.$var{$c};
break;
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
// characters U-00000000 - U-0000007F (same as ASCII)
$ascii .= $var{$c};
break;
case (($ord_var_c & 0xE0) == 0xC0):
// characters U-00000080 - U-000007FF, mask 110XXXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
$c += 1;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xF0) == 0xE0):
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}));
$c += 2;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xF8) == 0xF0):
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}));
$c += 3;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xFC) == 0xF8):
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}),
ord($var{$c + 4}));
$c += 4;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
case (($ord_var_c & 0xFE) == 0xFC):
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$char = pack('C*', $ord_var_c,
ord($var{$c + 1}),
ord($var{$c + 2}),
ord($var{$c + 3}),
ord($var{$c + 4}),
ord($var{$c + 5}));
$c += 5;
$utf16 = $this->utf82utf16($char);
$ascii .= sprintf('\u%04s', bin2hex($utf16));
break;
}
}
return '"'.$ascii.'"';
case 'array':
/*
* As per JSON spec if any array key is not an integer
* we must treat the the whole array as an object. We
* also try to catch a sparsely populated associative
* array with numeric keys here because some JS engines
* will create an array with empty indexes up to
* max_index which can cause memory issues and because
* the keys, which may be relevant, will be remapped
* otherwise.
*
* As per the ECMA and JSON specification an object may
* have any string as a property. Unfortunately due to
* a hole in the ECMA specification if the key is a
* ECMA reserved word or starts with a digit the
* parameter is only accessible using ECMAScript's
* bracket notation.
*/
// treat as a JSON object
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
$properties = array_map(array($this, 'name_value'),
array_keys($var),
array_values($var));
foreach($properties as $property) {
if(Services_JSON::isError($property)) {
return $property;
}
}
return '{' . join(',', $properties) . '}';
}
// treat it like a regular array
$elements = array_map(array($this, 'encode'), $var);
foreach($elements as $element) {
if(Services_JSON::isError($element)) {
return $element;
}
}
return '[' . join(',', $elements) . ']';
case 'object':
$vars = get_object_vars($var);
$properties = array_map(array($this, 'name_value'),
array_keys($vars),
array_values($vars));
foreach($properties as $property) {
if(Services_JSON::isError($property)) {
return $property;
}
}
return '{' . join(',', $properties) . '}';
default:
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
? 'null'
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
}
}
/**
* array-walking function for use in generating JSON-formatted name-value pairs
*
* @param string $name name of key to use
* @param mixed $value reference to an array element to be encoded
*
* @return string JSON-formatted name-value pair, like '"name":value'
* @access private
*/
function name_value($name, $value)
{
$encoded_value = $this->encode($value);
if(Services_JSON::isError($encoded_value)) {
return $encoded_value;
}
return $this->encode(strval($name)) . ':' . $encoded_value;
}
/**
* reduce a string by removing leading and trailing comments and whitespace
*
* @param $str string string value to strip of comments and whitespace
*
* @return string string value stripped of comments and whitespace
* @access private
*/
function reduce_string($str)
{
$str = preg_replace(array(
// eliminate single line comments in '// ...' form
'#^\s*//(.+)$#m',
// eliminate multi-line comments in '/* ... */' form, at start of string
'#^\s*/\*(.+)\*/#Us',
// eliminate multi-line comments in '/* ... */' form, at end of string
'#/\*(.+)\*/\s*$#Us'
), '', $str);
// eliminate extraneous space
return trim($str);
}
/**
* decodes a JSON string into appropriate variable
*
* @param string $str JSON-formatted string
*
* @return mixed number, boolean, string, array, or object
* corresponding to given JSON input string.
* See argument 1 to Services_JSON() above for object-output behavior.
* Note that decode() always returns strings
* in ASCII or UTF-8 format!
* @access public
*/
function decode($str)
{
$str = $this->reduce_string($str);
switch (strtolower($str)) {
case 'true':
return true;
case 'false':
return false;
case 'null':
return null;
default:
$m = array();
if (is_numeric($str)) {
// Lookie-loo, it's a number
// This would work on its own, but I'm trying to be
// good about returning integers where appropriate:
// return (float)$str;
// Return float or int, as appropriate
return ((float)$str == (integer)$str)
? (integer)$str
: (float)$str;
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
// STRINGS RETURNED IN UTF-8 FORMAT
$delim = substr($str, 0, 1);
$chrs = substr($str, 1, -1);
$utf8 = '';
$strlen_chrs = strlen($chrs);
for ($c = 0; $c < $strlen_chrs; ++$c) {
$substr_chrs_c_2 = substr($chrs, $c, 2);
$ord_chrs_c = ord($chrs{$c});
switch (true) {
case $substr_chrs_c_2 == '\b':
$utf8 .= chr(0x08);
++$c;
break;
case $substr_chrs_c_2 == '\t':
$utf8 .= chr(0x09);
++$c;
break;
case $substr_chrs_c_2 == '\n':
$utf8 .= chr(0x0A);
++$c;
break;
case $substr_chrs_c_2 == '\f':
$utf8 .= chr(0x0C);
++$c;
break;
case $substr_chrs_c_2 == '\r':
$utf8 .= chr(0x0D);
++$c;
break;
case $substr_chrs_c_2 == '\\"':
case $substr_chrs_c_2 == '\\\'':
case $substr_chrs_c_2 == '\\\\':
case $substr_chrs_c_2 == '\\/':
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
$utf8 .= $chrs{++$c};
}
break;
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
// single, escaped unicode character
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
. chr(hexdec(substr($chrs, ($c + 4), 2)));
$utf8 .= $this->utf162utf8($utf16);
$c += 5;
break;
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
$utf8 .= $chrs{$c};
break;
case ($ord_chrs_c & 0xE0) == 0xC0:
// characters U-00000080 - U-000007FF, mask 110XXXXX
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 2);
++$c;
break;
case ($ord_chrs_c & 0xF0) == 0xE0:
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 3);
$c += 2;
break;
case ($ord_chrs_c & 0xF8) == 0xF0:
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 4);
$c += 3;
break;
case ($ord_chrs_c & 0xFC) == 0xF8:
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 5);
$c += 4;
break;
case ($ord_chrs_c & 0xFE) == 0xFC:
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8 .= substr($chrs, $c, 6);
$c += 5;
break;
}
}
return $utf8;
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
// array, or object notation
if ($str{0} == '[') {
$stk = array(SERVICES_JSON_IN_ARR);
$arr = array();
} else {
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$stk = array(SERVICES_JSON_IN_OBJ);
$obj = array();
} else {
$stk = array(SERVICES_JSON_IN_OBJ);
$obj = new stdClass();
}
}
array_push($stk, array('what' => SERVICES_JSON_SLICE,
'where' => 0,
'delim' => false));
$chrs = substr($str, 1, -1);
$chrs = $this->reduce_string($chrs);
if ($chrs == '') {
if (reset($stk) == SERVICES_JSON_IN_ARR) {
return $arr;
} else {
return $obj;
}
}
//print("\nparsing {$chrs}\n");
$strlen_chrs = strlen($chrs);
for ($c = 0; $c <= $strlen_chrs; ++$c) {
$top = end($stk);
$substr_chrs_c_2 = substr($chrs, $c, 2);
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
// found a comma that is not inside a string, array, etc.,
// OR we've reached the end of the character list
$slice = substr($chrs, $top['where'], ($c - $top['where']));
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
if (reset($stk) == SERVICES_JSON_IN_ARR) {
// we are in an array, so just push an element onto the stack
array_push($arr, $this->decode($slice));
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
// we are in an object, so figure
// out the property name and set an
// element in an associative array,
// for now
$parts = array();
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
// "name":value pair
$key = $this->decode($parts[1]);
$val = $this->decode($parts[2]);
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$obj[$key] = $val;
} else {
$obj->$key = $val;
}
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
// name:value pair, where name is unquoted
$key = $parts[1];
$val = $this->decode($parts[2]);
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
$obj[$key] = $val;
} else {
$obj->$key = $val;
}
}
}
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
// found a quote, and we are not inside a string
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
//print("Found start of string at {$c}\n");
} elseif (($chrs{$c} == $top['delim']) &&
($top['what'] == SERVICES_JSON_IN_STR) &&
(($chrs{$c - 1} != '\\') ||
($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
// found a quote, we're in a string, and it's not escaped
array_pop($stk);
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
} elseif (($chrs{$c} == '[') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a left-bracket, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
//print("Found start of array at {$c}\n");
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
// found a right-bracket, and we're in an array
array_pop($stk);
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
} elseif (($chrs{$c} == '{') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a left-brace, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
//print("Found start of object at {$c}\n");
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
// found a right-brace, and we're in an object
array_pop($stk);
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
} elseif (($substr_chrs_c_2 == '/*') &&
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
// found a comment start, and we are in an array, object, or slice
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
$c++;
//print("Found start of comment at {$c}\n");
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
// found a comment end, and we're in one now
array_pop($stk);
$c++;
for ($i = $top['where']; $i <= $c; ++$i)
$chrs = substr_replace($chrs, ' ', $i, 1);
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
}
}
if (reset($stk) == SERVICES_JSON_IN_ARR) {
return $arr;
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
return $obj;
}
}
}
}
/**
* @todo Ultimately, this should just call PEAR::isError()
*/
function isError($data, $code = null)
{
if (class_exists('pear')) {
return PEAR::isError($data, $code);
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
is_subclass_of($data, 'services_json_error'))) {
return true;
}
return false;
}
}
if (class_exists('PEAR_Error')) {
class Services_JSON_Error extends PEAR_Error
{
function Services_JSON_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
}
}
} else {
/**
* @todo Ultimately, this class shall be descended from PEAR_Error
*/
class Services_JSON_Error
{
function Services_JSON_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
}
}
}
?>

View File

@ -246,7 +246,6 @@ class YShout {
} }
} }
} }
} }

View File

@ -1,8 +1,10 @@
<?php <?php
error_reporting(E_ALL); error_reporting(E_ALL);
ob_start(); ob_start();
set_error_handler('errorOccurred'); set_error_handler('errorOccurred');
include 'include.php'; include 'include.php';
if (isset($_POST['reqFor'])) if (isset($_POST['reqFor']))
switch($_POST['reqFor']) { switch($_POST['reqFor']) {
case 'shout': case 'shout':
@ -20,20 +22,17 @@ if (isset($_POST['reqFor']))
default: default:
exit; exit;
} else {
include 'example.html';
} }
else
include 'example.html';
function errorOccurred($num, $str, $file, $line) { function errorOccurred($num, $str, $file, $line) {
$err = array ( $err = array (
'yError' => "$str. \n File: $file \n Line: $line" 'yError' => "$str. \n File: $file \n Line: $line"
); );
if (function_exists('jsonEncode')) echo json_encode($err);
echo jsonEncode($err);
else
echo $err['yError'];
exit; exit;
} }
?>

View File

@ -12,8 +12,18 @@
require_once "lib/akismet.class.php"; require_once "lib/akismet.class.php";
class CommentPostingEvent extends Event { class CommentPostingEvent extends Event {
var $image_id, $user, $comment; /** @var int */
public $image_id;
/** @var \User */
public $user;
/** @var string */
public $comment;
/**
* @param int $image_id
* @param \User $user
* @param string $comment
*/
public function __construct($image_id, $user, $comment) { public function __construct($image_id, $user, $comment) {
$this->image_id = $image_id; $this->image_id = $image_id;
$this->user = $user; $this->user = $user;
@ -27,8 +37,12 @@ class CommentPostingEvent extends Event {
* and what should be kept? * and what should be kept?
*/ */
class CommentDeletionEvent extends Event { class CommentDeletionEvent extends Event {
var $comment_id; /** @var int */
public $comment_id;
/**
* @param int $comment_id
*/
public function __construct($comment_id) { public function __construct($comment_id) {
$this->comment_id = $comment_id; $this->comment_id = $comment_id;
} }
@ -54,11 +68,18 @@ class Comment {
$this->posted = $row['posted']; $this->posted = $row['posted'];
} }
/**
* @param \User $user
* @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));
} }
/**
* @return null|User
*/
public function get_owner() { public function get_owner() {
if(empty($this->owner)) $this->owner = User::by_id($this->owner_id); if(empty($this->owner)) $this->owner = User::by_id($this->owner_id);
return $this->owner; return $this->owner;
@ -265,19 +286,20 @@ class CommentList extends Extension {
} }
public function onSearchTermParse(SearchTermParseEvent $event) { public function onSearchTermParse(SearchTermParseEvent $event) {
global $database;
$matches = array(); $matches = array();
if(preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) { if(preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) {
$cmp = ltrim($matches[1], ":") ?: "="; $cmp = ltrim($matches[1], ":") ?: "=";
$comments = $matches[2]; $comments = $matches[2];
$event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM comments GROUP BY image_id HAVING count(image_id) $cmp $comments)")); $event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM comments GROUP BY image_id HAVING count(image_id) $cmp $comments)"));
} }
else if(preg_match("/^commented_by[=|:](.*)$/i", $event->term, $matches)) { else if(preg_match("/^commented_by[=|:](.*)$/i", $event->term, $matches)) {
global $database;
$user = User::by_name($matches[1]); $user = User::by_name($matches[1]);
if(!is_null($user)) { if(!is_null($user)) {
$user_id = $user->id; $user_id = $user->id;
} } else {
else {
$user_id = -1; $user_id = -1;
} }
@ -290,11 +312,16 @@ class CommentList extends Extension {
} }
// page building {{{ // page building {{{
/**
* @param int $current_page
*/
private function build_page(/*int*/ $current_page) { private function build_page(/*int*/ $current_page) {
global $page, $config, $database, $user; global $database, $user;
if(class_exists("Ratings")) { if(class_exists("Ratings")) {
$user_ratings = Ratings::get_user_privs($user); $user_ratings = Ratings::get_user_privs($user);
} else {
$user_ratings = "";
} }
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
@ -341,8 +368,12 @@ class CommentList extends Extension {
// }}} // }}}
// get comments {{{ // get comments {{{
/**
* @param int $count
* @return array
*/
private function get_recent_comments($count) { private function get_recent_comments($count) {
global $config, $database; global $database;
$rows = $database->get_all(" $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,
@ -361,8 +392,14 @@ class CommentList extends Extension {
return $comments; return $comments;
} }
/**
* @param int $user_id
* @param int $count
* @param int $offset
* @return array
*/
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 $config, $database; global $database;
$rows = $database->get_all(" $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,
@ -382,8 +419,12 @@ class CommentList extends Extension {
return $comments; return $comments;
} }
/**
* @param int $image_id
* @return array
*/
private function get_comments(/*int*/ $image_id) { private function get_comments(/*int*/ $image_id) {
global $config, $database; global $database;
$i_image_id = int_escape($image_id); $i_image_id = int_escape($image_id);
$rows = $database->get_all(" $rows = $database->get_all("
SELECT SELECT
@ -425,6 +466,9 @@ class CommentList extends Extension {
return (count($result) >= $max); return (count($result) >= $max);
} }
/**
* @return bool
*/
private function hash_match() { private function hash_match() {
return ($_POST['hash'] == $this->get_hash()); return ($_POST['hash'] == $this->get_hash());
} }
@ -440,6 +484,10 @@ class CommentList extends Extension {
return md5($_SERVER['REMOTE_ADDR'] . date("%Y%m%d")); return md5($_SERVER['REMOTE_ADDR'] . date("%Y%m%d"));
} }
/**
* @param string $text
* @return bool
*/
private function is_spam_akismet(/*string*/ $text) { private function is_spam_akismet(/*string*/ $text) {
global $config, $user; global $config, $user;
if(strlen($config->get_string('comment_wordpress_key')) > 0) { if(strlen($config->get_string('comment_wordpress_key')) > 0) {
@ -478,11 +526,22 @@ class CommentList extends Extension {
return false; return false;
} }
/**
* @param int $image_id
* @param int $comment
* @return null
*/
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){ private function sanity_check_pagenumber(/*int*/ $pagenum, /*int*/ $maxpage){
if (!is_numeric($pagenum)){ if (!is_numeric($pagenum)){
$pagenum=1; $pagenum=1;
@ -496,6 +555,12 @@ class CommentList extends Extension {
return $pagenum; return $pagenum;
} }
/**
* @param int $image_id
* @param User $user
* @param string $comment
* @throws CommentPostingException
*/
private function add_comment_wrapper(/*int*/ $image_id, User $user, /*string*/ $comment) { private function add_comment_wrapper(/*int*/ $image_id, User $user, /*string*/ $comment) {
global $database, $config; global $database, $config;

View File

@ -18,8 +18,12 @@ class CommentListTheme extends Themelet {
} }
/** /**
* Display a page with a list of images, and for each image, * Display a page with a list of images, and for each image, the image's comments.
* the image's comments *
* @param array $images
* @param int $page_number
* @param int $total_pages
* @param bool $can_post
*/ */
public function display_comment_list($images, $page_number, $total_pages, $can_post) { public function display_comment_list($images, $page_number, $total_pages, $can_post) {
global $config, $page, $user; global $config, $page, $user;
@ -119,9 +123,9 @@ class CommentListTheme extends Themelet {
/** /**
* Add some comments to the page, probably in a sidebar * Add some comments to the page, probably in a sidebar.
* *
* $comments = an array of Comment objects to be shown * @param \Comment[] $comments An array of Comment objects to be shown
*/ */
public function display_recent_comments($comments) { public function display_recent_comments($comments) {
global $page; global $page;
@ -136,7 +140,11 @@ class CommentListTheme extends Themelet {
/** /**
* Show comments for an image * Show comments for an image.
*
* @param Image $image
* @param \Comment[] $comments
* @param bool $postbox
*/ */
public function display_image_comments(Image $image, $comments, $postbox) { public function display_image_comments(Image $image, $comments, $postbox) {
global $page; global $page;
@ -153,9 +161,12 @@ class CommentListTheme extends Themelet {
/** /**
* Show comments made by a user * Show comments made by a user.
*
* @param \Comment[] $comments
* @param \User $user
*/ */
public function display_recent_user_comments($comments, $user) { public function display_recent_user_comments($comments, User $user) {
global $page; global $page;
$html = ""; $html = "";
foreach($comments as $comment) { foreach($comments as $comment) {
@ -170,7 +181,13 @@ class CommentListTheme extends Themelet {
$page->add_block(new Block("Comments", $html, "left", 70, "comment-list-user")); $page->add_block(new Block("Comments", $html, "left", 70, "comment-list-user"));
} }
public function display_all_user_comments($comments, $page_number, $total_pages, $user) { /**
* @param \Comment[] $comments
* @param int $page_number
* @param int $total_pages
* @param \User $user
*/
public function display_all_user_comments($comments, $page_number, $total_pages, User $user) {
global $page; global $page;
assert(is_numeric($page_number)); assert(is_numeric($page_number));
@ -203,7 +220,12 @@ class CommentListTheme extends Themelet {
$this->display_paginator($page, "comment/beta-search/{$user->name}", null, $page_number, $total_pages); $this->display_paginator($page, "comment/beta-search/{$user->name}", null, $page_number, $total_pages);
} }
protected function comment_to_html($comment, $trim=false) { /**
* @param \Comment $comment
* @param bool $trim
* @return string
*/
protected function comment_to_html(Comment $comment, $trim=false) {
global $config, $user; global $config, $user;
$tfe = new TextFormattingEvent($comment->comment); $tfe = new TextFormattingEvent($comment->comment);
@ -276,6 +298,10 @@ class CommentListTheme extends Themelet {
return $html; return $html;
} }
/**
* @param int $image_id
* @return string
*/
protected function build_postbox(/*int*/ $image_id) { protected function build_postbox(/*int*/ $image_id) {
global $config; global $config;

View File

@ -13,18 +13,32 @@
* add more emoticons by uploading images into that folder. * add more emoticons by uploading images into that folder.
*/ */
/**
* Class Emoticons
*/
class Emoticons extends FormatterExtension { class Emoticons extends FormatterExtension {
/**
* @param string $text
* @return string
*/
public function format(/*string*/ $text) { public function format(/*string*/ $text) {
$data_href = get_base_href(); $data_href = get_base_href();
$text = preg_replace("/:([a-z]*?):/s", "<img src='$data_href/ext/emoticons/default/\\1.gif'>", $text); $text = preg_replace("/:([a-z]*?):/s", "<img src='$data_href/ext/emoticons/default/\\1.gif'>", $text);
return $text; return $text;
} }
/**
* @param string $text
* @return string
*/
public function strip(/*string*/ $text) { public function strip(/*string*/ $text) {
return $text; return $text;
} }
} }
/**
* Class EmoticonList
*/
class EmoticonList extends Extension { class EmoticonList extends Extension {
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
if($event->page_matches("emote/list")) { if($event->page_matches("emote/list")) {

View File

@ -1,5 +1,8 @@
<?php <?php
class EmoticonListTheme extends Themelet { class EmoticonListTheme extends Themelet {
/**
* @param array $list
*/
public function display_emotes(/*array*/ $list) { public function display_emotes(/*array*/ $list) {
global $page; global $page;
$data_href = get_base_href(); $data_href = get_base_href();

View File

@ -81,6 +81,10 @@ class ExtensionInfo {
} }
} }
/**
* @param string $fname
* @return bool|null
*/
private function is_enabled(/*string*/ $fname) { private function is_enabled(/*string*/ $fname) {
$core = explode(",", CORE_EXTS); $core = explode(",", CORE_EXTS);
$extra = explode(",", EXTRA_EXTS); $extra = explode(",", EXTRA_EXTS);
@ -150,7 +154,10 @@ class ExtManager extends Extension {
} }
} }
/**
* @param bool $all
* @return array
*/
private function get_extensions(/*bool*/ $all) { private function get_extensions(/*bool*/ $all) {
$extensions = array(); $extensions = array();
if($all) { if($all) {

View File

@ -14,8 +14,18 @@
*/ */
class FavoriteSetEvent extends Event { class FavoriteSetEvent extends Event {
var $image_id, $user, $do_set; /** @var int */
public $image_id;
/** @var \User */
public $user;
/** @var bool */
public $do_set;
/**
* @param int $image_id
* @param User $user
* @param bool $do_set
*/
public function __construct(/*int*/ $image_id, User $user, /*boolean*/ $do_set) { public function __construct(/*int*/ $image_id, User $user, /*boolean*/ $do_set) {
assert(is_numeric($image_id)); assert(is_numeric($image_id));
assert(is_bool($do_set)); assert(is_bool($do_set));
@ -172,6 +182,11 @@ class Favorites extends Extension {
} }
} }
/**
* @param int $image_id
* @param int $user_id
* @param bool $do_set
*/
private function add_vote(/*int*/ $image_id, /*int*/ $user_id, /*bool*/ $do_set) { private function add_vote(/*int*/ $image_id, /*int*/ $user_id, /*bool*/ $do_set) {
global $database; global $database;
if ($do_set) { if ($do_set) {
@ -188,6 +203,10 @@ class Favorites extends Extension {
array("image_id"=>$image_id, "user_id"=>$user_id)); array("image_id"=>$image_id, "user_id"=>$user_id));
} }
/**
* @param Image $image
* @return array
*/
private function list_persons_who_have_favorited(Image $image) { private function list_persons_who_have_favorited(Image $image) {
global $database; global $database;

View File

@ -1,26 +1,37 @@
<?php <?php
class FeaturedTheme extends Themelet { class FeaturedTheme extends Themelet {
/* /**
* Show $text on the $page * Show $text on the $page.
*
* @param Page $page
* @param Image $image
*/ */
public function display_featured(Page $page, Image $image) { public function display_featured(Page $page, Image $image) {
$page->add_block(new Block("Featured Image", $this->build_featured_html($image), "left", 3)); $page->add_block(new Block("Featured Image", $this->build_featured_html($image), "left", 3));
} }
/**
* @param int $image_id
* @return string
*/
public function get_buttons_html(/*int*/ $image_id) { public function get_buttons_html(/*int*/ $image_id) {
global $user; global $user;
return " return "
".make_form(make_link("featured_image/set"))." ".make_form(make_link("featured_image/set"))."
".$user->get_auth_html()." ".$user->get_auth_html()."
<input type='hidden' name='image_id' value='$image_id'> <input type='hidden' name='image_id' value='{$image_id}'>
<input type='submit' value='Feature This'> <input type='submit' value='Feature This'>
</form> </form>
"; ";
} }
/**
* @param Image $image
* @param null|string $query
* @return string
*/
public function build_featured_html(Image $image, $query=null) { public function build_featured_html(Image $image, $query=null) {
global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
@ -29,7 +40,7 @@ class FeaturedTheme extends Themelet {
return " return "
<a href='$h_view_link'> <a href='$h_view_link'>
<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'> <img id='thumb_{$i_id}' title='{$h_tip}' alt='{$h_tip}' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='{$h_thumb_link}'>
</a> </a>
"; ";
} }

View File

@ -39,7 +39,10 @@ class ArchiveFileHandler extends Extension {
} }
} }
/**
* @param $ext
* @return bool
*/
private function supported_ext($ext) { private function supported_ext($ext) {
$exts = array("zip"); $exts = array("zip");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);

View File

@ -7,15 +7,29 @@
*/ */
class FlashFileHandler extends DataHandlerExtension { class FlashFileHandler extends DataHandlerExtension {
/**
* @param string $hash
* @return bool
*/
protected function create_thumb($hash) { protected function create_thumb($hash) {
copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash)); copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash));
return true;
} }
/**
* @param string $ext
* @return bool
*/
protected function supported_ext($ext) { protected function supported_ext($ext) {
$exts = array("swf"); $exts = array("swf");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param string $filename
* @param array $metadata
* @return Image|null
*/
protected function create_image_from_data(/*string*/ $filename, /*array*/ $metadata) { protected function create_image_from_data(/*string*/ $filename, /*array*/ $metadata) {
$image = new Image(); $image = new Image();
@ -35,6 +49,10 @@ class FlashFileHandler extends DataHandlerExtension {
return $image; return $image;
} }
/**
* @param $file
* @return bool
*/
protected function check_contents(/*string*/ $file) { protected function check_contents(/*string*/ $file) {
if (!file_exists($file)) return false; if (!file_exists($file)) return false;

View File

@ -49,12 +49,20 @@ class IcoFileHandler extends Extension {
} }
} }
/**
* @param $ext
* @return bool
*/
private function supported_ext($ext) { private function supported_ext($ext) {
$exts = array("ico", "ani", "cur"); $exts = array("ico", "ani", "cur");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param $filename
* @param $metadata
* @return Image
*/
private function create_image_from_data($filename, $metadata) { private function create_image_from_data($filename, $metadata) {
$image = new Image(); $image = new Image();
@ -77,6 +85,10 @@ class IcoFileHandler extends Extension {
return $image; return $image;
} }
/**
* @param $file
* @return bool
*/
private function check_contents($file) { private function check_contents($file) {
if(!file_exists($file)) return false; if(!file_exists($file)) return false;
$fp = fopen($file, "r"); $fp = fopen($file, "r");
@ -85,6 +97,10 @@ class IcoFileHandler extends Extension {
return ($header['null'] == 0 && ($header['type'] == 0 || $header['type'] == 1)); return ($header['null'] == 0 && ($header['type'] == 0 || $header['type'] == 1));
} }
/**
* @param $hash
* @return bool
*/
private function create_thumb($hash) { private function create_thumb($hash) {
global $config; global $config;

View File

@ -6,15 +6,29 @@
*/ */
class MP3FileHandler extends DataHandlerExtension { class MP3FileHandler extends DataHandlerExtension {
/**
* @param string $hash
* @return bool
*/
protected function create_thumb($hash) { protected function create_thumb($hash) {
copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash)); copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash));
return true;
} }
/**
* @param string $ext
* @return bool
*/
protected function supported_ext($ext) { protected function supported_ext($ext) {
$exts = array("mp3"); $exts = array("mp3");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param string $filename
* @param array $metadata
* @return Image|null
*/
protected function create_image_from_data($filename, $metadata) { protected function create_image_from_data($filename, $metadata) {
global $config; global $config;
@ -47,6 +61,10 @@ class MP3FileHandler extends DataHandlerExtension {
return $image; return $image;
} }
/**
* @param $file
* @return bool
*/
protected function check_contents($file) { protected function check_contents($file) {
if (file_exists($file)) { if (file_exists($file)) {
require_once('lib/getid3/getid3/getid3.php'); require_once('lib/getid3/getid3/getid3.php');

View File

@ -7,12 +7,21 @@
*/ */
class PixelFileHandler extends DataHandlerExtension { class PixelFileHandler extends DataHandlerExtension {
/**
* @param string $ext
* @return bool
*/
protected function supported_ext($ext) { protected function supported_ext($ext) {
$exts = array("jpg", "jpeg", "gif", "png"); $exts = array("jpg", "jpeg", "gif", "png");
$ext = (($pos = strpos($ext,'?')) !== false) ? substr($ext,0,$pos) : $ext; $ext = (($pos = strpos($ext,'?')) !== false) ? substr($ext,0,$pos) : $ext;
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param string $filename
* @param array $metadata
* @return Image|null
*/
protected function create_image_from_data(/*string*/ $filename, /*array*/ $metadata) { protected function create_image_from_data(/*string*/ $filename, /*array*/ $metadata) {
$image = new Image(); $image = new Image();
@ -32,6 +41,10 @@ class PixelFileHandler extends DataHandlerExtension {
return $image; return $image;
} }
/**
* @param string $file
* @return bool
*/
protected function check_contents(/*string*/ $file) { protected function check_contents(/*string*/ $file) {
$valid = Array(IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG); $valid = Array(IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG);
if(!file_exists($file)) return false; if(!file_exists($file)) return false;
@ -41,6 +54,10 @@ class PixelFileHandler extends DataHandlerExtension {
return false; return false;
} }
/**
* @param string $hash
* @return bool
*/
protected function create_thumb(/*string*/ $hash) { protected function create_thumb(/*string*/ $hash) {
$outname = warehouse_path("thumbs", $hash); $outname = warehouse_path("thumbs", $hash);
if(file_exists($outname)) { if(file_exists($outname)) {
@ -49,6 +66,10 @@ class PixelFileHandler extends DataHandlerExtension {
return $this->create_thumb_force($hash); return $this->create_thumb_force($hash);
} }
/**
* @param $hash
* @return bool
*/
protected function create_thumb_force(/*string*/ $hash) { protected function create_thumb_force(/*string*/ $hash) {
global $config; global $config;
@ -70,6 +91,9 @@ 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>
@ -91,6 +115,12 @@ class PixelFileHandler extends DataHandlerExtension {
} }
// IM thumber {{{ // IM thumber {{{
/**
* @param string $inname
* @param string $outname
* @return bool
*/
private function make_thumb_convert(/*string*/ $inname, /*string*/ $outname) { private function make_thumb_convert(/*string*/ $inname, /*string*/ $outname) {
global $config; global $config;
@ -124,6 +154,11 @@ class PixelFileHandler extends DataHandlerExtension {
} }
// }}} // }}}
// epeg thumber {{{ // epeg thumber {{{
/**
* @param string $inname
* @param string $outname
* @return bool
*/
private function make_thumb_epeg(/*string*/ $inname, /*string*/ $outname) { private function make_thumb_epeg(/*string*/ $inname, /*string*/ $outname) {
global $config; global $config;
$w = $config->get_int("thumb_width"); $w = $config->get_int("thumb_width");
@ -132,6 +167,11 @@ class PixelFileHandler extends DataHandlerExtension {
} }
// }}} // }}}
// GD thumber {{{ // GD thumber {{{
/**
* @param string $inname
* @param string $outname
* @return bool
*/
private function make_thumb_gd(/*string*/ $inname, /*string*/ $outname) { private function make_thumb_gd(/*string*/ $inname, /*string*/ $outname) {
global $config; global $config;
$thumb = $this->get_thumb($inname); $thumb = $this->get_thumb($inname);
@ -140,6 +180,10 @@ class PixelFileHandler extends DataHandlerExtension {
return $ok; return $ok;
} }
/**
* @param string $tmpname
* @return resource
*/
private function get_thumb(/*string*/ $tmpname) { private function get_thumb(/*string*/ $tmpname) {
global $config; global $config;

View File

@ -51,11 +51,20 @@ class SVGFileHandler extends Extension {
} }
} }
/**
* @param $ext
* @return bool
*/
private function supported_ext($ext) { private function supported_ext($ext) {
$exts = array("svg"); $exts = array("svg");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param $filename
* @param $metadata
* @return Image
*/
private function create_image_from_data($filename, $metadata) { private function create_image_from_data($filename, $metadata) {
global $config; global $config;
@ -75,21 +84,30 @@ class SVGFileHandler extends Extension {
return $image; return $image;
} }
/**
* @param $file
* @return bool
*/
private function check_contents($file) { private function check_contents($file) {
if(!file_exists($file)) return false; if(!file_exists($file)) return false;
$msp = new MiniSVGParser($file); $msp = new MiniSVGParser($file);
return $msp->valid; return bool_escape($msp->valid);
} }
} }
class MiniSVGParser { class MiniSVGParser {
var $valid=false, $width=0, $height=0; /** @var bool */
public $valid=false;
/** @var int */
public $width=0;
/** @var int */
public $height=0;
function __construct($file) { function __construct($file) {
$xml_parser = xml_parser_create(); $xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, array($this, "startElement"), array($this, "endElement")); xml_set_element_handler($xml_parser, array($this, "startElement"), array($this, "endElement"));
$this->valid = xml_parse($xml_parser, file_get_contents($file), true); $this->valid = bool_escape(xml_parse($xml_parser, file_get_contents($file), true));
xml_parser_free($xml_parser); xml_parser_free($xml_parser);
} }

View File

@ -2,6 +2,7 @@
/* /*
* Name: Handle Video * Name: Handle Video
* Author: velocity37 <velocity37@gmail.com> * Author: velocity37 <velocity37@gmail.com>
* Modified By: Shish <webmaster@shishnet.org>, jgen <jeffgenovy@gmail.com>
* License: GPLv2 * License: GPLv2
* Description: Handle FLV, MP4, OGV and WEBM video files. * Description: Handle FLV, MP4, OGV and WEBM video files.
* Documentation: * Documentation:
@ -17,17 +18,87 @@
*/ */
class VideoFileHandler extends DataHandlerExtension { class VideoFileHandler extends DataHandlerExtension {
protected function create_thumb($hash) { public function onInitExt(InitExtEvent $event) {
copy("ext/handle_video/thumb.jpg", warehouse_path("thumbs", $hash)); global $config;
$config->set_default_string('video_thumb_engine', 'static');
$config->set_default_string('thumb_ffmpeg_path', '');
} }
public function onSetupBuilding(SetupBuildingEvent $event) {
global $config;
$thumbers = array();
$thumbers['None'] = "static";
$thumbers['ffmpeg'] = "ffmpeg";
$sb = new SetupBlock("Video Thumbnail Options");
$sb->add_choice_option("video_thumb_engine", $thumbers, "Engine: ");
//if($config->get_string("video_thumb_engine") == "ffmpeg") {
$sb->add_label("<br>Path to ffmpeg: ");
$sb->add_text_option("thumb_ffmpeg_path");
//}
$event->panel->add_block($sb);
}
/**
* @param string $hash
* @return bool
*/
protected function create_thumb($hash) {
global $config;
// this is never used...
//$q = $config->get_int("thumb_quality");
$ok = false;
switch($config->get_string("video_thumb_engine"))
{
default:
case 'static':
$outname = warehouse_path("thumbs", $hash);
copy("ext/handle_video/thumb.jpg", $outname);
$ok = true;
break;
case 'ffmpeg':
$ffmpeg = escapeshellarg($config->get_string("thumb_ffmpeg_path"));
$w = (int)$config->get_int("thumb_width");
$h = (int)$config->get_int("thumb_height");
$inname = escapeshellarg(warehouse_path("images", $hash));
$outname = escapeshellarg(warehouse_path("thumbs", $hash));
$cmd = escapeshellcmd("{$ffmpeg} -i {$inname} -s {$w}x{$h} -ss 00:00:00.0 -f image2 -vframes 1 {$outname}");
exec($cmd, $output, $ret);
// TODO: We should really check the result of the exec to see if it really succeeded.
$ok = true;
log_debug('handle_video', "Generating thumbnail with command `$cmd`, returns $ret");
break;
}
return $ok;
}
/**
* @param string $ext
* @return bool
*/
protected function supported_ext($ext) { protected function supported_ext($ext) {
$exts = array("flv", "mp4", "m4v", "ogv", "webm"); $exts = array("flv", "mp4", "m4v", "ogv", "webm");
return in_array(strtolower($ext), $exts); return in_array(strtolower($ext), $exts);
} }
/**
* @param string $filename
* @param array $metadata
* @return Image|null
*/
protected function create_image_from_data($filename, $metadata) { protected function create_image_from_data($filename, $metadata) {
global $config; //global $config;
$image = new Image(); $image = new Image();
@ -67,12 +138,21 @@ class VideoFileHandler extends DataHandlerExtension {
return $image; return $image;
} }
/**
* @param $file
* @return bool
*/
protected function check_contents($file) { protected function check_contents($file) {
if (file_exists($file)) { if (file_exists($file)) {
require_once('lib/getid3/getid3/getid3.php'); require_once('lib/getid3/getid3/getid3.php');
$getID3 = new getID3; $getID3 = new getID3;
$ThisFileInfo = $getID3->analyze($file); $ThisFileInfo = $getID3->analyze($file);
if (isset($ThisFileInfo['mime_type']) && ($ThisFileInfo['mime_type'] == "video/webm" || $ThisFileInfo['mime_type'] == "video/quicktime" || $ThisFileInfo['mime_type'] == "application/ogg" || $ThisFileInfo['mime_type'] == 'video/x-flv')) { if (isset($ThisFileInfo['mime_type']) && (
$ThisFileInfo['mime_type'] == "video/webm" ||
$ThisFileInfo['mime_type'] == "video/quicktime" ||
$ThisFileInfo['mime_type'] == "application/ogg" ||
$ThisFileInfo['mime_type'] == 'video/x-flv')
) {
return TRUE; return TRUE;
} }
} }

View File

@ -7,27 +7,38 @@ class VideoFileHandlerTheme extends Themelet {
$ext = strtolower($image->get_ext()); $ext = strtolower($image->get_ext());
if ($ext == "mp4") { if ($ext == "mp4") {
$html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br><script language='JavaScript' type='text/javascript'> $html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br/>
<script language='JavaScript' type='text/javascript'>
if( navigator.userAgent.match(/Firefox/i) || if( navigator.userAgent.match(/Firefox/i) ||
navigator.userAgent.match(/Opera/i) || navigator.userAgent.match(/Opera/i) ||
(navigator.userAgent.match(/MSIE/i) && parseFloat(navigator.appVersion.split('MSIE')[1]) < 9)){ (navigator.userAgent.match(/MSIE/i) && parseFloat(navigator.appVersion.split('MSIE')[1]) < 9)){
document.write(\"<object data='$data_href/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'><param value='#000000' name='bgcolor'><param name='allowFullScreen' value='true'><param value='high' name='quality'><param value='opaque' name='wmode'><param value='source=$ilink&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'></object>\"); document.write(\"<object data='{$data_href}/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'><param value='#000000' name='bgcolor'><param name='allowFullScreen' value='true'><param value='high' name='quality'><param value='opaque' name='wmode'><param value='source=$ilink&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'></object>\");
} }
else { else {
document.write(\"<video controls='controls' autoplay='autoplay'>\"); document.write(\"<video controls autoplay loop'>\");
document.write(\"<source src='" . make_link("/image/" . $image->id) . "' type='video/mp4' />\"); document.write(\"<source src='" . make_link("/image/" . $image->id) . "' type='video/mp4' />\");
document.write(\"<object data='$data_href/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'><param value='#000000' name='bgcolor'><param name='allowFullScreen' value='true'><param value='high' name='quality'><param value='opaque' name='wmode'><param value='source=$ilink&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'></object>\"); document.write(\"<object data='{$data_href}/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'><param value='#000000' name='bgcolor'><param name='allowFullScreen' value='true'><param value='high' name='quality'><param value='opaque' name='wmode'><param value='source=$ilink&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'></object>\");
} }
</script> </script>
<noscript>Javascript appears to be disabled. Please enable it and try again.</noscript>"; <noscript>Javascript appears to be disabled. Please enable it and try again.</noscript>";
} elseif ($ext == "flv") { } elseif ($ext == "flv") {
$html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br><object data='$data_href/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'><param value='#000000' name='bgcolor'><param name='allowFullScreen' value='true'><param value='high' name='quality'><param value='opaque' name='wmode'><param value='source=$ilink&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'></object>"; $html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br/>
<object data='{$data_href}/lib/Jaris/bin/JarisFLVPlayer.swf' id='VideoPlayer' type='application/x-shockwave-flash' height='" . strval($image->height + 1). "px' width='" . strval($image->width) . "px'>
<param value='#000000' name='bgcolor'>
<param name='allowFullScreen' value='true'>
<param value='high' name='quality'>
<param value='opaque' name='wmode'>
<param value='source={$ilink}&amp;type=video&amp;streamtype=file&amp;controltype=0' name='flashvars'>
</object>";
} elseif ($ext == "ogv") { } elseif ($ext == "ogv") {
$html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br><video controls='controls' autoplay='autoplay'> $html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br/>
<video controls autoplay loop>
<source src='" . make_link("/image/" . $image->id) . "' type='video/ogg' /> <source src='" . make_link("/image/" . $image->id) . "' type='video/ogg' />
</video>"; </video>";
} elseif ($ext == "webm") { } elseif ($ext == "webm") {
$html = "Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br><video controls='controls' autoplay='autoplay'> $ie_only = "<!--[if IE]><p>To view webm files with IE, please <a href='http://tools.google.com/dlpage/webmmf/' target='_blank'>download this plugin</a>.</p><![endif]-->";
$html = $ie_only ."Video not playing? <a href='" . $image->parse_link_template(make_link('image/$id/$id%20-%20$tags.$ext')) . "'>Click here</a> to download the file.<br/>
<video controls autoplay loop>
<source src='" . make_link("/image/" . $image->id) . "' type='video/webm' /> <source src='" . make_link("/image/" . $image->id) . "' type='video/webm' />
</video>"; </video>";
} }

View File

@ -12,15 +12,17 @@
* An image is being added to the database. * An image is being added to the database.
*/ */
class ImageAdditionEvent extends Event { class ImageAdditionEvent extends Event {
var $user, $image; var $user;
/** @var \Image */
public $image;
/** /**
* Inserts a new image into the database with its associated * Inserts a new image into the database with its associated
* information. Also calls TagSetEvent to set the tags for * information. Also calls TagSetEvent to set the tags for
* this new image. * this new image.
* *
* @sa TagSetEvent * @see TagSetEvent
* @param $image Image The new image to add. * @param Image $image The new image to add.
*/ */
public function __construct(Image $image) { public function __construct(Image $image) {
$this->image = $image; $this->image = $image;
@ -39,14 +41,16 @@ class ImageAdditionException extends SCoreException {
* An image is being deleted. * An image is being deleted.
*/ */
class ImageDeletionEvent extends Event { class ImageDeletionEvent extends Event {
var $image; /** @var \Image */
public $image;
/** /**
* Deletes an image. * Deletes an image.
*
* Used by things like tags and comments handlers to * Used by things like tags and comments handlers to
* clean out related rows in their tables. * clean out related rows in their tables.
* *
* @param $image Image The image being deleted * @param Image $image The image being deleted.
*/ */
public function __construct(Image $image) { public function __construct(Image $image) {
$this->image = $image; $this->image = $image;
@ -57,18 +61,20 @@ class ImageDeletionEvent extends Event {
* An image is being replaced. * An image is being replaced.
*/ */
class ImageReplaceEvent extends Event { class ImageReplaceEvent extends Event {
var $id, $image; /** @var int */
public $id;
/** @var \Image */
public $image;
/** /**
* Replaces an image. * Replaces an image.
*
* Updates an existing ID in the database to use a new image * Updates an existing ID in the database to use a new image
* file, leaving the tags and such unchanged. Also removes * file, leaving the tags and such unchanged. Also removes
* the old image file and thumbnail from the disk. * the old image file and thumbnail from the disk.
* *
* @param $id * @param int $id The ID of the image to replace.
* The ID of the image to replace * @param Image $image The image object of the new image to use.
* @param $image
* The image object of the new image to use
*/ */
public function __construct(/*int*/ $id, Image $image) { public function __construct(/*int*/ $id, Image $image) {
$this->id = $id; $this->id = $id;
@ -77,8 +83,12 @@ class ImageReplaceEvent extends Event {
} }
class ImageReplaceException extends SCoreException { class ImageReplaceException extends SCoreException {
var $error; /** @var string */
public $error;
/**
* @param string $error
*/
public function __construct(/*string*/ $error) { public function __construct(/*string*/ $error) {
$this->error = $error; $this->error = $error;
} }
@ -88,14 +98,19 @@ class ImageReplaceException extends SCoreException {
* Request a thumbnail be made for an image object. * Request a thumbnail be made for an image object.
*/ */
class ThumbnailGenerationEvent extends Event { class ThumbnailGenerationEvent extends Event {
var $hash, $type, $force; /** @var string */
public $hash;
/** @var string */
public $type;
/** @var bool */
public $force;
/** /**
* Request a thumbnail be made for an image object * Request a thumbnail be made for an image object
* *
* @param $hash string The unique hash of the image * @param string $hash The unique hash of the image
* @param $type string The type of the image * @param string $type The type of the image
* @param $force boolean Regenerate the thumbnail even if one already exists * @param bool $force Regenerate the thumbnail even if one already exists
*/ */
public function __construct($hash, $type, $force=false) { public function __construct($hash, $type, $force=false) {
$this->hash = $hash; $this->hash = $hash;
@ -112,14 +127,27 @@ class ThumbnailGenerationEvent extends Event {
* $image -- the image who's link is being parsed * $image -- the image who's link is being parsed
*/ */
class ParseLinkTemplateEvent extends Event { class ParseLinkTemplateEvent extends Event {
var $link, $original, $image; /** @var string */
public $link;
/** @var string */
public $original;
/** @var \Image */
public $image;
/**
* @param string $link The formatted link
* @param Image $image The image who's link is being parsed
*/
public function __construct($link, Image $image) { public function __construct($link, Image $image) {
$this->link = $link; $this->link = $link;
$this->original = $link; $this->original = $link;
$this->image = $image; $this->image = $image;
} }
/**
* @param string $needle
* @param string $replace
*/
public function replace($needle, $replace) { public function replace($needle, $replace) {
$this->link = str_replace($needle, $replace, $this->link); $this->link = str_replace($needle, $replace, $this->link);
} }
@ -189,8 +217,7 @@ class ImageIO extends Extension {
} }
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) {
global $user; global $user, $config;
global $config;
if($user->can("delete_image")) { if($user->can("delete_image")) {
$event->add_part($this->theme->get_deleter_html($event->image->id)); $event->add_part($this->theme->get_deleter_html($event->image->id));
@ -277,6 +304,11 @@ class ImageIO extends Extension {
// add image {{{ // add image {{{
/**
* @param Image $image
* @return null
* @throws ImageAdditionException
*/
private function add_image(Image $image) { private function add_image(Image $image) {
global $page, $user, $database, $config; global $page, $user, $database, $config;
@ -346,6 +378,10 @@ class ImageIO extends Extension {
// }}} end add // }}} end add
// fetch image {{{ // fetch image {{{
/**
* @param int $image_id
* @param string $type
*/
private function send_file($image_id, $type) { private function send_file($image_id, $type) {
global $config; global $config;
global $database; global $database;
@ -398,6 +434,11 @@ class ImageIO extends Extension {
// }}} end fetch // }}} end fetch
// replace image {{{ // replace image {{{
/**
* @param int $id
* @param Image $image
* @throws ImageReplaceException
*/
private function replace_image($id, $image) { private function replace_image($id, $image) {
global $database; global $database;

View File

@ -159,23 +159,39 @@
* Signal that a search term needs parsing * Signal that a search term needs parsing
*/ */
class SearchTermParseEvent extends Event { class SearchTermParseEvent extends Event {
var $term = null; /** @var null|string */
var $context = null; public $term = null;
var $querylets = array(); /** @var null|array */
public $context = null;
/** @var \Querylet[] */
public $querylets = array();
/**
* @param string|null $term
* @param array|null $context
*/
public function __construct($term, $context) { public function __construct($term, $context) {
$this->term = $term; $this->term = $term;
$this->context = $context; $this->context = $context;
} }
/**
* @return bool
*/
public function is_querylet_set() { public function is_querylet_set() {
return (count($this->querylets) > 0); return (count($this->querylets) > 0);
} }
/**
* @return \Querylet[]
*/
public function get_querylets() { public function get_querylets() {
return $this->querylets; return $this->querylets;
} }
/**
* @param \Querylet $q
*/
public function add_querylet($q) { public function add_querylet($q) {
$this->querylets[] = $q; $this->querylets[] = $q;
} }
@ -185,13 +201,23 @@ class SearchTermParseException extends SCoreException {
} }
class PostListBuildingEvent extends Event { class PostListBuildingEvent extends Event {
var $search_terms = null; /** @var null|array */
var $parts = array(); public $search_terms = null;
/** @var array */
public $parts = array();
/**
* @param array|null $search
*/
public function __construct($search) { public function __construct($search) {
$this->search_terms = $search; $this->search_terms = $search;
} }
/**
* @param string $html
* @param int $position
*/
public function add_control(/*string*/ $html, /*int*/ $position=50) { public function add_control(/*string*/ $html, /*int*/ $position=50) {
while(isset($this->parts[$position])) $position++; while(isset($this->parts[$position])) $position++;
$this->parts[$position] = $html; $this->parts[$position] = $html;

View File

@ -109,7 +109,7 @@ class Notes extends Extension {
} }
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("note/updated")); $page->set_redirect(make_link("note/updated"));
break; break;
} }
case "add_note": case "add_note":
@ -118,7 +118,7 @@ class Notes extends Extension {
$this->add_new_note(); $this->add_new_note();
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/view/".$_POST["image_id"])); $page->set_redirect(make_link("post/view/".$_POST["image_id"]));
break; break;
} }
case "add_request": case "add_request":
@ -127,7 +127,7 @@ class Notes extends Extension {
$this->add_note_request(); $this->add_note_request();
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/view/".$_POST["image_id"])); $page->set_redirect(make_link("post/view/".$_POST["image_id"]));
break; break;
} }
case "nuke_notes": case "nuke_notes":
@ -136,7 +136,7 @@ class Notes extends Extension {
$this->nuke_notes(); $this->nuke_notes();
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/view/".$_POST["image_id"])); $page->set_redirect(make_link("post/view/".$_POST["image_id"]));
break; break;
} }
case "nuke_requests": case "nuke_requests":
@ -145,7 +145,7 @@ class Notes extends Extension {
$this->nuke_requests(); $this->nuke_requests();
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/view/".$_POST["image_id"])); $page->set_redirect(make_link("post/view/".$_POST["image_id"]));
break; break;
} }
case "edit_note": case "edit_note":
@ -238,18 +238,21 @@ class Notes extends Extension {
} }
/* /**
* HERE WE GET ALL NOTES FOR DISPLAYED IMAGE * HERE WE GET ALL NOTES FOR DISPLAYED IMAGE.
*
* @param int $imageID
* @return array
*/ */
private function get_notes($imageID) { private function get_notes($imageID) {
global $database; global $database;
return $database->get_all( return $database->get_all(
"SELECT * ". "SELECT * ".
"FROM notes ". "FROM notes ".
"WHERE enable = ? AND image_id = ? ". "WHERE enable = ? AND image_id = ? ".
"ORDER BY date ASC" "ORDER BY date ASC"
, array('1', $imageID)); , array('1', $imageID));
} }
@ -347,13 +350,12 @@ class Notes extends Extension {
} }
/* /*
* HERE WE DELETE THE NOTE * HERE WE DELETE THE NOTE
*/ */
private function delete_note() private function delete_note()
{ {
global $user; global $user;
$imageID = int_escape($_POST["image_id"]); $imageID = int_escape($_POST["image_id"]);
$noteID = int_escape($_POST["note_id"]); $noteID = int_escape($_POST["note_id"]);
@ -400,27 +402,26 @@ class Notes extends Extension {
log_info("notes", "Requests deleted from {$image_id} by {$user->name}"); log_info("notes", "Requests deleted from {$image_id} by {$user->name}");
} }
/**
* HERE WE ALL IMAGES THAT HAVE NOTES
* @param PageRequestEvent $event
*/
private function get_notes_list(PageRequestEvent $event) {
global $database, $config;
/*
* HERE WE ALL IMAGES THAT HAVE NOTES
*/
private function get_notes_list($event) {
$pageNumber = $event->get_arg(1); $pageNumber = $event->get_arg(1);
if(is_null($pageNumber) || !is_numeric($pageNumber))
$pageNumber = 0;
else if ($pageNumber <= 0)
$pageNumber = 0;
else
$pageNumber--;
global $config; if(is_null($pageNumber) || !is_numeric($pageNumber))
$pageNumber = 0;
else if ($pageNumber <= 0)
$pageNumber = 0;
else
$pageNumber--;
$notesPerPage = $config->get_int('notesNotesPerPage'); $notesPerPage = $config->get_int('notesNotesPerPage');
//$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=?", array($poolID)); //$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=?", array($poolID));
global $database;
$get_notes = " $get_notes = "
SELECT DISTINCT image_id ". SELECT DISTINCT image_id ".
"FROM notes ". "FROM notes ".
@ -441,21 +442,21 @@ class Notes extends Extension {
$this->theme->display_note_list($images, $pageNumber + 1, $totalPages); $this->theme->display_note_list($images, $pageNumber + 1, $totalPages);
} }
/**
* HERE WE GET ALL NOTE REQUESTS
* @param PageRequestEvent $event
*/
private function get_notes_requests(PageRequestEvent $event) {
global $config;
/*
* HERE WE GET ALL NOTE REQUESTS
*/
private function get_notes_requests($event) {
$pageNumber = $event->get_arg(1); $pageNumber = $event->get_arg(1);
if(is_null($pageNumber) || !is_numeric($pageNumber))
$pageNumber = 0;
else if ($pageNumber <= 0)
$pageNumber = 0;
else
$pageNumber--;
global $config; if(is_null($pageNumber) || !is_numeric($pageNumber))
$pageNumber = 0;
else if ($pageNumber <= 0)
$pageNumber = 0;
else
$pageNumber--;
$requestsPerPage = $config->get_int('notesRequestsPerPage'); $requestsPerPage = $config->get_int('notesRequestsPerPage');
@ -503,11 +504,11 @@ class Notes extends Extension {
} }
/**
/* * HERE WE GET ALL HISTORIES.
* HERE WE GET ALL HISTORIES. * @param PageRequestEvent $event
*/ */
private function get_histories($event){ private function get_histories(PageRequestEvent $event){
$pageNumber = $event->get_arg(1); $pageNumber = $event->get_arg(1);
if(is_null($pageNumber) || !is_numeric($pageNumber)) if(is_null($pageNumber) || !is_numeric($pageNumber))
$pageNumber = 0; $pageNumber = 0;
@ -535,11 +536,11 @@ class Notes extends Extension {
} }
/**
/* * HERE WE THE HISTORY FOR A SPECIFIC NOTE.
* HERE WE THE HISTORY FOR A SPECIFIC NOTE. * @param PageRequestEvent $event
*/ */
private function get_history($event){ private function get_history(PageRequestEvent $event){
$noteID = $event->get_arg(1); $noteID = $event->get_arg(1);
$pageNumber = $event->get_arg(2); $pageNumber = $event->get_arg(2);
if(is_null($pageNumber) || !is_numeric($pageNumber)) if(is_null($pageNumber) || !is_numeric($pageNumber))
@ -567,13 +568,13 @@ class Notes extends Extension {
$this->theme->display_history($histories, $pageNumber + 1, $totalPages); $this->theme->display_history($histories, $pageNumber + 1, $totalPages);
} }
/**
* HERE GO BACK IN HISTORY AND SET THE OLD NOTE. IF WAS REMOVED WE RE-ADD IT.
/* * @param int $noteID
* HERE GO BACK IN HISTORY AND SET THE OLD NOTE. IF WAS REMOVED WE READD IT. * @param int $reviewID
*/ */
private function revert_history($noteID, $reviewID){ private function revert_history($noteID, $reviewID){
global $user, $database; global $database;
$history = $database->get_row("SELECT * FROM note_histories WHERE note_id = ? AND review_id = ?",array($noteID, $reviewID)); $history = $database->get_row("SELECT * FROM note_histories WHERE note_id = ? AND review_id = ?",array($noteID, $reviewID));
@ -596,7 +597,6 @@ class Notes extends Extension {
"WHERE image_id = ? AND id = ?", array(1, $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText, $imageID, $noteID)); "WHERE image_id = ? AND id = ?", array(1, $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText, $imageID, $noteID));
$this->add_history($noteEnable, $noteID, $imageID, $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText); $this->add_history($noteEnable, $noteID, $imageID, $noteX1, $noteY1, $noteHeight, $noteWidth, $noteText);
} }
} }

View File

@ -284,6 +284,11 @@ class NumericScore extends Extension {
} }
} }
/**
* @param int $image_id
* @param int $user_id
* @param int $score
*/
private function add_vote(/*int*/ $image_id, /*int*/ $user_id, /*int*/ $score) { private function add_vote(/*int*/ $image_id, /*int*/ $user_id, /*int*/ $score) {
global $database; global $database;
$database->execute( $database->execute(

View File

@ -13,8 +13,12 @@
* This class is just a wrapper around SCoreException. * This class is just a wrapper around SCoreException.
*/ */
class PoolCreationException extends SCoreException { class PoolCreationException extends SCoreException {
var $error; /** @var string */
public $error;
/**
* @param string $error
*/
public function __construct($error) { public function __construct($error) {
$this->error = $error; $this->error = $error;
} }
@ -92,7 +96,7 @@ class Pools extends Extension {
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $page, $user; global $page, $user;
if ($event->page_matches("pool")) { if ($event->page_matches("pool")) {
@ -249,7 +253,7 @@ class Pools extends Extension {
* to the Next image in the pool. * to the Next image in the pool.
*/ */
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
global $config, $database, $page; global $config;
if($config->get_bool("poolsInfoOnViewImage")) { if($config->get_bool("poolsInfoOnViewImage")) {
$imageID = $event->image->id; $imageID = $event->image->id;
@ -341,7 +345,11 @@ class Pools extends Extension {
/** /**
* Check if the given user has permission to edit/change the pool. * Check if the given user has permission to edit/change the pool.
*
* TODO: Should the user variable be global? * TODO: Should the user variable be global?
*
* @param \User $user
* @param array $pool
* @return bool * @return bool
*/ */
private function have_permission($user, $pool) { private function have_permission($user, $pool) {
@ -354,8 +362,11 @@ class Pools extends Extension {
} }
} }
/* /**
* HERE WE GET THE LIST OF POOLS * HERE WE GET THE LIST OF POOLS.
*
* @param \Page $page
* @param int $pageNumber
*/ */
private function list_pools(Page $page, /*int*/ $pageNumber) { private function list_pools(Page $page, /*int*/ $pageNumber) {
global $config, $database; global $config, $database;
@ -399,8 +410,11 @@ class Pools extends Extension {
} }
/* /**
* HERE WE CREATE A NEW POOL * HERE WE CREATE A NEW POOL
*
* @return mixed
* @throws PoolCreationException
*/ */
private function add_pool() { private function add_pool() {
global $user, $database; global $user, $database;
@ -431,8 +445,11 @@ class Pools extends Extension {
/** /**
* Retrieve information about pools given multiple pool IDs. * Retrieve information about pools given multiple pool IDs.
* @param $poolID Array of integers *
* @return 2D Array * TODO: What is the difference between this and get_single_pool() other than the db query?
*
* @param int $poolID Array of integers
* @return array
*/ */
private function get_pool(/*int*/ $poolID) { private function get_pool(/*int*/ $poolID) {
global $database; global $database;
@ -441,8 +458,8 @@ class Pools extends Extension {
/** /**
* Retrieve information about a pool given a pool ID. * Retrieve information about a pool given a pool ID.
* @param $poolID Integer * @param int $poolID the pool id
* @return 2D array (with only 1 element in the one dimension) * @return array Array with only 1 element in the one dimension
*/ */
private function get_single_pool(/*int*/ $poolID) { private function get_single_pool(/*int*/ $poolID) {
global $database; global $database;
@ -451,8 +468,8 @@ class Pools extends Extension {
/** /**
* Retrieve information about a pool given a pool title. * Retrieve information about a pool given a pool title.
* @param $poolTitle Integer * @param string $poolTitle
* @return 2D array (with only 1 element in the one dimension) * @return array Array (with only 1 element in the one dimension)
*/ */
private function get_single_pool_from_title(/*string*/ $poolTitle) { private function get_single_pool_from_title(/*string*/ $poolTitle) {
global $database; global $database;
@ -461,20 +478,20 @@ 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 $imageID Integer * @param int $imageID Integer ID for the image
* @return 2D array * @return array
*/ */
private function get_pool_id(/*int*/ $imageID) { private function get_pool_id(/*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_all("SELECT pool_id FROM pool_images WHERE image_id=:iid", array("iid"=>$imageID));
} }
/**
/*
* HERE WE GET THE IMAGES FROM THE TAG ON IMPORT * HERE WE GET THE IMAGES FROM THE TAG ON IMPORT
* @param int $pool_id
*/ */
private function import_posts(/*int*/ $pool_id) { private function import_posts(/*int*/ $pool_id) {
global $page, $config, $database; global $page, $config;
$poolsMaxResults = $config->get_int("poolsMaxImportResults", 1000); $poolsMaxResults = $config->get_int("poolsMaxImportResults", 1000);
@ -483,10 +500,12 @@ class Pools extends Extension {
} }
/* /**
* HERE WE ADD CHECKED IMAGES FROM POOL AND UPDATE THE HISTORY * HERE WE ADD CHECKED IMAGES FROM POOL AND UPDATE THE HISTORY
* *
* TODO: Fix this so that the pool ID and images are passed as Arguments to the function. * TODO: Fix this so that the pool ID and images are passed as Arguments to the function.
*
* @return int
*/ */
private function add_posts() { private function add_posts() {
global $database; global $database;
@ -503,11 +522,10 @@ class Pools extends Extension {
$images .= " ".$imageID; $images .= " ".$imageID;
} }
} }
if(!strlen($images) == 0) { if(!strlen($images) == 0) {
$count = $database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", array("pid"=>$poolID)); $count = int_escape($database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", array("pid"=>$poolID)));
$this->add_history($poolID, 1, $images, $count); $this->add_history($poolID, 1, $images, $count);
} }
@ -520,8 +538,9 @@ class Pools extends Extension {
return $poolID; return $poolID;
} }
/* /**
* TODO: Fix this so that the pool ID and images are passed as Arguments to the function. * TODO: Fix this so that the pool ID and images are passed as Arguments to the function.
* @return int
*/ */
private function order_posts() { private function order_posts() {
global $database; global $database;
@ -541,11 +560,12 @@ class Pools extends Extension {
return $poolID; return $poolID;
} }
/**
/*
* HERE WE REMOVE CHECKED IMAGES FROM POOL AND UPDATE THE HISTORY * HERE WE REMOVE CHECKED IMAGES FROM POOL AND UPDATE THE HISTORY
* *
* TODO: Fix this so that the pool ID and images are passed as Arguments to the function. * TODO: Fix this so that the pool ID and images are passed as Arguments to the function.
*
* @return int
*/ */
private function remove_posts() { private function remove_posts() {
global $database; global $database;
@ -563,8 +583,9 @@ class Pools extends Extension {
return $poolID; return $poolID;
} }
/* /**
* Allows editing of pool description. * Allows editing of pool description.
* @return int
*/ */
private function edit_description() { private function edit_description() {
global $database; global $database;
@ -580,8 +601,8 @@ class Pools extends Extension {
* Used by add_posts() * Used by add_posts()
* *
* @see add_posts() * @see add_posts()
* @param $poolID integer * @param int $poolID
* @param $imageID integer * @param int $imageID
* @return bool * @return bool
*/ */
private function check_post(/*int*/ $poolID, /*int*/ $imageID) { private function check_post(/*int*/ $poolID, /*int*/ $imageID) {
@ -593,9 +614,9 @@ class Pools extends Extension {
/** /**
* Gets the next successive image from a pool, given a pool ID and an image ID. * Gets the next successive image from a pool, given a pool ID and an image ID.
* *
* @param $pool Array for the given pool * @param array $pool Array for the given pool
* @param $imageID Integer * @param int $imageID Integer
* @return Integer which is the next Image ID or NULL if none. * @return int Integer which is the next Image ID or NULL if none.
*/ */
private function get_next_post(/*array*/ $pool, /*int*/ $imageID) { private function get_next_post(/*array*/ $pool, /*int*/ $imageID) {
global $database; global $database;
@ -621,6 +642,9 @@ class Pools extends Extension {
/** /**
* Retrieve all the images in a pool, given a pool ID. * Retrieve all the images in a pool, given a pool ID.
*
* @param PageRequestEvent $event
* @param int $poolID
*/ */
private function get_posts($event, /*int*/ $poolID) { private function get_posts($event, /*int*/ $poolID) {
global $config, $user, $database; global $config, $user, $database;
@ -684,8 +708,8 @@ class Pools extends Extension {
/** /**
* This function gets the current order of images from a given pool. * This function gets the current order of images from a given pool.
* @param $poolID integer * @param int $poolID
* @return Array of image objects. * @return \Image[] Array of image objects.
*/ */
private function edit_posts(/*int*/ $poolID) { private function edit_posts(/*int*/ $poolID) {
global $database; global $database;
@ -702,8 +726,11 @@ class Pools extends Extension {
} }
/* /**
* WE GET THE ORDER OF THE IMAGES BUT HERE WE SEND KEYS ADDED IN ARRAY TO GET THE ORDER IN THE INPUT VALUE * WE GET THE ORDER OF THE IMAGES BUT HERE WE SEND KEYS ADDED IN ARRAY TO GET THE ORDER IN THE INPUT VALUE.
*
* @param int $poolID
* @return \Image[]
*/ */
private function edit_order(/*int*/ $poolID) { private function edit_order(/*int*/ $poolID) {
global $database; global $database;
@ -726,8 +753,10 @@ class Pools extends Extension {
} }
/* /**
* HERE WE NUKE ENTIRE POOL. WE REMOVE POOLS AND POSTS FROM REMOVED POOL AND HISTORIES ENTRIES FROM REMOVED POOL * HERE WE NUKE ENTIRE POOL. WE REMOVE POOLS AND POSTS FROM REMOVED POOL AND HISTORIES ENTRIES FROM REMOVED POOL.
*
* @param int $poolID
*/ */
private function nuke_pool(/*int*/ $poolID) { private function nuke_pool(/*int*/ $poolID) {
global $user, $database; global $user, $database;
@ -744,10 +773,13 @@ class Pools extends Extension {
} }
} }
/**
/* * HERE WE ADD A HISTORY ENTRY.
* HERE WE ADD A HISTORY ENTRY *
* FOR $action 1 (one) MEANS ADDED, 0 (zero) MEANS REMOVED * @param int $poolID
* @param int $action Action=1 (one) MEANS ADDED, Action=0 (zero) MEANS REMOVED
* @param string $images
* @param int $count
*/ */
private function add_history(/*int*/ $poolID, $action, $images, $count) { private function add_history(/*int*/ $poolID, $action, $images, $count) {
global $user, $database; global $user, $database;
@ -758,9 +790,9 @@ class Pools extends Extension {
array("pid"=>$poolID, "uid"=>$user->id, "act"=>$action, "img"=>$images, "count"=>$count)); array("pid"=>$poolID, "uid"=>$user->id, "act"=>$action, "img"=>$images, "count"=>$count));
} }
/**
/* * HERE WE GET THE HISTORY LIST.
* HERE WE GET THE HISTORY LIST * @param int $pageNumber
*/ */
private function get_history(/*int*/ $pageNumber) { private function get_history(/*int*/ $pageNumber) {
global $config, $database; global $config, $database;
@ -772,7 +804,6 @@ class Pools extends Extension {
else else
$pageNumber--; $pageNumber--;
$historiesPerPage = $config->get_int("poolsUpdatedPerPage"); $historiesPerPage = $config->get_int("poolsUpdatedPerPage");
$history = $database->get_all(" $history = $database->get_all("
@ -792,10 +823,9 @@ class Pools extends Extension {
$this->theme->show_history($history, $pageNumber + 1, $totalPages); $this->theme->show_history($history, $pageNumber + 1, $totalPages);
} }
/**
* HERE GO BACK IN HISTORY AND ADD OR REMOVE POSTS TO POOL.
/* * @param int $historyID
* HERE GO BACK IN HISTORY AND ADD OR REMOVE POSTS TO POOL
*/ */
private function revert_history(/*int*/ $historyID) { private function revert_history(/*int*/ $historyID) {
global $database; global $database;
@ -838,11 +868,13 @@ class Pools extends Extension {
} }
} }
/**
* HERE WE ADD A SIMPLE POST FROM POOL.
/* * USED WITH FOREACH IN revert_history() & onTagTermParse().
* HERE WE ADD A SIMPLE POST FROM POOL *
* USED WITH FOREACH IN revert_history() & onTagTermParse() * @param int $poolID
* @param int $imageID
* @param bool $history
*/ */
private function add_post(/*int*/ $poolID, /*int*/ $imageID, $history=false) { private function add_post(/*int*/ $poolID, /*int*/ $imageID, $history=false) {
global $database; global $database;
@ -862,11 +894,13 @@ class Pools extends Extension {
} }
} }
/**
* HERE WE REMOVE A SIMPLE POST FROM POOL.
/* * USED WITH FOREACH IN revert_history() & onTagTermParse().
* HERE WE REMOVE A SIMPLE POST FROM POOL *
* USED WITH FOREACH IN revert_history() & onTagTermParse() * @param int $poolID
* @param int $imageID
* @param bool $history
*/ */
private function delete_post(/*int*/ $poolID, /*int*/ $imageID, $history=false) { private function delete_post(/*int*/ $poolID, /*int*/ $imageID, $history=false) {
global $database; global $database;

View File

@ -11,6 +11,11 @@ class PoolsTheme extends Themelet {
} }
} }
/**
* @param Image $image
* @param array $pools
* @return string
*/
public function get_adder_html(Image $image, /*array*/ $pools) { public function get_adder_html(Image $image, /*array*/ $pools) {
$h = ""; $h = "";
foreach($pools as $pool) { foreach($pools as $pool) {
@ -27,9 +32,13 @@ class PoolsTheme extends Themelet {
return $editor; return $editor;
} }
/**
/* * HERE WE SHOWS THE LIST OF POOLS.
* HERE WE SHOWS THE LIST OF POOLS *
* @param Page $page
* @param array $pools
* @param int $pageNumber
* @param int $totalPages
*/ */
public function list_pools(Page $page, /*array*/ $pools, /*int*/ $pageNumber, /*int*/ $totalPages) { public function list_pools(Page $page, /*array*/ $pools, /*int*/ $pageNumber, /*int*/ $totalPages) {
global $user; global $user;
@ -105,7 +114,11 @@ class PoolsTheme extends Themelet {
$page->add_block(new Block("Create Pool", $create_html, "main", 20)); $page->add_block(new Block("Create Pool", $create_html, "main", 20));
} }
/**
* @param array $pools
* @param string $heading
* @param bool $check_all
*/
private function display_top(/*array*/ $pools, /*string*/ $heading, $check_all=false) { private function display_top(/*array*/ $pools, /*string*/ $heading, $check_all=false) {
global $page, $user; global $page, $user;
@ -150,8 +163,13 @@ class PoolsTheme extends Themelet {
} }
/* /**
* HERE WE DISPLAY THE POOL WITH TITLE DESCRIPTION AND IMAGES WITH PAGINATION * HERE WE DISPLAY THE POOL WITH TITLE DESCRIPTION AND IMAGES WITH PAGINATION.
*
* @param array $pools
* @param array $images
* @param int $pageNumber
* @param int $totalPages
*/ */
public function view_pool(/*array*/ $pools, /*array*/ $images, /*int*/ $pageNumber, /*int*/ $totalPages) { public function view_pool(/*array*/ $pools, /*array*/ $images, /*int*/ $pageNumber, /*int*/ $totalPages) {
global $user, $page; global $user, $page;
@ -176,8 +194,12 @@ class PoolsTheme extends Themelet {
} }
/* /**
* HERE WE DISPLAY THE POOL OPTIONS ON SIDEBAR BUT WE HIDE REMOVE OPTION IF THE USER IS NOT THE OWNER OR ADMIN * HERE WE DISPLAY THE POOL OPTIONS ON SIDEBAR BUT WE HIDE REMOVE OPTION IF THE USER IS NOT THE OWNER OR ADMIN.
*
* @param Page $page
* @param array $pool
* @param bool $check_all
*/ */
public function sidebar_options(Page $page, $pool, /*bool*/ $check_all) { public function sidebar_options(Page $page, $pool, /*bool*/ $check_all) {
global $user; global $user;
@ -240,8 +262,12 @@ class PoolsTheme extends Themelet {
} }
/* /**
* HERE WE DISPLAY THE RESULT OF THE SEARCH ON IMPORT * HERE WE DISPLAY THE RESULT OF THE SEARCH ON IMPORT.
*
* @param Page $page
* @param array $images
* @param int $pool_id
*/ */
public function pool_result(Page $page, /*array*/ $images, /*int*/ $pool_id) { public function pool_result(Page $page, /*array*/ $images, /*int*/ $pool_id) {
// TODO: this could / should be done using jQuery // TODO: this could / should be done using jQuery
@ -289,9 +315,13 @@ class PoolsTheme extends Themelet {
} }
/* /**
* HERE WE DISPLAY THE POOL ORDERER * HERE WE DISPLAY THE POOL ORDERER.
* WE LIST ALL IMAGES ON POOL WITHOUT PAGINATION AND WITH A TEXT INPUT TO SET A NUMBER AND CHANGE THE ORDER * WE LIST ALL IMAGES ON POOL WITHOUT PAGINATION AND WITH A TEXT INPUT TO SET A NUMBER AND CHANGE THE ORDER
*
* @param Page $page
* @param array $pools
* @param array $images
*/ */
public function edit_order(Page $page, /*array*/ $pools, /*array*/ $images) { public function edit_order(Page $page, /*array*/ $pools, /*array*/ $images) {
global $user; global $user;
@ -318,16 +348,19 @@ class PoolsTheme extends Themelet {
$page->add_block(new Block("Sorting Posts", $pool_images, "main", 30)); $page->add_block(new Block("Sorting Posts", $pool_images, "main", 30));
} }
/**
/* * HERE WE DISPLAY THE POOL EDITOR.
* HERE WE DISPLAY THE POOL EDITOR *
* WE LIST ALL IMAGES ON POOL WITHOUT PAGINATION AND WITH * WE LIST ALL IMAGES ON POOL WITHOUT PAGINATION AND WITH
* A CHECKBOX TO SELECT WHICH IMAGE WE WANT TO REMOVE * A CHECKBOX TO SELECT WHICH IMAGE WE WANT TO REMOVE
*
* @param Page $page
* @param array $pools
* @param array $images
*/ */
public function edit_pool(Page $page, /*array*/ $pools, /*array*/ $images) { public function edit_pool(Page $page, /*array*/ $pools, /*array*/ $images) {
global $user; global $user;
/* EDIT POOL DESCRIPTION */ /* EDIT POOL DESCRIPTION */
$desc_html = " $desc_html = "
".make_form(make_link("pool/edit_description"))." ".make_form(make_link("pool/edit_description"))."
@ -362,8 +395,12 @@ class PoolsTheme extends Themelet {
} }
/* /**
* HERE WE DISPLAY THE HISTORY LIST * HERE WE DISPLAY THE HISTORY LIST.
*
* @param array $histories
* @param int $pageNumber
* @param int $totalPages
*/ */
public function show_history($histories, /*int*/ $pageNumber, /*int*/ $totalPages) { public function show_history($histories, /*int*/ $pageNumber, /*int*/ $totalPages) {
global $page; global $page;

View File

@ -1,9 +1,12 @@
<?php <?php
class QRImageTheme extends Themelet { class QRImageTheme extends Themelet {
/**
* @param string $link
*/
public function links_block($link) { public function links_block($link) {
global $page; global $page;
$page->add_block( new Block( $page->add_block( new Block(
"QR Code","<img alt='QR Code' src='http://chart.apis.google.com/chart?chs=150x150&amp;cht=qr&amp;chl=$link' />","left",50)); "QR Code","<img alt='QR Code' src='http://chart.apis.google.com/chart?chs=150x150&amp;cht=qr&amp;chl={$link}' />","left",50));
} }
} }

View File

@ -22,7 +22,8 @@
class RandomImage extends Extension { class RandomImage extends Extension {
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $page;
if($event->page_matches("random_image")) { if($event->page_matches("random_image")) {
$action = ''; $action = '';
if($event->count_args() == 1) { if($event->count_args() == 1) {
@ -34,7 +35,7 @@ class RandomImage extends Extension {
$search_terms = explode(' ', $event->get_arg(1)); $search_terms = explode(' ', $event->get_arg(1));
} }
else { else {
# FIXME: throw exception throw new SCoreException("Error: too many arguments.");
} }
$image = Image::by_random($search_terms); $image = Image::by_random($search_terms);

View File

@ -1,12 +1,24 @@
<?php <?php
class RandomImageTheme extends Themelet { class RandomImageTheme extends Themelet
public function display_random(Page $page, Image $image) { {
/**
* @param Page $page
* @param Image $image
*/
public function display_random(Page $page, Image $image)
{
$page->add_block(new Block("Random Image", $this->build_random_html($image), "left", 8)); $page->add_block(new Block("Random Image", $this->build_random_html($image), "left", 8));
} }
public function build_random_html(Image $image, $query=null) { /**
global $config; * @param Image $image
* @param null|string $query
* @return string
*/
public function build_random_html(Image $image, $query = null)
{
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
@ -14,14 +26,14 @@ class RandomImageTheme extends Themelet {
$tsize = get_thumbnail_size($image->width, $image->height); $tsize = get_thumbnail_size($image->width, $image->height);
return " return "
<center><div> <center><div>
<a href='$h_view_link' style='position: relative; height: {$tsize[1]}px; width: {$tsize[0]}px;'> <a href='$h_view_link' style='position: relative; height: {$tsize[1]}px; width: {$tsize[0]}px;'>
<img id='thumb_rand_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'> <img id='thumb_rand_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'>
</a> </a>
</div></center> </div></center>
"; ";
} }
} }

View File

@ -1,4 +1,4 @@
<?php <?php
/* needed for access to build_thumb_html */ /* needed for access to build_thumb_html */
class RandomListTheme extends Themelet {} class RandomListTheme extends Themelet {}
?>

View File

@ -20,10 +20,18 @@
*/ */
class RatingSetEvent extends Event { class RatingSetEvent extends Event {
var $image, $rating; /** @var \Image */
public $image;
/** @var string */
public $rating;
/**
* @param Image $image
* @param string $rating
*/
public function __construct(Image $image, /*char*/ $rating) { public function __construct(Image $image, /*char*/ $rating) {
assert(in_array($rating, array("s", "q", "e", "u"))); assert(in_array($rating, array("s", "q", "e", "u")));
$this->image = $image; $this->image = $image;
$this->rating = $rating; $this->rating = $rating;
} }
@ -31,6 +39,9 @@ class RatingSetEvent extends Event {
class Ratings extends Extension { class Ratings extends Extension {
/**
* @return int
*/
public function get_priority() {return 50;} public function get_priority() {return 50;}
public function onInitExt(InitExtEvent $event) { public function onInitExt(InitExtEvent $event) {
@ -69,7 +80,7 @@ class Ratings extends Extension {
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
global $user, $database, $page; global $user, $page;
/** /**
* Deny images upon insufficient permissions. * Deny images upon insufficient permissions.
**/ **/
@ -97,8 +108,6 @@ class Ratings extends Extension {
} }
public function onImageInfoSet(ImageInfoSetEvent $event) { public function onImageInfoSet(ImageInfoSetEvent $event) {
global $user;
if($this->can_rate() && isset($_POST["rating"])) { if($this->can_rate() && isset($_POST["rating"])) {
send_event(new RatingSetEvent($event->image, $_POST['rating'])); send_event(new RatingSetEvent($event->image, $_POST['rating']));
} }
@ -125,11 +134,11 @@ class Ratings extends Extension {
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $database, $user, $page; global $user, $page;
if ($event->page_matches("admin/bulk_rate")) { if ($event->page_matches("admin/bulk_rate")) {
if(!$user->is_admin()) { if(!$user->is_admin()) {
throw PermissionDeniedException(); throw new PermissionDeniedException();
} }
else { else {
$n = 0; $n = 0;
@ -155,8 +164,13 @@ class Ratings extends Extension {
} }
} }
public static function get_user_privs($user) { /**
* @param \User $user
* @return null|string
*/
public static function get_user_privs(User $user) {
global $config; global $config;
if($user->is_anonymous()) { if($user->is_anonymous()) {
$sqes = $config->get_string("ext_rating_anon_privs"); $sqes = $config->get_string("ext_rating_anon_privs");
} }
@ -169,6 +183,10 @@ class Ratings extends Extension {
return $sqes; return $sqes;
} }
/**
* @param string $sqes
* @return string
*/
public static function privs_to_sql(/*string*/ $sqes) { public static function privs_to_sql(/*string*/ $sqes) {
$arr = array(); $arr = array();
$length = strlen($sqes); $length = strlen($sqes);
@ -179,6 +197,10 @@ class Ratings extends Extension {
return $set; return $set;
} }
/**
* @param string $rating
* @return string
*/
public static function rating_to_human(/*string*/ $rating) { public static function rating_to_human(/*string*/ $rating) {
switch($rating) { switch($rating) {
case "s": return "Safe"; case "s": return "Safe";
@ -188,7 +210,11 @@ class Ratings extends Extension {
} }
} }
// FIXME: this is a bit ugly and guessey, should have proper options /**
* FIXME: this is a bit ugly and guessey, should have proper options
*
* @return bool
*/
private function can_rate() { private function can_rate() {
global $config, $user; global $config, $user;
if($user->is_anonymous() && $config->get_string("ext_rating_anon_privs") == "sqeu") return false; if($user->is_anonymous() && $config->get_string("ext_rating_anon_privs") == "sqeu") return false;
@ -197,6 +223,10 @@ class Ratings extends Extension {
return false; return false;
} }
/**
* @param $context
* @return bool
*/
private function no_rating_query($context) { private function no_rating_query($context) {
foreach($context as $term) { foreach($context as $term) {
if(preg_match("/^rating[=|:]/", $term)) { if(preg_match("/^rating[=|:]/", $term)) {
@ -207,8 +237,7 @@ class Ratings extends Extension {
} }
private function install() { private function install() {
global $database; global $database, $config;
global $config;
if($config->get_int("ext_ratings2_version") < 1) { if($config->get_int("ext_ratings2_version") < 1) {
$database->Execute("ALTER TABLE images ADD COLUMN rating CHAR(1) NOT NULL DEFAULT 'u'"); $database->Execute("ALTER TABLE images ADD COLUMN rating CHAR(1) NOT NULL DEFAULT 'u'");
@ -227,6 +256,11 @@ class Ratings extends Extension {
} }
} }
/**
* @param int $image_id
* @param string $rating
* @param string $old_rating
*/
private function set_rating(/*int*/ $image_id, /*string*/ $rating, /*string*/ $old_rating) { private function set_rating(/*int*/ $image_id, /*string*/ $rating, /*string*/ $old_rating) {
global $database; global $database;
if($old_rating != $rating){ if($old_rating != $rating){

View File

@ -1,6 +1,11 @@
<?php <?php
class RatingsTheme extends Themelet { class RatingsTheme extends Themelet {
/**
* @param int $image_id
* @param string $rating
* @return string
*/
public function get_rater_html(/*int*/ $image_id, /*string*/ $rating) { public function get_rater_html(/*int*/ $image_id, /*string*/ $rating) {
$s_checked = $rating == 's' ? " checked" : ""; $s_checked = $rating == 's' ? " checked" : "";
$q_checked = $rating == 'q' ? " checked" : ""; $q_checked = $rating == 'q' ? " checked" : "";
@ -34,15 +39,6 @@ class RatingsTheme extends Themelet {
"; ";
$page->add_block(new Block("List Controls", $html, "left")); $page->add_block(new Block("List Controls", $html, "left"));
} }
public function rating_to_name(/*string*/ $rating) {
switch($rating) {
case 's': return "Safe";
case 'q': return "Questionable";
case 'e': return "Explicit";
default: return "Unknown";
}
}
} }

View File

@ -15,7 +15,7 @@
class RegenThumb extends Extension { class RegenThumb extends Extension {
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $page, $user;
if($event->page_matches("regen_thumb") && $user->can("delete_image") && isset($_POST['image_id'])) { if($event->page_matches("regen_thumb") && $user->can("delete_image") && isset($_POST['image_id'])) {
$image = Image::by_id(int_escape($_POST['image_id'])); $image = Image::by_id(int_escape($_POST['image_id']));

View File

@ -1,8 +1,11 @@
<?php <?php
class RegenThumbTheme extends Themelet { class RegenThumbTheme extends Themelet {
/* /**
* Show a form which offers to regenerate the thumb of an image with ID #$image_id * Show a form which offers to regenerate the thumb of an image with ID #$image_id
*
* @param int|string $image_id
* @return string
*/ */
public function get_buttons_html($image_id) { public function get_buttons_html($image_id) {
return " return "
@ -13,8 +16,11 @@ class RegenThumbTheme extends Themelet {
"; ";
} }
/* /**
* Show a link to the new thumbnail * Show a link to the new thumbnail.
*
* @param Page $page
* @param Image $image
*/ */
public function display_results(Page $page, Image $image) { public function display_results(Page $page, Image $image) {
$page->set_title("Thumbnail Regenerated"); $page->set_title("Thumbnail Regenerated");

View File

@ -21,7 +21,6 @@ class Relationships extends Extension {
} }
public function onImageInfoSet(ImageInfoSetEvent $event) { public function onImageInfoSet(ImageInfoSetEvent $event) {
global $user;
if(isset($_POST['tag_edit__tags']) ? !preg_match('/parent[=|:]/', $_POST["tag_edit__tags"]) : TRUE) { //Ignore tag_edit__parent if tags contain parent metatag if(isset($_POST['tag_edit__tags']) ? !preg_match('/parent[=|:]/', $_POST["tag_edit__tags"]) : TRUE) { //Ignore tag_edit__parent if tags contain parent metatag
if (isset($_POST["tag_edit__parent"]) ? ctype_digit($_POST["tag_edit__parent"]) : FALSE) { if (isset($_POST["tag_edit__parent"]) ? ctype_digit($_POST["tag_edit__parent"]) : FALSE) {
$this->set_parent($event->image->id, (int) $_POST["tag_edit__parent"]); $this->set_parent($event->image->id, (int) $_POST["tag_edit__parent"]);
@ -91,6 +90,10 @@ class Relationships extends Extension {
} }
} }
/**
* @param int $imageID
* @param int $parentID
*/
private function set_parent(/*int*/ $imageID, /*int*/ $parentID){ private function set_parent(/*int*/ $imageID, /*int*/ $parentID){
global $database; global $database;
@ -100,6 +103,10 @@ class Relationships extends Extension {
} }
} }
/**
* @param int $parentID
* @param int $childID
*/
private function set_child(/*int*/ $parentID, /*int*/ $childID){ private function set_child(/*int*/ $parentID, /*int*/ $childID){
global $database; global $database;
@ -109,6 +116,9 @@ class Relationships extends Extension {
} }
} }
/**
* @param int $imageID
*/
private function remove_parent(/*int*/ $imageID){ private function remove_parent(/*int*/ $imageID){
global $database; global $database;
$parentID = $database->get_one("SELECT parent_id FROM images WHERE id = :iid", array("iid"=>$imageID)); $parentID = $database->get_one("SELECT parent_id FROM images WHERE id = :iid", array("iid"=>$imageID));

View File

@ -1,6 +1,9 @@
<?php <?php
class RelationshipsTheme extends Themelet { class RelationshipsTheme extends Themelet {
/**
* @param \Image $image
*/
public function relationship_info($image) { public function relationship_info($image) {
global $page, $database; global $page, $database;
@ -25,6 +28,7 @@ class RelationshipsTheme extends Themelet {
public function get_parent_editor_html(Image $image) { public function get_parent_editor_html(Image $image) {
global $user; global $user;
$h_parent_id = $image->parent_id; $h_parent_id = $image->parent_id;
$s_parent_id = $h_parent_id ?: "None."; $s_parent_id = $h_parent_id ?: "None.";

View File

@ -10,18 +10,30 @@
*/ */
class RemoveReportedImageEvent extends Event { class RemoveReportedImageEvent extends Event {
var $id; /** @var int */
public $id;
/**
* @param int $id
*/
public function __construct($id) { public function __construct($id) {
$this->id = $id; $this->id = $id;
} }
} }
class AddReportedImageEvent extends Event { class AddReportedImageEvent extends Event {
var $reporter_id; /** @var int */
var $image_id; public $reporter_id;
var $reason; /** @var int */
public $image_id;
/** @var string */
public $reason;
/**
* @param int $image_id
* @param int $reporter_id
* @param string $reason
*/
public function __construct($image_id, $reporter_id, $reason) { public function __construct($image_id, $reporter_id, $reason) {
$this->reporter_id = $reporter_id; $this->reporter_id = $reporter_id;
$this->image_id = $image_id; $this->image_id = $image_id;
@ -89,7 +101,7 @@ class ReportImage extends Extension {
} }
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
global $config, $user, $page; global $user, $page;
if($user->can('create_image_report')) { if($user->can('create_image_report')) {
$reps = $this->get_reporters($event->image); $reps = $this->get_reporters($event->image);
$this->theme->display_image_banner($event->image, $reps); $this->theme->display_image_banner($event->image, $reps);
@ -112,8 +124,8 @@ class ReportImage extends Extension {
} }
protected function install() { protected function install() {
global $database; global $database, $config;
global $config;
if($config->get_int("ext_report_image_version") < 1) { if($config->get_int("ext_report_image_version") < 1) {
$database->create_table("image_reports", " $database->create_table("image_reports", "
id SCORE_AIPK, id SCORE_AIPK,
@ -127,8 +139,13 @@ class ReportImage extends Extension {
} }
} }
/**
* @param Image $image
* @return array
*/
public function get_reporters(Image $image) { public function get_reporters(Image $image) {
global $database; global $database;
return $database->get_col(" return $database->get_col("
SELECT users.name SELECT users.name
FROM image_reports FROM image_reports
@ -137,8 +154,12 @@ class ReportImage extends Extension {
", array("image_id" => $image->id)); ", array("image_id" => $image->id));
} }
/**
* @return array
*/
public function get_reported_images() { public function get_reported_images() {
global $config, $database; global $database;
$all_reports = $database->get_all(" $all_reports = $database->get_all("
SELECT image_reports.*, users.name AS reporter_name SELECT image_reports.*, users.name AS reporter_name
FROM image_reports FROM image_reports
@ -160,6 +181,9 @@ class ReportImage extends Extension {
return $reports; return $reports;
} }
/**
* @return mixed
*/
public function count_reported_images() { public function count_reported_images() {
global $database; global $database;

View File

@ -11,6 +11,10 @@
*/ */
class ReportImageTheme extends Themelet { class ReportImageTheme extends Themelet {
/**
* @param Page $page
* @param array $reports
*/
public function display_reported_images(Page $page, $reports) { public function display_reported_images(Page $page, $reports) {
global $config; global $config;
@ -57,11 +61,14 @@ class ReportImageTheme extends Themelet {
$page->set_heading("Reported Images"); $page->set_heading("Reported Images");
$page->add_block(new NavBlock()); $page->add_block(new NavBlock());
$page->add_block(new Block("Reported Images", $html)); $page->add_block(new Block("Reported Images", $html));
} }
/**
* @param Image $image
* @param array $reporters
*/
public function display_image_banner(Image $image, /*array*/ $reporters) { public function display_image_banner(Image $image, /*array*/ $reporters) {
global $config, $page; global $page;
$i_image = int_escape($image->id); $i_image = int_escape($image->id);
$html = ""; $html = "";

View File

@ -154,10 +154,15 @@ class ResizeImage extends Extension {
// Private functions // Private functions
/* ----------------------------- */ /* ----------------------------- */
/* /**
This function could be made much smaller by using the ImageReplaceEvent * This function could be made much smaller by using the ImageReplaceEvent
ie: Pretend that we are replacing the image with a resized copy. * ie: Pretend that we are replacing the image with a resized copy.
*/ *
* @param Image $image_obj
* @param int $width
* @param int $height
* @throws ImageResizeException
*/
private function resize_image(Image $image_obj, /*int*/ $width, /*int*/ $height) { private function resize_image(Image $image_obj, /*int*/ $width, /*int*/ $height) {
global $config, $user, $page, $database; global $config, $user, $page, $database;

View File

@ -16,8 +16,12 @@
* This class is just a wrapper around SCoreException. * This class is just a wrapper around SCoreException.
*/ */
class ImageRotateException extends SCoreException { class ImageRotateException extends SCoreException {
var $error; /** @var string */
public $error;
/**
* @param string $error
*/
public function __construct($error) { public function __construct($error) {
$this->error = $error; $this->error = $error;
} }
@ -101,10 +105,14 @@ class RotateImage extends Extension {
// Private functions // Private functions
/* ----------------------------- */ /* ----------------------------- */
/* /**
This function could be made much smaller by using the ImageReplaceEvent * This function could be made much smaller by using the ImageReplaceEvent
ie: Pretend that we are replacing the image with a rotated copy. * ie: Pretend that we are replacing the image with a rotated copy.
*/ *
* @param int $image_id
* @param int $deg
* @throws ImageRotateException
*/
private function rotate_image(/*int*/ $image_id, /*int*/ $deg) { private function rotate_image(/*int*/ $image_id, /*int*/ $deg) {
global $config, $user, $page, $database; global $config, $user, $page, $database;

View File

@ -1,12 +1,13 @@
<?php <?php
class RotateImageTheme extends Themelet { class RotateImageTheme extends Themelet {
/* /**
* Display a link to rotate an image * Display a link to rotate an image.
*
* @param int $image_id
* @return string
*/ */
public function get_rotate_html(/*int*/ $image_id) { public function get_rotate_html(/*int*/ $image_id) {
global $user, $config;
$html = " $html = "
".make_form(make_link('rotate/'.$image_id), 'POST')." ".make_form(make_link('rotate/'.$image_id), 'POST')."
<input type='hidden' name='image_id' value='$image_id'> <input type='hidden' name='image_id' value='$image_id'>
@ -18,6 +19,13 @@ class RotateImageTheme extends Themelet {
return $html; return $html;
} }
/**
* Display the error.
*
* @param Page $page
* @param string $title
* @param string $message
*/
public function display_rotate_error(Page $page, /*string*/ $title, /*string*/ $message) { public function display_rotate_error(Page $page, /*string*/ $title, /*string*/ $message) {
$page->set_title("Rotate Image"); $page->set_title("Rotate Image");
$page->set_heading("Rotate Image"); $page->set_heading("Rotate Image");

View File

@ -33,6 +33,11 @@ class RSS_Images extends Extension {
} }
} }
/**
* @param array $images
* @param array $search_terms
* @param int $page_number
*/
private function do_rss($images, $search_terms, /*int*/ $page_number) { private function do_rss($images, $search_terms, /*int*/ $page_number) {
global $page; global $page;
global $config; global $config;
@ -78,6 +83,10 @@ class RSS_Images extends Extension {
$page->set_data($xml); $page->set_data($xml);
} }
/**
* @param Image $image
* @return string
*/
private function thumb(Image $image) { private function thumb(Image $image) {
global $database; global $database;

View File

@ -12,8 +12,12 @@
* activated; new config options are in $_POST * activated; new config options are in $_POST
*/ */
class ConfigSaveEvent extends Event { class ConfigSaveEvent extends Event {
var $config; /** @var \Config */
public $config;
/**
* @param Config $config
*/
public function __construct(Config $config) { public function __construct(Config $config) {
$this->config = $config; $this->config = $config;
} }
@ -24,8 +28,12 @@ class ConfigSaveEvent extends Event {
* Sent when the setup page is ready to be added to * Sent when the setup page is ready to be added to
*/ */
class SetupBuildingEvent extends Event { class SetupBuildingEvent extends Event {
var $panel; /** @var \SetupPanel */
public $panel;
/**
* @param SetupPanel $panel
*/
public function __construct(SetupPanel $panel) { public function __construct(SetupPanel $panel) {
$this->panel = $panel; $this->panel = $panel;
} }
@ -35,8 +43,12 @@ class SetupBuildingEvent extends Event {
* *
*/ */
class SetupPanel { class SetupPanel {
var $blocks = array(); /** @var \SetupBlock[] */
public $blocks = array();
/**
* @param SetupBlock $block
*/
public function add_block(SetupBlock $block) { public function add_block(SetupBlock $block) {
$this->blocks[] = $block; $this->blocks[] = $block;
} }
@ -46,9 +58,14 @@ class SetupPanel {
* *
*/ */
class SetupBlock extends Block { class SetupBlock extends Block {
var $header; /** @var string */
var $body; public $header;
/** @var string */
public $body;
/**
* @param string $title
*/
public function __construct($title) { public function __construct($title) {
$this->header = $title; $this->header = $title;
$this->section = "main"; $this->section = "main";
@ -56,20 +73,31 @@ class SetupBlock extends Block {
$this->body = ""; $this->body = "";
} }
/**
* @param string $text
*/
public function add_label($text) { public function add_label($text) {
$this->body .= $text; $this->body .= $text;
} }
/**
* @param string $name
* @param null|string $label
*/
public function add_text_option($name, $label=null) { public function add_text_option($name, $label=null) {
global $config; global $config;
$val = html_escape($config->get_string($name)); $val = html_escape($config->get_string($name));
if(!is_null($label)) { if(!is_null($label)) {
$this->body .= "<label for='$name'>$label</label>"; $this->body .= "<label for='{$name}'>{$label}</label>";
} }
$this->body .= "<input type='text' id='$name' name='_config_$name' value='$val'>\n"; $this->body .= "<input type='text' id='{$name}' name='_config_{$name}' value='{$val}'>\n";
$this->body .= "<input type='hidden' name='_type_$name' value='string'>\n"; $this->body .= "<input type='hidden' name='_type_{$name}' value='string'>\n";
} }
/**
* @param string $name
* @param null|string $label
*/
public function add_longtext_option($name, $label=null) { public function add_longtext_option($name, $label=null) {
global $config; global $config;
$val = html_escape($config->get_string($name)); $val = html_escape($config->get_string($name));
@ -81,6 +109,10 @@ class SetupBlock extends Block {
$this->body .= "<input type='hidden' name='_type_$name' value='string'>\n"; $this->body .= "<input type='hidden' name='_type_$name' value='string'>\n";
} }
/**
* @param string $name
* @param null|string $label
*/
public function add_bool_option($name, $label=null) { public function add_bool_option($name, $label=null) {
global $config; global $config;
$checked = $config->get_bool($name) ? " checked" : ""; $checked = $config->get_bool($name) ? " checked" : "";
@ -97,6 +129,10 @@ class SetupBlock extends Block {
// $this->body .= "<input type='hidden' id='$name' name='$name' value='$val'>"; // $this->body .= "<input type='hidden' id='$name' name='$name' value='$val'>";
// } // }
/**
* @param string $name
* @param null|string $label
*/
public function add_int_option($name, $label=null) { public function add_int_option($name, $label=null) {
global $config; global $config;
$val = html_escape($config->get_string($name)); $val = html_escape($config->get_string($name));
@ -107,6 +143,10 @@ class SetupBlock extends Block {
$this->body .= "<input type='hidden' name='_type_$name' value='int'>\n"; $this->body .= "<input type='hidden' name='_type_$name' value='int'>\n";
} }
/**
* @param string $name
* @param null|string $label
*/
public function add_shorthand_int_option($name, $label=null) { public function add_shorthand_int_option($name, $label=null) {
global $config; global $config;
$val = to_shorthand_int($config->get_string($name)); $val = to_shorthand_int($config->get_string($name));

View File

@ -42,7 +42,7 @@ class _SafeImage {
$this->posted = $img->posted_timestamp; $this->posted = $img->posted_timestamp;
$this->source = $img->source; $this->source = $img->source;
$this->owner_id = $img->owner_id; $this->owner_id = $img->owner_id;
$this->tags = $img->tag_array; $this->tags = $img->get_tag_array();
} }
} }

View File

@ -19,7 +19,7 @@
* For Shimmie2 specific extensions, there is a ShimmieWebTestCase class which * For Shimmie2 specific extensions, there is a ShimmieWebTestCase class which
* includes functions to upload and delete images. * includes functions to upload and delete images.
* *
* For a quick guide on the spcifics of how to write tests, see \ref wut * For a quick guide on the specifics of how to write tests, see \ref wut
* *
* *
* \page wut Writing Unit Tests * \page wut Writing Unit Tests
@ -88,19 +88,24 @@ define('ADMIN_NAME', "demo");
define('ADMIN_PASS', "demo"); define('ADMIN_PASS', "demo");
/** /**
* A set of common SCore activities to test * Class SCoreWebTestCase
*
* A set of common SCore activities to test.
*/ */
class SCoreWebTestCase extends WebTestCase { class SCoreWebTestCase extends WebTestCase {
/** /**
* Click on a link or a button * Click on a link or a button.
* @param string $text
* @return string
*/ */
public function click($text) { public function click($text) {
return parent::click($text); return parent::click($text);
} }
/** /**
* Click the virtual browser's back button * Click the virtual browser's back button.
* @return bool
*/ */
public function back() { public function back() {
return parent::back(); return parent::back();
@ -165,9 +170,16 @@ class SCoreWebTestCase extends WebTestCase {
} }
/** /**
* A set of common Shimmie activities to test * Class ShimmieWebTestCase
*
* A set of common Shimmie activities to test.
*/ */
class ShimmieWebTestCase extends SCoreWebTestCase { class ShimmieWebTestCase extends SCoreWebTestCase {
/**
* @param string $filename
* @param string|string[] $tags
* @return int
*/
protected function post_image($filename, $tags) { protected function post_image($filename, $tags) {
$image_id = -1; $image_id = -1;
$this->setMaximumRedirects(0); $this->setMaximumRedirects(0);
@ -195,6 +207,9 @@ class ShimmieWebTestCase extends SCoreWebTestCase {
return $image_id; return $image_id;
} }
/**
* @param int $image_id
*/
protected function delete_image($image_id) { protected function delete_image($image_id) {
if($image_id > 0) { if($image_id > 0) {
$this->get_page('post/view/'.$image_id); $this->get_page('post/view/'.$image_id);

View File

@ -1,4 +1,5 @@
<?php <?php
/* /*
* Name: XML Sitemap * Name: XML Sitemap
* Author: Sein Kraft <mail@seinkraft.info> * Author: Sein Kraft <mail@seinkraft.info>
@ -9,159 +10,181 @@
* Documentation: * Documentation:
*/ */
class XMLSitemap extends Extension { class XMLSitemap extends Extension
private $sitemap_queue = ""; {
private $sitemap_filepath = ""; // set onPageRequest private $sitemap_queue = "";
private $sitemap_filepath = ""; // set onPageRequest
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event)
if($event->page_matches("sitemap.xml")) {
{ if ($event->page_matches("sitemap.xml")) {
global $config; global $config;
$this->sitemap_filepath = $_SERVER['DOCUMENT_ROOT']."/data/cache/sitemap.xml"; $this->sitemap_filepath = $_SERVER['DOCUMENT_ROOT'] . "/data/cache/sitemap.xml";
// determine if new sitemap needs to be generated // determine if new sitemap needs to be generated
if ($this->new_sitemap_needed()) if ($this->new_sitemap_needed()) {
{ // determine which type of sitemap to generate
// determine which type of sitemap to generate if ($config->get_bool("sitemap_generatefull", false)) {
if ($config->get_bool("sitemap_generatefull",false)) $this->handle_full_sitemap(); // default false until cache fixed
$this->handle_full_sitemap(); // default false until cache fixed } else {
else $this->handle_smaller_sitemap();
$this->handle_smaller_sitemap(); }
} } else $this->display_existing_sitemap();
else $this->display_existing_sitemap(); }
}
} }
public function onSetupBuilding(SetupBuildingEvent $event) { public function onSetupBuilding(SetupBuildingEvent $event)
{
$sb = new SetupBlock("Sitemap"); $sb = new SetupBlock("Sitemap");
$sb->add_bool_option("sitemap_generatefull", "Generate full sitemap"); $sb->add_bool_option("sitemap_generatefull", "Generate full sitemap");
$sb->add_label("<br>(Enabled: every image and tag in sitemap, generation takes longer)"); $sb->add_label("<br>(Enabled: every image and tag in sitemap, generation takes longer)");
$sb->add_label("<br>(Disabled: only display the last 50 uploads in the sitemap)"); $sb->add_label("<br>(Disabled: only display the last 50 uploads in the sitemap)");
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
// sitemap with only the latest 50 images // sitemap with only the latest 50 images
private function handle_smaller_sitemap() private function handle_smaller_sitemap()
{ {
/* --- Add latest images to sitemap with higher priority --- */ /* --- Add latest images to sitemap with higher priority --- */
$latestimages = Image::find_images(0, 50, array()); $latestimages = Image::find_images(0, 50, array());
$latestimages_urllist = array(); $latestimages_urllist = array();
foreach($latestimages as $arrayid => $image) foreach ($latestimages as $arrayid => $image) {
// 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)); }
/* --- Display page --- */ $this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", $image->posted_timestamp));
// when sitemap is ok, display it from the file
$this->generate_display_sitemap();
}
// Full sitemap /* --- Display page --- */
private function handle_full_sitemap() // when sitemap is ok, display it from the file
{ $this->generate_display_sitemap();
global $database, $config; }
// add index // Full sitemap
$index = array(); private function handle_full_sitemap()
$index[0] = $config->get_string("front_page"); {
$this->add_sitemap_queue($index, "weekly", "1"); global $database, $config;
/* --- Add 20 most used tags --- */ // add index
$popular_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 0,20"); $index = array();
foreach($popular_tags as $arrayid => $tag) { $index[0] = $config->get_string("front_page");
$tag = $tag['tag']; $this->add_sitemap_queue($index, "weekly", "1");
$popular_tags[$arrayid] = "post/list/$tag/";
}
$this->add_sitemap_queue($popular_tags, "monthly", "0.9" /* not sure how to deal with date here */);
/* --- Add latest images to sitemap with higher priority --- */ /* --- Add 20 most used tags --- */
$latestimages = Image::find_images(0, 50, array()); $popular_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 0,20");
$latestimages_urllist = array(); foreach ($popular_tags as $arrayid => $tag) {
foreach($latestimages as $arrayid => $image) $tag = $tag['tag'];
// create url from image id's $popular_tags[$arrayid] = "post/list/$tag/";
$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($popular_tags, "monthly", "0.9" /* not sure how to deal with date here */);
/* --- Add other tags --- */ /* --- Add latest images to sitemap with higher priority --- */
$other_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 21,10000000"); $latestimages = Image::find_images(0, 50, array());
foreach($other_tags as $arrayid => $tag) { $latestimages_urllist = array();
$tag = $tag['tag']; foreach ($latestimages as $arrayid => $image) {
// create url from tags (tagme ignored) // create url from image id's
if ($tag != "tagme") $latestimages_urllist[$arrayid] = "post/view/$image->id";
$other_tags[$arrayid] = "post/list/$tag/"; }
} $this->add_sitemap_queue($latestimages_urllist, "monthly", "0.8", date("Y-m-d", $image->posted_timestamp));
$this->add_sitemap_queue($other_tags, "monthly", "0.7" /* not sure how to deal with date here */);
/* --- Add all other images to sitemap with lower priority --- */ /* --- Add other tags --- */
$otherimages = Image::find_images(51, 10000000, array()); $other_tags = $database->get_all("SELECT tag, count FROM tags ORDER BY `count` DESC LIMIT 21,10000000");
foreach($otherimages as $arrayid => $image) foreach ($other_tags as $arrayid => $tag) {
// create url from image id's $tag = $tag['tag'];
$otherimages[$arrayid] = "post/view/$image->id"; // create url from tags (tagme ignored)
$this->add_sitemap_queue($otherimages, "monthly", "0.6", date("Y-m-d", $image->posted_timestamp)); if ($tag != "tagme")
$other_tags[$arrayid] = "post/list/$tag/";
}
$this->add_sitemap_queue($other_tags, "monthly", "0.7" /* not sure how to deal with date here */);
/* --- Add all other images to sitemap with lower priority --- */
$otherimages = Image::find_images(51, 10000000, array());
foreach ($otherimages as $arrayid => $image) {
// create url from image id's
$otherimages[$arrayid] = "post/view/$image->id";
}
$this->add_sitemap_queue($otherimages, "monthly", "0.6", date("Y-m-d", $image->posted_timestamp));
/* --- Display page --- */ /* --- Display page --- */
// when sitemap is ok, display it from the file // when sitemap is ok, display it from the file
$this->generate_display_sitemap(); $this->generate_display_sitemap();
} }
// Adds an array of urls to the sitemap with the given information /**
private function add_sitemap_queue(/*array(urls)*/ $urls, $changefreq="monthly", $priority="0.5", $date="2013-02-01") { * Adds an array of urls to the sitemap with the given information.
foreach($urls as $url) { *
$link = make_http(make_link("$url")); * @param array $urls
$this->sitemap_queue .= " * @param string $changefreq
* @param string $priority
* @param string $date
*/
private function add_sitemap_queue( /*array(urls)*/ $urls, $changefreq = "monthly",
$priority = "0.5", $date = "2013-02-01")
{
foreach ($urls as $url) {
$link = make_http(make_link("$url"));
$this->sitemap_queue .= "
<url> <url>
<loc>$link</loc> <loc>$link</loc>
<lastmod>$date</lastmod> <lastmod>$date</lastmod>
<changefreq>$changefreq</changefreq> <changefreq>$changefreq</changefreq>
<priority>$priority</priority> <priority>$priority</priority>
</url>"; </url>";
} }
} }
// sets sitemap with entries in sitemap_queue // sets sitemap with entries in sitemap_queue
private function generate_display_sitemap() private function generate_display_sitemap()
{ {
global $page; global $page;
$xml = "<"."?xml version=\"1.0\" encoding=\"utf-8\"?"."> $xml = "<" . "?xml version=\"1.0\" encoding=\"utf-8\"?" . ">
<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">
$this->sitemap_queue $this->sitemap_queue
</urlset>"; </urlset>";
// Generate new sitemap // Generate new sitemap
file_put_contents($this->sitemap_filepath, $xml); file_put_contents($this->sitemap_filepath, $xml);
$page->set_mode("data"); $page->set_mode("data");
$page->set_type("application/xml"); $page->set_type("application/xml");
$page->set_data($xml); $page->set_data($xml);
} }
// returns true if a new sitemap is needed /**
private function new_sitemap_needed() * Returns true if a new sitemap is needed.
{ *
$sitemap_generation_interval = 86400; // allow new site map every day * @return bool
$last_generated_time = filemtime($this->sitemap_filepath); */
private function new_sitemap_needed()
{
$sitemap_generation_interval = 86400; // allow new site map every day
$last_generated_time = filemtime($this->sitemap_filepath);
// if file doesn't exist, return true // if file doesn't exist, return true
if ($last_generated_time == false) return true; if ($last_generated_time == false) {
return true;
}
// if it's been a day since last sitemap creation, return true // if it's been a day since last sitemap creation, return true
if ($last_generated_time + $sitemap_generation_interval < time()) if ($last_generated_time + $sitemap_generation_interval < time()) {
return true; return true;
else return false; } else {
} return false;
}
}
private function display_existing_sitemap() private function display_existing_sitemap()
{ {
global $page; global $page;
$xml = file_get_contents($this->sitemap_filepath); $xml = file_get_contents($this->sitemap_filepath);
$page->set_mode("data"); $page->set_mode("data");
$page->set_type("application/xml"); $page->set_type("application/xml");
$page->set_data($xml); $page->set_data($xml);
} }
} }

View File

@ -113,8 +113,9 @@ class Source_History extends Extension {
} }
} }
/* /**
* this function is called when a revert request is received * This function is called when a revert request is received.
* @param int $revert_id
*/ */
private function process_revert_request($revert_id) { private function process_revert_request($revert_id) {
global $page; global $page;
@ -202,6 +203,10 @@ class Source_History extends Extension {
$this->theme->display_revert_ip_results(); $this->theme->display_revert_ip_results();
} }
/**
* @param int $revert_id
* @return mixed|null
*/
public function get_source_history_from_revert(/*int*/ $revert_id) { public function get_source_history_from_revert(/*int*/ $revert_id) {
global $database; global $database;
$row = $database->get_row(" $row = $database->get_row("
@ -212,6 +217,10 @@ class Source_History extends Extension {
return ($row ? $row : null); return ($row ? $row : null);
} }
/**
* @param int $image_id
* @return array
*/
public function get_source_history_from_id(/*int*/ $image_id) { public function get_source_history_from_id(/*int*/ $image_id) {
global $database; global $database;
$row = $database->get_all(" $row = $database->get_all("
@ -224,6 +233,10 @@ class Source_History extends Extension {
return ($row ? $row : array()); return ($row ? $row : array());
} }
/**
* @param int $page_id
* @return array
*/
public function get_global_source_history($page_id) { public function get_global_source_history($page_id) {
global $database; global $database;
$row = $database->get_all(" $row = $database->get_all("
@ -236,8 +249,12 @@ class Source_History extends Extension {
return ($row ? $row : array()); return ($row ? $row : array());
} }
/* /**
* This function attempts to revert all changes by a given IP within an (optional) timeframe. * This function attempts to revert all changes by a given IP within an (optional) timeframe.
*
* @param string $name
* @param string $ip
* @param string $date
*/ */
public function process_revert_all_changes($name, $ip, $date) { public function process_revert_all_changes($name, $ip, $date) {
global $database; global $database;
@ -332,8 +349,10 @@ class Source_History extends Extension {
log_info("source_history", 'Reverted '.count($result).' edits.'); log_info("source_history", 'Reverted '.count($result).' edits.');
} }
/* /**
* this function is called just before an images source is changed * This function is called just before an images source is changed.
* @param Image $image
* @param string $source
*/ */
private function add_source_history($image, $source) { private function add_source_history($image, $source) {
global $database, $config, $user; global $database, $config, $user;

View File

@ -2,6 +2,11 @@
class Source_HistoryTheme extends Themelet { class Source_HistoryTheme extends Themelet {
var $messages = array(); var $messages = array();
/**
* @param Page $page
* @param int $image_id
* @param array $history
*/
public function display_history_page(Page $page, /*int*/ $image_id, /*array*/ $history) { public function display_history_page(Page $page, /*int*/ $image_id, /*array*/ $history) {
global $user; global $user;
$start_string = " $start_string = "
@ -45,6 +50,11 @@ class Source_HistoryTheme extends Themelet {
$page->add_block(new Block("Source History", $history_html, "main", 10)); $page->add_block(new Block("Source History", $history_html, "main", 10));
} }
/**
* @param Page $page
* @param array $history
* @param int $page_number
*/
public function display_global_page(Page $page, /*array*/ $history, /*int*/ $page_number) { public function display_global_page(Page $page, /*array*/ $history, /*int*/ $page_number) {
$start_string = " $start_string = "
<div style='text-align: left'> <div style='text-align: left'>
@ -93,8 +103,9 @@ class Source_HistoryTheme extends Themelet {
$page->add_block(new Block("Navigation", $nav, "left")); $page->add_block(new Block("Navigation", $nav, "left"));
} }
/* /**
* Add a section to the admin page. * Add a section to the admin page.
* @param string $validation_msg
*/ */
public function display_admin_block(/*string*/ $validation_msg='') { public function display_admin_block(/*string*/ $validation_msg='') {
global $page; global $page;
@ -130,6 +141,10 @@ class Source_HistoryTheme extends Themelet {
$page->add_block(new Block("Bulk Revert Results", $html)); $page->add_block(new Block("Bulk Revert Results", $html));
} }
/**
* @param string $title
* @param string $body
*/
public function add_status(/*string*/ $title, /*string*/ $body) { public function add_status(/*string*/ $title, /*string*/ $body) {
$this->messages[] = '<p><b>'. $title .'</b><br>'. $body .'</p>'; $this->messages[] = '<p><b>'. $title .'</b><br>'. $body .'</p>';
} }

View File

@ -76,6 +76,9 @@ class StatsDInterface extends Extension {
StatsDInterface::$stats["shimmie.events.info-sets"] = "1|c"; StatsDInterface::$stats["shimmie.events.info-sets"] = "1|c";
} }
/**
* @return int
*/
public function get_priority() {return 99;} public function get_priority() {return 99;}

View File

@ -40,9 +40,15 @@
* *
*/ */
class OwnerSetEvent extends Event { class OwnerSetEvent extends Event {
var $image; /** @var \Image */
var $owner; public $image;
/** @var \User */
public $owner;
/**
* @param Image $image
* @param User $owner
*/
public function __construct(Image $image, User $owner) { public function __construct(Image $image, User $owner) {
$this->image = $image; $this->image = $image;
$this->owner = $owner; $this->owner = $owner;
@ -57,9 +63,15 @@ class OwnerSetEvent extends Event {
* *
*/ */
class SourceSetEvent extends Event { class SourceSetEvent extends Event {
var $image; /** @var \Image */
var $source; public $image;
/** @var string */
public $source;
/**
* @param Image $image
* @param string $source
*/
public function __construct(Image $image, $source) { public function __construct(Image $image, $source) {
$this->image = $image; $this->image = $image;
$this->source = $source; $this->source = $source;
@ -74,7 +86,8 @@ class SourceSetEvent extends Event {
* *
*/ */
class TagSetEvent extends Event { class TagSetEvent extends Event {
var $image; /** @var \Image */
public $image;
var $tags; var $tags;
public function __construct(Image $image, $tags) { public function __construct(Image $image, $tags) {
@ -90,9 +103,15 @@ class TagSetEvent extends Event {
* *
*/ */
class LockSetEvent extends Event { class LockSetEvent extends Event {
var $image; /** @var \Image */
var $locked; public $image;
/** @var bool */
public $locked;
/**
* @param Image $image
* @param bool $locked
*/
public function __construct(Image $image, $locked) { public function __construct(Image $image, $locked) {
assert(is_bool($locked)); assert(is_bool($locked));
$this->image = $image; $this->image = $image;
@ -107,13 +126,17 @@ class LockSetEvent extends Event {
class TagTermParseEvent extends Event { class TagTermParseEvent extends Event {
var $term = null; var $term = null;
var $id = null; var $id = null;
var $metatag = false; /** @var bool */
public $metatag = false;
public function __construct($term, $id) { public function __construct($term, $id) {
$this->term = $term; $this->term = $term;
$this->id = $id; $this->id = $id;
} }
/**
* @return bool
*/
public function is_metatag() { public function is_metatag() {
return $this->metatag; return $this->metatag;
} }
@ -150,10 +173,14 @@ class TagEdit extends Extension {
} }
public function onImageInfoSet(ImageInfoSetEvent $event) { public function onImageInfoSet(ImageInfoSetEvent $event) {
global $user, $page; global $user;
if($user->can("edit_image_owner")) { if($user->can("edit_image_owner")) {
$owner = User::by_name($_POST['tag_edit__owner']); $owner = User::by_name($_POST['tag_edit__owner']);
send_event(new OwnerSetEvent($event->image, $owner)); if ($owner instanceof User) {
send_event(new OwnerSetEvent($event->image, $owner));
} else {
throw new NullUserException("Error: No user with that name was found.");
}
} }
if($this->can_tag($event->image) && isset($_POST['tag_edit__tags'])) { if($this->can_tag($event->image) && isset($_POST['tag_edit__tags'])) {
send_event(new TagSetEvent($event->image, $_POST['tag_edit__tags'])); send_event(new TagSetEvent($event->image, $_POST['tag_edit__tags']));
@ -205,13 +232,15 @@ class TagEdit extends Extension {
$this->theme->display_mass_editor(); $this->theme->display_mass_editor();
} }
// When an alias is added, oldtag becomes inaccessable /**
* When an alias is added, oldtag becomes inaccessible.
* @param AddAliasEvent $event
*/
public function onAddAlias(AddAliasEvent $event) { public function onAddAlias(AddAliasEvent $event) {
$this->mass_tag_edit($event->oldtag, $event->newtag); $this->mass_tag_edit($event->oldtag, $event->newtag);
} }
public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) { public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) {
global $user;
$event->add_part($this->theme->get_user_editor_html($event->image), 39); $event->add_part($this->theme->get_user_editor_html($event->image), 39);
$event->add_part($this->theme->get_tag_editor_html($event->image), 40); $event->add_part($this->theme->get_tag_editor_html($event->image), 40);
$event->add_part($this->theme->get_source_editor_html($event->image), 41); $event->add_part($this->theme->get_source_editor_html($event->image), 41);
@ -229,19 +258,30 @@ class TagEdit extends Extension {
if(!empty($matches)) $event->metatag = true; if(!empty($matches)) $event->metatag = true;
} }
/**
* @param Image $image
* @return bool
*/
private function can_tag(Image $image) { private function can_tag(Image $image) {
global $config, $user; global $user;
return ($user->can("edit_image_tag") || !$image->is_locked()); return ($user->can("edit_image_tag") || !$image->is_locked());
} }
/**
* @param Image $image
* @return bool
*/
private function can_source(Image $image) { private function can_source(Image $image) {
global $config, $user; global $user;
return ($user->can("edit_image_source") || !$image->is_locked()); return ($user->can("edit_image_source") || !$image->is_locked());
} }
/**
* @param string $search
* @param string $replace
*/
private function mass_tag_edit($search, $replace) { private function mass_tag_edit($search, $replace) {
global $database; global $database;
global $config;
$search_set = Tag::explode(strtolower($search), false); $search_set = Tag::explode(strtolower($search), false);
$replace_set = Tag::explode(strtolower($replace), false); $replace_set = Tag::explode(strtolower($replace), false);
@ -296,10 +336,11 @@ class TagEdit extends Extension {
} }
} }
/**
* @param string|string[] $tags
* @param string $source
*/
private function mass_source_edit($tags, $source) { private function mass_source_edit($tags, $source) {
global $database;
global $config;
$tags = Tag::explode($tags); $tags = Tag::explode($tags);
$last_id = -1; $last_id = -1;

View File

@ -99,6 +99,10 @@ class TagEditTheme extends Themelet {
"; ";
} }
/**
* @param string $source
* @return string
*/
protected function format_source(/*string*/ $source) { protected function format_source(/*string*/ $source) {
if(!empty($source)) { if(!empty($source)) {
if(!startsWith($source, "http://") && !startsWith($source, "https://")) { if(!startsWith($source, "http://") && !startsWith($source, "https://")) {

View File

@ -51,7 +51,11 @@ class TagEditCloud extends Extension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
private function build_tag_map($image) { /**
* @param Image $image
* @return string
*/
private function build_tag_map(Image $image) {
global $database, $config; global $database, $config;
$html = ""; $html = "";
@ -75,23 +79,26 @@ class TagEditCloud extends Extension {
} }
} }
$tag_data = null;
switch($sort_method){ switch($sort_method){
case 'a': case 'a':
case 'p': case 'p':
$tag_data = $database->get_all("SELECT tag, FLOOR(LN(LN(count - :tag_min1 + 1)+1)*150)/200 AS scaled, count default:
FROM tags WHERE count >= :tag_min2 ORDER BY ".($sort_method == 'a' ? "tag" : "count DESC")." LIMIT :limit", $tag_data = $database->get_all("SELECT tag, FLOOR(LN(LN(count - :tag_min1 + 1)+1)*150)/200 AS scaled, count
array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count)); FROM tags WHERE count >= :tag_min2 ORDER BY ".($sort_method == 'a' ? "tag" : "count DESC")." LIMIT :limit",
break;
case 'r':
$relevant_tags = array_diff($image->get_tag_array(),$ignore_tags);
if(count($relevant_tags) > 0) {
$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)); array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count));
} break;
break; case 'r':
$relevant_tags = array_diff($image->get_tag_array(),$ignore_tags);
if(count($relevant_tags) > 0) {
$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;
} }
$counter = 1; $counter = 1;
@ -115,15 +122,15 @@ class TagEditCloud extends Extension {
$size = sprintf("%.2f", max($row['scaled'],0.5)); $size = sprintf("%.2f", max($row['scaled'],0.5));
$js = htmlspecialchars('tageditcloud_toggle_tag(this,'.json_encode($full_tag).')',ENT_QUOTES); //Ugly, but it works $js = htmlspecialchars('tageditcloud_toggle_tag(this,'.json_encode($full_tag).')',ENT_QUOTES); //Ugly, but it works
if(array_search($row['tag'],$image->tag_array) !== FALSE) { if(array_search($row['tag'],$image->get_tag_array()) !== FALSE) {
if($used_first) { if($used_first) {
$precloud .= "&nbsp;<span onclick='$js' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span>&nbsp;\n"; $precloud .= "&nbsp;<span onclick='{$js}' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>{$h_tag}</span>&nbsp;\n";
continue; continue;
} else { } else {
$entry = "&nbsp;<span onclick='$js' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span>&nbsp;\n"; $entry = "&nbsp;<span onclick='{$js}' class='tag-selected' style='font-size: ${size}em$color' title='${row['count']}'>{$h_tag}</span>&nbsp;\n";
} }
} else { } else {
$entry = "&nbsp;<span onclick='$js' style='font-size: ${size}em$color' title='${row['count']}'>$h_tag</span>&nbsp;\n"; $entry = "&nbsp;<span onclick='{$js}' style='font-size: ${size}em$color' title='${row['count']}'>{$h_tag}</span>&nbsp;\n";
} }
if($counter++ <= $def_count) { if($counter++ <= $def_count) {
@ -134,24 +141,28 @@ class TagEditCloud extends Extension {
} }
if($precloud != '') { if($precloud != '') {
$html .= "<div id='tagcloud_set'>$precloud</div>"; $html .= "<div id='tagcloud_set'>{$precloud}</div>";
} }
if($postcloud != '') { if($postcloud != '') {
$postcloud = "<div id='tagcloud_extra' style='display: none;'>$postcloud</div>"; $postcloud = "<div id='tagcloud_extra' style='display: none;'>{$postcloud}</div>";
} }
$html .= "<div id='tagcloud_unset'>$cloud$postcloud</div>"; $html .= "<div id='tagcloud_unset'>{$cloud}{$postcloud}</div>";
if($sort_method != 'a' && $counter > $def_count) { if($sort_method != 'a' && $counter > $def_count) {
$rem = $counter - $def_count; $rem = $counter - $def_count;
$html .= "</div><br>[<span onclick='tageditcloud_toggle_extra(this);' style='color: #0000EF; font-weight:bold;'>show $rem more tags</span>]"; $html .= "</div><br>[<span onclick='tageditcloud_toggle_extra(this);' style='color: #0000EF; font-weight:bold;'>show {$rem} more tags</span>]";
} }
return "<div id='tageditcloud' class='tageditcloud'>$html</div>"; // FIXME: stupidasallhell return "<div id='tageditcloud' class='tageditcloud'>{$html}</div>"; // FIXME: stupidasallhell
} }
private function can_tag($image) { /**
* @param Image $image
* @return bool
*/
private function can_tag(Image $image) {
global $user; global $user;
return ($user->can("edit_image_tag") && (!$image->is_locked() || $user->can("edit_image_lock"))); return ($user->can("edit_image_tag") && (!$image->is_locked() || $user->can("edit_image_lock")));
} }

View File

@ -24,7 +24,7 @@ class Tag_History extends Extension {
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $page, $user; global $page, $user;
if($event->page_matches("tag_history/revert")) { if($event->page_matches("tag_history/revert")) {
// this is a request to revert to a previous version of the tags // this is a request to revert to a previous version of the tags
@ -113,8 +113,11 @@ class Tag_History extends Extension {
} }
} }
/* /**
* this function is called when a revert request is received * This function is called when a revert request is received.
*
* @param int $revert_id
* @throws ImageDoesNotExist
*/ */
private function process_revert_request($revert_id) { private function process_revert_request($revert_id) {
global $page; global $page;
@ -200,6 +203,10 @@ class Tag_History extends Extension {
$this->theme->display_revert_ip_results(); $this->theme->display_revert_ip_results();
} }
/**
* @param int $revert_id
* @return mixed|null
*/
public function get_tag_history_from_revert(/*int*/ $revert_id) { public function get_tag_history_from_revert(/*int*/ $revert_id) {
global $database; global $database;
$row = $database->get_row(" $row = $database->get_row("
@ -210,6 +217,10 @@ class Tag_History extends Extension {
return ($row ? $row : null); return ($row ? $row : null);
} }
/**
* @param int $image_id
* @return array
*/
public function get_tag_history_from_id(/*int*/ $image_id) { public function get_tag_history_from_id(/*int*/ $image_id) {
global $database; global $database;
$row = $database->get_all(" $row = $database->get_all("
@ -222,6 +233,10 @@ class Tag_History extends Extension {
return ($row ? $row : array()); return ($row ? $row : array());
} }
/**
* @param int $page_id
* @return array
*/
public function get_global_tag_history($page_id) { public function get_global_tag_history($page_id) {
global $database; global $database;
$row = $database->get_all(" $row = $database->get_all("
@ -328,16 +343,19 @@ class Tag_History extends Extension {
log_info("tag_history", 'Reverted '.count($result).' edits.'); log_info("tag_history", 'Reverted '.count($result).' edits.');
} }
/* /**
* this function is called just before an images tag are changed * This function is called just before an images tag are changed.
*
* @param Image $image
* @param string|string[] $tags
*/ */
private function add_tag_history($image, $tags) { private function add_tag_history(Image $image, $tags) {
global $database, $config, $user; global $database, $config, $user;
$new_tags = Tag::implode($tags); $new_tags = Tag::implode($tags);
$old_tags = Tag::implode($image->get_tag_array()); $old_tags = Tag::implode($image->get_tag_array());
if($new_tags == $old_tags) return; if($new_tags == $old_tags) { return; }
if(empty($old_tags)) { if(empty($old_tags)) {
/* no old tags, so we are probably adding the image for the first time */ /* no old tags, so we are probably adding the image for the first time */
@ -348,7 +366,7 @@ class Tag_History extends Extension {
} }
$allowed = $config->get_int("history_limit"); $allowed = $config->get_int("history_limit");
if($allowed == 0) return; if($allowed == 0) { return; }
// if the image has no history, make one with the old tags // if the image has no history, make one with the old tags
$entries = $database->get_one("SELECT COUNT(*) FROM tag_histories WHERE image_id = ?", array($image->id)); $entries = $database->get_one("SELECT COUNT(*) FROM tag_histories WHERE image_id = ?", array($image->id));
@ -368,7 +386,7 @@ class Tag_History extends Extension {
$entries++; $entries++;
// if needed remove oldest one // if needed remove oldest one
if($allowed == -1) return; if($allowed == -1) { return; }
if($entries > $allowed) { if($entries > $allowed) {
// TODO: Make these queries better // TODO: Make these queries better
/* /*

View File

@ -7,6 +7,11 @@
class Tag_HistoryTheme extends Themelet { class Tag_HistoryTheme extends Themelet {
var $messages = array(); var $messages = array();
/**
* @param Page $page
* @param int $image_id
* @param array $history
*/
public function display_history_page(Page $page, /*int*/ $image_id, /*array*/ $history) { public function display_history_page(Page $page, /*int*/ $image_id, /*array*/ $history) {
global $user; global $user;
$start_string = " $start_string = "
@ -57,6 +62,11 @@ class Tag_HistoryTheme extends Themelet {
$page->add_block(new Block("Tag History", $history_html, "main", 10)); $page->add_block(new Block("Tag History", $history_html, "main", 10));
} }
/**
* @param Page $page
* @param array $history
* @param int $page_number
*/
public function display_global_page(Page $page, /*array*/ $history, /*int*/ $page_number) { public function display_global_page(Page $page, /*array*/ $history, /*int*/ $page_number) {
$start_string = " $start_string = "
<div style='text-align: left'> <div style='text-align: left'>
@ -105,8 +115,10 @@ class Tag_HistoryTheme extends Themelet {
$page->add_block(new Block("Navigation", $nav, "left")); $page->add_block(new Block("Navigation", $nav, "left"));
} }
/* /**
* Add a section to the admin page. * Add a section to the admin page.
*
* @param string $validation_msg
*/ */
public function display_admin_block(/*string*/ $validation_msg='') { public function display_admin_block(/*string*/ $validation_msg='') {
global $page; global $page;
@ -142,6 +154,10 @@ class Tag_HistoryTheme extends Themelet {
$page->add_block(new Block("Bulk Revert Results", $html)); $page->add_block(new Block("Bulk Revert Results", $html));
} }
/**
* @param string $title
* @param string $body
*/
public function add_status(/*string*/ $title, /*string*/ $body) { public function add_status(/*string*/ $title, /*string*/ $body) {
$this->messages[] = '<p><b>'. $title .'</b><br>'. $body .'</p>'; $this->messages[] = '<p><b>'. $title .'</b><br>'. $body .'</p>';
} }

View File

@ -121,6 +121,10 @@ class TagList extends Extension {
} }
// }}} // }}}
// misc {{{ // misc {{{
/**
* @param string $tag
* @return string
*/
private function tag_link(/*string*/ $tag) { private function tag_link(/*string*/ $tag) {
$u_tag = url_escape($tag); $u_tag = url_escape($tag);
return make_link("post/list/$u_tag/1"); return make_link("post/list/$u_tag/1");
@ -129,7 +133,8 @@ class TagList extends Extension {
/** /**
* Get the minimum number of times a tag needs to be used * Get the minimum number of times a tag needs to be used
* in order to be considered in the tag list. * in order to be considered in the tag list.
* @retval int *
* @return int
*/ */
private function get_tags_min() { private function get_tags_min() {
if(isset($_GET['mincount'])) { if(isset($_GET['mincount'])) {
@ -141,6 +146,9 @@ class TagList extends Extension {
} }
} }
/**
* @return string
*/
private function get_starts_with() { private function get_starts_with() {
global $config; global $config;
if(isset($_GET['starts_with'])) { if(isset($_GET['starts_with'])) {
@ -156,6 +164,9 @@ class TagList extends Extension {
} }
} }
/**
* @return string
*/
private function build_az() { private function build_az() {
global $database; global $database;
@ -179,6 +190,10 @@ class TagList extends Extension {
} }
// }}} // }}}
// maps {{{ // maps {{{
/**
* @return string
*/
private function build_navigation() { private function build_navigation() {
$h_index = "<a href='".make_link()."'>Index</a>"; $h_index = "<a href='".make_link()."'>Index</a>";
$h_map = "<a href='".make_link("tags/map")."'>Map</a>"; $h_map = "<a href='".make_link("tags/map")."'>Map</a>";
@ -189,6 +204,9 @@ class TagList extends Extension {
return "$h_index<br>&nbsp;<br>$h_map<br>$h_alphabetic<br>$h_popularity<br>$h_cats<br>&nbsp;<br>$h_all"; return "$h_index<br>&nbsp;<br>$h_map<br>$h_alphabetic<br>$h_popularity<br>$h_cats<br>&nbsp;<br>$h_all";
} }
/**
* @return string
*/
private function build_tag_map() { private function build_tag_map() {
global $config, $database; global $config, $database;
@ -226,6 +244,9 @@ class TagList extends Extension {
return $html; return $html;
} }
/**
* @return string
*/
private function build_tag_alphabetic() { private function build_tag_alphabetic() {
global $config, $database; global $config, $database;
@ -279,6 +300,9 @@ class TagList extends Extension {
return $html; return $html;
} }
/**
* @return string
*/
private function build_tag_popularity() { private function build_tag_popularity() {
global $database; global $database;
@ -318,6 +342,9 @@ class TagList extends Extension {
return $html; return $html;
} }
/**
* @return string
*/
private function build_tag_list() { private function build_tag_list() {
global $database; global $database;
@ -344,9 +371,12 @@ class TagList extends Extension {
} }
// }}} // }}}
// blocks {{{ // blocks {{{
/**
* @param Page $page
* @param Image $image
*/
private function add_related_block(Page $page, Image $image) { private function add_related_block(Page $page, Image $image) {
global $database; global $database, $config;
global $config;
$query = " $query = "
SELECT t3.tag AS tag, t3.count AS calc_count, it3.tag_id SELECT t3.tag AS tag, t3.count AS calc_count, it3.tag_id
@ -376,9 +406,12 @@ class TagList extends Extension {
} }
} }
/**
* @param Page $page
* @param Image $image
*/
private function add_split_tags_block(Page $page, Image $image) { private function add_split_tags_block(Page $page, Image $image) {
global $database; global $database;
global $config;
$query = " $query = "
SELECT tags.tag, tags.count as calc_count SELECT tags.tag, tags.count as calc_count
@ -395,9 +428,12 @@ class TagList extends Extension {
} }
} }
/**
* @param Page $page
* @param Image $image
*/
private function add_tags_block(Page $page, Image $image) { private function add_tags_block(Page $page, Image $image) {
global $database; global $database;
global $config;
$query = " $query = "
SELECT tags.tag, tags.count as calc_count SELECT tags.tag, tags.count as calc_count
@ -414,9 +450,11 @@ class TagList extends Extension {
} }
} }
/**
* @param Page $page
*/
private function add_popular_block(Page $page) { private function add_popular_block(Page $page) {
global $database; global $database, $config;
global $config;
$tags = $database->cache->get("popular_tags"); $tags = $database->cache->get("popular_tags");
if(empty($tags)) { if(empty($tags)) {
@ -437,9 +475,12 @@ class TagList extends Extension {
} }
} }
/**
* @param Page $page
* @param string[] $search
*/
private function add_refine_block(Page $page, /*array(string)*/ $search) { private function add_refine_block(Page $page, /*array(string)*/ $search) {
global $database; global $database, $config;
global $config;
$wild_tags = Tag::explode($search); $wild_tags = Tag::explode($search);
$str_search = Tag::implode($search); $str_search = Tag::implode($search);

View File

@ -1,13 +1,23 @@
<?php <?php
class TagListTheme extends Themelet { class TagListTheme extends Themelet {
var $heading = ""; /** @var string */
var $list = ""; public $heading = "";
/** @var string|string[] */
public $list = "";
public $navigation;
/**
* @param string $text
*/
public function set_heading($text) { public function set_heading($text) {
$this->heading = $text; $this->heading = $text;
} }
/**
* @param string|string[] $list
*/
public function set_tag_list($list) { public function set_tag_list($list) {
$this->list = $list; $this->list = $list;
} }
@ -219,6 +229,11 @@ class TagListTheme extends Themelet {
return array($category, $display_html); return array($category, $display_html);
} }
/**
* @param string $tag
* @param string[] $tags
* @return string
*/
protected function ars(/*string*/ $tag, /*array(string)*/ $tags) { protected function ars(/*string*/ $tag, /*array(string)*/ $tags) {
assert(is_array($tags)); assert(is_array($tags));
@ -234,6 +249,11 @@ class TagListTheme extends Themelet {
return $html; return $html;
} }
/**
* @param array $tags
* @param string $tag
* @return string
*/
protected function get_remove_link($tags, $tag) { protected function get_remove_link($tags, $tag) {
if(!in_array($tag, $tags) && !in_array("-$tag", $tags)) { if(!in_array($tag, $tags) && !in_array("-$tag", $tags)) {
return ""; return "";
@ -245,6 +265,11 @@ class TagListTheme extends Themelet {
} }
} }
/**
* @param array $tags
* @param string $tag
* @return string
*/
protected function get_add_link($tags, $tag) { protected function get_add_link($tags, $tag) {
if(in_array($tag, $tags)) { if(in_array($tag, $tags)) {
return ""; return "";
@ -256,6 +281,11 @@ class TagListTheme extends Themelet {
} }
} }
/**
* @param array $tags
* @param string $tag
* @return string
*/
protected function get_subtract_link($tags, $tag) { protected function get_subtract_link($tags, $tag) {
if(in_array("-$tag", $tags)) { if(in_array("-$tag", $tags)) {
return ""; return "";
@ -267,6 +297,10 @@ class TagListTheme extends Themelet {
} }
} }
/**
* @param string $tag
* @return string
*/
protected function tag_link($tag) { protected function tag_link($tag) {
$u_tag = url_escape($tag); $u_tag = url_escape($tag);
return make_link("post/list/$u_tag/1"); return make_link("post/list/$u_tag/1");

View File

@ -132,10 +132,13 @@ class Tips extends Extension {
$this->theme->showAll($url, $tips); $this->theme->showAll($url, $tips);
} }
/**
* @param int $tipID
*/
private function setStatus($tipID) { private function setStatus($tipID) {
global $database; global $database;
$tip = $database->get_row("SELECT * FROM tips WHERE id = ? ", array($tipID)); $tip = $database->get_row("SELECT * FROM tips WHERE id = ? ", array(int_escape($tipID)));
if (bool_escape($tip['enable'])) { if (bool_escape($tip['enable'])) {
$enable = "N"; $enable = "N";
@ -143,12 +146,15 @@ class Tips extends Extension {
$enable = "Y"; $enable = "Y";
} }
$database->execute("UPDATE tips SET enable = ? WHERE id = ?", array ($enable, $tipID)); $database->execute("UPDATE tips SET enable = ? WHERE id = ?", array ($enable, int_escape($tipID)));
} }
/**
* @param int $tipID
*/
private function deleteTip($tipID) { private function deleteTip($tipID) {
global $database; global $database;
$database->execute("DELETE FROM tips WHERE id = ?", array($tipID)); $database->execute("DELETE FROM tips WHERE id = ?", array(int_escape($tipID)));
} }
} }

View File

@ -46,6 +46,9 @@ class Update extends Extension {
} }
} }
/**
* @return bool
*/
private function download_shimmie() { private function download_shimmie() {
global $config; global $config;
@ -70,6 +73,9 @@ class Update extends Extension {
return false; return false;
} }
/**
* @return bool
*/
private function update_shimmie() { private function update_shimmie() {
global $config, $page; global $config, $page;

View File

@ -10,14 +10,23 @@
* Occurs when some data is being uploaded. * Occurs when some data is being uploaded.
*/ */
class DataUploadEvent extends Event { class DataUploadEvent extends Event {
var $tmpname, $metadata, $hash, $type, $image_id = -1; /** @var string */
public $tmpname;
/** @var array */
public $metadata;
/** @var string */
public $hash;
/** @var string */
public $type;
/** @var int */
public $image_id = -1;
/** /**
* Some data is being uploaded. * Some data is being uploaded.
* This should be caught by a file handler. * This should be caught by a file handler.
* -- Removed: param $user The user uploading the data. * -- Removed: param $user The user uploading the data.
* @param $tmpname string The temporary file used for upload. * @param string $tmpname The temporary file used for upload.
* @param $metadata array Info about the file, should contain at least "filename", "extension", "tags" and "source". * @param array $metadata Info about the file, should contain at least "filename", "extension", "tags" and "source".
*/ */
public function __construct(/*string*/ $tmpname, /*array*/ $metadata) { public function __construct(/*string*/ $tmpname, /*array*/ $metadata) {
assert(file_exists($tmpname)); assert(file_exists($tmpname));
@ -42,10 +51,14 @@ class UploadException extends SCoreException {}
* This also includes transloaded files as well. * This also includes transloaded files as well.
*/ */
class Upload extends Extension { class Upload extends Extension {
/** @var bool */
public $is_full; public $is_full;
// early, so it can stop the DataUploadEvent before any data handlers see it /**
* Early, so it can stop the DataUploadEvent before any data handlers see it.
*
* @return int
*/
public function get_priority() {return 40;} public function get_priority() {return 40;}
public function onInitExt(InitExtEvent $event) { public function onInitExt(InitExtEvent $event) {
@ -109,8 +122,8 @@ class Upload extends Extension {
} }
} }
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $page, $user; global $page, $user;
if($event->page_matches("upload/replace")) { if($event->page_matches("upload/replace")) {
// check if the user is an administrator and can upload files. // check if the user is an administrator and can upload files.
@ -215,6 +228,10 @@ class Upload extends Extension {
} }
} }
/**
* @param string|int $id
* @return array
*/
private function tags_for_upload_slot($id) { private function tags_for_upload_slot($id) {
if(isset($_POST["tags$id"])) { if(isset($_POST["tags$id"])) {
# merge then explode, not explode then merge - else # merge then explode, not explode then merge - else
@ -237,8 +254,8 @@ class Upload extends Extension {
* *
* TODO: Make these messages user/admin editable * TODO: Make these messages user/admin editable
* *
* @param $error_code integer PHP error code * @param int $error_code PHP error code
* @return String * @return string
*/ */
private function upload_error_message($error_code) { private function upload_error_message($error_code) {
switch ($error_code) { switch ($error_code) {
@ -316,11 +333,12 @@ class Upload extends Extension {
/** /**
* Handle an transload. * Handle an transload.
* @param $url *
* @param $tags * @param string $url
* @param $source * @param mixed $tags
* @param string $source
* @param string $replace * @param string $replace
* @return bool TRUE on transload successful. * @return bool Returns TRUE on transload successful.
*/ */
private function try_transload($url, $tags, $source, $replace='') { private function try_transload($url, $tags, $source, $replace='') {
global $page, $config, $user; global $page, $config, $user;
@ -360,7 +378,6 @@ class Upload extends Extension {
"No data found -- perhaps the site has hotlink protection?"); "No data found -- perhaps the site has hotlink protection?");
$ok = false; $ok = false;
}else{ }else{
global $user;
$pathinfo = pathinfo($url); $pathinfo = pathinfo($url);
$metadata = array(); $metadata = array();
$metadata['filename'] = $filename; $metadata['filename'] = $filename;

View File

@ -37,6 +37,9 @@ class UploadTheme extends Themelet {
} }
} }
/**
* @return string
*/
protected function h_upload_list_1() { protected function h_upload_list_1() {
global $config; global $config;
$upload_list = ""; $upload_list = "";
@ -83,6 +86,9 @@ class UploadTheme extends Themelet {
return $upload_list; return $upload_list;
} }
/**
* @return string
*/
protected function h_upload_List_2() { protected function h_upload_List_2() {
global $config; global $config;
@ -180,6 +186,9 @@ class UploadTheme extends Themelet {
return $upload_list; return $upload_list;
} }
/**
* @return string
*/
protected function h_bookmarklets() { protected function h_bookmarklets() {
global $config; global $config;
$link = make_http(make_link("upload")); $link = make_http(make_link("upload"));
@ -232,7 +241,12 @@ class UploadTheme extends Themelet {
return $html; return $html;
} }
/* only allows 1 file to be uploaded - for replacing another image file */ /**
* Only allows 1 file to be uploaded - for replacing another image file.
*
* @param Page $page
* @param int $image_id
*/
public function display_replace_page(Page $page, /*int*/ $image_id) { public function display_replace_page(Page $page, /*int*/ $image_id) {
global $config, $page; global $config, $page;
$tl_enabled = ($config->get_string("transload_engine", "none") != "none"); $tl_enabled = ($config->get_string("transload_engine", "none") != "none");
@ -276,6 +290,10 @@ class UploadTheme extends Themelet {
$page->add_block(new Block("Upload Replacement Image", $html, "main", 20)); $page->add_block(new Block("Upload Replacement Image", $html, "main", 20));
} }
/**
* @param Page $page
* @param bool $ok
*/
public function display_upload_status(Page $page, /*bool*/ $ok) { public function display_upload_status(Page $page, /*bool*/ $ok) {
if($ok) { if($ok) {
$page->set_mode("redirect"); $page->set_mode("redirect");
@ -288,10 +306,18 @@ class UploadTheme extends Themelet {
} }
} }
/**
* @param Page $page
* @param string $title
* @param string $message
*/
public function display_upload_error(Page $page, /*string*/ $title, /*string*/ $message) { public function display_upload_error(Page $page, /*string*/ $title, /*string*/ $message) {
$page->add_block(new Block($title, $message)); $page->add_block(new Block($title, $message));
} }
/**
* @return string
*/
protected function build_upload_block() { protected function build_upload_block() {
global $config; global $config;

View File

@ -6,8 +6,14 @@
*/ */
class UserBlockBuildingEvent extends Event { class UserBlockBuildingEvent extends Event {
var $parts = array(); /** @var array */
public $parts = array();
/**
* @param string $name
* @param string $link
* @param int $position
*/
public function add_link($name, $link, $position=50) { public function add_link($name, $link, $position=50) {
while(isset($this->parts[$position])) $position++; while(isset($this->parts[$position])) $position++;
$this->parts[$position] = array("name" => $name, "link" => $link); $this->parts[$position] = array("name" => $name, "link" => $link);
@ -15,24 +21,41 @@ class UserBlockBuildingEvent extends Event {
} }
class UserPageBuildingEvent extends Event { class UserPageBuildingEvent extends Event {
var $display_user; /** @var \User */
var $stats = array(); public $display_user;
/** @var array */
public $stats = array();
/**
* @param User $display_user
*/
public function __construct(User $display_user) { public function __construct(User $display_user) {
$this->display_user = $display_user; $this->display_user = $display_user;
} }
/**
* @param string $html
* @param int $position
*/
public function add_stats($html, $position=50) { public function add_stats($html, $position=50) {
while(isset($this->stats[$position])) $position++; while(isset($this->stats[$position])) { $position++; }
$this->stats[$position] = $html; $this->stats[$position] = $html;
} }
} }
class UserCreationEvent extends Event { class UserCreationEvent extends Event {
var $username; /** @var string */
var $password; public $username;
var $email; /** @var string */
public $password;
/** @var string */
public $email;
/**
* @param string $name
* @param string $pass
* @param string $email
*/
public function __construct($name, $pass, $email) { public function __construct($name, $pass, $email) {
$this->username = $name; $this->username = $name;
$this->password = $pass; $this->password = $pass;
@ -41,8 +64,12 @@ class UserCreationEvent extends Event {
} }
class UserDeletionEvent extends Event { class UserDeletionEvent extends Event {
var $id; /** @var int */
public $id;
/**
* @param int $id
*/
public function __construct($id) { public function __construct($id) {
$this->id = $id; $this->id = $id;
} }
@ -65,7 +92,7 @@ class UserPage extends Extension {
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $config, $page, $user;
// user info is shown on all pages // user info is shown on all pages
if($user->is_anonymous()) { if($user->is_anonymous()) {
@ -221,8 +248,11 @@ class UserPage extends Extension {
} }
} }
/**
* @param UserPageBuildingEvent $event
*/
public function onUserPageBuilding(UserPageBuildingEvent $event) { public function onUserPageBuilding(UserPageBuildingEvent $event) {
global $page, $user, $config; global $user, $config;
$h_join_date = autodate($event->display_user->join_date); $h_join_date = autodate($event->display_user->join_date);
if($event->display_user->can("hellbanned")) { if($event->display_user->can("hellbanned")) {
@ -251,6 +281,9 @@ class UserPage extends Extension {
} }
} }
/**
* @param UserPageBuildingEvent $event
*/
private function display_stats(UserPageBuildingEvent $event) { private function display_stats(UserPageBuildingEvent $event) {
global $user, $page, $config; global $user, $page, $config;
@ -273,6 +306,9 @@ class UserPage extends Extension {
} }
} }
/**
* @param SetupBuildingEvent $event
*/
public function onSetupBuilding(SetupBuildingEvent $event) { public function onSetupBuilding(SetupBuildingEvent $event) {
global $config; global $config;
@ -301,23 +337,32 @@ class UserPage extends Extension {
"<br>Rating: "); "<br>Rating: ");
} }
$sb->add_choice_option("user_loginshowprofile", array( $sb->add_choice_option("user_loginshowprofile", array(
"return to previous page" => 0, // 0 is default "return to previous page" => 0, // 0 is default
"send to user profile" => 1), "send to user profile" => 1),
"<br>When user logs in/out"); "<br>When user logs in/out");
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
/**
* @param UserBlockBuildingEvent $event
*/
public function onUserBlockBuilding(UserBlockBuildingEvent $event) { public function onUserBlockBuilding(UserBlockBuildingEvent $event) {
$event->add_link("My Profile", make_link("user")); $event->add_link("My Profile", make_link("user"));
$event->add_link("Log Out", make_link("user_admin/logout"), 99); $event->add_link("Log Out", make_link("user_admin/logout"), 99);
} }
/**
* @param UserCreationEvent $event
*/
public function onUserCreation(UserCreationEvent $event) { public function onUserCreation(UserCreationEvent $event) {
$this->check_user_creation($event); $this->check_user_creation($event);
$this->create_user($event); $this->create_user($event);
} }
/**
* @param SearchTermParseEvent $event
*/
public function onSearchTermParse(SearchTermParseEvent $event) { public function onSearchTermParse(SearchTermParseEvent $event) {
global $user; global $user;
@ -343,9 +388,11 @@ class UserPage extends Extension {
} }
// }}} // }}}
// Things done *with* the user {{{ // Things done *with* the user {{{
/**
* @param Page $page
*/
private function login(Page $page) { private function login(Page $page) {
global $user; global $user, $config;
global $config;
$name = $_POST['user']; $name = $_POST['user'];
$pass = $_POST['pass']; $pass = $_POST['pass'];
@ -379,13 +426,18 @@ class UserPage extends Extension {
} }
} }
private function check_user_creation($event) { // FIXME type /**
* @param UserCreationEvent $event
* @throws UserCreationException
*/
private function check_user_creation(UserCreationEvent $event)
{
global $database;
$name = $event->username; $name = $event->username;
$pass = $event->password; $pass = $event->password;
$email = $event->email; $email = $event->email;
global $database;
if(strlen($name) < 1) { if(strlen($name) < 1) {
throw new UserCreationException("Username must be at least 1 character"); throw new UserCreationException("Username must be at least 1 character");
} }
@ -399,7 +451,8 @@ class UserPage extends Extension {
} }
} }
private function create_user($event) { // FIXME type private function create_user(UserCreationEvent $event)
{
global $database, $user; global $database, $user;
$hash = md5(strtolower($event->username) . $event->password); $hash = md5(strtolower($event->username) . $event->password);
@ -417,6 +470,10 @@ class UserPage extends Extension {
log_info("user", "Created User #$uid ({$event->username})"); log_info("user", "Created User #$uid ({$event->username})");
} }
/**
* @param string $name
* @param string $pass
*/
private function set_login_cookie(/*string*/ $name, /*string*/ $pass) { private function set_login_cookie(/*string*/ $name, /*string*/ $pass) {
global $config; global $config;
@ -430,6 +487,11 @@ class UserPage extends Extension {
} }
//}}} //}}}
// Things done *to* the user {{{ // Things done *to* the user {{{
/**
* @param User $a
* @param User $b
* @return bool
*/
private function user_can_edit_user(User $a, User $b) { private function user_can_edit_user(User $a, User $b) {
if($a->is_anonymous()) { if($a->is_anonymous()) {
$this->theme->display_error(401, "Error", "You aren't logged in"); $this->theme->display_error(401, "Error", "You aren't logged in");
@ -469,6 +531,11 @@ class UserPage extends Extension {
} }
} }
/**
* @param User $duser
* @param string $pass1
* @param string $pass2
*/
private function change_password_wrapper(User $duser, $pass1, $pass2) { private function change_password_wrapper(User $duser, $pass1, $pass2) {
global $user; global $user;
@ -490,6 +557,10 @@ class UserPage extends Extension {
} }
} }
/**
* @param User $duser
* @param string $address
*/
private function change_email_wrapper(User $duser, /*string(email)*/ $address) { private function change_email_wrapper(User $duser, /*string(email)*/ $address) {
global $user; global $user;
@ -501,6 +572,11 @@ class UserPage extends Extension {
} }
} }
/**
* @param User $duser
* @param string $class
* @throws NullUserException
*/
private function change_class_wrapper(User $duser, /*string(class)*/ $class) { private function change_class_wrapper(User $duser, /*string(class)*/ $class) {
global $user; global $user;
@ -517,6 +593,10 @@ class UserPage extends Extension {
} }
// }}} // }}}
// ips {{{ // ips {{{
/**
* @param User $duser
* @return array
*/
private function count_upload_ips(User $duser) { private function count_upload_ips(User $duser) {
global $database; global $database;
$rows = $database->get_pairs(" $rows = $database->get_pairs("
@ -530,6 +610,11 @@ class UserPage extends Extension {
ORDER BY most_recent DESC", array("id"=>$duser->id)); ORDER BY most_recent DESC", array("id"=>$duser->id));
return $rows; return $rows;
} }
/**
* @param User $duser
* @return array
*/
private function count_comment_ips(User $duser) { private function count_comment_ips(User $duser) {
global $database; global $database;
$rows = $database->get_pairs(" $rows = $database->get_pairs("
@ -544,10 +629,13 @@ class UserPage extends Extension {
return $rows; return $rows;
} }
/**
* @param Page $page
* @param bool $with_images
* @param bool $with_comments
*/
private function delete_user(Page $page, /*boolean*/ $with_images=false, /*boolean*/ $with_comments=false) { private function delete_user(Page $page, /*boolean*/ $with_images=false, /*boolean*/ $with_comments=false) {
global $user; global $user, $config, $database;
global $config;
global $database;
$page->set_title("Error"); $page->set_title("Error");
$page->set_heading("Error"); $page->set_heading("Error");

View File

@ -110,6 +110,11 @@ class UserPageTheme extends Themelet {
$page->add_block(new Block("Login", $html, "left", 90)); $page->add_block(new Block("Login", $html, "left", 90));
} }
/**
* @param Page $page
* @param array $uploads
* @param array $comments
*/
public function display_ip_list(Page $page, $uploads, $comments) { public function display_ip_list(Page $page, $uploads, $comments) {
$html = "<table id='ip-history'>"; $html = "<table id='ip-history'>";
$html .= "<tr><td>Uploaded from: "; $html .= "<tr><td>Uploaded from: ";

View File

@ -15,27 +15,46 @@
* which only appears when an image actually exists. * which only appears when an image actually exists.
*/ */
class DisplayingImageEvent extends Event { class DisplayingImageEvent extends Event {
var $image, $page, $context; /** @var \Image */
public $image;
public $page, $context;
/**
* @param Image $image
*/
public function __construct(Image $image) { public function __construct(Image $image) {
$this->image = $image; $this->image = $image;
} }
/**
* @return Image
*/
public function get_image() { public function get_image() {
return $this->image; return $this->image;
} }
} }
class ImageInfoBoxBuildingEvent extends Event { class ImageInfoBoxBuildingEvent extends Event {
var $parts = array(); /** @var array */
var $image; public $parts = array();
var $user; /** @var \Image */
public $image;
/** @var \User */
public $user;
/**
* @param Image $image
* @param User $user
*/
public function __construct(Image $image, User $user) { public function __construct(Image $image, User $user) {
$this->image = $image; $this->image = $image;
$this->user = $user; $this->user = $user;
} }
/**
* @param string $html
* @param int $position
*/
public function add_part($html, $position=50) { public function add_part($html, $position=50) {
while(isset($this->parts[$position])) $position++; while(isset($this->parts[$position])) $position++;
$this->parts[$position] = $html; $this->parts[$position] = $html;
@ -43,23 +62,38 @@ class ImageInfoBoxBuildingEvent extends Event {
} }
class ImageInfoSetEvent extends Event { class ImageInfoSetEvent extends Event {
var $image; /** @var \Image */
public $image;
/**
* @param Image $image
*/
public function __construct(Image $image) { public function __construct(Image $image) {
$this->image = $image; $this->image = $image;
} }
} }
class ImageAdminBlockBuildingEvent extends Event { class ImageAdminBlockBuildingEvent extends Event {
/** @var array */
var $parts = array(); var $parts = array();
var $image = null; /** @var \Image|null */
var $user = null; public $image = null;
/** @var null|\User */
public $user = null;
/**
* @param Image $image
* @param User $user
*/
public function __construct(Image $image, User $user) { public function __construct(Image $image, User $user) {
$this->image = $image; $this->image = $image;
$this->user = $user; $this->user = $user;
} }
/**
* @param string $html
* @param int $position
*/
public function add_part(/*string*/ $html, /*int*/ $position=50) { public function add_part(/*string*/ $html, /*int*/ $position=50) {
while(isset($this->parts[$position])) $position++; while(isset($this->parts[$position])) $position++;
$this->parts[$position] = $html; $this->parts[$position] = $html;

View File

@ -9,9 +9,15 @@
*/ */
class WikiUpdateEvent extends Event { class WikiUpdateEvent extends Event {
var $user; /** @var \User */
var $wikipage; public $user;
/** @var \WikiPage */
public $wikipage;
/**
* @param User $user
* @param WikiPage $wikipage
*/
public function __construct(User $user, WikiPage $wikipage) { public function __construct(User $user, WikiPage $wikipage) {
$this->user = $user; $this->user = $user;
$this->wikipage = $wikipage; $this->wikipage = $wikipage;
@ -22,32 +28,52 @@ class WikiUpdateException extends SCoreException {
} }
class WikiPage { class WikiPage {
var $id; /** @var int|string */
public $id;
var $owner_id; var $owner_id;
var $owner_ip; var $owner_ip;
var $date; var $date;
var $title;
/** @var string */
public $title;
var $revision; var $revision;
var $locked;
var $body;
public function __construct($row) { /** @var bool */
assert(!empty($row)); public $locked;
$this->id = $row['id']; /** @var string */
$this->owner_id = $row['owner_id']; public $body;
$this->owner_ip = $row['owner_ip'];
$this->date = $row['date']; /**
$this->title = $row['title']; * @param mixed $row
$this->revision = $row['revision']; */
$this->locked = ($row['locked'] == 'Y'); public function __construct($row=null) {
$this->body = $row['body']; //assert(!empty($row));
if (!is_null($row)) {
$this->id = $row['id'];
$this->owner_id = $row['owner_id'];
$this->owner_ip = $row['owner_ip'];
$this->date = $row['date'];
$this->title = $row['title'];
$this->revision = $row['revision'];
$this->locked = ($row['locked'] == 'Y');
$this->body = $row['body'];
}
} }
/**
* @return null|User
*/
public function get_owner() { public function get_owner() {
return User::by_id($this->owner_id); return User::by_id($this->owner_id);
} }
/**
* @return bool
*/
public function is_locked() { public function is_locked() {
return $this->locked; return $this->locked;
} }
@ -55,8 +81,7 @@ class WikiPage {
class Wiki extends Extension { class Wiki extends Extension {
public function onInitExt(InitExtEvent $event) { public function onInitExt(InitExtEvent $event) {
global $database; global $database, $config;
global $config;
if($config->get_int("ext_wiki_version", 0) < 1) { if($config->get_int("ext_wiki_version", 0) < 1) {
$database->create_table("wiki_pages", " $database->create_table("wiki_pages", "
@ -105,7 +130,7 @@ class Wiki extends Extension {
if($this->can_edit($user, $this->get_page($title))) { if($this->can_edit($user, $this->get_page($title))) {
$wikipage = $this->get_page($title); $wikipage = $this->get_page($title);
$wikipage->rev = $rev; $wikipage->revision = $rev;
$wikipage->body = $body; $wikipage->body = $body;
$wikipage->locked = $lock; $wikipage->locked = $lock;
try { try {
@ -160,7 +185,7 @@ class Wiki extends Extension {
$database->Execute(" $database->Execute("
INSERT INTO wiki_pages(owner_id, owner_ip, date, title, revision, locked, body) INSERT INTO wiki_pages(owner_id, owner_ip, date, title, revision, locked, body)
VALUES (?, ?, now(), ?, ?, ?, ?)", array($event->user->id, $_SERVER['REMOTE_ADDR'], VALUES (?, ?, now(), ?, ?, ?, ?)", array($event->user->id, $_SERVER['REMOTE_ADDR'],
$wpage->title, $wpage->rev, $wpage->locked?'Y':'N', $wpage->body)); $wpage->title, $wpage->revision, $wpage->locked?'Y':'N', $wpage->body));
} }
catch(Exception $e) { catch(Exception $e) {
throw new WikiUpdateException("Somebody else edited that page at the same time :-("); throw new WikiUpdateException("Somebody else edited that page at the same time :-(");
@ -168,13 +193,13 @@ class Wiki extends Extension {
} }
/** /**
* See if the given user is allowed to edit the given page * See if the given user is allowed to edit the given page.
* *
* @retval boolean * @param User $user
* @param WikiPage $page
* @return bool
*/ */
public static function can_edit(User $user, WikiPage $page) { public static function can_edit(User $user, WikiPage $page) {
global $config;
// admins can edit everything // admins can edit everything
if($user->is_admin()) return true; if($user->is_admin()) return true;
@ -187,6 +212,11 @@ class Wiki extends Extension {
return false; return false;
} }
/**
* @param string $title
* @param int|null $revision
* @return WikiPage
*/
private function get_page($title, $revision=-1) { private function get_page($title, $revision=-1) {
global $database; global $database;
// first try and get the actual page // first try and get the actual page

View File

@ -1,14 +1,16 @@
<?php <?php
class WikiTheme extends Themelet { class WikiTheme extends Themelet {
/* /**
* Show a page * Show a page.
* *
* $page = the shimmie page object * @param Page $page The shimmie page object
* $wiki_page = the wiki page, has ->title and ->body * @param WikiPage $wiki_page The wiki page, has ->title and ->body
* $nav_page = a wiki page object with navigation, has ->body * @param WikiPage|null $nav_page A wiki page object with navigation, has ->body
*/ */
public function display_page(Page $page, WikiPage $wiki_page, $nav_page) { // $nav_page = WikiPage or null public function display_page(Page $page, WikiPage $wiki_page, $nav_page) {
global $user;
if(is_null($nav_page)) { if(is_null($nav_page)) {
$nav_page = new WikiPage(); $nav_page = new WikiPage();
$nav_page->body = ""; $nav_page->body = "";
@ -18,7 +20,6 @@ class WikiTheme extends Themelet {
send_event($tfe); send_event($tfe);
// only the admin can edit the sidebar // only the admin can edit the sidebar
global $user;
if($user->is_admin()) { if($user->is_admin()) {
$tfe->formatted .= "<p>(<a href='".make_link("wiki/wiki:sidebar", "edit=on")."'>Edit</a>)"; $tfe->formatted .= "<p>(<a href='".make_link("wiki/wiki:sidebar", "edit=on")."'>Edit</a>)";
} }
@ -61,12 +62,13 @@ class WikiTheme extends Themelet {
} }
protected function create_display_html(WikiPage $page) { protected function create_display_html(WikiPage $page) {
global $user;
$owner = $page->get_owner(); $owner = $page->get_owner();
$tfe = new TextFormattingEvent($page->body); $tfe = new TextFormattingEvent($page->body);
send_event($tfe); send_event($tfe);
global $user;
$edit = "<table><tr>"; $edit = "<table><tr>";
$edit .= Wiki::can_edit($user, $page) ? $edit .= Wiki::can_edit($user, $page) ?
" "

View File

@ -23,6 +23,10 @@ class WordFilter extends Extension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
/**
* @param string $text
* @return string
*/
private function filter(/*string*/ $text) { private function filter(/*string*/ $text) {
$map = $this->get_map(); $map = $this->get_map();
foreach($map as $search => $replace) { foreach($map as $search => $replace) {

View File

@ -66,7 +66,7 @@ class ShimmieInstallerTest extends WebTestCase {
$this->clickSubmit("Go!"); $this->clickSubmit("Go!");
if (!$this->assertText("Installation Succeeded!")) { if (!$this->assertText("Installation Succeeded!")) {
print "ERROR --- '" + $db + "'"; print "ERROR --- '" . $db . "'";
$this->showSource(); $this->showSource();
} }
} }

View File

@ -1,6 +1,12 @@
<?php <?php
class CustomCommentListTheme extends CommentListTheme { class CustomCommentListTheme extends CommentListTheme {
/**
* @param array $images
* @param int $page_number
* @param int $total_pages
* @param bool $can_post
*/
public function display_comment_list($images, $page_number, $total_pages, $can_post) { public function display_comment_list($images, $page_number, $total_pages, $can_post) {
global $config, $page, $user; global $config, $page, $user;
@ -86,7 +92,11 @@ class CustomCommentListTheme extends CommentListTheme {
// no recent comments in this theme // no recent comments in this theme
} }
/**
* @param Comment $comment
* @param bool $trim
* @return string
*/
protected function comment_to_html($comment, $trim=false) { protected function comment_to_html($comment, $trim=false) {
global $user; global $user;

View File

@ -1,7 +1,9 @@
<?php <?php
class CustomPage extends Page { class CustomPage extends Page {
var $left_enabled = true; /** @var bool */
public $left_enabled = true;
public function disable_left() { public function disable_left() {
$this->left_enabled = false; $this->left_enabled = false;
} }

View File

@ -1,6 +1,10 @@
<?php <?php
class CustomIndexTheme extends IndexTheme { class CustomIndexTheme extends IndexTheme {
/**
* @param Page $page
* @param null|Image[] $images
*/
public function display_page(Page $page, $images) { public function display_page(Page $page, $images) {
global $config; global $config;
@ -33,7 +37,12 @@ class CustomIndexTheme extends IndexTheme {
} }
} }
/**
* @param int $page_number
* @param int $total_pages
* @param array $search_terms
* @return string
*/
protected function build_navigation($page_number, $total_pages, $search_terms) { protected function build_navigation($page_number, $total_pages, $search_terms) {
$h_search_string = count($search_terms) == 0 ? "" : html_escape(implode(" ", $search_terms)); $h_search_string = count($search_terms) == 0 ? "" : html_escape(implode(" ", $search_terms));
$h_search_link = make_link(); $h_search_link = make_link();
@ -48,6 +57,11 @@ class CustomIndexTheme extends IndexTheme {
return $h_search; return $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'>";

View File

@ -1,16 +1,38 @@
<?php <?php
class Themelet extends BaseThemelet { class Themelet extends BaseThemelet {
/**
* @param Page $page
* @param string $base
* @param string $query
* @param int $page_number
* @param int $total_pages
*/
public function display_paginator(Page $page, $base, $query, $page_number, $total_pages) { public function display_paginator(Page $page, $base, $query, $page_number, $total_pages) {
if($total_pages == 0) $total_pages = 1; if($total_pages == 0) $total_pages = 1;
$body = $this->build_paginator($page_number, $total_pages, $base, $query); $body = $this->build_paginator($page_number, $total_pages, $base, $query);
$page->add_block(new Block(null, $body, "main", 90)); $page->add_block(new Block(null, $body, "main", 90));
} }
/**
* @param string $base_url
* @param string $query
* @param int|string $page
* @param string $name
* @return string
*/
private function gen_page_link($base_url, $query, $page, $name) { private function gen_page_link($base_url, $query, $page, $name) {
$link = make_link("$base_url/$page", $query); $link = make_link("$base_url/$page", $query);
return "<a href='$link'>$name</a>"; return "<a href='$link'>$name</a>";
} }
/**
* @param string $base_url
* @param string $query
* @param int|string $page
* @param int|string $current_page
* @param string $name
* @return string
*/
private function gen_page_link_block($base_url, $query, $page, $current_page, $name) { private function gen_page_link_block($base_url, $query, $page, $current_page, $name) {
$paginator = ""; $paginator = "";
if($page == $current_page) $paginator .= "<b>$page</b>"; if($page == $current_page) $paginator .= "<b>$page</b>";
@ -18,6 +40,13 @@ class Themelet extends BaseThemelet {
return $paginator; return $paginator;
} }
/**
* @param int $current_page
* @param int $total_pages
* @param string $base_url
* @param string $query
* @return string
*/
private function build_paginator($current_page, $total_pages, $base_url, $query) { private function build_paginator($current_page, $total_pages, $base_url, $query) {
$next = $current_page + 1; $next = $current_page + 1;
$prev = $current_page - 1; $prev = $current_page - 1;

View File

@ -76,6 +76,11 @@ class CustomUserPageTheme extends UserPageTheme {
$page->add_block(new Block("Signup", $html)); $page->add_block(new Block("Signup", $html));
} }
/**
* @param Page $page
* @param array $uploads
* @param array $comments
*/
public function display_ip_list(Page $page, $uploads, $comments) { public function display_ip_list(Page $page, $uploads, $comments) {
$html = "<table id='ip-history' style='width: 400px;'>"; $html = "<table id='ip-history' style='width: 400px;'>";
$html .= "<tr><td>Uploaded from: "; $html .= "<tr><td>Uploaded from: ";

View File

@ -1,10 +1,20 @@
<?php <?php
class CustomExtManagerTheme extends ExtManagerTheme { class CustomExtManagerTheme extends ExtManagerTheme {
/**
* @param Page $page
* @param array $extensions
* @param bool $editable
*/
public function display_table(Page $page, /*array*/ $extensions, /*bool*/ $editable) { public function display_table(Page $page, /*array*/ $extensions, /*bool*/ $editable) {
$page->disable_left(); $page->disable_left();
parent::display_table($page, $extensions, $editable); parent::display_table($page, $extensions, $editable);
} }
/**
* @param Page $page
* @param ExtensionInfo $info
*/
public function display_doc(Page $page, ExtensionInfo $info) { public function display_doc(Page $page, ExtensionInfo $info) {
$page->disable_left(); $page->disable_left();
parent::display_doc($page, $info); parent::display_doc($page, $info);

View File

@ -1,16 +1,38 @@
<?php <?php
class Themelet extends BaseThemelet { class Themelet extends BaseThemelet {
/**
* @param Page $page
* @param string $base
* @param string $query
* @param int $page_number
* @param int $total_pages
*/
public function display_paginator(Page $page, $base, $query, $page_number, $total_pages) { public function display_paginator(Page $page, $base, $query, $page_number, $total_pages) {
if($total_pages == 0) $total_pages = 1; if($total_pages == 0) $total_pages = 1;
$body = $this->build_paginator($page_number, $total_pages, $base, $query); $body = $this->build_paginator($page_number, $total_pages, $base, $query);
$page->add_block(new Block(null, $body, "main", 90)); $page->add_block(new Block(null, $body, "main", 90));
} }
/**
* @param string $base_url
* @param string $query
* @param int|string $page
* @param string $name
* @return string
*/
private function gen_page_link($base_url, $query, $page, $name) { private function gen_page_link($base_url, $query, $page, $name) {
$link = make_link("$base_url/$page", $query); $link = make_link("$base_url/$page", $query);
return "<a href='$link'>$name</a>"; return "<a href='$link'>$name</a>";
} }
/**
* @param string $base_url
* @param string $query
* @param int|string $page
* @param int|string $current_page
* @param string $name
* @return string
*/
private function gen_page_link_block($base_url, $query, $page, $current_page, $name) { private function gen_page_link_block($base_url, $query, $page, $current_page, $name) {
$paginator = ""; $paginator = "";
if($page == $current_page) $paginator .= "<b>$page</b>"; if($page == $current_page) $paginator .= "<b>$page</b>";
@ -18,6 +40,13 @@ class Themelet extends BaseThemelet {
return $paginator; return $paginator;
} }
/**
* @param int $current_page
* @param int $total_pages
* @param string $base_url
* @param string $query
* @return string
*/
private function build_paginator($current_page, $total_pages, $base_url, $query) { private function build_paginator($current_page, $total_pages, $base_url, $query) {
$next = $current_page + 1; $next = $current_page + 1;
$prev = $current_page - 1; $prev = $current_page - 1;

Some files were not shown because too many files have changed in this diff Show More