Initial commit

This commit is contained in:
Dominic Szablewski 2012-07-14 23:13:47 +02:00
commit 064c61dc55
60 changed files with 5152 additions and 0 deletions

219
image-grid-examples.html Normal file
View File

@ -0,0 +1,219 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Picturelicious 2.0 - Image Grid Example Configurations</title>
<style type="text/css">
body {
background-color: #222;
color: #fff;
font-family: Helvetica, Arial, Verdana, Sans-Serif;
font-size: 12pt;
padding: 0;
width: 660px;
margin: 0 auto 8em auto;
}
h1 {
font-size: 130%;
font-weight: normal;
padding: 4.2em 0 0 0;
margin: 0;
border-bottom: 1px solid #333;
}
h2 {
font-size: 100%;
font-weight: bold;
padding: 2.2em 0 0 0;
margin: 0;
border-bottom: 1px solid #333;
}
ul {
list-style-type: square;
}
ol > li {
margin: 0.5em 0;
}
dt, code, pre {
font-family:Courier New,Lucida Console,Bitstream Vera Sans Mono,monospace;
}
pre {
font-size: 90%;
}
dd {
margin-bottom: 0.8em;
}
p {
padding: 0;
margin: 1em 0 0 0;
line-height: 1.3em;
}
</style>
</head>
<body>
<h1>Picturelicious - Image Grid Example Configurations</h1>
<h1>Quadratic Thumbs in 3 Different Sizes (Default Configuration)</h1>
<h2>lib/config.php</h2>
<pre>
public static $gridView = array(
'gridSize' => 64,
'gridWidth' => 12,
'borderWidth' => 2,
'classes' => array(
'b2' => array( 'width'=>1, 'height'=>1, 'percentage'=>0.60, 'dir'=>'64x64' ),
'b1' => array( 'width'=>2, 'height'=>2, 'percentage'=>0.35, 'dir'=>'128x128' ),
'b0' => array( 'width'=>3, 'height'=>3, 'percentage'=>0.05, 'dir'=>'192x192' )
),
);
</pre>
<h2>media/picturelicious.js</h2>
<pre>
var gridSize = 64;
var gridMinWidth = 6;
var gridWidth = 0;
var grid = null;
var boxDef = {
'b0': {'width': 3, 'height': 3},
'b1': {'width': 2, 'height': 2},
'b2': {'width': 1, 'height': 1}
};
</pre>
<h2>media/styles.css</h2>
<pre>
.b0 {
width: 192px;
height: 192px;
}
.b1 {
width: 128px;
height: 128px;
}
.b2 {
width: 64x;
height: 64px;
}
</pre>
<h1>Large Spacing between Thumbnails</h1>
<h2>lib/config.php</h2>
<pre>
public static $gridView = array(
'gridSize' => 88,
'gridWidth' => 12,
'borderWidth' => 2,
'classes' => array(
'b2' => array( 'width'=>1, 'height'=>1, 'percentage'=>0.6, 'dir'=>'64x64' ),
'b1' => array( 'width'=>2, 'height'=>2, 'percentage'=>0.35, 'dir'=>'128x128' ),
'b0' => array( 'width'=>3, 'height'=>3, 'percentage'=>0.05, 'dir'=>'192x192' )
),
);
</pre>
<h2>media/picturelicious.js</h2>
<pre>
var gridSize = 88;
var gridMinWidth = 6;
var gridWidth = 0;
var grid = null;
var boxDef = {
'b0': {'width': 3, 'height': 3},
'b1': {'width': 2, 'height': 2},
'b2': {'width': 1, 'height': 1}
};
</pre>
<h2>media/styles.css</h2>
<pre>
.b0 {
padding-left: 32px;
padding-top: 32px;
width: 192px;
height: 192px;
}
.b1 {
padding-left: 24px;
padding-top: 24px;
width: 128px;
height: 128px;
}
.b2 {
padding-left: 12px;
padding-top: 12px;
width: 64x;
height: 64px;
}
</pre>
<h1>4 Thumbnail sizes in 4:3 and 2:3 aspect ratios</h1>
<h2>lib/config.php</h2>
<pre>
public static $gridView = array(
'gridSize' => 32,
'gridWidth' => 24,
'borderWidth' => 2,
'classes' => array(
'b3' => array( 'width'=>2, 'height'=>3, 'percentage'=>0.58, 'dir'=>'64x96' ),
'b2' => array( 'width'=>4, 'height'=>3, 'percentage'=>0.3, 'dir'=>'128x96' ),
'b1' => array( 'width'=>4, 'height'=>6, 'percentage'=>0.10, 'dir'=>'128x192' ),
'b0' => array( 'width'=>6, 'height'=>9, 'percentage'=>0.02, 'dir'=>'192x288' )
),
);
</pre>
<h2>media/picturelicious.js</h2>
<pre>
var gridSize = 32;
var gridMinWidth = 6;
var gridWidth = 0;
var grid = null;
var boxDef = {
'b0': {'width': 6, 'height': 9},
'b1': {'width': 4, 'height': 6},
'b2': {'width': 4, 'height': 3}
'b3': {'width': 2, 'height': 3}
};
</pre>
<h2>media/styles.css</h2>
<pre>
.b0 {
width: 192px;
height: 288px;
}
.b1 {
width: 128px;
height: 192px;
}
.b2 {
width: 128px;
height: 96px;
}
.b3 {
width: 64px;
height: 96px;
}
</pre>
</body>
</html>

372
installation-readme.html Normal file
View File

@ -0,0 +1,372 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Picturelicious 2.0 - Readme</title>
<style type="text/css">
body {
background-color: #222;
color: #fff;
font-family: Helvetica, Arial, Verdana, Sans-Serif;
font-size: 12pt;
padding: 0;
width: 660px;
margin: 0 auto 8em auto;
}
h1 {
font-size: 130%;
font-weight: normal;
padding: 2.2em 0 0 0;
margin: 0;
border-bottom: 1px solid #333;
}
h2 {
font-size: 100%;
font-weight: bold;
padding: 2.2em 0 0 0;
margin: 0;
border-bottom: 1px solid #333;
}
ul {
list-style-type: square;
}
ol > li {
margin: 0.5em 0;
}
dt, code {
font-family:Courier New,Lucida Console,Bitstream Vera Sans Mono,monospace;
}
dd {
margin-bottom: 0.8em;
}
p {
padding: 0;
margin: 1em 0 0 0;
line-height: 1.3em;
}
</style>
</head>
<body>
<h1>Picturelicious v2.0</h1>
<h1>Installation</h1>
<ol>
<li>
<p>
Edit the <code>lib/config.php</code>. Things you absolutely need to change
are the <code>$frontendPath</code> and <code>$db</code> (Database) settings.
</p>
</li>
<li>
<p>
Upload everything from the <code>picturelicious/</code> directory, so that the
<code>index.php</code> is at the root of your installation. Make sure you also
upload the <code>.htacces</code> file (it is initially hidden on MacOS).
</p>
</li>
<li>
<p>
Make sure PHP has writing permissions on the following directories:
</p>
<ul>
<li>cache</li>
<li>data/avatars</li>
<li>data/images</li>
<li>data/thumbs</li>
<li>import</li>
</ul>
<p>
You can change permissions (chmod) with your FTP client. Many server configurations
require you to set permissions to <code>0777</code> (all permissions set).
</p>
</li>
<li>
<p>
Import the <code>picturelicious.sql</code> with PHPMyAdmin into your database.
</p>
</li>
<li>
<p>
Register a new user on your site. You can give this user Admin rights, by changing
the <code>admin</code> value for this user to <code>1</code> in the <code>pl_users</code>
table. Again, use PHPMyAdmin to do so.
</p>
<p>
<strong>Important:</strong> If you want to use the vbb-Forum integration, you have to install
the forum and activate it in your config before(!) any users are registered.
</p>
</li>
</ol>
<h1>Mass importing images</h1>
<p>
You can import many images at once. Just upload all images you want to appear on your site into the
<code>import/</code> directory of your installation, log in as an admin user and choose <em>Import</em>
from the menu. You can then click on <em>Import Images</em> at the bottom of the page. Please note that
this may take a while.
</p>
<h1>Customizing the Image Grid</h1>
<p>
The Image Grid or <em>"Image Cloud"</em> is highly customizable but requires some understanding.
When a page is loaded, all images are assigned to one of the available thumbnail sizes and the Image Grid
is then generated in a fixed width. This is important for users who have Javascript disabled. When Javascript is
enabled, the Image Grid will adept to the available width of the browser window. The width and height of each
thumbnail in this grid is also specified in the <code>style.css</code>. Therefore, if you want to change
the layout, you have to edit three different files:
</p>
<ul>
<li>lib/config.php ($gridView)</li>
<li>media/picturelicious.js (boxDef, gridSize)</li>
<li>media/style.css (.b0, .b1, .b2)</li>
</ul>
<p>
The Image Grid is ultimately defined by the different thumbnail sizes that are available. In the default configuration,
thumbnails are generated in 3 different, qudratic sizes 64x64, 128x128 and 192x192. Since the gridSize is set to 64,
the size of the thumbnails is only specified by 1, 2 or 3 - a multiple of the gridSize.
</p>
<p>
The percentage setting in the <code>lib/config.php</code> specifies how many of the images are assigned to each of the
box definitions. All of these percentage settings should add up to 1. The order of these box definitions is also important:
the first definition is the "least important", while the last one is the "most important", meaning that images with a bad rating
will be assigned to the first one, while images with a good rating, will be assigned to the last one.
</p>
<p>
Take a look at the <code>image-grid-examples.html</code> for some example configurations.
</p>
<p>
Please note that whenever you change the size of one of these thumbnail definitions, the thumbnails have to be regenerated. There is
no tool included for doing so <em>on the fly</em>. The simplest solution is, to move all images into the <code>import/</code>
directory, clear the database and import these images again.
</p>
<h1>Using the Random Thumbnail Widget</h1>
<p>
To promote your Picturelicious site on other websites, you can easily embed some thumbnails from
Picturelicious by using the following code snippet:
</p>
<p>
<code>&lt;script type=&quot;text/javascript&quot; src=&quot;http://example.com/random/4/64x64/&quot;&gt;</script></code>
</p>
<p>
This will insert 4 thumbnails in 64x64 wherever you put this snippet to. Also take a look at the
configuration (Random Thumbnail Widget).
</p>
<h1>Configuration</h1>
<p>
All configuration settings can be found in <code>lib/config.php</code>. Following is a list of
these settings and their meaning. Many of this settings are only needed for fine tuning.
</p>
<h2>Names and URLs for your installation</h2>
<dl>
<dt>$absolutePath</dt>
<dd>
The absolute path to your Picturelicious installation from your domain root. If Picturelicious
is installed on <code>http://example.com/picturelicious/</code>, your $absolutePath must be set to
<code>/picturelicious/</code>. If Picturelicious is not in a sub-directory, the default setting (<code>/</code>)
is the right one.
</dd>
<dt>$frontendPath</dt>
<dd>
The complete URL to you Picturelicious installation.
</dd>
<dt>$siteName</dt>
<dd>
The name of your site. This value is extensivly used in numerous templates and the registration mail
</dd>
<dt>$siteTitle</dt>
<dd>
The title of your site to appear in the browser window's title bar
</dd>
</dl>
<h2>Cookies</h2>
<dl>
<dt>$sessionCookie</dt>
<dd>
The name of the session cookie - a normal user will never see this
</dd>
<dt>$rememberCookie</dt>
<dd>
The name of the remember cookie - a normal user will never see this
</dd>
</dl>
<h2>Spam protection</h2>
<dl>
<dt>$ipLockTime</dt>
<dd>
The time in seconds to lock an IP-adress from voting for the same image again
</dd>
<dt>$uploadLockTime</dt>
<dd>
The time in seconds to which the <code>$maxNumUploads</code> setting corresponds
</dd>
<dt>$maxNumUploads</dt>
<dd>
The maximum number of image uploads allowed in <code>$uploadLockTime</code> seconds
</dd>
</dl>
<h2>User scores</h2>
<dl>
<dt>$votingScore</dt>
<dd>
The score a user gains for voting for an image
</dd>
<dt>$postScore</dt>
<dd>
The score a user gainr for posting an image
</dd>
<dt>$tagScorePerChar</dt>
<dd>
The score a user gains for each character he writes in a tag
</dd>
<dt>$tagScoreMax</dt>
<dd>
The maximum score when tagging an image
</dd>
</dl>
<h2>Misc settings</h2>
<dl>
<dt>$usersPerPage</dt>
<dd>
The number of users to show on one page in the user list
</dd>
<dt>$defaultChmod</dt>
<dd>
The permissions to use when creating a new directory. Chances are, you have to
keep this setting at 0777
</dd>
<dt>$templates</dt>
<dd>
The directory in which all templates are stored
</dd>
<dt>$keywordWordSeperator</dt>
<dd>
The seperator between words when a keyword for an image is generated. Feel free to change this to
'<code>_</code>' or an empty value for no word seperation
</dd>
</dl>
<dl>
<dt>$colorSearchDev</dt>
<dd>
The maximum deviation for each color channel (R, G, B) when searching for colors
</dd>
</dl>
<h2>Random Thumbnail Widget</h2>
<dl>
<dt>$maxRandomThumbs</dt>
<dd>
Maximum number of thumbnails to show on the random thumb widget
</dd>
<dt>$minRandomScore</dt>
<dd>
Minimum score of an image to be shown on the random thumb widget
</dd>
</dl>
<h2>vbb Forum integration</h2>
<dl>
<dt>$vbbIntegration</dt>
<dd>
<dl>
<dt>enabled</dt>
<dd>Whether to enable the vbb integration (true|false)</dd>
<dt>path</dt>
<dd>relative path to the installation directory of vbb-Forum</dd>
</dl>
</dd>
</dl>
<h2>Cache settings</h2>
<dl>
<dt>$cache</dt>
<dd>
<dl>
<dt>enabled</dt>
<dd>Whether to enable the cache</dd>
<dt>path</dt>
<dd>relative path to the cache directory</dd>
<dt>clearEvery</dt>
<dd>The cache is cleared at every image upload or at least every <em>n</em>'th vote</dd>
</dl>
</dd>
</dl>
<h2>Database settings</h2>
<dl>
<dt>$db</dt>
<dd>
<dl>
<dt>host</dt>
<dd>The hostname of your database server (in most cases this should be <code>localhost</code>)</dd>
<dt>database</dt>
<dd>The name of the database where all the Picturelicious tables reside</dd>
<dt>user</dt>
<dd>username for the database login</dd>
<dt>password</dt>
<dd>password for the database login</dd>
<dt>prefix</dt>
<dd>prefix for all tables (note that you manually have to rename your tables if you want to change this setting)</dd>
</dl>
</dd>
</dl>
<h2>Image processing and thumbnail creation</h2>
<dl>
<dt>$images</dt>
<dd>
<dl>
<dt>thumbsPerPage</dt>
<dd>Number of images to show in the browse mode (i.e. the image cloud)</dd>
<dt>imagePath</dt>
<dd>File path to the images</dd>
<dt>thumbPath</dt>
<dd>File path to the thumbnails</dd>
<dt>avatarsPath</dt>
<dd>File path to the avatar images</dd>
<dt>maxDownload</dt>
<dd>Maximum file size when copying images from a remote URL</dd>
<dt>jpegQuality</dt>
<dd>Quality level for the created thumbnails (0-100)</dd>
<dt>sharpen</dt>
<dd>Whether to sharpen thumbnails after resizing. <em>Note:</em> This only works with PHP 5.1 and newer and is
automatically disabled on older versions.</dd>
</dl>
</dd>
</dl>
<h2>Grid Solver settings</h2>
<dl>
<dt>$gridView</dt>
<dd>Refer to the Grid View section in this readme</dd>
</dl>
</body>
</html>

85
picturelicious.sql Normal file
View File

