2007-04-16 11:58:25 +00:00
< ? php
2009-07-19 07:38:13 +00:00
/**
2009-01-04 13:53:14 +00:00
* All the imageboard - specific bits of code should be in this file , everything
* else in / core should be standard SCore bits .
*/
2009-07-21 03:18:40 +00:00
/**
* \page search Shimmie2 : Searching
*
* The current search system is built of several search item -> image ID list
* translators , eg :
*
* \li the item " fred " will search the image_tags table to find image IDs with the fred tag
* \li the item " size=640x480 " will search the images table to find image IDs of 640 x480 images
*
* So the search " fred size=640x480 " will calculate two lists and take the
* intersection . ( There are some optimisations in there making it more
* complicated behind the scenes , but as long as you can turn a single word
* into a list of image IDs , making a search plugin should be simple )
*/
2009-01-04 13:53:14 +00:00
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \
* Classes *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-03-14 12:44:58 +00:00
$tag_n = 0 ; // temp hack
2012-01-16 02:53:38 +00:00
$_flexihash = null ;
$_fh_last_opts = null ;
2011-03-14 12:44:58 +00:00
2012-02-02 04:35:26 +00:00
require_once " lib/flexihash.php " ;
2009-07-19 07:38:13 +00:00
/**
2007-12-06 11:01:18 +00:00
* 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 .
*/
2007-04-16 11:58:25 +00:00
class Image {
var $id = null ;
var $height , $width ;
var $hash , $filesize ;
var $filename , $ext ;
2007-06-03 10:27:15 +00:00
var $owner_ip ;
2007-05-03 15:18:22 +00:00
var $posted ;
2007-07-16 14:36:29 +00:00
var $source ;
2010-02-17 14:16:20 +00:00
var $locked ;
2007-04-16 11:58:25 +00:00
2009-07-19 07:38:13 +00:00
/**
* One will very rarely construct an image directly , more common
* would be to use Image :: by_id , Image :: by_hash , etc
2009-01-04 16:15:00 +00:00
*/
2007-12-06 11:01:18 +00:00
public function Image ( $row = null ) {
if ( ! is_null ( $row )) {
foreach ( $row as $name => $value ) {
2009-07-16 23:27:40 +00:00
// some databases use table.name rather than name
$name = str_replace ( " images. " , " " , $name );
2007-12-06 11:01:18 +00:00
$this -> $name = $value ; // hax
}
2008-10-09 01:58:22 +00:00
$this -> posted_timestamp = strtotime ( $this -> posted ); // pray
2012-04-15 23:28:27 +00:00
$this -> locked = bool_escape ( $this -> locked );
2010-02-02 00:29:38 +00:00
assert ( is_numeric ( $this -> id ));
assert ( is_numeric ( $this -> height ));
assert ( is_numeric ( $this -> width ));
2007-10-02 22:23:29 +00:00
}
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Find an image by ID
*
2009-07-21 06:36:12 +00:00
* @ retval Image
2009-07-19 07:38:13 +00:00
*/
2012-02-02 13:58:48 +00:00
public static function by_id ( /*int*/ $id ) {
2008-08-26 09:11:40 +00:00
assert ( is_numeric ( $id ));
2009-05-11 14:04:33 +00:00
global $database ;
2008-08-26 09:11:40 +00:00
$image = null ;
2011-01-01 15:28:30 +00:00
$row = $database -> get_row ( " SELECT * FROM images WHERE images.id=:id " , array ( " id " => $id ));
2008-08-26 09:11:40 +00:00
return ( $row ? new Image ( $row ) : null );
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Find an image by hash
*
2009-07-21 06:36:12 +00:00
* @ retval Image
2009-07-19 07:38:13 +00:00
*/
2012-02-02 13:58:48 +00:00
public static function by_hash ( /*string*/ $hash ) {
2008-10-09 03:21:18 +00:00
assert ( is_string ( $hash ));
2009-05-11 14:04:33 +00:00
global $database ;
2008-10-09 03:21:18 +00:00
$image = null ;
2011-01-01 16:28:04 +00:00
$row = $database -> get_row ( " SELECT images.* FROM images WHERE hash=:hash " , array ( " hash " => $hash ));
2008-10-09 03:21:18 +00:00
return ( $row ? new Image ( $row ) : null );
}
2009-07-19 07:38:13 +00:00
/**
* Pick a random image out of a set
*
2009-07-21 06:36:12 +00:00
* @ retval Image
2009-07-19 07:38:13 +00:00
*/
2009-05-11 14:04:33 +00:00
public static function by_random ( $tags = array ()) {
assert ( is_array ( $tags ));
$max = Image :: count_images ( $tags );
2011-09-12 01:41:46 +00:00
if ( $max < 1 ) return null ; // From Issue #22 - opened by HungryFeline on May 30, 2011.
2008-11-07 11:46:34 +00:00
$rand = mt_rand ( 0 , $max - 1 );
2009-05-11 14:04:33 +00:00
$set = Image :: find_images ( $rand , 1 , $tags );
2008-10-09 03:21:18 +00:00
if ( count ( $set ) > 0 ) return $set [ 0 ];
else return null ;
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Search for an array of images
2012-02-08 01:05:38 +00:00
*
* @ retval Array
2009-07-19 07:38:13 +00:00
*/
2012-02-08 01:05:38 +00:00
public static function find_images ( /*int*/ $start , /*int*/ $limit , $tags = array ()) {
2008-10-17 20:34:48 +00:00
assert ( is_numeric ( $start ));
assert ( is_numeric ( $limit ));
2009-05-11 14:04:33 +00:00
assert ( is_array ( $tags ));
2012-02-05 04:21:03 +00:00
global $database , $user ;
2009-05-11 14:04:33 +00:00
$images = array ();
2008-10-09 03:21:18 +00:00
if ( $start < 0 ) $start = 0 ;
if ( $limit < 1 ) $limit = 1 ;
2009-01-04 19:18:37 +00:00
2012-02-05 04:21:03 +00:00
if ( SPEED_HAX ) {
2012-02-07 15:15:18 +00:00
if ( ! $user -> can ( " big_search " ) and count ( $tags ) > 3 ) {
2012-02-05 04:21:03 +00:00
die ( " Anonymous users may only search for up to 3 tags at a time " ); // FIXME: throw an exception?
}
}
2009-05-11 14:04:33 +00:00
$querylet = Image :: build_search_querylet ( $tags );
2011-01-01 15:28:30 +00:00
$querylet -> append ( new Querylet ( " ORDER BY images.id DESC LIMIT :limit OFFSET :offset " , array ( " limit " => $limit , " offset " => $start )));
2011-03-14 14:20:30 +00:00
#var_dump($querylet->sql); var_dump($querylet->variables);
2008-10-17 19:57:56 +00:00
$result = $database -> execute ( $querylet -> sql , $querylet -> variables );
2009-01-04 19:18:37 +00:00
2011-01-01 15:28:30 +00:00
while ( $row = $result -> fetch ()) {
$images [] = new Image ( $row );
2008-10-09 03:21:18 +00:00
}
return $images ;
}
2009-01-04 16:15:00 +00:00
/*
* Image - related utility functions
*/
2009-07-19 07:38:13 +00:00
/**
* Count the number of image results for a given search
*/
2009-05-11 14:04:33 +00:00
public static function count_images ( $tags = array ()) {
assert ( is_array ( $tags ));
global $database ;
2008-10-09 03:28:58 +00:00
if ( count ( $tags ) == 0 ) {
2010-02-02 00:29:38 +00:00
$total = $database -> cache -> get ( " image-count " );
if ( ! $total ) {
2011-01-01 15:28:30 +00:00
$total = $database -> get_one ( " SELECT COUNT(*) FROM images " );
2010-02-02 00:29:38 +00:00
$database -> cache -> set ( " image-count " , $total , 600 );
}
return $total ;
2008-10-09 03:28:58 +00:00
}
2012-09-03 10:13:08 +00:00
else if ( count ( $tags ) == 1 && ! preg_match ( " /[:=>< \ * \ ?]/ " , $tags [ 0 ])) {
2012-02-12 07:30:16 +00:00
$term = Tag :: resolve_alias ( $tags [ 0 ]);
2011-01-01 15:28:30 +00:00
return $database -> get_one (
2012-06-23 23:57:55 +00:00
$database -> scoreql_to_sql ( " SELECT count FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag) " ),
2012-02-12 07:30:16 +00:00
array ( " tag " => $term ));
2010-02-02 16:33:56 +00:00
}
2008-10-09 03:28:58 +00:00
else {
2009-05-11 14:04:33 +00:00
$querylet = Image :: build_search_querylet ( $tags );
2008-10-09 03:28:58 +00:00
$result = $database -> execute ( $querylet -> sql , $querylet -> variables );
2011-01-01 15:58:09 +00:00
return $result -> rowCount ();
2008-10-09 03:28:58 +00:00
}
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Count the number of pages for a given search
*/
2009-05-11 14:04:33 +00:00
public static function count_pages ( $tags = array ()) {
assert ( is_array ( $tags ));
global $config , $database ;
2012-04-01 16:47:39 +00:00
return ceil ( Image :: count_images ( $tags ) / $config -> get_int ( 'index_images' ));
2008-10-09 03:28:58 +00:00
}
2009-01-04 16:15:00 +00:00
/*
* Accessors & mutators
*/
2009-07-19 07:38:13 +00:00
/**
* Find the next image in the sequence .
*
* Rather than simply $this_id + 1 , one must take into account
* deleted images and search queries
*
2009-07-21 06:36:12 +00:00
* @ retval Image
2009-07-19 07:38:13 +00:00
*/
2008-10-09 03:21:18 +00:00
public function get_next ( $tags = array (), $next = true ) {
assert ( is_array ( $tags ));
assert ( is_bool ( $next ));
2009-05-11 14:04:33 +00:00
global $database ;
2009-01-04 19:18:37 +00:00
2008-10-09 03:21:18 +00:00
if ( $next ) {
$gtlt = " < " ;
$dir = " DESC " ;
}
else {
$gtlt = " > " ;
$dir = " ASC " ;
}
if ( count ( $tags ) == 0 ) {
2012-01-11 20:08:27 +00:00
$row = $database -> get_row ( 'SELECT images.* FROM images WHERE images.id ' . $gtlt . ' ' . $this -> id . ' ORDER BY images.id ' . $dir . ' LIMIT 1' );
2008-10-09 03:21:18 +00:00
}
else {
2012-01-11 20:08:27 +00:00
$tags [] = 'id' . $gtlt . $this -> id ;
2009-05-11 14:04:33 +00:00
$querylet = Image :: build_search_querylet ( $tags );
2012-01-11 20:08:27 +00:00
$querylet -> append_sql ( ' ORDER BY images.id ' . $dir . ' LIMIT 1' );
2011-01-01 16:28:04 +00:00
$row = $database -> get_row ( $querylet -> sql , $querylet -> variables );
2008-10-09 03:21:18 +00:00
}
2009-01-04 19:18:37 +00:00
2008-10-09 03:21:18 +00:00
return ( $row ? new Image ( $row ) : null );
}
2009-07-19 07:38:13 +00:00
/**
* The reverse of get_next
*
2009-07-21 06:36:12 +00:00
* @ retval Image
2009-07-19 07:38:13 +00:00
*/
2008-10-09 03:21:18 +00:00
public function get_prev ( $tags = array ()) {
return $this -> get_next ( $tags , false );
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Find the User who owns this Image
*
2009-07-21 06:36:12 +00:00
* @ retval User
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_owner () {
2009-05-11 14:04:33 +00:00
return User :: by_id ( $this -> owner_id );
2007-04-16 11:58:25 +00:00
}
2012-02-09 17:03:39 +00:00
/**
* Set the image ' s owner
*/
public function set_owner ( User $owner ) {
global $database ;
if ( $owner -> id != $this -> owner_id ) {
$database -> execute ( " UPDATE images SET owner_id=:owner_id WHERE id=:id " , array ( " owner_id " => $owner -> id , " id " => $this -> id ));
2012-03-13 04:54:38 +00:00
log_info ( " core-image " , " Owner for Image # { $this -> id } set to { $owner -> name } " );
2012-02-09 17:03:39 +00:00
}
}
2009-07-19 07:38:13 +00:00
/**
* Get this image ' s tags as an array
*/
2007-04-16 11:58:25 +00:00
public function get_tag_array () {
2009-05-11 14:04:33 +00:00
global $database ;
2007-04-16 11:58:25 +00:00
if ( ! isset ( $this -> tag_array )) {
2011-01-01 15:28:30 +00:00
$this -> tag_array = $database -> get_col ( " SELECT tag FROM image_tags JOIN tags ON image_tags.tag_id = tags.id WHERE image_id=:id ORDER BY tag " , array ( " id " => $this -> id ));
2007-04-16 11:58:25 +00:00
}
return $this -> tag_array ;
}
2009-07-19 07:38:13 +00:00
/**
* Get this image ' s tags as a string
*/
2007-04-16 11:58:25 +00:00
public function get_tag_list () {
2009-08-24 02:33:51 +00:00
return Tag :: implode ( $this -> get_tag_array ());
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get the URL for the full size image
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_image_link () {
2009-05-11 14:04:33 +00:00
global $config ;
2012-01-31 13:30:57 +00:00
2012-01-13 04:07:14 +00:00
$image_ilink = $config -> get_string ( 'image_ilink' ); // store a copy for speed.
2012-01-31 13:30:57 +00:00
2012-01-13 04:07:14 +00:00
if ( ! empty ( $image_ilink ) ) { /* empty is faster than strlen */
2012-01-31 15:11:06 +00:00
if ( ! startsWith ( $image_ilink , " http:// " ) && ! startsWith ( $image_ilink , " / " )) {
$image_ilink = make_link ( $image_ilink );
}
return $this -> parse_link_template ( $image_ilink );
2008-12-27 10:17:53 +00:00
}
2009-05-11 14:04:33 +00:00
else if ( $config -> get_bool ( 'nice_urls' , false )) {
2012-03-13 07:01:15 +00:00
return $this -> parse_link_template ( make_link ( '_images/$hash/$id%20-%20$tags.$ext' ));
2008-12-27 10:17:53 +00:00
}
else {
2009-01-22 13:42:44 +00:00
return $this -> parse_link_template ( make_link ( 'image/$id.$ext' ));
2008-12-27 10:17:53 +00:00
}
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get a short link to the full size image
*
* @ deprecated
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_short_link () {
2009-05-11 14:04:33 +00:00
global $config ;
return $this -> parse_link_template ( $config -> get_string ( 'image_slink' ));
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get the URL for the thumbnail
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_thumb_link () {
2009-05-11 14:04:33 +00:00
global $config ;
2012-01-13 02:17:37 +00:00
$image_tlink = $config -> get_string ( 'image_tlink' ); // store a copy for speed.
if ( ! empty ( $image_tlink ) ) { /* empty is faster than strlen */
2012-01-31 15:11:06 +00:00
if ( ! startsWith ( $image_tlink , " http:// " ) && ! startsWith ( $image_tlink , " / " )) {
$image_tlink = make_link ( $image_tlink );
}
2012-01-13 02:17:37 +00:00
return $this -> parse_link_template ( $image_tlink );
2008-12-27 10:17:53 +00:00
}
2009-05-11 14:04:33 +00:00
else if ( $config -> get_bool ( 'nice_urls' , false )) {
2009-01-22 10:49:22 +00:00
return $this -> parse_link_template ( make_link ( '_thumbs/$hash/thumb.jpg' ));
2008-12-27 10:17:53 +00:00
}
else {
2009-12-24 07:34:29 +00:00
return $this -> parse_link_template ( make_link ( 'thumb/$id.jpg' ));
2008-12-27 10:17:53 +00:00
}
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get the tooltip for this image , formatted according to the
* configured template
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_tooltip () {
global $config ;
2012-03-12 05:08:40 +00:00
$tt = $this -> parse_link_template ( $config -> get_string ( 'image_tip' ), " no_escape " );
// Removes the size tag if the file is an mp3
if ( $this -> ext === 'mp3' ){
$iitip = $tt ;
$mp3tip = array ( " 0x0 " );
$h_tip = str_replace ( $mp3tip , " " , $iitip );
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array ( " // " , " // " , " // " , " // " , " " );
if ( strstr ( $h_tip , " " )) {
$h_tip = html_escape ( str_replace ( $justincase , " " , $h_tip ));
} else {
$h_tip = html_escape ( $h_tip );
}
return $h_tip ;
}
else {
return $tt ;
}
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Figure out where the full size image is on disk
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_image_filename () {
2010-02-02 00:29:38 +00:00
return warehouse_path ( " images " , $this -> hash );
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Figure out where the thumbnail is on disk
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_thumb_filename () {
2010-02-02 00:29:38 +00:00
return warehouse_path ( " thumbs " , $this -> hash );
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get the original filename
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_filename () {
return $this -> filename ;
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Get the image ' s mime type
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_mime_type () {
2012-09-22 22:15:25 +00:00
return getMimeType ( $this -> get_image_filename (), $this -> get_ext ());
2007-04-16 11:58:25 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Get the image ' s filename extension
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-04-16 11:58:25 +00:00
public function get_ext () {
return $this -> ext ;
}
2009-07-19 07:38:13 +00:00
/**
* Get the image ' s source URL
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2008-02-06 17:33:08 +00:00
public function get_source () {
return $this -> source ;
}
2009-01-04 19:18:37 +00:00
2009-07-19 07:38:13 +00:00
/**
* Set the image ' s source URL
*/
2013-05-07 08:13:03 +00:00
public function set_source ( /*string*/ $new_source ) {
2009-05-11 14:04:33 +00:00
global $database ;
2013-05-07 08:13:03 +00:00
$old_source = $this -> source ;
if ( empty ( $new_source )) $new_source = null ;
if ( $new_source != $old_source ) {
$database -> execute ( " UPDATE images SET source=:source WHERE id=:id " , array ( " source " => $new_source , " id " => $this -> id ));
log_info ( " core-image " , " Source for Image # { $this -> id } set to: $new_source (was $old_source ) " );
2012-01-21 00:17:07 +00:00
}
2009-01-04 16:15:00 +00:00
}
2012-02-08 01:05:38 +00:00
/**
* Check if the image is locked .
* @ retval bool
*/
2010-02-17 14:16:20 +00:00
public function is_locked () {
2012-03-10 18:53:42 +00:00
return $this -> locked ;
2010-02-17 14:16:20 +00:00
}
2012-03-10 18:53:42 +00:00
2012-01-27 16:27:02 +00:00
public function set_locked ( $tf ) {
2010-02-17 14:16:20 +00:00
global $database ;
$ln = $tf ? " Y " : " N " ;
2012-06-23 23:57:55 +00:00
$sln = $database -> scoreql_to_sql ( 'SCORE_BOOL_' . $ln );
2010-02-17 14:16:20 +00:00
$sln = str_replace ( " ' " , " " , $sln );
$sln = str_replace ( '"' , " " , $sln );
2012-04-15 23:28:27 +00:00
if ( bool_escape ( $sln ) !== $this -> locked ) {
2012-01-21 00:17:07 +00:00
$database -> execute ( " UPDATE images SET locked=:yn WHERE id=:id " , array ( " yn " => $sln , " id " => $this -> id ));
2012-01-26 02:15:06 +00:00
log_info ( " core-image " , " Setting Image # { $this -> id } lock to: $ln " );
2012-01-21 00:17:07 +00:00
}
2010-02-17 14:16:20 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Delete all tags from this image .
*
* Normally in preparation to set them to a new set .
*/
2009-01-04 16:15:00 +00:00
public function delete_tags_from_image () {
2009-05-11 14:04:33 +00:00
global $database ;
$database -> execute (
2009-01-04 16:15:00 +00:00
" UPDATE tags SET count = count - 1 WHERE id IN " .
2011-01-01 15:58:09 +00:00
" (SELECT tag_id FROM image_tags WHERE image_id = :id) " , array ( " id " => $this -> id ));
$database -> execute ( " DELETE FROM image_tags WHERE image_id=:id " , array ( " id " => $this -> id ));
2009-01-04 16:15:00 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Set the tags for this image
*/
2012-01-27 16:27:02 +00:00
public function set_tags ( $tags ) {
2009-05-11 14:04:33 +00:00
global $database ;
2012-01-27 16:27:02 +00:00
2013-08-04 17:11:02 +00:00
assert ( is_array ( $tags ));
2013-08-04 17:13:50 +00:00
$tags = Tag :: resolve_aliases ( $tags );
2009-01-04 16:15:00 +00:00
2009-01-18 01:07:06 +00:00
assert ( is_array ( $tags ));
assert ( count ( $tags ) > 0 );
2012-01-21 00:17:07 +00:00
$new_tags = implode ( " " , $tags );
2012-01-27 16:27:02 +00:00
if ( $new_tags != $this -> get_tag_list ()) {
2012-01-21 00:17:07 +00:00
// delete old
$this -> delete_tags_from_image ();
// insert each new tags
foreach ( $tags as $tag ) {
$id = $database -> get_one (
2012-06-23 23:57:55 +00:00
$database -> scoreql_to_sql (
2012-01-21 00:17:07 +00:00
" SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag) "
),
2011-01-01 15:58:09 +00:00
array ( " tag " => $tag ));
2012-01-21 00:17:07 +00:00
if ( empty ( $id )) {
// a new tag
$database -> execute (
" INSERT INTO tags(tag) VALUES (:tag) " ,
array ( " tag " => $tag ));
$database -> execute (
" INSERT INTO image_tags(image_id, tag_id)
VALUES ( : id , ( SELECT id FROM tags WHERE tag = : tag )) " ,
array ( " id " => $this -> id , " tag " => $tag ));
}
else {
// user of an existing tag
$database -> execute (
" INSERT INTO image_tags(image_id, tag_id) VALUES(:iid, :tid) " ,
array ( " iid " => $this -> id , " tid " => $id ));
}
2009-05-11 14:04:33 +00:00
$database -> execute (
2012-06-23 23:57:55 +00:00
$database -> scoreql_to_sql (
2012-01-21 00:17:07 +00:00
" UPDATE tags SET count = count + 1 WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag) "
),
array ( " tag " => $tag ));
2009-01-22 17:08:33 +00:00
}
2009-01-19 18:27:53 +00:00
2012-01-21 00:17:07 +00:00
log_info ( " core-image " , " Tags for Image # { $this -> id } set to: " . implode ( " " , $tags ));
$database -> cache -> delete ( " image- { $this -> id } -tags " );
}
2009-01-04 16:15:00 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* Delete this image from the database and disk
2009-01-04 16:15:00 +00:00
*/
public function delete () {
2009-05-11 14:04:33 +00:00
global $database ;
2009-05-11 14:48:18 +00:00
$this -> delete_tags_from_image ();
2011-01-01 15:58:09 +00:00
$database -> execute ( " DELETE FROM images WHERE id=:id " , array ( " id " => $this -> id ));
2012-01-12 19:46:58 +00:00
log_info ( " core-image " , 'Deleted Image #' . $this -> id . ' (' . $this -> hash . ')' );
2009-01-04 19:18:37 +00:00
2009-01-04 16:15:00 +00:00
unlink ( $this -> get_image_filename ());
unlink ( $this -> get_thumb_filename ());
}
2008-02-06 17:33:08 +00:00
2011-08-25 00:53:53 +00:00
/**
* This function removes an image ( and thumbnail ) from the DISK ONLY .
* It DOES NOT remove anything from the database .
*/
public function remove_image_only () {
2012-01-12 19:46:58 +00:00
log_info ( " core-image " , 'Removed Image File (' . $this -> hash . ')' );
2011-09-04 15:17:14 +00:00
@ unlink ( $this -> get_image_filename ());
@ unlink ( $this -> get_thumb_filename ());
2011-08-25 00:53:53 +00:00
}
2009-07-19 07:38:13 +00:00
/**
2009-07-21 06:36:12 +00:00
* Someone please explain this
2009-07-19 07:38:13 +00:00
*
2009-07-21 06:36:12 +00:00
* @ retval string
2009-07-19 07:38:13 +00:00
*/
2007-07-16 16:48:35 +00:00
public function parse_link_template ( $tmpl , $_escape = " url_escape " ) {
2009-05-11 14:04:33 +00:00
global $config ;
2007-04-16 11:58:25 +00:00
// don't bother hitting the database if it won't be used...
2009-08-11 14:12:48 +00:00
$tags = " " ;
2007-04-16 11:58:25 +00:00
if ( strpos ( $tmpl , '$tags' ) !== false ) { // * stabs dynamically typed languages with a rusty spoon *
2009-08-11 14:12:48 +00:00
$tags = $this -> get_tag_list ();
$tags = str_replace ( " / " , " " , $tags );
$tags = preg_replace ( " /^ \ .+/ " , " " , $tags );
2007-04-16 11:58:25 +00:00
}
2009-05-11 14:04:33 +00:00
$base_href = $config -> get_string ( 'base_href' );
2007-05-07 00:18:52 +00:00
$fname = $this -> get_filename ();
2007-04-16 11:58:25 +00:00
$base_fname = strpos ( $fname , '.' ) ? substr ( $fname , 0 , strrpos ( $fname , '.' )) : $fname ;
2007-05-07 00:18:52 +00:00
$tmpl = str_replace ( '$id' , $this -> id , $tmpl );
2009-11-12 09:27:09 +00:00
$tmpl = str_replace ( '$hash_ab' , substr ( $this -> hash , 0 , 2 ), $tmpl );
$tmpl = str_replace ( '$hash_cd' , substr ( $this -> hash , 2 , 2 ), $tmpl );
2009-11-12 09:30:41 +00:00
$tmpl = str_replace ( '$hash' , $this -> hash , $tmpl );
2009-08-11 14:12:48 +00:00
$tmpl = str_replace ( '$tags' , $_escape ( $tags ), $tmpl );
2007-05-07 00:18:52 +00:00
$tmpl = str_replace ( '$base' , $base_href , $tmpl );
$tmpl = str_replace ( '$ext' , $this -> ext , $tmpl );
$tmpl = str_replace ( '$size' , " { $this -> width } x { $this -> height } " , $tmpl );
$tmpl = str_replace ( '$filesize' , to_shorthand_int ( $this -> filesize ), $tmpl );
2007-07-16 16:48:35 +00:00
$tmpl = str_replace ( '$filename' , $_escape ( $base_fname ), $tmpl );
2009-05-11 14:04:33 +00:00
$tmpl = str_replace ( '$title' , $_escape ( $config -> get_string ( " title " )), $tmpl );
2007-04-16 11:58:25 +00:00
2011-12-24 14:49:55 +00:00
// nothing seems to use this, sending the event out to 50 exts is a lot of overhead
if ( ! SPEED_HAX ) {
$plte = new ParseLinkTemplateEvent ( $tmpl , $this );
send_event ( $plte );
$tmpl = $plte -> link ;
}
2007-11-04 08:16:41 +00:00
2012-01-16 02:53:38 +00:00
global $_flexihash , $_fh_last_opts ;
$matches = array ();
2012-01-16 19:58:03 +00:00
if ( preg_match ( " /(.*) { (.*)}(.*)/ " , $tmpl , $matches )) {
2012-01-16 02:53:38 +00:00
$pre = $matches [ 1 ];
$opts = $matches [ 2 ];
$post = $matches [ 3 ];
if ( $opts != $_fh_last_opts ) {
$_fh_last_opts = $opts ;
$_flexihash = new Flexihash ();
foreach ( explode ( " , " , $opts ) as $opt ) {
2012-01-17 15:47:58 +00:00
$parts = explode ( " = " , $opt );
$opt_val = " " ;
$opt_weight = 0 ;
if ( count ( $parts ) == 2 ) {
$opt_val = $parts [ 0 ];
$opt_weight = $parts [ 1 ];
}
elseif ( count ( $parts ) == 1 ) {
$opt_val = $parts [ 0 ];
$opt_weight = 1 ;
}
$_flexihash -> addTarget ( $opt_val , $opt_weight );
2012-01-16 02:53:38 +00:00
}
}
$choice = $_flexihash -> lookup ( $pre . $post );
$tmpl = $pre . $choice . $post ;
}
2007-04-16 11:58:25 +00:00
return $tmpl ;
}
2008-10-09 03:28:58 +00:00
2009-05-11 14:04:33 +00:00
private static function build_search_querylet ( $terms ) {
assert ( is_array ( $terms ));
global $database ;
2012-06-23 23:57:55 +00:00
if ( $database -> get_driver_name () === " mysql " )
2009-05-11 14:04:33 +00:00
return Image :: build_ugly_search_querylet ( $terms );
2009-05-11 10:52:48 +00:00
else
2009-05-11 14:04:33 +00:00
return Image :: build_accurate_search_querylet ( $terms );
2009-05-11 10:52:48 +00:00
}
2010-02-09 02:07:19 +00:00
/**
2012-05-16 04:12:19 +00:00
* WARNING : this description is no longer accurate , though it does get across
* the general idea - the actual method has a few extra optimisiations
*
2010-02-09 02:07:19 +00:00
* " foo bar -baz user=foo " becomes
*
* SELECT * FROM images WHERE
* images . id IN ( SELECT image_id FROM image_tags WHERE tag = 'foo' )
* AND images . id IN ( SELECT image_id FROM image_tags WHERE tag = 'bar' )
* AND NOT images . id IN ( SELECT image_id FROM image_tags WHERE tag = 'baz' )
* AND images . id IN ( SELECT id FROM images WHERE owner_name = 'foo' )
*
* This is :
* A ) Incredibly simple :
* Each search term maps to a list of image IDs
* B ) Runs really fast on a good database :
* These lists are calucalted once , and the set intersection taken
* C ) Runs really slow on bad databases :
* All the subqueries are executed every time for every row in the
* images table . Yes , MySQL does suck this much .
*/
2009-05-11 14:04:33 +00:00
private static function build_accurate_search_querylet ( $terms ) {
global $config , $database ;
2008-10-09 03:28:58 +00:00
$tag_querylets = array ();
$img_querylets = array ();
2008-10-09 05:56:48 +00:00
$positive_tag_count = 0 ;
2008-10-09 03:28:58 +00:00
2008-10-17 19:58:37 +00:00
$stpe = new SearchTermParseEvent ( null , $terms );
2008-10-17 19:57:18 +00:00
send_event ( $stpe );
if ( $stpe -> is_querylet_set ()) {
2008-10-17 20:18:38 +00:00
foreach ( $stpe -> get_querylets () as $querylet ) {
$img_querylets [] = new ImgQuerylet ( $querylet , true );
}
2008-10-17 19:57:18 +00:00
}
2008-10-09 03:28:58 +00:00
// parse the words that are searched for into
// various types of querylet
foreach ( $terms as $term ) {
$positive = true ;
2012-01-31 13:20:43 +00:00
if ( is_string ( $term ) && ! empty ( $term ) && ( $term [ 0 ] == '-' )) {
2008-10-09 03:28:58 +00:00
$positive = false ;
$term = substr ( $term , 1 );
}
2012-01-26 17:16:06 +00:00
if ( strlen ( $term ) == 0 ) {
continue ;
}
2009-01-04 19:18:37 +00:00
2009-01-04 18:39:11 +00:00
$term = Tag :: resolve_alias ( $term );
2008-10-09 03:28:58 +00:00
2008-10-17 19:58:37 +00:00
$stpe = new SearchTermParseEvent ( $term , $terms );
2008-10-09 03:28:58 +00:00
send_event ( $stpe );
if ( $stpe -> is_querylet_set ()) {
2008-10-17 20:18:38 +00:00
foreach ( $stpe -> get_querylets () as $querylet ) {
$img_querylets [] = new ImgQuerylet ( $querylet , $positive );
}
2008-10-09 03:28:58 +00:00
}
else {
2013-03-03 18:26:47 +00:00
$expansions = Tag :: resolve_wildcard ( $term );
if ( $expansions && $positive ) $positive_tag_count ++ ;
foreach ( $expansions as $term ) {
$tag_querylets [] = new TagQuerylet ( $term , $positive );
2008-10-09 03:28:58 +00:00
}
}
}
// merge all the image metadata searches into one generic querylet
$n = 0 ;
$sql = " " ;
$terms = array ();
foreach ( $img_querylets as $iq ) {
if ( $n ++ > 0 ) $sql .= " AND " ;
if ( ! $iq -> positive ) $sql .= " NOT " ;
$sql .= " ( " . $iq -> qlet -> sql . " ) " ;
$terms = array_merge ( $terms , $iq -> qlet -> variables );
}
$img_search = new Querylet ( $sql , $terms );
// no tags, do a simple search (+image metadata if we have any)
if ( count ( $tag_querylets ) == 0 ) {
$query = new Querylet ( " SELECT images.* FROM images " );
2012-01-13 04:07:14 +00:00
if ( ! empty ( $img_search -> sql )) {
2008-10-09 03:28:58 +00:00
$query -> append_sql ( " WHERE " );
$query -> append ( $img_search );
}
}
// one positive tag (a common case), do an optimised search
else if ( count ( $tag_querylets ) == 1 && $tag_querylets [ 0 ] -> positive ) {
2012-06-23 23:57:55 +00:00
$query = new Querylet ( $database -> scoreql_to_sql ( "
2008-10-09 03:28:58 +00:00
SELECT images .* FROM images
2012-05-16 06:36:20 +00:00
JOIN image_tags ON images . id = image_tags . image_id
JOIN tags ON image_tags . tag_id = tags . id
WHERE SCORE_STRNORM ( tag ) = SCORE_STRNORM ( : tag )
2011-01-01 15:58:09 +00:00
" ), array( " tag " => $tag_querylets[0] ->tag));
2008-10-09 03:28:58 +00:00
2012-01-13 04:07:14 +00:00
if ( ! empty ( $img_search -> sql )) {
2008-10-09 03:28:58 +00:00
$query -> append_sql ( " AND " );
$query -> append ( $img_search );
}
}
// more than one positive tag, or more than zero negative tags
else {
$positive_tag_id_array = array ();
$negative_tag_id_array = array ();
$tags_ok = true ;
foreach ( $tag_querylets as $tq ) {
2011-01-03 15:18:24 +00:00
$tag_ids = $database -> get_col (
2012-06-23 23:57:55 +00:00
$database -> scoreql_to_sql (
2011-01-01 15:58:09 +00:00
" SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag) "
2010-02-02 11:11:03 +00:00
),
2011-01-01 15:58:09 +00:00
array ( " tag " => $tq -> tag ));
2008-10-09 03:28:58 +00:00
if ( $tq -> positive ) {
$positive_tag_id_array = array_merge ( $positive_tag_id_array , $tag_ids );
$tags_ok = count ( $tag_ids ) > 0 ;
if ( ! $tags_ok ) break ;
}
else {
$negative_tag_id_array = array_merge ( $negative_tag_id_array , $tag_ids );
}
}
if ( $tags_ok ) {
$have_pos = count ( $positive_tag_id_array ) > 0 ;
$have_neg = count ( $negative_tag_id_array ) > 0 ;
2012-05-16 04:12:19 +00:00
$sql = " SELECT images.* FROM images WHERE images.id IN ( " ;
2008-10-09 03:28:58 +00:00
if ( $have_pos ) {
$positive_tag_id_list = join ( ', ' , $positive_tag_id_array );
$sql .= "
2012-05-16 04:12:19 +00:00
SELECT image_id
FROM image_tags
WHERE tag_id IN ( $positive_tag_id_list )
GROUP BY image_id
HAVING COUNT ( image_id ) >= $positive_tag_count
2008-10-09 03:28:58 +00:00
" ;
}
if ( $have_pos && $have_neg ) {
2012-05-16 04:12:19 +00:00
$sql .= " EXCEPT " ;
2008-10-09 03:28:58 +00:00
}
if ( $have_neg ) {
$negative_tag_id_list = join ( ', ' , $negative_tag_id_array );
$sql .= "
2012-05-16 04:12:19 +00:00
SELECT image_id
FROM image_tags
WHERE tag_id IN ( $negative_tag_id_list )
2008-10-09 03:28:58 +00:00
" ;
}
2012-05-16 04:12:19 +00:00
$sql .= " ) " ;
2008-10-09 03:28:58 +00:00
$query = new Querylet ( $sql );
if ( strlen ( $img_search -> sql ) > 0 ) {
2008-10-09 03:41:39 +00:00
$query -> append_sql ( " AND " );
2008-10-09 03:28:58 +00:00
$query -> append ( $img_search );
}
}
else {
# one of the positive tags had zero results, therefor there
# can be no results; "where 1=0" should shortcut things
$query = new Querylet ( "
SELECT images .*
FROM images
WHERE 1 = 0
" );
}
}
return $query ;
}
2009-05-11 10:52:48 +00:00
2010-02-09 02:07:19 +00:00
/**
* this function exists because mysql is a turd , see the docs for
* build_accurate_search_querylet () for a full explanation
*/
2009-05-11 14:04:33 +00:00
private static function build_ugly_search_querylet ( $terms ) {
global $config , $database ;
2009-05-11 10:52:48 +00:00
$tag_querylets = array ();
$img_querylets = array ();
$positive_tag_count = 0 ;
$negative_tag_count = 0 ;
$stpe = new SearchTermParseEvent ( null , $terms );
send_event ( $stpe );
if ( $stpe -> is_querylet_set ()) {
foreach ( $stpe -> get_querylets () as $querylet ) {
$img_querylets [] = new ImgQuerylet ( $querylet , true );
}
}
2012-02-04 20:35:21 +00:00
reset ( $terms ); // rewind to first element in array.
2009-05-11 10:52:48 +00:00
// turn each term into a specific type of querylet
foreach ( $terms as $term ) {
$negative = false ;
2012-01-13 04:07:14 +00:00
if ( ! empty ( $term ) && ( $term [ 0 ] == '-' )) {
2009-05-11 10:52:48 +00:00
$negative = true ;
$term = substr ( $term , 1 );
}
$term = Tag :: resolve_alias ( $term );
$stpe = new SearchTermParseEvent ( $term , $terms );
send_event ( $stpe );
if ( $stpe -> is_querylet_set ()) {
foreach ( $stpe -> get_querylets () as $querylet ) {
$img_querylets [] = new ImgQuerylet ( $querylet , ! $negative );
}
}
else {
$term = str_replace ( " * " , " % " , $term );
$term = str_replace ( " ? " , " _ " , $term );
if ( ! preg_match ( " /^[%_]+ $ / " , $term )) {
$tag_querylets [] = new TagQuerylet ( $term , ! $negative );
}
}
}
// merge all the tag querylets into one generic one
$sql = " 0 " ;
$terms = array ();
foreach ( $tag_querylets as $tq ) {
2011-03-14 12:44:58 +00:00
global $tag_n ;
2009-05-11 10:52:48 +00:00
$sign = $tq -> positive ? " + " : " - " ;
2012-01-11 20:57:00 +00:00
//$sql .= " $sign (tag LIKE :tag$tag_n)";
$sql .= ' ' . $sign . ' (tag LIKE :tag' . $tag_n . ')' ;
//$terms["tag$tag_n"] = $tq->tag;
$terms [ 'tag' . $tag_n ] = $tq -> tag ;
2011-03-14 12:44:58 +00:00
$tag_n ++ ;
2009-05-11 10:52:48 +00:00
2012-01-11 20:57:00 +00:00
if ( $sign === " + " ) $positive_tag_count ++ ;
2009-05-11 10:52:48 +00:00
else $negative_tag_count ++ ;
}
$tag_search = new Querylet ( $sql , $terms );
// merge all the image metadata searches into one generic querylet
$n = 0 ;
$sql = " " ;
$terms = array ();
foreach ( $img_querylets as $iq ) {
if ( $n ++ > 0 ) $sql .= " AND " ;
if ( ! $iq -> positive ) $sql .= " NOT " ;
$sql .= " ( " . $iq -> qlet -> sql . " ) " ;
$terms = array_merge ( $terms , $iq -> qlet -> variables );
}
$img_search = new Querylet ( $sql , $terms );
// no tags, do a simple search (+image metadata if we have any)
if ( $positive_tag_count + $negative_tag_count == 0 ) {
$query = new Querylet ( " SELECT images.*,UNIX_TIMESTAMP(posted) AS posted_timestamp FROM images " );
2012-01-13 04:07:14 +00:00
if ( ! empty ( $img_search -> sql )) {
2009-05-11 10:52:48 +00:00
$query -> append_sql ( " WHERE " );
$query -> append ( $img_search );
}
}
// one positive tag (a common case), do an optimised search
2012-01-11 20:57:00 +00:00
else if ( $positive_tag_count === 1 && $negative_tag_count === 0 ) {
2009-05-11 10:52:48 +00:00
$query = new Querylet (
// MySQL is braindead, and does a full table scan on images, running the subquery once for each row -_-
// "{$this->get_images} WHERE images.id IN (SELECT image_id FROM tags WHERE tag LIKE ?) ",
"
SELECT images .* , UNIX_TIMESTAMP ( posted ) AS posted_timestamp
FROM tags , image_tags , images
WHERE
2011-03-14 14:20:30 +00:00
tag LIKE : tag0
2009-05-11 10:52:48 +00:00
AND tags . id = image_tags . tag_id
AND image_tags . image_id = images . id
" ,
$tag_search -> variables );
2012-01-13 04:07:14 +00:00
if ( ! empty ( $img_search -> sql )) {
2009-05-11 10:52:48 +00:00
$query -> append_sql ( " AND " );
$query -> append ( $img_search );
}
}
// more than one positive tag, or more than zero negative tags
else {
$s_tag_array = array_map ( " sql_escape " , $tag_search -> variables );
$s_tag_list = join ( ', ' , $s_tag_array );
$tag_id_array = array ();
$tags_ok = true ;
foreach ( $tag_search -> variables as $tag ) {
2011-01-01 15:58:09 +00:00
$tag_ids = $database -> get_col ( " SELECT id FROM tags WHERE tag LIKE :tag " , array ( " tag " => $tag ));
2009-05-11 10:52:48 +00:00
$tag_id_array = array_merge ( $tag_id_array , $tag_ids );
$tags_ok = count ( $tag_ids ) > 0 ;
if ( ! $tags_ok ) break ;
}
if ( $tags_ok ) {
$tag_id_list = join ( ', ' , $tag_id_array );
2012-01-11 20:57:00 +00:00
$subquery = new Querylet ( '
SELECT images .* , SUM ( '.$tag_search->sql.' ) AS score
2009-05-11 10:52:48 +00:00
FROM images
LEFT JOIN image_tags ON image_tags . image_id = images . id
JOIN tags ON image_tags . tag_id = tags . id
2012-01-11 20:57:00 +00:00
WHERE tags . id IN ( '.$tag_id_list.' )
2009-05-11 10:52:48 +00:00
GROUP BY images . id
2012-01-11 20:57:00 +00:00
HAVING score = : score ' ,
2009-05-11 10:52:48 +00:00
array_merge (
$tag_search -> variables ,
2011-01-01 15:58:09 +00:00
array ( " score " => $positive_tag_count )
2009-05-11 10:52:48 +00:00
)
);
2012-01-11 20:57:00 +00:00
$query = new Querylet ( '
2009-05-11 10:52:48 +00:00
SELECT * , UNIX_TIMESTAMP ( posted ) AS posted_timestamp
2012-01-11 20:57:00 +00:00
FROM ( '.$subquery->sql.' ) AS images ' , $subquery -> variables );
2009-05-11 10:52:48 +00:00
2012-01-13 04:07:14 +00:00
if ( ! empty ( $img_search -> sql )) {
2009-05-11 10:52:48 +00:00
$query -> append_sql ( " WHERE " );
$query -> append ( $img_search );
}
}
else {
# there are no results, "where 1=0" should shortcut things
$query = new Querylet ( "
SELECT images .*
FROM images
WHERE 1 = 0
" );
}
}
2011-10-18 21:32:04 +00:00
$tag_n = 0 ;
2009-05-11 10:52:48 +00:00
return $query ;
}
2009-01-04 13:53:14 +00:00
}
2009-07-19 07:38:13 +00:00
/**
* A class for organising the tag related functions .
*
* All the methods are static , one should never actually use a tag object .
*/
2009-01-04 18:39:11 +00:00
class Tag {
2009-07-19 07:38:13 +00:00
/**
* Remove any excess fluff from a user - input tag
*/
2009-01-04 18:39:11 +00:00
public static function sanitise ( $tag ) {
assert ( is_string ( $tag ));
$tag = preg_replace ( " /[ \ s?*]/ " , " " , $tag );
$tag = preg_replace ( " / \ .+/ " , " . " , $tag );
$tag = preg_replace ( " /^( \ .+[ \ / \\ \\ ])+/ " , " " , $tag );
return $tag ;
}
2009-07-19 07:38:13 +00:00
/**
* Turn any string or array into a valid tag array
*/
2013-08-04 17:11:02 +00:00
public static function explode ( $tags , $tagme = true ) {
2009-07-19 07:38:13 +00:00
assert ( is_string ( $tags ) || is_array ( $tags ));
2009-01-24 11:32:48 +00:00
if ( is_string ( $tags )) {
2013-08-04 17:11:02 +00:00
$tags = explode ( ' ' , trim ( $tags ));
2009-01-24 11:32:48 +00:00
}
2012-01-11 20:57:00 +00:00
//else if(is_array($tags)) {
2009-01-24 11:32:48 +00:00
// do nothing
2012-01-11 20:57:00 +00:00
//}
2009-01-24 11:32:48 +00:00
$tag_array = array ();
foreach ( $tags as $tag ) {
2012-03-11 14:54:14 +00:00
$tag = trim ( $tag , " , \t \n \r \0 \x0B " );
2012-01-13 04:07:14 +00:00
if ( is_string ( $tag ) && ! empty ( $tag )) {
2009-01-24 11:32:48 +00:00
$tag_array [] = $tag ;
}
}
2013-08-04 17:11:02 +00:00
if ( count ( $tag_array ) == 0 && $tagme ) {
2009-01-24 11:32:48 +00:00
$tag_array = array ( " tagme " );
}
2011-01-01 18:40:21 +00:00
sort ( $tag_array );
2009-01-24 11:32:48 +00:00
return $tag_array ;
}
2009-08-24 02:33:51 +00:00
public static function implode ( $tags ) {
assert ( is_string ( $tags ) || is_array ( $tags ));
2012-01-11 20:57:00 +00:00
if ( is_array ( $tags )) {
2011-01-01 18:40:21 +00:00
sort ( $tags );
2009-08-24 02:33:51 +00:00
$tags = implode ( ' ' , $tags );
}
2012-01-11 20:57:00 +00:00
//else if(is_string($tags)) {
// do nothing
//}
2009-08-24 02:33:51 +00:00
return $tags ;
}
2009-01-04 18:39:11 +00:00
public static function resolve_alias ( $tag ) {
assert ( is_string ( $tag ));
2013-08-04 17:19:23 +00:00
$negative = false ;
if ( ! empty ( $tag ) && ( $tag [ 0 ] == '-' )) {
$negative = true ;
$tag = substr ( $tag , 1 );
}
2009-01-04 18:39:11 +00:00
global $database ;
2011-01-22 15:51:55 +00:00
$newtag = $database -> get_one (
2012-06-23 23:57:55 +00:00
$database -> scoreql_to_sql ( " SELECT newtag FROM aliases WHERE SCORE_STRNORM(oldtag)=SCORE_STRNORM(:tag) " ),
2011-01-22 15:51:55 +00:00
array ( " tag " => $tag ));
2013-08-04 17:19:23 +00:00
if ( empty ( $newtag )) {
$newtag = $tag ;
2009-01-04 18:39:11 +00:00
}
2013-08-04 17:19:23 +00:00
return $negative ? " - $newtag " : $newtag ;
2009-01-04 18:39:11 +00:00
}
public static function resolve_wildcard ( $tag ) {
2013-03-03 18:26:47 +00:00
// if there is no wildcard, return the tag
if ( strpos ( $tag , " * " ) === false ) {
2009-01-04 18:39:11 +00:00
return array ( $tag );
}
2013-03-03 18:26:47 +00:00
// if the whole match is wild, return null to save the database
2013-03-03 18:34:27 +00:00
else if ( str_replace ( " * " , " " , $tag ) == " " ) {
2013-03-03 18:26:47 +00:00
return array ();
}
// else find some matches
2009-01-04 18:39:11 +00:00
else {
global $database ;
2013-03-03 18:26:47 +00:00
$db_wild_tag = str_replace ( " % " , " \ % " , $tag );
$db_wild_tag = str_replace ( " * " , " % " , $tag );
$newtags = $database -> get_col ( $database -> scoreql_to_sql ( " SELECT tag FROM tags WHERE SCORE_STRNORM(tag) LIKE SCORE_STRNORM(?) " ), array ( $db_wild_tag ));
2009-01-04 18:39:11 +00:00
if ( count ( $newtags ) > 0 ) {
$resolved = $newtags ;
} else {
$resolved = array ( $tag );
}
return $resolved ;
}
}
2009-01-24 11:32:48 +00:00
2012-02-04 20:35:21 +00:00
/**
* This function takes a list ( array ) of tags and changes any tags that have aliases
*
* @ param $tags Array of tags
* @ return Array of tags
*/
2013-08-04 17:13:50 +00:00
public static function resolve_aliases ( $tags ) {
2013-08-04 17:11:02 +00:00
assert ( is_array ( $tags ));
2009-01-24 11:32:48 +00:00
$new = array ();
foreach ( $tags as $tag ) {
$new_set = explode ( ' ' , Tag :: resolve_alias ( $tag ));
foreach ( $new_set as $new_one ) {
$new [] = $new_one ;
}
}
2013-08-04 17:11:02 +00:00
2009-01-24 11:32:48 +00:00
$new = array_map ( array ( 'Tag' , 'sanitise' ), $new );
$new = array_iunique ( $new ); // remove any duplicate tags
return $new ;
}
2009-01-04 18:39:11 +00:00
}
2008-10-09 03:28:58 +00:00
2009-01-04 13:53:14 +00:00
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \
* Misc functions *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-19 07:38:13 +00:00
/**
* Move a file from PHP 's temporary area into shimmie' s image storage
* heirachy , or throw an exception trying
*/
2012-02-02 13:58:48 +00:00
function move_upload_to_archive ( DataUploadEvent $event ) {
2010-02-02 00:29:38 +00:00
$target = warehouse_path ( " images " , $event -> hash );
if ( !@ copy ( $event -> tmpname , $target )) {
2011-11-08 11:02:04 +00:00
$errors = error_get_last (); // note: requires php 5.2
throw new UploadException ( " Failed to copy file from uploads ( { $event -> tmpname } ) to archive ( $target ): { $errors [ 'type' ] } / { $errors [ 'message' ] } " );
2009-01-04 13:53:14 +00:00
return false ;
}
return true ;
}
2009-07-19 07:38:13 +00:00
/**
* Given a full size pair of dimentions , return a pair scaled down to fit
* into the configured thumbnail square , with ratio intact
*/
2012-02-02 13:58:48 +00:00
function get_thumbnail_size ( /*int*/ $orig_width , /*int*/ $orig_height ) {
2009-01-04 13:53:14 +00:00
global $config ;
if ( $orig_width == 0 ) $orig_width = 192 ;
if ( $orig_height == 0 ) $orig_height = 192 ;
2011-02-13 11:18:23 +00:00
if ( $orig_width > $orig_height * 5 ) $orig_width = $orig_height * 5 ;
if ( $orig_height > $orig_width * 5 ) $orig_height = $orig_width * 5 ;
2009-01-04 13:53:14 +00:00
$max_width = $config -> get_int ( 'thumb_width' );
$max_height = $config -> get_int ( 'thumb_height' );
$xscale = ( $max_height / $orig_height );
$yscale = ( $max_width / $orig_width );
$scale = ( $xscale < $yscale ) ? $xscale : $yscale ;
if ( $scale > 1 && $config -> get_bool ( 'thumb_upscale' )) {
return array (( int ) $orig_width , ( int ) $orig_height );
}
else {
return array (( int )( $orig_width * $scale ), ( int )( $orig_height * $scale ));
}
}
2007-04-16 11:58:25 +00:00
?>