@ -0,0 +1,85 @@
CREATE TABLE `pl_comments` (
`id` int(11) NOT NULL auto_increment,
`imageId` int(11) NOT NULL,
`userId` int(11) NOT NULL,
`created` datetime NOT NULL,
`content` text collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `imageId` (`imageId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_imagecolors` (
`id` int(11) NOT NULL auto_increment,
`imageId` int(11) NOT NULL,
`r` tinyint(3) unsigned NOT NULL default '0',
`g` tinyint(3) unsigned NOT NULL default '0',
`b` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_images` (
`id` int(11) NOT NULL auto_increment,
`logged` datetime NOT NULL,
`user` int(11) NOT NULL,
`score` float NOT NULL default '0',
`votes` int(11) NOT NULL default '0',
`keyword` varchar(255) collate utf8_unicode_ci NOT NULL,
`tags` text collate utf8_unicode_ci NOT NULL,
`image` varchar(255) collate utf8_unicode_ci NOT NULL,
`thumb` varchar(255) collate utf8_unicode_ci NOT NULL,
`hash` char(32) collate utf8_unicode_ci NOT NULL,
`source` varchar(255) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `keyword` (`keyword`),
FULLTEXT KEY `tags` (`tags`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_iplock` (
`ip` int(11) NOT NULL,
`imageId` int(11) NOT NULL,
`ts` int(11) NOT NULL,
PRIMARY KEY (`ip`,`imageId`),
KEY `ts` (`ts`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_taglog` (
`id` int(11) NOT NULL auto_increment,
`tagged` datetime NOT NULL,
`userId` int(11) NOT NULL,
`imageId` int(11) NOT NULL,
`locked` tinyint(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `tagged` (`tagged`),
KEY `userId` (`userId`),
KEY `imageId` (`imageId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_uploadlock` (
`id` int(11) NOT NULL auto_increment,
`ip` int(11) NOT NULL,
`ts` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `pl_users` (
`id` int(11) NOT NULL auto_increment,
`registered` datetime NOT NULL,
`name` varchar(255) collate utf8_unicode_ci NOT NULL,
`pass` char(32) collate utf8_unicode_ci NOT NULL,
`valid` tinyint(4) NOT NULL,
`remember` char(32) collate utf8_unicode_ci NOT NULL,
`admin` tinyint(4) NOT NULL default '0',
`score` int(11) NOT NULL,
`images` int(11) NOT NULL default '0',
`avatar` varchar(255) collate utf8_unicode_ci NOT NULL,
`website` varchar(255) collate utf8_unicode_ci NOT NULL,
`email` varchar(255) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

7
picturelicious/.htaccess Normal file
View File

@ -0,0 +1,7 @@
RewriteEngine on
#not a real file or directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]*|search/.*)$ index.php?s=$1

View File

@ -0,0 +1,52 @@
<?php
require_once( 'lib/config.php' );
require_once( 'lib/users.php' );
require_once( 'lib/db.php' );
header("Content-type: text/html; charset=UTF-8");
$user = new User();
$user->login();
if( !$user->admin ) {
echo "You need to be logged in as an admin user!";
exit();
}
$newComments = DB::query(
'SELECT
c.id, c.content, u.name, u.avatar,
UNIX_TIMESTAMP(c.created) AS created,
i.keyword FROM '.TABLE_COMMENTS.' c
LEFT JOIN '.TABLE_USERS.' u
ON u.id = c.userId
LEFT JOIN '.TABLE_IMAGES.' i
ON i.id = c.imageId
ORDER BY c.created DESC LIMIT 100'
);
include( 'templates/header.tpl.php' );
?>
<h2>Newest Comments:</h2>
<div style="width: 700px;">
<?php foreach( $newComments as $c ) {?>
<div class="comment">
<div class="commentHead">
<img class="avatarSmall" width="16" height="16" src="<?php echo Config::$absolutePath.$c['avatar']; ?>"/>
<a href="<?php echo Config::$absolutePath.'user/'.$c['name']; ?>"><?php echo $c['name']; ?></a>
at <?php echo date('d. M Y H:i',$c['created']); ?>
[bild:<a href="<?php echo Config::$absolutePath.'all/view/'.$c['keyword']; ?>"><?php echo $c['keyword']; ?></a>]
<?php if($user->admin) { ?>
<div style="float:right;" id="del">
<a href="#" onclick="return delComment(<?php echo $c['id']; ?>, this)">[x]</a>
</div>
<?php } ?>
</div>
<?php echo $c['content']; ?>
</div>
<?php } ?>
</div>
<?php
include( 'templates/footer.tpl.php' );
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

View File

@ -0,0 +1,57 @@
<?php
require_once( 'lib/config.php' );
require_once( 'lib/users.php' );
require_once( 'lib/db.php' );
require_once( 'lib/imageuploader.php' );
header("Content-type: text/html; charset=UTF-8");
$user = new User();
$user->login();
if( !$user->admin ) {
echo "You need to be logged in as an admin user!";
exit();
}
set_time_limit(0);
$files = glob( 'import/*.*' );
include( 'templates/header.tpl.php' );
if( isset($_POST['import']) ) {
echo "<h2>Imported Images:</h2><ul>";
foreach( $files as $f ) {
$errors = array();
if( ImageUploader::process( basename($f), $f, '', false, $errors ) ) {
echo "<li><a href=\"$f\">$f</a> - OK</li>";
} else {
echo "<li><a href=\"$f\">$f</a> - FAILED</li>";
}
}
echo "</ul>";
require_once( 'lib/cache.php' );
$cache = new Cache( Config::$cache['path'], 'index' );
$cache->clear();
} else {
echo "<h2>Images ready to import:</h2>";
if( !empty($files) ) {
echo "<ul>";
foreach( $files as $f ) {
echo "<li><a href=\"$f\">$f</a></li>";
}
echo '</ul><form action="imageimport.php" method="post"><input type="submit" name="import" value="Import Images!"/></form>';
} else {
echo "<p>No images found in the <i>import/</i> directory!</p>";
}
}
?>
<?php
include( 'templates/footer.tpl.php' );
?>

283
picturelicious/index.php Normal file
View File

@ -0,0 +1,283 @@
<?php
/*
Picturelicious
(c) 2008 Dominic Szablewski
*/
header("Content-type: text/html; charset=UTF-8");
require_once( 'lib/config.php' );
// No JS - redirect to GET search url
if( isset($_POST['q']) ) {
header( 'location: '.Config::$absolutePath.'search/'.$_POST['q'] );
exit;
}
require_once( 'lib/cache.php' );
$cache = new Cache( Config::$cache['path'], !empty($_GET['s']) ? $_GET['s'] : 'index' );
if( !Config::$cache['enabled'] ) {
$cache->disable();
}
// no session or remember cookie -> get the page from cache
if(
empty($_COOKIE[Config::$sessionCookie]) &&
empty($_COOKIE[Config::$rememberCookie])
) {
$cache->lookup();
}
require_once( 'lib/users.php' );
require_once( 'lib/db.php' );
// If the User logged in with POST or a remember cookie, we need forumops.php
// to log him in the forum, too.
if(
isset($_POST['login']) ||
(
empty($_COOKIE[Config::$sessionCookie]) &&
!empty($_COOKIE[Config::$rememberCookie])
)
) {
if( Config::$vbbIntegration['enabled'] ) { require_once( 'lib/class.forumops.php' ); }
}
$user = new User();
$user->login();
if( $user->id ) {
// Don't cache pages for logged-in users
$cache->disable();
}
$messages = array();
$query = !empty($_GET['s']) ? $_GET['s'] : '';
$r = explode( '/', $query );
if( $r[0] == 'login' ) { //---------------------------------------- login
if( Config::$vbbIntegration['enabled'] ) { require_once( 'lib/class.forumops.php' ); }
if( !empty( $r[1] ) ) {
if( $user->validate($r[1]) ) {
header( 'location: '.Config::$absolutePath );
} else {
header( 'location: '.Config::$absolutePath.'login' );
}
exit(0);
}
if( $user->id ) {
header( 'location: '.Config::$absolutePath );
exit();
}
if( isset($_POST['login']) ) {
$messages['wrongLogin'] = true;
}
include( Config::$templates.'login.tpl.php' );
}
else if( $r[0] == 'static' ) {
preg_match('/(\w+)/', $r[1], $m );
if( !empty($m[1]) && file_exists('static/'.$m[1].'.html.php') ) {
include( Config::$templates.'header.tpl.php' );
include( 'static/'.$m[1].'.html.php' );
include( Config::$templates.'footer.tpl.php' );
} else {
header( 'HTTP/1.0 404 Not Found' );
include( Config::$templates.'404.tpl.php' );
}
}
else if( $r[0] == 'logout' ) { //---------------------------------- logout
if( Config::$vbbIntegration['enabled'] ) { require_once( 'lib/class.forumops.php' ); }
$user->logout();
header( 'location: '.Config::$absolutePath );
exit();
}
else if( $r[0] == 'register' ) { //-------------------------------- new user
if( Config::$vbbIntegration['enabled'] ) { require_once( 'lib/class.forumops.php' ); }
if( $user->id ) {
header( 'location: '.Config::$absolutePath );
exit();
}
if( isset($_POST['register']) && $user->register( $messages ) ) {
include( Config::$templates.'registered.tpl.php' );
} else {
include( Config::$templates.'register.tpl.php' );
}
}
else if( //----------------------------------------------------- view
($r[0] == 'all' && $r[1] == 'view') ||
( in_array($r[0], array('user', 'search')) && $r[2] == 'view')
) {
require_once( 'lib/imageviewer.php' );
$iv = new ImageViewer();
if( $r[0] == 'all' ) { // /all/view/2007/09/hans
$iv->setCurrent( $r[2].'/'.$r[3].'/'.$r[4] );
}
else if( $r[0] == 'user' ) { // /user/name/view/2007/09/hans
$iv->setCurrent( $r[3].'/'.$r[4].'/'.$r[5] );
$iv->setUser( $r[1] );
}
else if( $r[0] == 'search' ) { // /search/term/view/2007/09/hans
list( $term, $keyword ) = explode( '/view/', str_ireplace('search/', '', $query) );
$iv->setCurrent( $keyword );
$iv->setSearch( $term );
}
$iv->load();
// Add comment if we have one
if( $_POST['addComment'] && $iv->addComment($user->id, $_POST['content']) ) {
$cache->clear( $iv->image['keyword'] );
header( 'Location: '.Config::$absolutePath.$iv->basePath.'view/'.$iv->image['keyword'] );
exit();
}
if( !empty($iv->image['id']) ) {
$iv->loadComments();
$cache->capture();
include( Config::$templates.'view.tpl.php' );
} else {
header( 'HTTP/1.0 404 Not Found' );
include( Config::$templates.'404.tpl.php' );
}
}
else if( //----------------------------------------------------- browse
empty($r[0]) ||
in_array( $r[0], array('all', 'user', 'search') )
) {
require_once( 'lib/imagebrowser.php' );
$ib = new ImageBrowser( Config::$images['thumbsPerPage'] );
if( empty($r[0]) || $r[0] == 'all' ) { // /all/page/2
$ib->setPage( $r[2] );
}
else if( $r[0] == 'user' ) { // /user/name/page/2
$ib->setPage( $r[3] );
$ib->setUser( $r[1] );
}
else if( $r[0] == 'search' ) { // /search/term/page/2
list( $term, $page ) = explode( '/page/', str_ireplace('search/', '', $query) );
$ib->setPage( $page );
$ib->setSearch( $term );
}
$ib->load();
if( !empty($ib->thumbs) ) {
require_once( 'lib/gridview.php' );
$gv = new GridView( Config::$gridView['gridWidth'] );
$gv->solve( $ib->thumbs );
$cache->capture();
include( Config::$templates.'browse.tpl.php' );
} else {
header( 'HTTP/1.0 404 Not Found' );
include( Config::$templates.'404.tpl.php' );
}
}
else if( $r[0] == 'random' ) {
$count = max( 1, min( Config::$maxRandomThumbs, intval($r[1]) ) );
$size = '';
foreach( Config::$gridView['classes'] as $c ) {
if( $r[2] == $c['dir'] ) {
$size = $r[2];
break;
}
if( empty($size) ) {
$size = $c['dir'];
}
}
require_once( 'lib/imagebrowser.php' );
$ib = new ImageBrowser( $count );
$ib->loadRandom( Config::$minRandomScore, $size );
$cache->forceEnable();
$cache->capture();
include( Config::$templates.'random.js.php' );
}
else if( $r[0] == 'upload' ) {
if( $user->id ) {
$uploadErrors = array();
if( $user->isSpamLocked() ) {
$uploadErrors[] = 'No more than 10 images in 2 hours!';
}
else if( !empty( $_POST ) ) {
require_once( 'lib/imageuploader.php' );
if(
(
!empty($_POST['url']) &&
ImageUploader::copyFromUrl( $_POST['url'], $_POST['tags'], false, $uploadErrors)
) ||
(
!empty($_FILES['image']['name']) &&
ImageUploader::process($_FILES['image']['name'], $_FILES['image']['tmp_name'], $_POST['tags'], true, $uploadErrors)
)
) {
$cache->clear();
$user->logUpload();
header( "Location: ".Config::$absolutePath );
exit(0);
}
}
include( Config::$templates.'upload.tpl.php' );
} else {
header( 'location: '.Config::$absolutePath.'login' );
}
}
else if( $r[0] == 'profile' ) {
if( $user->id ) {
if( Config::$vbbIntegration['enabled'] ) { require_once( 'lib/class.forumops.php' ); }
$messages = array();
if( !empty( $_POST ) ) {
$user->profile( $_FILES['avatar']['tmp_name'], $messages );
if( empty( $messages ) ) {
header( 'location: '.Config::$absolutePath );
}
}
$user->loadEmail();
include( Config::$templates.'profile.tpl.php' );
} else {
header( 'location: '.Config::$absolutePath.'login' );
}
}
else if( $r[0] == 'users' ) {
require_once( 'lib/userlist.php' );
$ul = new UserList( Config::$usersPerPage );
$ul->setPage( $r[2] );
$ul->load();
$cache->capture();
include( Config::$templates.'userlist.tpl.php' );
}
else if( $r[0] == 'quicktags' ) { //------------------------------------------- quicktagger
if( $user->id ) {
include( Config::$templates.'quicktags.tpl.php' );
} else {
header( 'location: '.Config::$absolutePath.'login' );
}
}
else { //------------------------------------------------------- 404
header( 'HTTP/1.0 404 Not Found' );
include( Config::$templates.'404.tpl.php' );
$cache->disable();
}
$cache->write();
?>

189
picturelicious/json.php Normal file
View File

@ -0,0 +1,189 @@
<?php
require_once( 'lib/config.php' );
require_once( 'lib/users.php' );
require_once( 'lib/db.php' );
$user = new User();
$user->login();
require_once( 'lib/cache.php' );
$cache = new Cache( Config::$cache['path'], '' );
if( isset($_GET['addTags']) && $user->id && strlen(trim($_POST['tags'])) >= 3 ) {
$i = DB::getRow( 'SELECT id, tags, keyword FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
if( !empty( $i ) ) {
if($user->admin) {
$tags = trim($_POST['tags']);
} else {
$tags = trim(trim($i['tags'])." ".trim($_POST['tags']));
}
DB::updateRow( TABLE_IMAGES,
array('id' => $i['id']),
array( 'tags' => $tags )
);
$score = strlen(trim($_POST['tags'])) * Config::$tagScorePerChar;
$user->increaseScore( min($score, Config::$tagScoreMax) );
$cache->clear( $i['keyword'] );
echo '{"id":"'.$i['id'].'","tags":"'.addslashes(htmlspecialchars($tags)).'"}';
exit(0);
}
}
if( isset($_GET['quickTag']) && $user->id ) {
if( !empty($_POST['id']) ) {
// remove lock
DB::updateRow( TABLE_TAGLOG,
array( 'id' => $_POST['logId'], 'userId' => $user->id ),
array( 'locked' => 0 )
);
if( strlen(trim($_POST['tags'])) >= 3 ) {
$i = DB::getRow( 'SELECT id, tags, keyword FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
if( !empty( $i ) ) {
$tags = trim(trim($i['tags'])." ".trim($_POST['tags']));
DB::updateRow( TABLE_IMAGES,
array('id' => $i['id']),
array( 'tags' => $tags )
);
}
$score = strlen(trim($_POST['tags'])) * Config::$tagScorePerChar;
$user->increaseScore( min($score, Config::$tagScoreMax) );
$cache->clear( $i['keyword'] );
}
}
$i = DB::getRow(
'SELECT i.id, i.keyword, i.tags, i.image, UNIX_TIMESTAMP(i.logged) AS loggedTS
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_TAGLOG.' t
ON t.imageId = i.id AND (
(
t.userId = :1 AND
t.tagged > NOW() - INTERVAL 24 HOUR
) OR (
t.locked = 1 AND
t.tagged > NOW() - INTERVAL 5 MINUTE
)
)
WHERE t.id IS NULL
ORDER BY LENGTH(i.tags), i.logged DESC
LIMIT 1',
$user->id
);
if( !empty( $i ) ) {
DB::insertRow( TABLE_TAGLOG,
array(
'tagged' => date( 'Y.m.d H:i:s' ),
'userId' => $user->id,
'imageId' => $i['id'],
'locked' => 1
)
);
$logId = DB::insertId();
$link = Config::$absolutePath.'all/view/'.$i['keyword'];
$image =
Config::$absolutePath
.Config::$images['imagePath']
.date('Y/m/', $i['loggedTS'])
.$i['image'];
echo '{"id":"'.$i['id'].'","tags":"'.addslashes(htmlspecialchars($i['tags'])).'"'
.',"link":"'.$link.'","image":"'.$image.'","logId":"'.$logId.'"}';
exit(0);
}
}
else if( isset($_GET['delete']) && $user->id && $user->admin ) {
$i = DB::getRow( 'SELECT id, logged, image, thumb, user FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
if( !empty($i) ) {
DB::query( 'DELETE FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
DB::query( 'DELETE FROM '.TABLE_IMAGECOLORS.' WHERE imageId = :1', $_POST['id'] );
DB::query( 'DELETE FROM '.TABLE_COMMENTS.' WHERE imageId = :1', $_POST['id'] );
foreach( Config::$gridView['classes'] as $c ) {
unlink(
Config::$images['thumbPath'] .
str_replace( '-', '/', substr( $i['logged'], 0, 7 ) ).'/'.
$c['dir'].'/'.
$i['thumb']
);
}
unlink(
Config::$images['imagePath'] .
str_replace( '-', '/', substr( $i['logged'], 0, 7 ) ).'/'.
$i['image']
);
DB::query(
'UPDATE '.TABLE_USERS.' SET images = images -1, score = score - :2
WHERE id = :1',
$i['user'], Config::$postScore
);
$cache->clear();
}
echo "{}";
}
else if( isset($_GET['deleteComment']) && $user->id && $user->admin ) {
DB::query( 'DELETE FROM '.TABLE_COMMENTS.' WHERE id = :1', $_POST['id'] );
$cache->clear();
echo "{}";
}
else if( isset($_GET['rate']) ) {
// score is in valid range / not float?
if( in_array( $_POST['score'], array(1,2,3,4,5) ) ) {
// check if this ip has allready rated this quote
list(, $ip) = unpack('l',pack('l',ip2long($_SERVER['REMOTE_ADDR'])));
$r = DB::getRow( 'SELECT ip FROM '.TABLE_IPLOCK.'
WHERE ip = :1 AND imageId = :2',
$ip, $_POST['id']
);
// not rated?
if( empty( $r ) ) {
// insert ip
DB::insertRow( TABLE_IPLOCK,
array(
'ip' => $ip,
'imageId' => $_POST['id'],
'ts' => time()
)
);
// update score
DB::query( 'UPDATE '.TABLE_IMAGES.' SET
score = ( score * votes + :1 ) / ( votes + 1 ),
votes = votes + 1
WHERE id = :2',
$_POST['score'], $_POST['id']
);
$user->increaseScore( Config::$votingScore );
if( rand(1, Config::$cache['clearEvery']) == 1 ) {
$cache->clear();
}
else {
$i = DB::getRow( 'SELECT keyword FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
$cache->clear( $i['keyword'] );
}
}
}
// delete all ips older than IP_LOCK_TIME
DB::query( 'DELETE FROM '.TABLE_IPLOCK.' WHERE ts < :1', time() - Config::$ipLockTime );
// return JSON Data
header( 'Content-Type', 'text/plain' );
$r = DB::getRow( 'SELECT id, score, votes FROM '.TABLE_IMAGES.' WHERE id = :1', $_POST['id'] );
echo '{"id":"'.$r['id'].'","score":"'.number_format($r['score'],1).'","votes":"'.($r['votes']).'"}';
exit(0);
}
echo "{}";
?>

View File

@ -0,0 +1,72 @@
<?php
/*
The Cache class reads and writes complete pages from the cache.
The name of a cache file is based on its URL
*/
class Cache {
private $fileName = '';
private $path = '';
private $enabled = true;
private $captured = false;
public function __construct( $path, $pageName ) {
$this->path = $path;
$this->fileName = $this->path . strtr( $pageName, '?&', '--' ) . '.html';
if( $_SERVER['REQUEST_METHOD'] != 'GET' ) {
$this->enabled = false;
}
}
public function disable() {
$this->enabled = false;
}
public function forceEnable() {
$this->enabled = true;
}
public function lookup() {
if( $this->enabled && file_exists($this->fileName) ) {
$fp = fopen($this->fileName, 'rb');
fpassthru($fp);
fclose($fp);
exit();
}
}
public function capture() {
if( $this->enabled ) {
ob_start();
$this->captured = true;
}
}
public function clear( $pattern = '' ) {
require_once( 'lib/filesystem.php' );
if( empty($pattern) && !empty($this->path) ) {
Filesystem::rmdirr( $this->path, true );
} else {
$files = glob( $this->path . 'all/view/' . strtr( $pattern, '?&', '--' ) . '.html' );
foreach( $files as $f ) {
unlink( $f );
}
$files = glob( $this->path . 'user/*/view/' . strtr( $pattern, '?&', '--' ) . '.html' );
foreach( $files as $f ) {
unlink( $f );
}
}
}
public function write() {
if( $this->captured ) {
require_once( 'lib/filesystem.php' );
Filesystem::mkdirr( dirname($this->fileName) );
file_put_contents( $this->fileName, ob_get_contents() );
}
}
}
?>

View File

@ -0,0 +1,323 @@
<?php
define('FORUMPATH', realpath(dirname(__FILE__)).Config::$vbbIntegration['path']);
function userdata_convert(&$userdata) {
$vbuser = array( 'username' => $userdata['name'] );
if (isset($userdata['email']))
$vbuser['email'] = $userdata['email'];
if (isset($userdata['pass']))
$vbuser['password'] = $userdata['pass'];
return $vbuser;
}
define('REGISTERED_USERGROUP', 2); // typical default for registered users
define('PERMANENT_COOKIE', false); // false=session cookies (recommended)
define('THIS_SCRIPT', __FILE__);
$cwd = getcwd();
chdir(FORUMPATH);
require_once('./includes/init.php'); // includes class_core.php
require_once('./includes/class_dm.php'); // for class_dm_user.php
require_once('./includes/class_dm_user.php'); // for user functions
require_once('./includes/functions.php'); // vbsetcookie etc.
require_once('./includes/functions_login.php'); // process login/logout
//---------------------------------------------------------------------
// This function duplicates the functionality of fetch_userinfo(),
// using the user name instead of numeric ID as the argument.
// See comments in includes/functions.php for documentation.
//---------------------------------------------------------------------
function fetch_userinfo_from_username(&$username, $option=0, $languageid=0)
{
global $vbulletin;
$useridq = $vbulletin->db->query_first_slave("SELECT userid FROM "
. TABLE_PREFIX . "user WHERE username='{$username}'");
if (!$useridq) return $useridq;
$userid = $useridq['userid'];
return fetch_userinfo($userid, $option, $languageid);
}
//---------------------------------------------------------------------
// CLASS ForumOps
//---------------------------------------------------------------------
class ForumOps extends vB_DataManager_User {
var $userdm;
// *********************************************************************************************************
function __construct( &$vbulletin ) // constructor
{
$this->vbulletin =& $vbulletin;
$this->userdm =& datamanager_init('user', $vbulletin, ERRTYPE_ARRAY);
}
function ForumOps() // constructor
{
global $vbulletin;
$this->userdm =& datamanager_init('User', $vbulletin, ERRTYPE_ARRAY);
}
// *********************************************************************************************************
//======== USER REGISTRATION / UPDATE / DELETE ========
function register_newuser(&$userdata, $login = true)
{
global $vbulletin;
$vbuser = userdata_convert($userdata);
foreach($vbuser as $key => $value)
$this->userdm->set($key, $value);
$this->userdm->set('usergroupid', REGISTERED_USERGROUP);
$this->userdm->set('timezoneoffset', 1);
// Bitfields; set to desired defaults.
// Comment out those you have set as defaults
// in the vBuleltin admin control panel
$this->userdm->set_bitfield('options', 'adminemail', 1);
$this->userdm->set_bitfield('options', 'showsignatures', 1);
$this->userdm->set_bitfield('options', 'showavatars', 0);
$this->userdm->set_bitfield('options', 'showimages', 1);
$this->userdm->set_bitfield('options', 'showemail', 0);
if ($login) $this->login($vbuser);
//$this->userdm->errors contains error messages
if (empty($this->userdm->errors))
$vbulletin->userinfo['userid'] = $this->userdm->save();
else
return implode('<br>', $this->userdm->errors);
return NULL;
}
// *********************************************************************************************************
function update_user(&$userdata)
{
global $vbulletin;
$vbuser = userdata_convert($userdata);
if (!($existing_user = fetch_userinfo_from_username($vbuser['username'])))
return 'fetch_userinfo_from_username() failed.';
$this->userdm->set_existing($existing_user);
foreach($vbuser as $key => $value)
$this->userdm->set($key, $value);
// reset password cookie in case password changed
if (isset($vbuser['password']))
vbsetcookie('password',
md5($vbulletin->userinfo['password'].COOKIE_SALT),
PERMANENT_COOKIE, true, true);
if (count($this->userdm->errors))
return implode('<br>', $this->userdm->errors);
$vbulletin->userinfo['userid'] = $this->userdm->save();
return NULL;
}
// *********************************************************************************************************
function update_avatar(&$userdata) {
global $vbulletin;
$vbuser = userdata_convert($userdata);
if (!($existing_user = fetch_userinfo_from_username($vbuser['username'])))
return 'fetch_userinfo_from_username() failed.';
$this->userdm->set_existing($existing_user);
// update avatar in case it should be
if (!empty($vbuser['avatarurl'])) {
//~ echo"<pre>";
//~ print_r ($existing_user);
//~ echo "</pre>";
// begin custom avatar code
require_once(DIR . '/includes/class_upload.php');
require_once(DIR . '/includes/class_image.php');
$upload = new vB_Upload_Userpic($vbulletin);
$upload->data =& datamanager_init('Userpic_Avatar', $vbulletin, ERRTYPE_STANDARD, 'userpic');
$upload->image =& vB_Image::fetch_library($vbulletin);
$upload->userinfo =& $existing_user;
cache_permissions($existing_user, false);
$upload->maxwidth = $vbulletin->userinfo['permissions']['avatarmaxwidth'];
$upload->maxheight = $vbulletin->userinfo['permissions']['avatarmaxheight'];
if (!$upload->process_upload($vbuser['avatarurl'])) {
echo $upload->fetch_error();
}
}
else { // no avatar used!
$userpic =& datamanager_init('Userpic_Avatar', $vbulletin, ERRTYPE_CP, 'userpic');
$userpic->condition = "userid = " . $existing_user['userid'];
$userpic->delete();
}
$this->userdm->set_existing($vbulletin->userinfo);
($hook = vBulletinHook::fetch_hook('profile_updateavatar_complete')) ? eval($hook) : false;
return NULL;
}
// *********************************************************************************************************
function delete_user(&$username)
{
// The vBulletin documentation suggests using userdm->delete()
// to delete a user, but upon examining the code, this doesn't
// delete everything associated with the user. The following
// is adapted from admincp/user.php instead.
// NOTE: THIS MAY REQUIRE MAINTENANCE WITH NEW VBULLETIN UPDATES.
global $vbulletin;
$db = &$vbulletin->db;
$userdata = $db->query_first_slave("SELECT userid FROM "
. TABLE_PREFIX . "user WHERE username='{$username}'");
$userid = $userdata['userid'];
if ($userid) {
// from admincp/user.php 'do prune users (step 1)'
// delete subscribed forums
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "subscribeforum WHERE userid={$userid}");
// delete subscribed threads
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "subscribethread WHERE userid={$userid}");
// delete events
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "event WHERE userid={$userid}");
// delete event reminders
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "subscribeevent WHERE userid={$userid}");
// delete custom avatars
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "customavatar WHERE userid={$userid}");
$customavatars = $db->query_read("SELECT userid, avatarrevision FROM "
. TABLE_PREFIX . "user WHERE userid={$userid}");
while ($customavatar = $db->fetch_array($customavatars)) {
@unlink($vbulletin->options['avatarpath'] . "/avatar{$customavatar['userid']}_{$customavatar['avatarrevision']}.gif");
}
// delete custom profile pics
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "customprofilepic WHERE userid={$userid}");
$customprofilepics = $db->query_read(
"SELECT userid, profilepicrevision FROM "
. TABLE_PREFIX . "user WHERE userid={$userid}");
while ($customprofilepic = $db->fetch_array($customprofilepics)) {
@unlink($vbulletin->options['profilepicpath'] . "/profilepic$customprofilepic[userid]_$customprofilepic[profilepicrevision].gif");
}
// delete user forum access
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "access WHERE userid={$userid}");
// delete moderator
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "moderator WHERE userid={$userid}");
// delete private messages
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "pm WHERE userid={$userid}");
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "pmreceipt WHERE userid={$userid}");
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "session WHERE userid={$userid}");
// delete user group join requests
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "usergrouprequest WHERE userid={$userid}");
// delete bans
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "userban WHERE userid={$userid}");
// delete user notes
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "usernote WHERE userid={$userid}");
// from admincp/users.php 'do prune users (step 2)'
// update deleted user's posts with userid=0
$db->query_write("UPDATE " . TABLE_PREFIX
. "thread SET postuserid = 0, postusername = '"
. $db->escape_string($username)
. "' WHERE postuserid = $userid");
$db->query_write("UPDATE " . TABLE_PREFIX
. "post SET userid = 0, username = '"
. $db->escape_string($username)
. "' WHERE userid = $userid");
// finally, delete the user
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "usertextfield WHERE userid={$userid}");
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "userfield WHERE userid={$userid}");
$db->query_write("DELETE FROM " . TABLE_PREFIX
. "user WHERE userid={$userid}");
}
/*
the following is suggested in the documentation but doesn't work:
$existing_user = fetch_userinfo_from_username($username);
$this->userdm->set_existing($existing_user);
return $this->userdm->delete();
*/
}
function set_email( $username, $email ) {
global $vbulletin;
$db = &$vbulletin->db;
$db->query_write("UPDATE " . TABLE_PREFIX . "user SET email = '"
.mysql_real_escape_string($email)."' WHERE username = '"
.mysql_real_escape_string($username)."'"
);
}
function set_pass( $username, $pass ) {
global $vbulletin;
$db = &$vbulletin->db;
$pass = md5($pass);
$salt = $this->fetch_user_salt();
$db->query_write("UPDATE " . TABLE_PREFIX . "user SET password = '"
.mysql_real_escape_string(md5($pass.$salt))."',
salt = '".mysql_real_escape_string($salt)."' WHERE username = '"
.mysql_real_escape_string($username)."'"
);
}
function fetch_user_salt($length = SALT_LENGTH) {
$salt = '';
for ($i = 0; $i < $length; $i++)
{
$salt .= chr(rand(33, 126));
}
return $salt;
}
// ======== USER LOGIN / LOGOUT ========
function login($vbuser)
{
global $vbulletin;
$vbulletin->userinfo = fetch_userinfo_from_username($vbuser['username']);
// set cookies
vbsetcookie('userid', $vbulletin->userinfo['userid'],
PERMANENT_COOKIE, true, true);
vbsetcookie('password',
md5($vbulletin->userinfo['password'].COOKIE_SALT),
PERMANENT_COOKIE, true, true);
// create session stuff
process_new_login('', 1, '');
}
function logout()
{
process_logout(); // unsets all cookies and session data
}
} // end class ForumOps
chdir($cwd);
?>

View File

@ -0,0 +1,112 @@
<?php
/*
All config settings are defined in this file. Please refer to your readme
for an in depth explanation of each value.
*/
class Config {
// Names and URLs for your installation
public static $absolutePath = '/';
public static $frontendPath = 'http://picturelicious.net/';
public static $siteName = 'Picturelicious';
public static $siteTitle = 'Picturelicious - Social Imaging';
public static $sessionCookie = 'sid';
public static $rememberCookie = 'remember';
// Spam protection
public static $ipLockTime = 3600;
public static $uploadLockTime = 7200;
public static $maxNumUploads = 10;
// User score
public static $votingScore = 5;
public static $postScore = 10;
public static $tagScorePerChar = 0.5;
public static $tagScoreMax = 20;
// Misc settings
public static $usersPerPage = 50;
public static $defaultChmod = 0777;
public static $templates = 'templates/';
public static $keywordWordSeperator = '-';
public static $colorSearchDev = 50;
public static $maxRandomThumbs = 10;
public static $minRandomScore = 4.0;
// vbb Forum integration
public static $vbbIntegration = array(
'enabled' => false,
'path' => '/../forum'
);
// Cache settings
public static $cache = array(
'enabled' => true,
'path' => 'cache/',
'clearEvery' => 10
);
// Database settings
public static $db = array(
'host' => 'localhost',
'database' => 'picturelicious',
'user' => 'root',
'password' => '',
'prefix' => 'pl_'
);
// Image processing and thumbnail creation
public static $images = array(
'thumbsPerPage' => 90,
'imagePath' => 'data/images/',
'thumbPath' => 'data/thumbs/',
'avatarsPath' => 'data/avatars/',
'maxDownload' => 2097152,
'jpegQuality' => 80,
'sharpen' => true
);
// Grid Solver settings
public static $gridView = array(
'gridSize' => 64,
'gridWidth' => 12,
'borderWidth' => 2,
// Definition of all Thumbnail classes ---------------------------
// KEY: CSS-className
// width/ height: Size of the thumb in grid units
// percentage: Percentage of thumbnails in this size
// dir: Name of the subdir with thumbs in this size
'classes' => array(
'b2' => array( 'width'=>1, 'height'=>1, 'percentage'=>0.6, 'dir'=>'64x64' ),
'b1' => array( 'width'=>2, 'height'=>2, 'percentage'=>0.35, 'dir'=>'128x128' ),
'b0' => array( 'width'=>3, 'height'=>3, 'percentage'=>0.05, 'dir'=>'192x192' )
),
);
}
// Edit below this line only if you know what you're doing!
// -----------------------------------------------------------------------
// MySQL Table names
define( 'TABLE_IMAGES', Config::$db['prefix'].'images' );
define( 'TABLE_IMAGECOLORS',Config::$db['prefix'].'imagecolors' );
define( 'TABLE_USERS', Config::$db['prefix'].'users' );
define( 'TABLE_IPLOCK', Config::$db['prefix'].'iplock' );
define( 'TABLE_UPLOADLOCK', Config::$db['prefix'].'uploadlock' );
define( 'TABLE_TAGLOG', Config::$db['prefix'].'taglog' );
define( 'TABLE_COMMENTS', Config::$db['prefix'].'comments' );
// MagicQuotes undo
if( function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ) {
$_GET = array_map( 'stripslashes', $_GET );
$_POST = array_map( 'stripslashes', $_POST );
}
?>

130
picturelicious/lib/db.php Normal file
View File

@ -0,0 +1,130 @@
<?php
/*
This class handles all database IO. To prevent SQL-Injections, all variables
that are passed to the database must be specified as additional parameters to
your query. e.g.
$res = DB::query( 'SELECT * FROM images WHERE user = :1 AND tags LIKE :2', 'testuser', 'funny' );
query() and getRow() return a 2-dimensional array instead of a result resource.
*/
require_once( 'lib/config.php' );
class DB {
private static $link = null;
private static $result;
public static $sql;
public static $numQueries = 0;
private static function connect() {
self::$link = @mysql_connect( Config::$db['host'], Config::$db['user'], Config::$db['password'] )
or die( "Couldn't establish link to database-server: ".Config::$db['host'] );
mysql_select_db( Config::$db['database'] )
or die( "Couldn't select Database: ".Config::$db['database'] );
mysql_query( 'SET NAMES utf8', self::$link );
}
public static function foundRows() {
$r = self::query( 'SELECT FOUND_ROWS() AS foundRows' );
return $r[0]['foundRows'];
}
public static function numRows() {
return mysql_num_rows( self::$result );
}
public static function affectedRows() {
return mysql_affected_rows( self::$link );
}
public static function insertId() {
return mysql_insert_id( self::$link );
}
public static function query( $q, $params = array() ) {
if( self::$link === null ) {
self::connect();
}
if( !is_array( $params ) ) {
$params = array_slice( func_get_args(), 1 );
}
if( !empty( $params ) ) {
$q = preg_replace('/:(\d+)/e', 'self::quote($params[$1 - 1])', $q );
}
self::$numQueries++;
self::$sql = $q;
self::$result = mysql_query( $q, self::$link );
echo self::getError();
if( !self::$result ) {
return false;
}
else if( !is_resource( self::$result ) ) {
return true;
}
$rset = array();
while ( $row = mysql_fetch_assoc( self::$result ) ) {
$rset[] = $row;
}
return $rset;
}
public static function getRow( $q, $params = array() ) {
if( !is_array( $params ) ) {
$params = array_slice( func_get_args(), 1 );
}
$r = self::query( $q, $params );
return array_shift( $r );
}
public static function updateRow( $table, $idFields, $updateFields ) {
$updateString = implode( ',', self::quoteArray( $updateFields, true ) );
$idString = implode( ' AND ', self::quoteArray( $idFields, true ) );
return self::query( "UPDATE $table SET $updateString WHERE $idString" );
}
public static function insertRow( $table, $insertFields ) {
$insertString = implode( ',', self::quoteArray( $insertFields, true ) );
return self::query( "INSERT INTO $table SET $insertString" );
}
public static function getError() {
if( $e = mysql_error( self::$link ) ) {
return "MySQL reports: '$e' on query\n".self::$sql;
}
return false;
}
public static function quote( $s ) {
if( self::$link === null ) {
self::connect();
}
if( !isset($s) || $s === false ) {
return 0;
}
else if( $s === true ) {
return 1;
}
else if( is_numeric( $s ) ) {
return $s;
}
else {
return "'".mysql_real_escape_string( $s )."'";
}
}
public static function quoteArray( &$fields, $useKeys = false ) {
$r = array();
foreach( $fields as $key => &$value ) {
$r[] = ( $useKeys ? "`$key`=":'' ) . self::quote( $value );
}
return $r;
}
}
?>

View File

@ -0,0 +1,90 @@
<?php
/*
Various functions regarding file handling
*/
require_once( 'lib/config.php' );
class Filesystem {
public static function rmdirr( $dir, $clearOnly = false ) {
$dh = opendir( $dir );
while ( $file = readdir( $dh ) ) {
if( $file != '.' && $file != '..' ) {
$fullpath = $dir.'/'.$file;
if( !is_dir( $fullpath ) ) {
@unlink( $fullpath );
}
else {
self::rmdirr( $fullpath );
}
}
}
closedir( $dh );
if( !$clearOnly && @rmdir( $dir ) ) {
return true;
}
else {
return false;
}
}
public static function mkdirr( $pathname ) {
// Check if directory already exists
if( empty($pathname) || is_dir($pathname) ) {
return true;
}
if ( is_file($pathname) ) {
return false;
}
// Crawl up the directory tree
$nextPathname = substr( $pathname, 0, strrpos( $pathname, '/' ) );
if( self::mkdirr( $nextPathname ) ) {
if( !file_exists( $pathname ) ) {
$oldUmask = umask(0);
$success = @mkdir( $pathname, Config::$defaultChmod );
umask( $oldUmask );
return $success;
}
}
return false;
}
public static function download( $url, $target, $maxSize = 2097152, $referer = false ) {
$contents = '';
$bytesRead = 0;
if( $referer ) {
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Referer: $referer\r\n"
)
);
$context = stream_context_create($opts);
$fp = fopen( $url, 'r', false, $context );
} else {
$fp = @fopen( $url, 'r' );
}
if( !$fp ) {
return false;
}
while ( !feof( $fp ) ) {
$chunk = fread( $fp, 8192 );
$bytesRead += strlen( $chunk );
if( $bytesRead > $maxSize) {
return false;
}
$contents .= $chunk;
}
fclose( $fp );
file_put_contents( $target, $contents );
return true;
}
}
?>

View File

@ -0,0 +1,172 @@
<?php
/*
This class takes an array of images and sorts them into a grid view.
This is the equivalent of the javascript gridSolve function in picturelicious.js
with the difference that it runs server side of course.
*/
require_once( 'lib/config.php' );
class GridView {
public $height = 0;
protected $grid = array();
protected $gridWidth = 20;
public function __construct( $gridWidth = 20 ) {
$this->gridWidth = $gridWidth;
$this->grid = array_fill( 0, $this->gridWidth, 0 );
}
// solve expects an array with thumbnails with the keys name and score
public function solve( &$thumbs ) {
if( !is_array( $thumbs ) ) {
return false;
}
// Order thumbs by importance (score), but leave the keys as they are
uasort( $thumbs, array( $this, 'compareScore' ) );
// How many thumbs get which CSS-Class? The first n thumbnails
// get the biggest box etc.
$total = count( $thumbs );
$classCounts = array();
$currentCount = 0;
foreach( Config::$gridView['classes'] as $className => $gc ) {
$currentCount += $gc['percentage'] * $total;
$classCounts[$className] = ceil( $currentCount );
}
// Assign a CSS-Class to each thumb
$currentMax = -1;
$currentClass = '';
$j = 0;
foreach( array_keys( $thumbs ) as $i ) {
if( $j >= $currentMax ) {
list( $currentClass, $currentMax ) = each( $classCounts );
}
$j++;
$thumbs[$i]['class'] = $currentClass;
$thumbs[$i]['thumb'] = Config::$absolutePath . Config::$images['thumbPath'] .
str_replace( '-', '/', substr( $thumbs[$i]['logged'], 0, 7 ) )
.'/'. Config::$gridView['classes'][$currentClass]['dir']
.'/'. $thumbs[$i]['thumb'];
}
// Sort the thumbs back in the order we got them
ksort( $thumbs );
// Now that every thumb has a CSS-Class, we can sort them into our grid
for( $i = 0; $i < $total; $i++ ) {
list( $x, $y ) = $this->insert(
Config::$gridView['classes'][$thumbs[$i]['class']]['width'],
Config::$gridView['classes'][$thumbs[$i]['class']]['height']
);
$thumbs[$i]['left'] = $x * Config::$gridView['gridSize'];
$thumbs[$i]['top'] = $y * Config::$gridView['gridSize'];
}
// Calculate the final grid height
for( $i = 0; $i < $this->gridWidth; $i++ ) {
if( $this->grid[$i] > $this->height ) {
$this->height = $this->grid[$i];
}
}
return true;
}
// Callback for uasort()
protected function compareScore( $a, $b ) {
return $a['score'] > $b['score'] ?
1 :
( $a['score'] == $b['score'] && $a['votes'] > $b['votes'] ?
1 :
-1
);
}
protected function insert( $boxWidth, $boxHeight ) {
// Height of the grid
$maxHeight = 0;
// Height of the grid at the last position
$currentHeight = $this->grid[0];
// Find free spots within the grid and collect them in an arry
// A spot is a area in the grid with equal height
$spotWidth = 0; // Width of the spot in grid units
$spotLeft = 0; // Position in the grid (relative to left border)
$freeSpots = array();
for( $i = 0; $i < $this->gridWidth; $i++ ) {
// Height is the same as at the last position?
// -> increase the size of this spot
if( $currentHeight == $this->grid[$i] ) {
$spotWidth++;
}
// The height is different from the last position, and our current spot
// is wider than 0
if( ( $currentHeight != $this->grid[$i] || $i+1 == $this->gridWidth) && $spotWidth > 0 ) {
$freeSpots[] = array( 'width' =>$spotWidth, 'left' => $spotLeft, 'height' => $currentHeight );
$spotWidth = 1;
$spotLeft = $i;
// Make sure we don't miss the last one
if( $currentHeight != $this->grid[$i] && $i+1 == $this->gridWidth ) {
$freeSpots[] = array( 'width' =>$spotWidth, 'left' => $spotLeft, 'height' => $this->grid[$i] );
}
}
$currentHeight = $this->grid[$i];
$maxHeight = max( $maxHeight, $this->grid[$i] );
}
// Loop through all found spots and rate them, based on their size and height
// This way the smallest possible spot in the lowest possible height is filled
$targetHeight = 0;
$targetLeft = 0;
// Default spot (left border) if we don't find a better one
for( $i = 0; $i < $boxWidth; $i++ ) {
if( $this->grid[$i] > $targetHeight ) {
$targetHeight = $this->grid[$i];
}
}
$bestScore = -1;
foreach( array_keys( $freeSpots ) as $i ) {
// Difference of the height of this spot to the total height of the grid
$heightScore = ( $maxHeight - $freeSpots[$i]['height'] );
// Relation of the required and the available space
$widthScore = $boxWidth / $freeSpots[$i]['width'];
// The score for this spot is calculated by these both criteria
$score = $heightScore * $heightScore + $widthScore * 2;
// Is the score for this spot higher than for the last one we found?
if( $freeSpots[$i]['width'] >= $boxWidth && $score > $bestScore ) {
$targetHeight = $freeSpots[$i]['height'];
$targetLeft = $freeSpots[$i]['left'];
$bestScore = $score;
}
}
$newHeight = $targetHeight + $boxHeight;
// Adjust grid height
for( $j = 0; $j < $boxWidth; $j++ ) {
$this->grid[$targetLeft + $j] = $newHeight;
}
return array( $targetLeft, $targetHeight );
}
}
?>

View File

@ -0,0 +1,145 @@
<?php
/*
ImageBrowser loads a set of images specified by a search term, user and page.
*/
require_once( 'lib/imagecatalog.php' );
class ImageBrowser extends ImageCatalog {
protected $page = 0;
protected $thumbsPerPage = 0;
public $thumbs = array();
public $pages = array();
public function __construct( $thumbsPerPage = 20 ) {
$this->thumbsPerPage = abs(intval($thumbsPerPage));
}
public function setPage( $page ) {
$page = intval($page);
$this->page = $page > 0 ? $page - 1 : 0;
}
public function load() {
if( !empty( $this->searchColor ) ) { // ----------------------------------- color search
$this->thumbs = DB::query(
'SELECT SQL_CALC_FOUND_ROWS
i.logged, UNIX_TIMESTAMP(i.logged) AS loggedTS,
i.keyword, i.thumb, i.score, i.votes,
u.name AS userName,
MIN( ABS(ic.r - :3) + ABS(ic.g - :4) + ABS(ic.b - :5) ) AS deviation
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_USERS.' u
ON u.id = i.user
LEFT JOIN '.TABLE_IMAGECOLORS.' ic
ON ic.imageId = i.id
WHERE
ic.r BETWEEN :3 - :6 AND :3 + :6
AND
ic.g BETWEEN :4 - :6 AND :4 + :6
AND
ic.b BETWEEN :5 - :6 AND :5 + :6
GROUP BY i.id
ORDER BY deviation, i.id DESC
LIMIT :1, :2',
$this->page * $this->thumbsPerPage,
$this->thumbsPerPage,
$this->searchColor['r'],
$this->searchColor['g'],
$this->searchColor['b'],
Config::$colorSearchDev
);
}
else if( $this->searchTerm ) { // ------------------------ fulltext search
$ftq = preg_replace( '/\s+/',' +', $this->searchTerm );
$this->thumbs = DB::query(
'SELECT SQL_CALC_FOUND_ROWS
i.logged, UNIX_TIMESTAMP(i.logged) AS loggedTS,
i.keyword, i.thumb, i.score, i.votes,
u.name AS userName
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_USERS.' u
ON u.id = i.user
WHERE
i.image LIKE :3
OR MATCH( i.tags ) AGAINST ( :4 IN BOOLEAN MODE )
ORDER BY i.id DESC
LIMIT :1, :2',
$this->page * $this->thumbsPerPage,
$this->thumbsPerPage,
'%'.$this->searchTerm.'%',
$ftq
);
}
else { // -------------------------------------------------------- user/all
$conditions = '';
if( !empty($this->user) ) {
$conditions .= ' AND i.user = :3';
}
$this->thumbs = DB::query(
'SELECT SQL_CALC_FOUND_ROWS
i.logged, UNIX_TIMESTAMP(i.logged) AS loggedTS,
i.keyword, i.thumb, i.score, i.votes,
u.name AS userName
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_USERS.' u
ON u.id = i.user
WHERE 1 '.$conditions.'
ORDER BY i.id DESC
LIMIT :1, :2',
$this->page * $this->thumbsPerPage,
$this->thumbsPerPage,
$this->user['id']
);
}
$this->totalResults = DB::foundRows();
// compute previoues, current and next page
if( $this->totalResults > 0 ) {
$this->pages['current'] = $this->page+1;
$this->pages['total'] = ceil($this->totalResults / $this->thumbsPerPage);
if( $this->page > 0 ) {
$this->pages['prev'] = $this->page;
}
if( $this->totalResults > $this->thumbsPerPage * $this->page + $this->thumbsPerPage ) {
$this->pages['next'] = $this->page + 2;
}
}
}
public function loadRandom( $minScore, $thumbSize ) {
$this->thumbs = DB::query(
'SELECT SQL_CALC_FOUND_ROWS
i.logged, UNIX_TIMESTAMP(i.logged) AS loggedTS,
i.keyword, i.thumb, i.score, i.votes,
u.name AS userName
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_USERS.' u
ON u.id = i.user
WHERE i.score >= :2
ORDER BY RAND()
LIMIT :1',
$this->thumbsPerPage,
$minScore
);
foreach( array_keys( $this->thumbs ) as $i ) {
$this->thumbs[$i]['thumb'] = Config::$images['thumbPath'] .
str_replace( '-', '/', substr( $this->thumbs[$i]['logged'], 0, 7 ) )
.'/'. $thumbSize
.'/'. $this->thumbs[$i]['thumb'];
}
}
}
?>

View File

@ -0,0 +1,61 @@
<?php
/*
ImageCatalog is the abstract base class for ImageBrowser and ImageViewer. It provides
the basic functionality to help build queries to get the images out of the database.
*/
require_once( 'lib/config.php' );
require_once( 'lib/db.php' );
class ImageCatalog {
public $user = array();
public $searchTerm = '';
public $searchColor = array();
public $totalResults = 0;
public $basePath = 'all/';
public function setUser( $name ) {
$this->user = DB::getRow(
'SELECT id, name, score, images, avatar, website
FROM '.TABLE_USERS.'
WHERE
valid = 1 AND
name = :1',
$name
);
if( !empty($this->user) ) {
$this->basePath = 'user/'.$this->user['name'].'/';
}
}
public function setSearch( $term ) {
$this->basePath = 'search/'.htmlspecialchars($term).'/';
if( preg_match( '/^\s*0x([0-9a-f]{6})\s*$/i', $term, $m ) ) {
$c = str_split( $m[1], 2 );
$this->searchColor = array(
'r' => hexdec($c[0]),
'g' => hexdec($c[1]),
'b' => hexdec($c[2]),
);
}
else if( !empty($term) ) {
$this->searchTerm = $term;
$ftq = preg_replace( '/\s+/',' +', $this->searchTerm );
$this->seachCondition .= " AND (
i.image LIKE ".DB::quote('%'.$this->searchTerm.'%')."
OR MATCH( i.tags ) AGAINST ( ".DB::quote($ftq)." IN BOOLEAN MODE )
)";
}
}
public function load() {
}
}
?>

View File

@ -0,0 +1,98 @@
<?php
/*
Various functions regarding thumbnail creation and color extraction
*/
require_once( 'lib/config.php' );
class Image {
public static function createThumb( $imgPath, $thumbPath, $thumbWidth, $thumbHeight ) {
list( $srcWidth, $srcHeight, $type ) = getimagesize( $imgPath );
$srcX = 0;
$srcY = 0;
if(
$srcWidth < 1 || $srcWidth > 4096
|| $srcHeight < 1 || $srcHeight > 4096
) {
return false;
}
if( $type == IMAGETYPE_JPEG ) {
$imgcreate = 'ImageCreateFromJPEG';
} else if( $type == IMAGETYPE_GIF ) {
$imgcreate = 'ImageCreateFromGIF';
} else if( $type == IMAGETYPE_PNG ) {
$imgcreate = 'ImageCreateFromPNG';
} else {
return false;
}
$thumbDirName = dirname( $thumbPath );
if( ( $srcWidth/$srcHeight ) > ( $thumbWidth/$thumbHeight ) ) {
$zoom = ($srcWidth/$srcHeight) / ($thumbWidth/$thumbHeight);
$srcX = ($srcWidth - $srcWidth / $zoom) / 2;
$srcWidth = $srcWidth / $zoom;
}
else {
$zoom = ($thumbWidth/$thumbHeight) / ($srcWidth/$srcHeight);
$srcY = ($srcHeight - $srcHeight / $zoom) / 2;
$srcHeight = $srcHeight / $zoom;
}
$thumb = Imagecreatetruecolor( $thumbWidth, $thumbHeight );
$orig = $imgcreate( $imgPath );
Imagecopyresampled($thumb, $orig, 0, 0, $srcX, $srcY, $thumbWidth, $thumbHeight, $srcWidth, $srcHeight);
if( Config::$images['sharpen'] && function_exists('imageconvolution') ) {
$sharpenMatrix = array( array(-1,-1,-1), array(-1,16,-1), array(-1,-1,-1) );
imageconvolution($thumb, $sharpenMatrix, 8, 0);
}
imagejpeg( $thumb, $thumbPath, Config::$images['jpegQuality'] );
// clean up
Imagedestroy( $thumb );
Imagedestroy( $orig );
return true;
}
public static function getColors( $imgPath, $size ) {
list( $srcWidth, $srcHeight, $type ) = getimagesize( $imgPath );
if( $type == IMAGETYPE_JPEG ) {
$imgcreate = 'ImageCreateFromJPEG';
} else if( $type == IMAGETYPE_GIF ) {
$imgcreate = 'ImageCreateFromGIF';
} else if( $type == IMAGETYPE_PNG ) {
$imgcreate = 'ImageCreateFromPNG';
} else {
return array();
}
$orig = $imgcreate( $imgPath );
$thumb = Imagecreatetruecolor( $size, $size );
Imagecopyresampled($thumb, $orig, 0, 0, 0, 0, $size, $size, $srcWidth, $srcHeight);
$colors = array();
for( $x = 0; $x < $size; $x++ ) {
for( $y = 0; $y < $size; $y++ ) {
$rgb = ImageColorAt($thumb, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$colors[] = array(
'r' => $r,
'g' => $g,
'b' => $b
);
}
}
return $colors;
}
}
?>

View File

@ -0,0 +1,170 @@
<?php
/*
The ImageUploader class handles the insertion of images into the system -
whether they were uploaded or should be copied from a remote URL
*/
require_once( 'lib/config.php' );
require_once( 'lib/db.php' );
require_once( 'lib/filesystem.php' );
require_once( 'lib/images.php' );
require_once( 'lib/users.php' );
require_once( 'lib/keyword.php' );
class ImageUploader {
public static function copyFromUrl( $url, $tags, $referer, &$errors ) {
if( stripos( $url, 'http://' ) !== 0 ) {
$url = 'http://'.$url;
}
// no recursion, no non-images
if(
stripos( $url, Config::$frontendPath ) !== false ||
!preg_match( '/([^\/]*?)\.(gif|jpg|jpeg|png)$/i', $url, $fileMatch )
) {
$errors['downloadFailed'] = 'The Image could not be downloaded!';
return false;
}
$fileName = $fileMatch[1];
// use the domain name as part of the keyword
$urlParts = parse_url( $url );
if( preg_match( '/(^|\.)([\w\-]+)\.\w+$/', $urlParts['host'], $m ) ) {
$fileName = strtolower($m[2]).'-'.$fileName;
}
$fileName = Keyword::get( $fileName ).'.'.$fileMatch[2];
$targetPath = './import/'.$fileName;
if( !Filesystem::download( $url, $targetPath, Config::$images['maxDownload'], $referer ) ) {
$errors['downloadFailed'] = 'The Image could not be downloaded!';
return false;
}
if( self::process( $fileName, $targetPath, $tags, false, $errors, $url ) ) {
return true;
} else {
@unlink( $targePath );
return false;
}
}
public static function process( $name, $localPath, $tags, $uploaded = true, &$errors, $source = '' ) {
$user = new User();
$user->login();
if( !$user->id ) {
$errors['notLoggedIn'] = 'You are not logged in!';
return false;
}
// no non-images
if(
!preg_match( '/([^\/]*?)\.(gif|jpg|jpeg|png)$/i', $name, $fileMatch )
) {
$errors['wrongExtension'] = 'Your file has not the right extension (gif, jpg or png)!';
return false;
}
$time = time();
$keyword = Keyword::get( $fileMatch[1] );
// Iterate over all keywords, if this one is allready taken
$taken = array();
$r = DB::query( 'SELECT keyword FROM '.TABLE_IMAGES.' WHERE keyword LIKE :1', date('Y/m/',$time).$keyword.'%' );
foreach( $r as $v ) {
$taken[] = substr($v['keyword'],8); // Keyword without date!
}
$keyword = Keyword::iterate( $keyword, $taken );
list( $srcWidth, $srcHeight, $type ) = getimagesize( $localPath );
if( $type == IMAGETYPE_JPEG ) {
$extension = 'jpg';
} else if( $type == IMAGETYPE_GIF ) {
$extension = 'gif';
} else if( $type == IMAGETYPE_PNG ) {
$extension = 'png';
} else {
return false;
}
$thumbName = $keyword.".jpg"; // all thumbs are jpegs!
$name = $keyword.".".$extension;
$imageDir = Config::$images['imagePath'] . date('Y/m', $time);
$thumbDir = Config::$images['thumbPath'] . date('Y/m', $time);
$imagePath = $imageDir.'/'.$name;
if( !Filesystem::mkdirr($imageDir) || !Filesystem::mkdirr($thumbDir) ) {
return false;
}
if( $uploaded ) {
if( !@move_uploaded_file( $localPath, $imagePath ) ) {
return false;
}
} else {
if( !@rename( $localPath, $imagePath ) ) {
return false;
}
}
$hash = md5_file( $imagePath );
$c = DB::query('SELECT id FROM '.TABLE_IMAGES.' WHERE hash = :1', $hash);
if( !empty( $c ) ) {
unlink( $imagePath );
$errors['duplicate'] = 'This image is already in our database!';
return false;
}
// make thumbs
foreach( Config::$gridView['classes'] as $gc ) {
$thumbPath = $thumbDir.'/'.$gc['dir'].'/'.$thumbName;
Filesystem::mkdirr($thumbDir.'/'.$gc['dir']);
if( !Image::createThumb( $imagePath, $thumbPath,
$gc['width'] * Config::$gridView['gridSize'] - Config::$gridView['borderWidth'],
$gc['height'] * Config::$gridView['gridSize'] - Config::$gridView['borderWidth']
)) {
unlink( $imagePath );
$errors['internalError'] = 'Internal error processing the image!';
return false;
}
}
$user->increaseScore( Config::$postScore );
DB::query( 'UPDATE '.TABLE_USERS.' SET images = images + 1 WHERE id = :1', $user->id );
DB::insertRow( TABLE_IMAGES,
array(
'logged' => date('Y-m-d H:i:s', $time),
'user' => $user->id,
'score' => 3,
'votes' => 0,
'keyword' => date('Y/m/', $time).$keyword,
'tags' => $tags,
'image' => $name,
'thumb' => $thumbName,
'hash' => $hash,
'source' => $source
)
);
$imageId = DB::insertId();
$colors = Image::getColors( $imagePath, 4 );
foreach( $colors as $c ) {
DB::insertRow( TABLE_IMAGECOLORS,
array(
'imageId' => $imageId,
'r' => $c['r'],
'g' => $c['g'],
'b' => $c['b']
)
);
}
return true;
}
}
?>

View File

@ -0,0 +1,122 @@
<?php
/*
ImageViewer loads a single image and its comments specified by a keyword
*/
require_once( 'lib/imagecatalog.php' );
class ImageViewer extends ImageCatalog {
protected $position = 0;
protected $keyword = '';
public $image = array();
public $stream = array();
public $userInfo = array();
public function setCurrent( $keyword ) {
$this->keyword = $keyword;
}
public function addComment( $userId, $comment ) {
if( $this->image['id'] && $userId && !empty($comment) ) {
DB::insertRow( TABLE_COMMENTS, array(
'imageId' => $this->image['id'],
'userId' => $userId,
'created' => date( 'Y.m.d H:i:s' ),
'content' => $comment
));
return true;
} else {
return false;
}
}
public function load() {
$conditions = '';
if( !empty($this->user) ) {
$conditions .= ' AND i.user = :2';
$this->userInfo = $this->user;
}
$this->image = DB::getRow(
'SELECT
i.id, i.logged, UNIX_TIMESTAMP(i.logged) AS loggedTS,
i.keyword, i.image, i.score, i.votes,
tags, u.name AS userName, i.user
FROM '.TABLE_IMAGES.' i
LEFT JOIN '.TABLE_USERS.' u
ON u.id = i.user
WHERE i.keyword = :1 '.$conditions,
$this->keyword,
$this->user['id']
);
$this->image['path'] = date('Y/m/', $this->image['loggedTS']).$this->image['image'];
if( empty( $this->user) ) {
$this->userInfo = DB::getRow(
'SELECT id, name, score, images, avatar, website
FROM '.TABLE_USERS.'
WHERE
id = :1',
$this->image['user']
);
}
// compute previoues and next page
$next = DB::getRow(
'SELECT i.keyword
FROM '.TABLE_IMAGES.' i
WHERE i.id < :1 '.$conditions.'
ORDER BY id DESC
LIMIT 1',
$this->image['id'],
$this->user['id']
);
$prev = DB::getRow(
'SELECT i.keyword
FROM '.TABLE_IMAGES.' i
WHERE i.id > :1 '.$conditions.'
ORDER BY id ASC
LIMIT 1',
$this->image['id'],
$this->user['id']
);
if( !empty($next) ) {
$this->stream['next'] = $next['keyword'];
}
if( !empty($prev) ) {
$this->stream['prev'] = $prev['keyword'];
}
}
public function loadComments() {
$this->comments = DB::query(
'SELECT
c.id, c.content, u.name, u.avatar,
UNIX_TIMESTAMP(c.created) AS created
FROM '.TABLE_COMMENTS.' c
LEFT JOIN '.TABLE_USERS.' u
ON u.id = c.userId
WHERE c.imageId = :1
ORDER BY created',
$this->image['id']
);
$this->commentCount = count( $this->comments );
foreach( array_keys($this->comments) as $i ) {
$this->comments[$i]['content'] = preg_replace(
'#(?<!\w)((http://)|(www\.))([^\s<>]+)#i',
"<a href=\"http://$3$4\">$3$4</a>",
nl2br( htmlspecialchars($this->comments[$i]['content']) )
);
}
}
}
?>

View File

@ -0,0 +1,41 @@
<?php
require_once( 'lib/config.php' );
class Keyword {
// Get a keyword from a string
// ----------------------------------------------------------------------------
public static function get( $kw ) {
// narf, since the .php source files are saved as 8859-1 (php doesn't like BOMs)
// utf8_decode is invoked, so str_replace actually finds something for these 8859-1
// encoded special chars
$kw = utf8_decode( $kw );
$kw = str_replace( array( 'Ä','Ö','Ü','ä','ö','ü','ß',"'" ), array( 'Ae','Oe','Ue','ae','oe','ue','ss','' ), $kw );
$kw = preg_replace( '/[^a-zA-Z\d]+/', '#', $kw );
$kw = preg_replace( '/^\#+|\#+$/', '', $kw ); // Trim seperators
$kw = str_replace( '#', Config::$keywordWordSeperator, $kw ); // replace # with final word seperator
if( $kw == "" ) {// no keyword?
$kw = 'Untitled'; // Assign default keyword
}
$kw = strtolower( $kw );
return $kw;
}
// Check if a keyword has allready been taken. if so, return $keyword-N, where N is an increasing number
// ----------------------------------------------------------------------------
public static function iterate( $kw, $taken ) {
$kwLower = strtolower( $kw );
if( in_array( $kwLower, $taken ) ) {
for( $i = 2; in_array( $kwLower, $taken); $i++ ) {
$kwLower = strtolower( $kw . Config::$keywordWordSeperator . $i );
}
return $kw . Config::$keywordWordSeperator . ( $i-1 );
}
else {
return $kw;
}
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
/*
The UserList class loads a number of users from the database, specified by a page
*/
require_once( 'lib/config.php' );
require_once( 'lib/db.php' );
class UserList {
protected $page = 0;
protected $usersPerPage = 0;
protected $totalResults = 0;
public $users = array();
public $pages = array();
public function __construct( $usersPerPage ) {
$this->usersPerPage = abs(intval($usersPerPage));
}
public function setPage( $page ) {
$page = intval($page);
$this->page = $page > 0 ? $page - 1 : 0;
}
public function load() {
$this->users = DB::query(
'SELECT SQL_CALC_FOUND_ROWS
UNIX_TIMESTAMP( u.registered ) as registered,
u.name, u.score, u.images, u.avatar, u.website
FROM '.TABLE_USERS.' u
WHERE valid = 1
GROUP BY u.id
ORDER BY u.score DESC
LIMIT :1, :2',
$this->page * $this->usersPerPage,
$this->usersPerPage
);
$this->totalResults = DB::foundRows();
// compute previoues, current and next page
if( $this->totalResults > 0 ) {
$this->pages['current'] = $this->page+1;
$this->pages['total'] = ceil($this->totalResults / $this->usersPerPage);
if( $this->page > 0 ) {
$this->pages['prev'] = $this->page;
}
if( $this->totalResults > $this->usersPerPage * $this->page + $this->usersPerPage ) {
$this->pages['next'] = $this->page + 2;
}
}
}
}
?>

View File

@ -0,0 +1,295 @@
<?php
/*
An object of this class represents a user on the site. All user
related tasks (registration, login, profile etc.) are handled here.
A user object is created and attempted to login on each page load.
*/
require_once( 'lib/config.php' );
require_once( 'lib/db.php' );
class User {
public $name = '';
public $id = 0;
public $validationString = '';
public $admin = 0;
public $website = 0;
public function __construct() {
}
public function validate( $id ) {
$u = DB::getRow(
'SELECT id, name, admin, website FROM '.TABLE_USERS.' WHERE valid = 0 AND remember = :1',
$id
);
if( empty($u) ) {
return false;
}
DB::updateRow( TABLE_USERS, array('id' => $u['id']), array( 'valid' => 1) );
session_name( Config::$sessionCookie );
session_start();
$_SESSION['id'] = $this->id = $u['id'];
$_SESSION['name'] = $this->name = $u['name'];
$_SESSION['admin'] = $this->admin = $u['admin'];
$_SESSION['website'] = $this->website = $u['website'];
setcookie( Config::$rememberCookie, $id, time() + 3600 * 24 * 365, Config::$absolutePath );
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
$forum->login(array('username' => $u['name']));
}
return true;
}
public function isSpamLocked() {
// delete all ips older than IP_LOCK_TIME
DB::query( 'DELETE FROM '.TABLE_UPLOADLOCK.' WHERE ts < :1', time() - Config::$uploadLockTime );
list(, $ip) = unpack('l',pack('l',ip2long($_SERVER['REMOTE_ADDR'])));
$r = DB::getRow( 'SELECT COUNT(*) AS c FROM '.TABLE_UPLOADLOCK.'
WHERE ip = :1',
$ip
);
if( $r['c'] > Config::$maxNumUploads ) {
return true;
} else {
return false;
}
}
public function logUpload() {
list(, $ip) = unpack('l',pack('l',ip2long($_SERVER['REMOTE_ADDR'])));
DB::insertRow( TABLE_UPLOADLOCK, array('ip' => $ip, 'ts' => time()) );
}
public function login() {
// attempt to login via post, session or remeber cookie
session_name( Config::$sessionCookie );
if( isset($_POST['login']) ) { // post login
$u = DB::getRow(
'SELECT id, name, admin, website FROM '.TABLE_USERS.' WHERE name = :1 AND pass = :2 and valid = 1',
$_POST['name'], md5($_POST['pass'])
);
if( !empty($u) ) {
session_start();
$_SESSION['id'] = $this->id = $u['id'];
$_SESSION['name'] = $this->name = $u['name'];
$_SESSION['admin'] = $this->admin = $u['admin'];
$_SESSION['website'] = $this->website = $u['website'];
if( !empty($_POST['remember']) ) {
$r = md5(uniqid(rand()));
DB::updateRow( TABLE_USERS, array('id' => $this->id), array('remember' => $r ) );
setcookie( Config::$rememberCookie, $r, time() + 3600 * 24 * 365, Config::$absolutePath );
}
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
$forum->login(array('username' => $u['name']));
}
}
}
else if( !empty($_COOKIE[Config::$sessionCookie]) ) { // session running
session_start();
if( empty($_SESSION['id']) ) {
setcookie(Config::$sessionCookie, false, time() - 3600, Config::$absolutePath );
} else {
$this->id = $_SESSION['id'];
$this->name = $_SESSION['name'];
$this->admin = $_SESSION['admin'];
$this->website = $_SESSION['website'];
}
}
else if( !empty($_COOKIE[Config::$rememberCookie]) ) { // remember cookie found
$u = DB::getRow(
'SELECT id, name, admin, website FROM '.TABLE_USERS.' WHERE remember = :1',
$_COOKIE[Config::$rememberCookie]
);
if( !empty($u) ) {
session_start();
$_SESSION['id'] = $this->id = $u['id'];
$_SESSION['name'] = $this->name = $u['name'];
$_SESSION['admin'] = $this->admin = $u['admin'];
$_SESSION['website'] = $this->website = $u['website'];
// refresh for another year
setcookie( Config::$rememberCookie, $_COOKIE[Config::$rememberCookie], time() + 3600 * 24 * 365, Config::$absolutePath );
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
$forum->login(array('username' => $u['name']));
}
}
}
}
public function profile( $localFile, &$messages ) {
$upd = array( 'website' => $_POST['website'] );
$_SESSION['website'] = $_POST['website'];
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
}
$p = trim($_POST['cpass']);
if( !empty( $p ) ) {
if( strlen($_POST['cpass']) < 6 ) {
$messages['passToShort'] = true;
}
else if( $_POST['cpass'] != $_POST['cpass2'] ) {
$messages['passNotEqual'] = true;
}
else {
$upd['pass'] = md5($_POST['cpass2']);
if( Config::$vbbIntegration['enabled'] ) {
$forum->set_pass( $_SESSION['name'], $_POST['cpass2']);
}
}
}
if( !empty( $localFile ) ) {
require_once( 'lib/images.php' );
$name = Config::$images['avatarsPath'].uniqid().'.jpg';
if( Image::createThumb( $localFile, $name, 40,40 ) ) {
$upd['avatar'] = $name;
} else {
$messages['avatarFailed'] = true;
}
}
if( empty($this->email) &&
preg_match('/^[\.\w\-]{1,}@[\.\w\-]{2,}\.[\w]{2,}$/', $_POST['email'])
) {
if( Config::$vbbIntegration['enabled'] ) {
$forum->set_email( $_SESSION['name'], $_POST['email']);
}
$upd['email'] = $_POST['email'];
}
DB::updateRow( TABLE_USERS, array( 'id' => $this->id ), $upd );
}
public function loadEmail() {
$tmp = DB::getRow(
'SELECT email FROM '.TABLE_USERS.' WHERE id = :1',
$this->id
);
$this->email = $tmp['email'];
}
public function logout() {
session_unset();
session_destroy();
$_SESSION = array();
setcookie( Config::$rememberCookie, false, time() - 3600, Config::$absolutePath );
setcookie( Config::$sessionCookie, false, time() - 3600, Config::$absolutePath );
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
$forum->logout();
}
}
public function increaseScore( $amount ) {
DB::query(
'UPDATE '.TABLE_USERS.' SET score = score + :1 WHERE id = :2',
intval( $amount ),
$this->id
);
}
public function register( &$messages ) {
DB::query( 'DELETE FROM '.TABLE_USERS.' WHERE valid = 0 AND registered < NOW() - INTERVAL 30 MINUTE' );
if( !preg_match('/^\w{2,20}$/', $_POST['name']) ) {
$messages['nameInvalid'] = true;
} else {
$u = DB::getRow( 'SELECT * FROM '.TABLE_USERS.' WHERE name = :1', $_POST['name'] );
if( !empty($u) ) {
$messages['nameInUse'] = true;
}
}
if( strlen($_POST['pass']) < 6 ) {
$messages['passToShort'] = true;
}
else if( $_POST['pass'] != $_POST['pass2'] ) {
$messages['passNotEqual'] = true;
}
if( !preg_match( '/^[\.\w\-]{1,}@[\.\w\-]{2,}\.[\w]{2,}$/', $_POST['email'] ) ) {
$messages['wrongEmail'] = true;
} else {
$u = DB::getRow( 'SELECT * FROM '.TABLE_USERS.' WHERE email = :1', $_POST['email'] );
if( !empty($u) ) {
$messages['emailInUse'] = true;
}
}
if( !empty($messages) ) {
return false;
}
$this->validationString = md5(uniqid(rand()));
DB::insertRow( TABLE_USERS, array(
'registered' => date('Y-m-d H:i:s'),
'name' => $_POST['name'],
'pass' => md5($_POST['pass']),
'valid' => 0,
'score' => 0,
'images' => 0,
'website' => '',
'avatar' => Config::$images['avatarsPath'].'default.png',
'remember' => $this->validationString,
'admin' => 0,
'email' => $_POST['email']
));
if( Config::$vbbIntegration['enabled'] ) {
global $vbulletin;
$forum = new ForumOps($vbulletin);
$user['name'] = $_POST['name'];
$user['pass'] = $_POST['pass'];
$user['email'] = $_POST['email'];
echo $forum->register_newuser($user, false);
}
$mail = file_get_contents( Config::$templates.'registrationmail.txt' );
preg_match( '/From: (?<from>.*?)\r?\nSubject: (?<subject>.*?)\r?\n\r?\n(?<text>.*)/sim', $mail, $mail );
$mail['text'] = str_replace( '%validationString%', $this->validationString, $mail['text'] );
$mail['text'] = str_replace( '%siteName%', Config::$siteName, $mail['text'] );
$mail['text'] = str_replace( '%frontendPath%', Config::$frontendPath, $mail['text'] );
$mail['text'] = str_replace( '%userName%', $_POST['name'], $mail['text'] );
$mail['subject'] = str_replace( '%siteName%', Config::$siteName, $mail['subject'] );
$mail['subject'] = str_replace( '%userName%', $_POST['name'], $mail['subject'] );
mail( $_POST['email'], $mail['subject'], $mail['text'], 'FROM: '.$mail['from'] );
return true;
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

View File

@ -0,0 +1,400 @@
function $(id){return document.getElementById(id)}
function gridView(id){ gridSolve(id); gridSolve(id); window.setInterval("gridSolve('"+id+"')",250); }
function swap(e, c1, c2) { e.className = e.className == c1 ? c2 : c1; };
// GridSolver ------------------------------------------------------------
var gridSize = 64;
var gridMinWidth = 6;
var gridWidth = 0;
var grid = null;
var boxDef = {
'b0': {'width': 3, 'height': 3},
'b1': {'width': 2, 'height': 2},
'b2': {'width': 1, 'height': 1}
};
function gridSolve( cid ) {
var container = $(cid);
var newWidth = parseInt( container.offsetWidth );
var newGridWidth = parseInt( newWidth / gridSize );
newGridWidth = newGridWidth < gridMinWidth ? gridMinWidth : newGridWidth;
if( gridWidth == newGridWidth )
return;
else
gridWidth = newGridWidth;
boxes = new Array();
while( container.hasChildNodes() ) {
e = container.removeChild( container.firstChild );
if( e.tagName == 'DIV' ) {
boxes.push( e );
}
}
grid = new Array( gridWidth );
for( var i = 0; i < grid.length; i++ ) {
grid[i] = 0;
}
for(var i = 0; i < boxes.length; i++) {
insertThumb( boxes[i], cid )
}
var maxHeight = 0;
for( var i = 0; i < grid.length; i++) {
maxHeight = Math.max( maxHeight,grid[i] );
}
container.style.height = (maxHeight * gridSize) + 'px';
$('images').style.height = (maxHeight * gridSize) + 'px';
}
function insertThumb( box, cid ) {
var boxWidth = boxDef[box.className]['width'];
var boxHeight = boxDef[box.className]['height'];
var maxHeight = 0;
var currentHeight = -1;
var spotWidth = 0;
var spotLeft = 0;
var freeSpots = new Array();
for( var i = 0; i < grid.length; i++) {
if( currentHeight == grid[i] ) {
spotWidth++;
}
if( (currentHeight != grid[i] || i+1 == grid.length) && spotWidth > 0) {
freeSpots.push({'width': spotWidth, 'left': spotLeft, 'height': currentHeight});
spotWidth = 1;
spotLeft = i;
if(currentHeight != grid[i] && i+1 == grid.length) {
freeSpots.push({'width': spotWidth, 'left': spotLeft, 'height': grid[i]});
}
}
else if( spotWidth == 0 ) {
spotWidth = 1;
}
currentHeight = grid[i];
if( grid[i] > maxHeight ) {
maxHeight = grid[i];
}
}
var targetHeight = 0;
var targetLeft = 0;
var bestScore = -1;
for( var j = 0; j < boxWidth; j++ ) {
if( grid[j] > targetHeight ) {
targetHeight = grid[j];
}
}
var newHeight = targetHeight + boxHeight;
for( var i = 0; i < freeSpots.length; i++ ) {
var heightScore = ( maxHeight - freeSpots[i]['height'] );
var widthScore = boxWidth / freeSpots[i]['width'];
var score = heightScore * heightScore + widthScore * 2;
if( freeSpots[i]['width'] >= boxWidth && score > bestScore ) {
targetHeight = freeSpots[i]['height'];
targetLeft = freeSpots[i]['left'];
newHeight = freeSpots[i]['height'] + boxHeight;
bestScore = score;
}
}
for( var j = 0; j < boxWidth; j++ ) {
grid[targetLeft + j] = newHeight;
}
var container = $( cid );
container.appendChild( box );
box.style.left = (targetLeft * gridSize) + 'px';
box.style.top = (targetHeight * gridSize) + 'px';
return true;
}
// Colorpicker -----------------------------------------------------------
function colorpicker( id, size, onchange, onshow ) {
var that = this;
this.size = size;
this.onchange = onchange;
this.onshow = onshow;
this.mode = 'none';
this.sv = $(id+'SV');
this.svselect = $(id+'SVSelect');
this.h = $(id+'H');
this.hselect = $(id+'HSelect');
this.value = $(id+'Value');
this.current = $(id+'Current');
this.cap = function( v, min, max ) {
return Math.min(Math.max(min,v),max);
}
this.getMousPos = function( event ) {
if(event.pageX || event.pageY){
return {
'x': event.pageX,
'y': event.pageY
};
}
return {
'x': event.clientX + document.body.scrollLeft - document.body.clientLeft,
'y': event.clientY + document.body.scrollTop - document.body.clientTop
};
}
this.getObjPos = function( obj ) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
}
return {
'x':curleft,
'y':curtop
};
}
this.release = function() {
document.onmousemove = '';
this.mode = 'none';
}
this.move = function( event ) {
if (!event) var event = window.event;
if(event.pageX || event.pageY) {
var mx = event.pageX;
var my = event.pageY;
} else {
var mx = event.clientX + document.body.scrollLeft - document.body.clientLeft;
var my = event.clientY + document.body.scrollTop - document.body.clientTop;
}
if( this.mode == 'sv' ) {
var obj = this.getObjPos( this.sv );
var x = this.cap(mx - obj.x - 3, -4, this.size - 4);
var y = this.cap(my - obj.y - 3, -4, this.size - 4);
this.svselect.style.left = x + "px";
this.svselect.style.top = y + "px";
}
else if ( this.mode == 'h' ) {
var obj = this.getObjPos( this.sv );
var y = this.cap(my - obj.y - 2, -2, this.size - 3);
this.hselect.style.top = y + "px";
this.sv.style.backgroundColor = '#' + this.rgb2hex(this.hsv2rgb( {'h':1-((y+3)/this.size), 's':1, 'v':1} ));
}
else return false;
var hex = this.getHex();
this.current.style.backgroundColor = '#' + hex;
this.value.innerHTML = '#' + hex;
this.onchange( this );
return false;
}
this.sv.onmousedown = function() {
that.mode = 'sv';
document.onmousemove = function( event ) { that.move( event ) };
document.onmouseup = that.release;
return false;
}
this.h.onmousedown = function() {
that.mode = 'h';
document.onmousemove = function( event ) { that.move( event ) };
document.onmouseup = that.release;
return false;
}
this.getHSV = function() {
var svpos = this.getObjPos( this.sv );
var svselectpos = this.getObjPos( this.svselect );
var hpos = this.getObjPos( this.h );
var hselectpos = this.getObjPos( this.hselect );
return {
'h': 1 - (this.cap(hselectpos.y - hpos.y + 3, 0, this.size) / this.size),
's': this.cap(svselectpos.x - svpos.x + 2, 0, this.size) / this.size,
'v': 1 - (this.cap(svselectpos.y - svpos.y + 4, 0, this.size) / this.size)
}
}
this.getRGB = function() {
return this.hsv2rgb( this.getHSV() );
}
this.getHex = function() {
return this.rgb2hex( this.getRGB() );
}
this.toHex = function(v) { v=Math.round(Math.min(Math.max(0,v),255)); return("0123456789ABCDEF".charAt((v-v%16)/16)+"0123456789ABCDEF".charAt(v%16)); }
this.rgb2hex = function(c) { return this.toHex(c.r)+this.toHex(c.g)+this.toHex(c.b); }
this.hsv2rgb = function( c ) {
var R, B, G, H = c.h, S = c.s, V = c.v;
if( S>0 ) {
if(H>=1) H=0;
H=6*H; F=H-Math.floor(H);
A=Math.round(255*V*(1.0-S));
B=Math.round(255*V*(1.0-(S*F)));
C=Math.round(255*V*(1.0-(S*(1.0-F))));
V=Math.round(255*V);
switch(Math.floor(H)) {
case 0: R=V; G=C; B=A; break;
case 1: R=B; G=V; B=A; break;
case 2: R=A; G=V; B=C; break;
case 3: R=A; G=B; B=V; break;
case 4: R=C; G=A; B=V; break;
case 5: R=V; G=A; B=B; break;
}
return {'r': (R?R:0), 'g': (G?G:0), 'b': (B?B:0)};
}
else {
return {'r': (Math.round(V*255)), 'g': (Math.round(V*255)), 'b': (Math.round(V*255))};
}
}
}
// Adjust height of prev/next bars in IE ---------------------------------
var ieAdjustCount = 0;
function ieAdjustHeight( oldHeight ) {
var pe = ($('viewer') ? $('viewer') : $('images'));
if(
!document.all || // IE
!( pe ) ||
(
pe.scrollHeight < oldHeight + 50 &&
ieAdjustCount > 10
)
) {
return;
}
ieAdjustCount++;
var newHeight = pe.scrollHeight;
$('prevBar').style.height = pe.scrollHeight + 'px';
$('nextBar').style.height = pe.scrollHeight + 'px';
setTimeout( 'ieAdjustHeight(' + newHeight + ')', 100 );
}
// JSON functions for tagging, rating, deleting... -----------------------
function post( url, params, callback ) {
if (window.ActiveXObject) { // ie
try {
req = new ActiveXObject( 'Msxml2.XMLHTTP' );
}
catch (e) {
try {
req = new ActiveXObject( 'Microsoft.XMLHTTP' );
}
catch (e) {}
}
}
else if (window.XMLHttpRequest) { // moz
req = new XMLHttpRequest();
req.overrideMimeType( 'text/plain' );
}
req.onreadystatechange = function(){
if (req.readyState == 4 && req.status == 200) {
callback();
}
};
if( !req ) return false;
req.open( 'POST', url, true );
req.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded; charset=UTF-8' );
req.setRequestHeader( 'Content-length', params.length );
req.setRequestHeader( 'Connection', 'close' );
req.send( params );
}
function addTags( imageId, inputField, admin ) {
$( 'loadTags' ).style.display = 'block';
var tags = encodeURIComponent(inputField.value);
if( !admin ) {
inputField.value = '';
}
post(
$('home').href + 'json.php?addTags',
'id='+imageId+'&tags='+tags,
function(){
q = ( eval('('+req.responseText+')') );
if( q.tags ) {
$('tags').innerHTML = q.tags;
}
$('addTag').className='hidden';
$( 'loadTags' ).style.display = 'none';
}
);
return false;
}
function del( imageId ) {
if( !confirm( 'Delete this image?' ) ) return false;
$( 'loadDelete' ).style.display = 'block';
post(
$('home').href + 'json.php?delete',
'id='+imageId,
function(){
$( 'loadDelete' ).style.display = 'none';
$( 'del' ).style.display = 'none';
}
);
return false;
}
function delComment( commentId, e ) {
if( !confirm( 'Delete this comment?' ) ) return false;
var cdiv = e.parentNode.parentNode.parentNode;
post(
$('home').href + 'json.php?deleteComment',
'id='+commentId,
function(){
cdiv.style.display = 'none';
}
);
return false;
}
// mouseover for rating stars
function sr( id, scale ) {
$( id ).style.backgroundPosition = ( (20 * scale) - 100 ) + 'px 0';
}
function rate( imageId, score ) {
$( 'loadRating' ).style.display = 'block';
post(
$('home').href + 'json.php?rate',
'id='+imageId+'&score='+score,
function() {
q = ( eval('('+req.responseText+')') );
$( 'loadRating' ).style.display = 'none';
$( 'currentRating' ).style.width = 20 * parseFloat(q.score) + 'px';
$( 'ratingDescription' ).innerHTML = q.score + ' after ' + q.votes + ' Vote' + ( q.votes > 1 ? 's' : '' );
}
);
return false;
}
function s() {
var q = $( 'q' );
if( q && q.value ) {
window.location = $('home').href + 'search/' + encodeURI( q.value );
}
return false;
}

View File

@ -0,0 +1,146 @@
<?php
require_once( '../lib/config.php' );
header( 'Content-type: text/javascript; charset=utf-8' );
?>
function RP_RemotePost( postURL, stylesheet ) {
this.postURL = postURL;
this.stylesheet = stylesheet;
this.visible = false;
this.menu = null;
this.dialog = null;
this.iframe = null;
this.checkSuccessInterval = 0;
this.minImageSize = 32;
this.create = function(){
var that = this;
var css = document.createElement('link');
css.type = 'text/css';
css.rel = 'stylesheet';
css.href = this.stylesheet;
if( document.getElementsByTagName("head").item(0) ) {
document.getElementsByTagName("head").item(0).appendChild( css );
} else {
document.getElementsByTagName("body").item(0).appendChild( css );
}
var closeButton = document.createElement('a');
closeButton.appendChild( document.createTextNode("x") );
closeButton.className = 'close';
closeButton.onclick = function() { return that.toggle(); }
closeButton.href = '#';
this.dialog = document.createElement('div');
this.dialog.id = 'RP_Dialog';
this.iframe = document.createElement('iframe');
this.iframe.src = 'about:blank';
this.dialog.appendChild( this.iframe );
this.dialog.appendChild( closeButton );
document.body.appendChild( this.dialog );
this.loadIFrame( {} );
}
this.loadIFrame = function( params ) {
var reqUrl = this.postURL + '?nocache=' + parseInt(Math.random()*10000);
for( p in params ) {
reqUrl += '&' + p + '=' + encodeURIComponent( params[p] );
}
this.iframe.src = reqUrl;
}
this.selectImage = function( image ) {
var title = image.title ? image.title : ( image.alt ? image.alt : document.title );
var imageSrc = image.src;
if(
image.parentNode.tagName.match(/^a$/i) &&
image.parentNode.href &&
image.parentNode.href.match(/\.(jpe?g|gif|png)$/i)
) {
imageSrc = image.parentNode.href;
}
this.loadIFrame( {
'url': imageSrc,
'xhrLocation': document.location.href.replace(/#.*$/,'')
});
return false;
}
this.checkSuccess = function() {
if( document.location.href.match(/#RP_Success/) ) {
var that = this;
document.location.href = document.location.href.replace(/#.*$/, '#');
setTimeout( function() { that.hide() }, 500 );
}
}
this.show = function() {
this.visible = true;
var that = this;
this.checkSuccessInterval = setInterval( function() { that.checkSuccess(); }, 500 );
this.dialog.style.display = 'block';
var images = document.getElementsByTagName('img');
for( var i=0; i<images.length; i++ ) {
var img = images[i];
if( img && img.src && img.src.match(/(space|blank)[^\/]*\.gif$/i) ) {
img.style.display = 'none';
}
else if( img && img.src && img.width > this.minImageSize && img.height > this.minImageSize) {
img.onclick = function( ev ) {
if( ev && ev.stopPropagation ) {
ev.stopPropagation();
}
return that.selectImage(this);
};
img.className = img.className ? img.className + ' RP_PostImage' : 'RP_PostImage';
}
}
}
this.hide = function() {
this.visible = false;
clearInterval( this.checkSuccessInterval );
this.dialog.style.display = 'none';
var images = document.getElementsByTagName('img');
for( var i=0; i<images.length; i++ ) {
var img = images[i];
if( img && img.src && img.width > this.minImageSize && img.height > this.minImageSize) {
img.onclick = null;
img.className = img.className.replace(/\s*RP_PostImage/, '');
}
}
}
this.toggle = function() {
if( !this.visible ) {
this.show();
} else {
this.hide();
}
return false;
}
this.create();
}
if( typeof(RP_Instance) == 'undefined' ) {
var RP_Instance = new RP_RemotePost(
'<?php echo Config::$frontendPath; ?>remotepost.php',
'<?php echo Config::$frontendPath; ?>media/remotepost.css'
);
}
RP_Instance.toggle();

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

View File

@ -0,0 +1,44 @@
var nextImage = {};
var preload = null;
function quickTag( logId, imageId, inputField ) {
var tags = encodeURIComponent(inputField.value);
// swap nextImage
$('imageLocation').href = nextImage['link'];
$('imageLocation').innerHTML = nextImage['link'];
$('imageId').value = nextImage['id'];
$('logId').value = nextImage['logId'];
$('image').src = nextImage['image'];
$('tags').innerHTML = nextImage['tags'];
$('tagText').value = '';
$('tagText').focus();
if( !nextImage['link'] ) {
$('imageInfo').innerHTML = 'No more Images found';
}
post(
$('home').href + 'json.php?quickTag',
'logId='+logId+'&id='+imageId+'&tags='+tags,
function(){
nextImage = ( eval('('+req.responseText+')') );
preload = new Image(1,1)
preload.src=nextImage['image'];
}
);
return false;
}
function quickTagInit() {
swap($('quickTagIntro'), 'article', 'hidden');
swap($('viewer'), 'hidden', 'visible');
post(
$('home').href + 'json.php?quickTag',
'',
function(){
nextImage = ( eval('('+req.responseText+')') );
quickTag( 0, 0, $('tagText') );
}
);
return false;
}

View File

@ -0,0 +1,58 @@
img.RP_PostImage {
border: 2px dashed #00adef !important;
cursor: pointer !important;
}
img.RP_PostImage:hover, img.RP_PostImageActive {
border: 2px solid #00adef !important;
}
#RP_Dialog {
position: fixed;
top: 0;
left: 50%;
width: 450px;
margin-left: -243px;
padding: 0 18px 0 0;
z-index: 99999;
background-color: #222 !important;
color: #ccc !important;
font-size: 12pt;
font-family: Arial, Helvetica, sans-serif;
font-weight: normal;
font-style: normal;
text-align: left;
border-left: 1px solid #fff;
border-right: 1px solid #ccc;
border-bottom: 1px solid #aaa;
}
#RP_Dialog iframe {
width: 450px;
height: 100px;
border: 0;
}
#RP_Dialog a {
color: #fff !important;
background: transparent none !important;
text-decoration: none !important;
border: 0 !important;
}
#RP_Dialog a:hover {
color: #000 !important;
background: #fff none !important;
text-decoration: none !important;
border: 0 !important;
}
#RP_Dialog a.close {
position: absolute !important;
top: 0 !important;
right: 0 !important;
padding: 3px 10px;
font-weight: bold;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

View File

@ -0,0 +1,587 @@
/* -----------------------------------------------
layout & typo */
body {
background-color: #222;
color: #ccc;
font-family: Arial, Verdana, Trebuchet MS;
font-size: 10pt;
margin: 0;
padding: 0 0 1em 0;
}
div#menu {
height: 67px;
background-color: #000;
border-bottom: 1px solid #333;
}
div.userMenu {
float: right;
font-size: 90%;
margin: 30px 30px 0 0;
}
div.search {
position: relative;
float: left;
font-size: 70%;
margin: 30px 30px 0 30px;
}
div.menuItems {
position: relative;
float: left;
font-size: 90%;
}
div.menuItems a {
float: left;
display: block;
height: 37px;
padding: 30px 12px 0 12px;
border-left: 1px solid #222;
background-color: #111;
}
div.menuItems a:hover {
background-color: #333;
color: #fff;
}
div.search input {
font-size: 100%;
}
input.search {
background-image: url(search.png);
background-repeat: no-repeat;
background-position: 2px 2px;
color: #fff;
text-align: right;
width: auto;
padding-left: 14px;
}
input.color {
background-image: url(color.png);
background-repeat: no-repeat;
width: 18px;
}
img#logo {
float: left;
}
img {
border: 0;
}
div#content {
margin: 0.3em 1em;
}
div#footer {
color: #444;
text-align: right;
margin: 0.3em 1em;
}
span.love {
color: #7b0043;
}
h1 {
color: #fff;
font-size: 90%;
font-weight: normal;
text-transform: uppercase;
}
h1.remotePost {
font-size: 110%;
font-weight: bold;
text-transform: none;
}
h2 {
margin-top: 3em;
color: #fff;
font-size: 110%;
font-weight: bold;
}
a {
color: #fff;
text-decoration: none;
}
a:hover {
color: #000;
background-color: #fff;
}
div.article {
margin-left: 1em;
width: 40em;
}
ul {
list-style-type: square;
}
/* -----------------------------------------------
prev next bars */
a.next, a.prev, div.noPrev, div.noNext {
text-indent: 16px;
color: #fff;
width: 12px;
overflow: hidden;
display: block;
text-align: center;
position: absolute;
}
/* Hide from IE < 7 */
a.next[class], a.prev[class], div.noPrev[class], div.noNext[class] {
height: 100%;
}
a.prev {
background-color: #4bbed5;
background-image: url(prev.png);
background-position: -12px 0;
left: 0;
top: 0;
}
a.prev:hover {
background-position: -24px 0;
}
a.next {
background-color: #4bbed5;
background-image: url(next.png);
background-position: -12px 0;
right: 0;
top: 0;
}
a.next:hover {
background-position: 0 0;
}
div.noPrev {
background-image: url(prev.png);
background-position: 0 0;
left: 0;
top: 0;
}
div.noNext {
background-image: url(next.png);
background-position: -24px 0;
right: 0;
top: 0;
}
/* -----------------------------------------------
grid view */
div#images {
position: relative;
}
div#imageGrid {
margin: 0 13px;
left: 0;
top: 0;
position: relative;
}
#imageGrid div {
position: absolute;
overflow: hidden;
}
.b0 {
width: 192px;
height: 192px;
}
.b1 {
width: 128px;
height: 128px;
}
.b2 {
width: 64x;
height: 64px;
}
a.thumb {
display: block;
padding: 1px;
background-color: #fff;
}
a.thumb:hover img {
opacity: 0.8;
filter: alpha( opacity = 80 );
}
/* -----------------------------------------------
single image view */
div#viewer {
position: relative;
}
div#imageContainer {
margin: 0 14px;
overflow: auto;
}
img#image {
display:block;
border: 2px solid #fff;
margin: 1em auto;
}
img#image[src] {
cursor: pointer;
}
img.scaled {
max-width: 90%;
max-height: 500px;
}
img.full {
max-width: none;
max-height: none;
}
div#imageInfo {
width: 500px;
margin: 1em auto;
overflow: hidden;
background-color: #1a1a1a;
padding: 1em;
position: relative;
}
div.date {
position: absolute;
right: 1em;
top: 1em;
font-style: italic;
}
div.teaser {
margin: 1em 0;
}
.hidden {
display: none;
}
.visible {
display: block;
}
/* Comments
---------------------------------------------------------*/
div.comments h3 {
font-size: 10pt;
color: #fff;
}
form.addComment {
margin-top: 10px;
}
textarea {
font-family: Arial, Verdana, Trebuchet MS;
font-size: 10pt;
border: 1px solid #333;
background-color: #000;
color: #fff;
margin-bottom: 3px;
width: 100%;
}
textarea:focus {
border: 1px solid #fff;
}
div.comment {
background-color: #000;
padding: 2px 5px;
border-left: 2px solid #444;
margin: 10px 0;
}
div.commentHead {
color: #888;
font-style: italic;
margin-bottom: 2px;
}
img.avatarSmall {
height:16px;
width:16px;
vertical-align:bottom;
}
/* image rating
---------------------------------------------------------*/
div.rating {
font-weight: bold;
margin-bottom: 0.5em;
position: relative;
}
div.rating span {
display: block;
padding-top: 2px;
}
div.ratingBase {
position: relative;
float: left;
margin-right: 0.5em;
width: 102px;
height: 20px;
background-image: url( star-base.png );
}
div.ratingCurrent {
position: absolute;
top: 0;
left: 0;
height: 20px;
background-image: url( star-current.png );
}
div.ratingRate {
position: absolute;
top: 0;
left: 0;
width: 102px;
height: 20px;
background-image: url( star-rate.png );
background-repeat: no-repeat;
background-position: -100px 0;
}
div.ratingRate a {
display: block;
height: 20px;
width: 20px;
float: left;
}
div.ratingRate a:hover {
background: transparent;
}
div.load {
background-image: url( loading.gif );
background-repeat: no-repeat;
float: left;
margin-top: 3px;
width: 14px;
height: 14px;
display: none;
}
/* UserInfo
---------------------------------------------------------*/
div.userInfo {
margin: 1em 0;
border: 1px solid #555;
background-color: #333;
color: #fff;
position: relative;
}
img.avatar {
float: left;
margin-right: 1em;
position: relative;
}
div.name {
margin-top: 0.1em;
font-size: 130%;
}
a.textPrev, div.textNoPrev {
display: block;
float: left;
}
a.textNext, div.textNoNext {
display: block;
float: right;
}
/* Forms
---------------------------------------------------------*/
div.warn {
background-color: #7a0d00;
padding: 0.1em 0.4em;
border: 1px solid #fd5c6a;
color: #fff;
margin: 2em;
}
input {
background-color: #000;
border: 1px solid #666;
color: #fff;
width: 12em;
}
input.button {
background-color: #111;
border-left: 1px solid #ccc;
border-top: 1px solid #ccc;
width: auto;
}
input.check {
width: auto;
}
input.login, input.register {
margin-top: 1em;
padding: 0 1em;
}
input:focus, input.button:focus {
border: 1px solid #fff;
}
dl.form dd {
margin: 0.4em 0;
}
dl.form dt {
margin-right: 0.5em;
padding: 0.4em 0 0 1em;
width: 8em;
height: 1em;
text-align: right;
display: block;
float: left;
font-style: italic;
color: #fff;
}
fieldset {
width: 48em;
margin-top: 0.5em;
border: 1px solid #444;
}
legend {
color: #fff;
font-size: 90%;
font-weight: normal;
text-transform: uppercase;
}
pre {
font-family: Bitstream Vera Sans Mono, Courier New, Lucida Console, monospace;
font-size: 9pt;
border-top: 1px solid #444;
border-bottom: 1px solid #333;
padding: 0.4em;
color: #fff;
}
/* colorpicker
---------------------------------------------------------*/
div#colorpicker {
position: absolute;
top: 16px;
left: 0;
width: 80px;
height: 76px;
background-color: #333;
border: 1px solid #777;
z-index: 10;
}
div#colorpickerSV {
background-color: #f00;
position: absolute;
bottom: 0;
left: 0;
width: 64px;
height: 64px;
background-image: url(colorpicker-sv.png);
}
div#colorpickerH {
position: absolute;
bottom: 0;
right: 0;
width: 14px;
height: 64px;
background-image: url(colorpicker-h.png);
background-repeat: no-repeat;
}
div#colorpickerSVSelect {
position: absolute;
top: -4px;
left: -4px;
width: 9px;
height: 9px;
background-image: url(colorpicker-select-sv.png);
}
div#colorpickerHSelect {
position: absolute;
top: -2px;
right: 1px;
width: 3px;
height: 5px;
background-image: url(colorpicker-select-h.png);
}
div#colorpickerCurrent {
background-color: #fff;
position: absolute;
top: 2px;
left: 1px;
width: 8px;
height: 8px;
}
div#colorpickerValue {
font-size: 9px;
font-family: arial;
color: #fff;
position: absolute;
top: 0;
left: 12px;
height: 8px;
}

View File

@ -0,0 +1,27 @@
<?php
header("Content-type: text/html; charset=UTF-8");
require_once( 'lib/config.php' );
require_once( 'lib/users.php' );
require_once( 'lib/db.php' );
$user = new User();
$user->login();
$status = 'ready';
if( $user->id && !$user->isSpamLocked() && !empty($_GET['url'])) {
$uploadErrors = array();
require_once( 'lib/imageuploader.php' );
if(
ImageUploader::copyFromUrl( $_GET['url'], '', $_SERVER['HTTP_REFERER'], $uploadErrors)
) {
$status = 'posted';
$user->logUpload();
} else {
$status = 'failed';
}
}
include( Config::$templates.'remotepost.tpl.php' );
?>

View File

@ -0,0 +1,21 @@
<h1>&raquo; Bookmarklet</h1>
<div class="article">
<h2><?php echo Config::$siteName ?> Remote Post Bookmarklet</h2>
<p>
With the Remote Post Bookmarklet you can easily post images to <?php echo Config::$siteName ?> with one simple click.
Please note that you need a decent Browser, like <a href="http://getfirefox.com/">Firefox</a> or
<a href="http://www.opera.com/">Opera</a>, or at least Microsofts IE7 for this to work.
</p>
<p>
To use the bookmarklet just drag the following link somewhere to your bookmarks (or in Opera right click it
and choose <em>Bookmark link</em>):
&raquo; <a onclick="alert('Drag this Link to your Bookmarks!'); return false;" href="javascript:void((function(){var%20e=document.createElement('script');e.setAttribute('type','text/javascript');e.setAttribute('src','<?php echo Config::$frontendPath; ?>media/post.js.php');document.body.appendChild(e)})());">Post to <?php echo Config::$siteName ?></a> &laquo;
</p>
<p>
Now, if you're on a website where you see an image you want to post, just click on your newly created bookmark
and then on the image you want to post. Thats all. Really!
</p>
</div>

View File

@ -0,0 +1,8 @@
<?php include( $templates.'header.tpl.php' ); ?>
<div class="warn">No Images found</div>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,77 @@
<?php include( $templates.'header.tpl.php' ); ?>
<h1>
&raquo; Browsing
<?php if( !empty($ib->user) ) { ?>
User: <a href="<?php echo Config::$absolutePath.'user/'.$ib->user['name']; ?>"><?php echo $ib->user['name']; ?></a>
<?php } else if( !empty($ib->channel) ) { ?>
Channel: <a href="<?php echo Config::$absolutePath.'channel/'.$ib->channel['keyword']; ?>"><?php echo $ib->channel['name']; ?></a>,
<?php } else if( !empty($ib->searchColor) || !empty($ib->searchTerm) ) { ?>
Results for <?php echo htmlspecialchars($term); ?>,
<?php } else { ?>
All,
<?php } ?>
Page: <?php echo $ib->pages['current']; ?> of <?php echo $ib->pages['total']; ?>
</h1>
<?php if( $ib->user['id'] ) {?>
<div class="userInfo">
<img class="avatar" width="40" height="40" src="<?php echo Config::$absolutePath.$ib->user['avatar']; ?>"/>
<div class="name">
<strong>
<a href="<?php echo Config::$absolutePath.'user/'.$ib->user['name']; ?>"><?php echo $ib->user['name']; ?></a>
</strong>
</div>
<div class="info">
Score: <strong><?php echo $ib->user['score']; ?></strong> /
Images: <strong><?php echo $ib->user['images']; ?></strong>
<?php if( !empty($ib->user['website'])) { ?>/
Website: <strong><a href="<?php echo htmlspecialchars($ib->user['website']); ?>" target="_blank">
<?php echo htmlspecialchars($ib->user['website']); ?>
</a></strong>
<?php } ?>
</div>
<div style="clear:both;"></div>
</div>
<?php } ?>
<div id="images" style="height:<?php echo $gv->height * Config::$gridView['gridSize']; ?>px">
<?php if( isset($ib->pages['prev']) ) { ?>
<a href="<?php echo Config::$absolutePath.$ib->basePath.'page/'.$ib->pages['prev']; ?>" class="prev" title="Previous" id="prevBar">Previous</a>
<?php } else { ?>
<div class="noPrev" id="prevBar">Previous</div>
<?php } ?>
<?php if( isset($ib->pages['next']) ) { ?>
<a href="<?php echo Config::$absolutePath.$ib->basePath.'page/'.$ib->pages['next']; ?>" class="next" title="Next" id="nextBar">Next</a>
<?php } else { ?>
<div class="noNext" id="nextBar">Next</div>
<?php } ?>
<div id="imageGrid" style="height:<?php echo $gv->height * Config::$gridView['gridSize']; ?>px">
<?php
if( !empty($ib->searchColor) || !empty($ib->searchTerm) ) {
$imgBasePath = 'all/';
} else {
$imgBasePath = $ib->basePath;
}
foreach( $ib->thumbs as $thumb ) {
if( isset( $thumb['left'] ) ) {
echo '<div class="'.$thumb['class'].'" style="left:'.$thumb['left'].'px;top:'.$thumb['top'].'px;"><a class="thumb" href="'
.Config::$absolutePath.$imgBasePath.'view/'.$thumb['keyword'].'">'
.'<img src="'.$thumb['thumb'].'" alt="'.$thumb['keyword'].'" title="'.$thumb['userName'].' - '.
date('d. M Y H:i',$thumb['loggedTS']).'"/></a></div>'."\n";
}
}
?>
</div>
</div>
<script type="text/javascript">
gridView('imageGrid');
ieAdjustHeight(0);
</script>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,9 @@
</div>
<div id="footer">
Copyright &copy; <?php echo date('Y'); ?> <?php echo Config::$siteName; ?>. All Rights Reserved
</div>
</body>
</html>

View File

@ -0,0 +1,67 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title><?php if( $iv && $iv->image && $iv->image['tags']){ echo htmlspecialchars($iv->image['tags'])?> - <?php } ?><?php echo Config::$siteTitle; ?></title>
<link rel="stylesheet" type="text/css" href="<?php echo Config::$absolutePath; ?>media/styles.css" />
<link rel="icon" href="<?php echo Config::$absolutePath; ?>media/favicon.ico"/>
<script type="text/javascript" src="<?php echo Config::$absolutePath; ?>media/picturelicious.js"></script>
</head>
<body>
<div id="menu">
<a href="<?php echo Config::$absolutePath; ?>" id="home"><img title="Home" id="logo" alt="" src="<?php echo Config::$absolutePath; ?>media/logo.png"/></a>
<div class="search">
<form action="<?php echo Config::$absolutePath; ?>" method="post" onsubmit="return s()">
<input type="text" name="q" value="<?php echo htmlspecialchars($term); ?>" id="q"/>
<input type="button" class="color" value="" onclick="swap($('colorpicker'),'hidden','visible')"/>
<input type="submit" name="search" class="search" value="search"/>
<div id="colorpicker" class="hidden">
<div id="colorpickerCurrent"></div>
<div id="colorpickerValue">#FFFFFF</div>
<div id="colorpickerSV"><div id="colorpickerSVSelect"></div></div>
<div id="colorpickerH"><div id="colorpickerHSelect"></div></div>
</div>
<script type="text/javascript">
var cp = new colorpicker( 'colorpicker', 64, function(cp) {$('q').value = '0x' + cp.getHex();} );
</script>
</form>
</div>
<div class="menuItems">
<a href="<?php echo Config::$absolutePath; ?>upload">Upload</a>
<a href="<?php echo Config::$absolutePath; ?>users">Users</a>
<a href="<?php echo Config::$absolutePath; ?>quicktags">Quick-Tagging</a>
<a href="<?php echo Config::$absolutePath; ?>static/bookmarklet">Bookmarklet</a>
<?php if( Config::$vbbIntegration['enabled'] ) { ?>
<a href="<?php echo Config::$absolutePath; ?>forum/">Forum</a>
<?php } ?>
</div>
<div class="userMenu">
<?php if( $user->id ) { ?>
Hello
<a href="<?php echo Config::$absolutePath; ?>user/<?php echo $user->name; ?>"><?php echo $user->name; ?></a>
(<a href="<?php echo Config::$absolutePath; ?>profile">profile</a> /
<a href="<?php echo Config::$absolutePath; ?>logout">logout</a>)
<?php } else { ?>
Hello Anonymous
(<a href="<?php echo Config::$absolutePath; ?>login">login</a> /
<a href="<?php echo Config::$absolutePath; ?>register">register</a>)
<?php } ?>
<?php if( $user->admin ) { ?>
<br/>Admin:
<a href="<?php echo Config::$absolutePath; ?>comments.php">Comments</a> /
<a href="<?php echo Config::$absolutePath; ?>imageimport.php">Import</a>
<?php } ?>
</div>
<div style="clear:both;"></div>
</div>
<div id="content">

View File

@ -0,0 +1,40 @@
<?php include( $templates.'header.tpl.php' ); ?>
<form action="<?php echo Config::$absolutePath; ?>login" method="post">
<fieldset>
<legend>Login</legend>
<?php if( isset($messages['wrongLogin']) ) { ?>
<div class="warn">
Wrong user or password!
</div>
<?php } ?>
<dl class="form">
<dt>Name:</dt>
<dd>
<input type="text" name="name" value="<?php echo htmlspecialchars($_POST['name']); ?>"/>
</dd>
<dt>Passwort:</dt>
<dd>
<input type="password" name="pass" />
</dd>
<dt>&nbsp;</dt>
<dd>
<input class="check" type="checkbox" name="remember" id="inputRemember" value="1"/>
<label for="inputRemember">Remember me!</label>
</dd>
<dt>&nbsp;</dt>
<dd>
<input type="submit" class="button login" name="login" value="Login" />
</dd>
</dl>
Don't have an account yet? <a href="<?php echo Config::$absolutePath; ?>register">Register!</a>
</fieldset>
</form>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,58 @@
<?php include( $templates.'header.tpl.php' ); ?>
<form action="<?php echo Config::$absolutePath; ?>profile" enctype="multipart/form-data" method="post">
<fieldset>
<legend>Change Profile</legend>
<?php if( isset($messages['passToShort']) ) { ?>
<div class="warn">Your password must be at least 6 characters long!</div>
<?php } ?>
<?php if( isset($messages['passNotEqual']) ) { ?>
<div class="warn">Your both passwords are not equal!</div>
<?php } ?>
<?php if( isset($messages['avatarFailed']) ) { ?>
<div class="warn">Your avatar Image could not be processed!</div>
<?php } ?>
<dl class="form">
<dt>Passwort:</dt>
<dd>
<input type="password" name="cpass" /> (leave empty, if you don't want to change it)
</dd>
<dt>(Repeat)</dt>
<dd>
<input type="password" name="cpass2" />
</dd>
<dt>&nbsp;</dt>
<dd>&nbsp;</dd>
<?php if( empty($user->email) ) { ?>
<dt>E-Mail:</dt>
<dd>
<input type="text" name="email" />
</dd>
<?php } ?>
<dt>Website:</dt>
<dd>
<input type="text" name="website" value="<?php echo htmlspecialchars( $user->website ); ?>"/>
</dd>
<dt>Avatar:</dt>
<dd>
<input type="file" name="avatar" style="color: #000; background-color: #fff;"/><br/>
</dd>
<dt>&nbsp;</dt>
<dd>
<input type="submit" name="save" class="button" value="Save" />
</dd>
</dl>
</fieldset>
</form>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,77 @@
<?php include( $templates.'header.tpl.php' ); ?>
<script type="text/javascript" src="<?php echo Config::$absolutePath; ?>media/quicktags.js"></script>
<h1>
&raquo; Quicktagger
</h1>
<div class="article" id="quickTagIntro">
<h2>Quick tagging?</h2>
<p>
This special site automatically searches for images which are in desperate need of getting tagged.
That is: new images without any or very few tags.
</p>
<p>
This site is carefully designed to allow efficient tagging of images. You don't have to move your hands
away from the keyboard - just write and press enter for the next image. Make sure javascript is
enabled in your browser, or you wont see anything.
</p>
<h2>A few words about tagging</h2>
<p>
If you are unsure what tags to write, just imagine you are searching for this image - what word(s) would you
search for?
</p>
<p>
Also, is there any written text on the image itself? Try to write only the most essential words down. For instance
if you see a motivational with the text:
</p>
<blockquote>
<strong>Huddle House</strong><br/>
For those times when Waffle House isn't quite white trashy enough
</blockquote>
<p>
good tags for this image would be "<em>motivational huddle house white trash</em>"
</p>
<p>
If you don't know what to write, just press enter to skip the image.
</p>
<p>
<strong>Don't abuse the system in any way, or the wrath of the administrator will come done on you!</strong>
</p>
<h2><a href="#" onclick="return quickTagInit();"> &raquo; I get it, let's start already!</a></h2>
</div>
<div id="viewer" class="hidden">
<div id="imageInfo">
<div>
location: <a id="imageLocation" href="#"></a>
</div>
<div>
<div>
Tags: <span id="tags"></span>
</div>
<form class="visible" id="addTag" action="" onsubmit="return quickTag($('logId').value, $('imageId').value, $('tagText'));">
<input type="text" name="tags" id="tagText"/>
<input type="hidden" id="imageId" name="imageId" value="0"/>
<input type="hidden" id="logId" name="logId" value="0"/>
<input type="button" name="save" value="Add Tags" class="button" onclick="quickTag($('logId').value, $('imageId').value, $('tagText'));"/>
</form>
</div>
</div>
<div id="imageContainer">
<img id="image" onclick="swap(this, 'scaled', 'full')" class="scaled" src=""/>
</div>
<br/>
</div>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,6 @@
<?php
header( 'Content-type: text/javascript; charset=utf-8' );
?>
<?php foreach($ib->thumbs as $t ) { ?>
document.write('<a href="<?php echo Config::$frontendPath; ?>all/view/<?php echo $t['keyword']; ?>" target="_blank"><img border="0" src="<?php echo Config::$frontendPath; ?><?php echo $t['thumb']; ?>" alt=""/></a>');
<?php } ?>

View File

@ -0,0 +1,63 @@
<?php include( $templates.'header.tpl.php' ); ?>
<form action="<?php echo Config::$absolutePath; ?>register" method="post">
<fieldset>
<legend>Create Account</legend>
<?php if( isset($messages['nameInUse']) ) { ?>
<div class="warn">This Username is allready registered!</div>
<?php } ?>
<?php if( isset($messages['nameInvalid']) ) { ?>
<div class="warn">Your name must be at least 2 characters long an may not have any special characters!</div>
<?php } ?>
<?php if( isset($messages['passToShort']) ) { ?>
<div class="warn">Your password must be at least 6 characters long!</div>
<?php } ?>
<?php if( isset($messages['passNotEqual']) ) { ?>
<div class="warn">Your both passwords are not equal!</div>
<?php } ?>
<?php if( isset($messages['emailInUse']) ) { ?>
<div class="warn">There is already a registered user with this E-Mail address!</div>
<?php } ?>
<?php if( isset($messages['wrongEmail']) ) { ?>
<div class="warn">Your E-Mail address seems to be invalid!</div>
<?php } ?>
<dl class="form">
<dt>Name:</dt>
<dd>
<input type="text" name="name" value="<?php echo htmlspecialchars($_POST['name']); ?>"/>
Only letters and numbers; at least 2 characters long
</dd>
<dt>E-Mail:</dt>
<dd>
<input type="text" name="email" value="<?php echo htmlspecialchars($_POST['email']); ?>"/>
Must be valid!
</dd>
<dt>Password:</dt>
<dd>
<input type="password" name="pass" class="pass"/>
</dd>
<dt>(Repeat)</dt>
<dd>
<input type="password" name="pass2" class="pass"/>
</dd>
<dt>&nbsp;</dt>
<dd>
<input type="submit" name="register" class="button register" value="Register" />
</dd>
</dl>
</fieldset>
</form>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,7 @@
<?php include( $templates.'header.tpl.php' ); ?>
<div class="article">
<h2>Account successfully created</h2>
<p>In order to activate your account, please check your mail and click on the activation link.</p>
</div>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,11 @@
From: no-reply@picturelicious.net
Subject: Welcome to %siteName%!
Hello %userName%,
thank you for your registration at %siteName%.
To activate your account, please click the following link
%frontendPath%login/%validationString%
Your %siteName% Team

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title><?php echo Config::$siteTitle ?></title>
<link rel="stylesheet" type="text/css" href="<?php echo Config::$absolutePath; ?>media/styles.css" />
<link rel="Shortcut Icon" href="<?php echo Config::$absolutePath; ?>media/favicon.ico"/>
<script type="text/javascript" src="<?php echo Config::$absolutePath; ?>media/general.js"></script>
</head>
<body style="margin: 0.2em 1em 0 1em; padding: 0;">
<h1 class="remotePost"><?php echo Config::$siteName ?></h1>
<?php if( !$user->id ) { ?>
<form action="remotepost.php" method="post">
<em>Name:</em>
<input type="text" name="name" style="width: 80px; margin-right: 10px" value="<?php echo htmlspecialchars($_POST['name']); ?>"/>
<em>Passwort:</em>
<input type="password" style="width: 80px; margin-right: 10px" name="pass" />
<input type="submit" class="button login" name="login" value="Login" />
<input type="hidden" name="remember" value="1"/>
</form>
<?php } else if( $user->isSpamLocked() ) { ?>
<p>Sorry, you are not allowed to post more than 10 Images in 2 Hours.</p>
<?php } else if( $status == 'ready' ) { ?>
<p>Please click on the Image you want to post!</p>
<?php } else if( $status == 'failed' ) { ?>
<p>Sorry, the Image could not be posted for the following reason:</p>
<p><strong><?php echo implode(' ', $uploadErrors); ?></strong></p>
<?php } else if( $status == 'posted' ) { ?>
<p>Image posted! Thank you!</p>
<script type="text/javascript">
if( parent ) {
parent.location = "<?php echo addslashes($_GET['xhrLocation']) ?>#RP_Success";
}
</script>
<?php } ?>
</body>
</html>

View File

@ -0,0 +1,56 @@
<?php include( $templates.'header.tpl.php' ); ?>
<form action="<?php echo Config::$absolutePath; ?>upload" enctype="multipart/form-data" method="POST">
<fieldset>
<legend>Upload / Post</legend>
<p>
Images must be no larger than <strong>4069x4096</strong> and must not exceed <strong>2 MB</strong>.
If the image is already in our Database, the upload will fail. Please follow our rules:
</p>
<ul>
<li> Absolutely NO pictures of child (Less 18 Yrs.), preteen or animal porn.</li>
<li> NO pictures of racist propaganda. No snuff pictures!</li>
<li> NO HARDCORE (porn) contents!!</li>
<li> No crappy low quality pics!</li>
</ul>
<p>You can either upload an Image directly from your Computer, or specify an URL to copy the image From.</p>
<?php if( !empty( $uploadErrors ) ) { ?>
<div class="warn">
There was an issue uploading your image:
<ul>
<?php foreach( $uploadErrors as $msg ) { ?>
<li class="error"><?php echo $msg?></li>
<?php }/*foreach*/?>
</ul>
</div>
<?php }/*if*/?>
<dl class="form">
<dt>File:</dt>
<dd>
<input type="file" name="image" style="color: #000; background-color: #fff;"/>
</dd>
<dt>or URL:</dt>
<dd>
<input type="text" name="url" value="<?php echo htmlspecialchars( $_POST['url'] ); ?>"/>
</dd>
<dt>Tags:</dt>
<dd>
<input type="text" name="tags" value="<?php echo htmlspecialchars( $_POST['tags'] ); ?>"/>
</dd>
<dt>&nbsp;</dt>
<dd>
<input type="submit" name="upload" value="Upload" class="button"/>
</dd>
</dl>
</fieldset>
</form>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,45 @@
<?php include( $templates.'header.tpl.php' ); ?>
<h1>
&raquo; Browsing Users,
Page: <?php echo $ul->pages['current']; ?> of <?php echo $ul->pages['total']; ?>
</h1>
<?php foreach( $ul->users as $i => $u ) { ?>
<div class="userInfo">
<img class="avatar" width="40" height="40" src="<?php echo Config::$absolutePath.$u['avatar']; ?>"/>
<div class="name">
<strong>
<a href="<?php echo Config::$absolutePath.'user/'.$u['name']; ?>"><?php echo $u['name']; ?></a>
</strong>
</div>
<div class="info">
Score: <strong><?php echo $u['score']; ?></strong> /
Images: <strong><?php echo $u['images']; ?></strong>
<?php if( !empty($u['website'])) { ?>/
Website: <strong><a href="<?php echo htmlspecialchars($u['website']); ?>" target="_blank">
<?php echo htmlspecialchars($u['website']); ?>
</a></strong>
<?php } ?>
</div>
<div style="clear:both;"></div>
</div>
<?php } ?>
<div class="userInfo">
<?php if( isset($ul->pages['prev']) ) { ?>
<a href="<?php echo Config::$absolutePath.'users/page/'.$ul->pages['prev']; ?>" class="textPrev" title="Previous">&laquo; Previous</a>
<?php } else { ?>
<div class="textNoPrev">&laquo; Previous</div>
<?php } ?>
<?php if( isset($ul->pages['next']) ) { ?>
<a href="<?php echo Config::$absolutePath.'users/page/'.$ul->pages['next']; ?>" class="textNext" title="Next">Next &raquo;</a>
<?php } else { ?>
<div class="textNoNext">Next &raquo;</div>
<?php } ?>
<div style="clear: both;"></div>
</div>
<?php include( $templates.'footer.tpl.php' ); ?>

View File

@ -0,0 +1,142 @@
<?php include( $templates.'header.tpl.php' ); ?>
<h1>
&raquo; Viewing
<?php if( !empty($iv->user) ) { ?>
User: <a href="<?php echo Config::$absolutePath.'user/'.$iv->user['name']; ?>"><?php echo $iv->user['name']; ?></a>
<?php } else if( !empty($iv->channel) ) { ?>
Channel: <a href="<?php echo Config::$absolutePath.'channel/'.$iv->channel['keyword']; ?>"><?php echo $iv->channel['name']; ?></a>
<?php } else { ?>
All
<?php } ?>
</h1>
<div class="userInfo">
<img class="avatar" width="40" height="40" src="<?php echo Config::$absolutePath.$iv->userInfo['avatar']; ?>"/>
<div class="name">
<strong>
<a href="<?php echo Config::$absolutePath.'user/'.$iv->userInfo['name']; ?>"><?php echo $iv->userInfo['name']; ?></a>
</strong>
</div>
<div class="info">
Score: <strong><?php echo $iv->userInfo['score']; ?></strong> /
Images: <strong><?php echo $iv->userInfo['images']; ?></strong>
<?php if( !empty($iv->userInfo['website'])) { ?>/
Website: <strong><a href="<?php echo htmlspecialchars($iv->userInfo['website']); ?>" target="_blank">
<?php echo htmlspecialchars($iv->userInfo['website']); ?>
</a></strong>
<?php } ?>
</div>
<div style="clear:both;"></div>
</div>
<div id="viewer">
<?php if( isset($iv->stream['prev']) ) { ?>
<a href="<?php echo Config::$absolutePath.$iv->basePath.'view/'.$iv->stream['prev']; ?>" class="prev" id="prevBar" title="Previous">Previous</a>
<?php } else { ?>
<div class="noPrev" id="prevBar">Previous</div>
<?php } ?>
<?php if( isset($iv->stream['next']) ) { ?>
<a href="<?php echo Config::$absolutePath.$iv->basePath.'view/'.$iv->stream['next']; ?>" class="next" id="nextBar" title="Next">Next</a>
<?php } else { ?>
<div class="noNext" id="nextBar">Next</div>
<?php } ?>
<div id="imageContainer">
<img id="image" onclick="swap(this, 'scaled', 'full')" class="scaled" src="<?php echo Config::$absolutePath.Config::$images['imagePath'].$iv->image['path']; ?>" alt="<?php echo htmlspecialchars($iv->image['tags']) ?>"/>
</div>
<div id="imageInfo">
<div class="rating">
<div class="ratingBase">
<div class="ratingCurrent" id="currentRating" style="width: <?php echo $iv->image['votes'] > 0 ? ($iv->image['score']) / 0.05 : 0;?>px"></div>
<div class="ratingRate" id="userRating">
<a href="#" onclick="return rate(<?php echo $iv->image['id'];?>,1);" onmouseout="sr('userRating',0);" onmouseover="sr('userRating',1);"></a>
<a href="#" onclick="return rate(<?php echo $iv->image['id'];?>,2);" onmouseout="sr('userRating',0);" onmouseover="sr('userRating',2);"></a>
<a href="#" onclick="return rate(<?php echo $iv->image['id'];?>,3);" onmouseout="sr('userRating',0);" onmouseover="sr('userRating',3);"></a>
<a href="#" onclick="return rate(<?php echo $iv->image['id'];?>,4);" onmouseout="sr('userRating',0);" onmouseover="sr('userRating',4);"></a>
<a href="#" onclick="return rate(<?php echo $iv->image['id'];?>,5);" onmouseout="sr('userRating',0);" onmouseover="sr('userRating',5);"></a>
</div>
</div>
<div id="loadRating" class="load"></div>
<span id="ratingDescription">
<?php if($iv->image['votes'] > 0 ) { ?>
<?php echo number_format($iv->image['score'],1);?> after <?php echo $iv->image['votes'];?> Vote<?php echo $iv->image['votes'] > 1 ? 's' : '' ?>
<?php } else { ?>
No votes yet!
<?php } ?>
</span>
<div style="clear: both;"></div>
<?php if($user->admin) { ?>
<div style="float:right;" id="del">
<div class="load" id="loadDelete"></div>
<a href="#" onclick="del(<?php echo $iv->image['id']; ?>)">[x]</a>
</div>
<?php } ?>
</div>
<div class="date">
<?php echo date('d. M Y H:i',$iv->image['loggedTS']); ?>
</div>
<div>
Tags: <span id="tags"><?php echo !empty($iv->image['tags']) ? htmlspecialchars($iv->image['tags']) : '<em>none</em>'; ?></span>
<?php if( $user->id ) { ?>
<a href="#" onclick="swap($('addTag'), 'hidden', 'visible'); $('tagText').focus(); return false;">(add)</a>
<form class="hidden" id="addTag" action="" onsubmit="return addTags(<?php echo $iv->image['id']; ?>, $('tagText'), <?php echo $user->admin ? 'true' : 'false';?>);">
<input type="text" name="tags" id="tagText" <?php if($user->admin) {?>value="<?php echo htmlspecialchars($iv->image['tags']);?>"<?php } ?>/>
<input type="button" name="save" value="Add Tags" class="button" onclick="addTags(<?php echo $iv->image['id']; ?>, $('tagText'), <?php echo $user->admin ? 'true' : 'false';?>);"/>
<div id="loadTags" class="load"></div>
</form>
<?php } ?>
</div>
Post in Forum: <input type="text" readonly="1" value="[URL=<?php echo Config::$frontendPath ?>][IMG]<?php echo Config::$frontendPath.Config::$images['imagePath'].$iv->image['path']; ?>[/IMG][/URL]" style="width: 400px; font-size:10px" onclick="this.focus();this.select();"/>
<div class="comments">
<?php if( $iv->commentCount == 1 ) { ?>
<h3>1 Comment:</h3>
<?php } else if( $iv->commentCount > 1 ) { ?>
<h3><?php echo $iv->commentCount ?> Comments:</h3>
<?php } else { ?>
<h3>No comments yet!</h3>
<?php } ?>
<?php foreach( $iv->comments as $c ) { ?>
<div class="comment">
<div class="commentHead">
<img class="avatarSmall" width="16" height="16" src="<?php echo Config::$absolutePath.$c['avatar']; ?>"/>
<a href="<?php echo Config::$absolutePath.'user/'.$c['name']; ?>"><?php echo $c['name']; ?></a>
at <?php echo date('d. M Y H:i',$c['created']); ?>
<?php if($user->admin) { ?>
<div style="float:right;" id="del">
<a href="#" onclick="return delComment(<?php echo $c['id']; ?>, this)">[x]</a>
</div>
<?php } ?>
</div>
<?php echo $c['content']; ?>
</div>
<?php } ?>
<?php if( $user->id ) { ?>
<form method="post" class="addComment" action="<?php echo Config::$absolutePath.$iv->basePath.'view/'.$iv->image['keyword']; ?>">
<div>
<textarea name="content" rows="3" cols="60"></textarea>
<input class="submit" type="submit" name="addComment" value="Submit Comment"/>
</div>
</form>
<?php } ?>
</div>
</div>
</div>
<script type="text/javascript">
ieAdjustHeight(0);
</script>
<?php include( $templates.'footer.tpl.php' ); ?>

10
readme.md Normal file
View File

@ -0,0 +1,10 @@
Picturelicious
==========
A Multiuser Image Gallery written in PHP and MySQL.
More info: http://www.picturelicious.net/
Demo: http://demo.picturelicious.net/
MIT License.