Initial commit
219
image-grid-examples.html
Normal 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
@ -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><script type="text/javascript" src="http://example.com/random/4/64x64/"></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
@ -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
@ -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
|
||||
|
52
picturelicious/comments.php
Normal 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' );
|
||||
?>
|
BIN
picturelicious/data/avatars/default.png
Normal file
After Width: | Height: | Size: 340 B |
57
picturelicious/imageimport.php
Normal 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
@ -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
@ -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 "{}";
|
||||
?>
|
72
picturelicious/lib/cache.php
Normal 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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
323
picturelicious/lib/class.forumops.php
Normal 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);
|
||||
?>
|
112
picturelicious/lib/config.php
Normal 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
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
90
picturelicious/lib/filesystem.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
172
picturelicious/lib/gridview.php
Normal 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 );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
145
picturelicious/lib/imagebrowser.php
Normal 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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
61
picturelicious/lib/imagecatalog.php
Normal 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() {
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
98
picturelicious/lib/images.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
170
picturelicious/lib/imageuploader.php
Normal 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;
|
||||
}
|
||||
}
|
||||
?>
|
122
picturelicious/lib/imageviewer.php
Normal 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']) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
41
picturelicious/lib/keyword.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
57
picturelicious/lib/userlist.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
295
picturelicious/lib/users.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
BIN
picturelicious/media/color.png
Normal file
After Width: | Height: | Size: 156 B |
BIN
picturelicious/media/colorpicker-h.png
Normal file
After Width: | Height: | Size: 206 B |
BIN
picturelicious/media/colorpicker-select-h.png
Normal file
After Width: | Height: | Size: 90 B |
BIN
picturelicious/media/colorpicker-select-sv.png
Normal file
After Width: | Height: | Size: 131 B |
BIN
picturelicious/media/colorpicker-sv.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
picturelicious/media/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
picturelicious/media/loading.gif
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
picturelicious/media/logo.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
picturelicious/media/next.png
Normal file
After Width: | Height: | Size: 436 B |
400
picturelicious/media/picturelicious.js
Normal 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;
|
||||
}
|
146
picturelicious/media/post.js.php
Normal 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();
|
BIN
picturelicious/media/prev.png
Normal file
After Width: | Height: | Size: 397 B |
44
picturelicious/media/quicktags.js
Normal 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;
|
||||
}
|
58
picturelicious/media/remotepost.css
Normal 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;
|
||||
}
|
BIN
picturelicious/media/search.png
Normal file
After Width: | Height: | Size: 264 B |
BIN
picturelicious/media/star-base.png
Normal file
After Width: | Height: | Size: 616 B |
BIN
picturelicious/media/star-current.png
Normal file
After Width: | Height: | Size: 782 B |
BIN
picturelicious/media/star-rate.png
Normal file
After Width: | Height: | Size: 998 B |
587
picturelicious/media/styles.css
Normal 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;
|
||||
}
|
||||
|
27
picturelicious/remotepost.php
Normal 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' );
|
||||
|
||||
?>
|
21
picturelicious/static/bookmarklet.html.php
Normal file
@ -0,0 +1,21 @@
|
||||
<h1>» 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>):
|
||||
» <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> «
|
||||
</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>
|
8
picturelicious/templates/404.tpl.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php include( $templates.'header.tpl.php' ); ?>
|
||||
|
||||
|
||||
<div class="warn">No Images found</div>
|
||||
|
||||
|
||||
|
||||
<?php include( $templates.'footer.tpl.php' ); ?>
|
77
picturelicious/templates/browse.tpl.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php include( $templates.'header.tpl.php' ); ?>
|
||||
|
||||
<h1>
|
||||
» 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' ); ?>
|
9
picturelicious/templates/footer.tpl.php
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
Copyright © <?php echo date('Y'); ?> <?php echo Config::$siteName; ?>. All Rights Reserved
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
67
picturelicious/templates/header.tpl.php
Normal 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">
|
||||
|
||||
|
||||
|
||||
|
40
picturelicious/templates/login.tpl.php
Normal 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> </dt>
|
||||
<dd>
|
||||
<input class="check" type="checkbox" name="remember" id="inputRemember" value="1"/>
|
||||
<label for="inputRemember">Remember me!</label>
|
||||
</dd>
|
||||
|
||||
<dt> </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' ); ?>
|
58
picturelicious/templates/profile.tpl.php
Normal 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> </dt>
|
||||
<dd> </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> </dt>
|
||||
<dd>
|
||||
<input type="submit" name="save" class="button" value="Save" />
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<?php include( $templates.'footer.tpl.php' ); ?>
|
77
picturelicious/templates/quicktags.tpl.php
Normal 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>
|
||||
» 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();"> » 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' ); ?>
|
6
picturelicious/templates/random.js.php
Normal 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 } ?>
|
63
picturelicious/templates/register.tpl.php
Normal 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> </dt>
|
||||
<dd>
|
||||
<input type="submit" name="register" class="button register" value="Register" />
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<?php include( $templates.'footer.tpl.php' ); ?>
|
7
picturelicious/templates/registered.tpl.php
Normal 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' ); ?>
|
11
picturelicious/templates/registrationmail.txt
Normal 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
|
41
picturelicious/templates/remotepost.tpl.php
Normal 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>
|
56
picturelicious/templates/upload.tpl.php
Normal 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> </dt>
|
||||
<dd>
|
||||
<input type="submit" name="upload" value="Upload" class="button"/>
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<?php include( $templates.'footer.tpl.php' ); ?>
|
45
picturelicious/templates/userlist.tpl.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php include( $templates.'header.tpl.php' ); ?>
|
||||
<h1>
|
||||
» 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">« Previous</a>
|
||||
<?php } else { ?>
|
||||
<div class="textNoPrev">« 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 »</a>
|
||||
<?php } else { ?>
|
||||
<div class="textNoNext">Next »</div>
|
||||
<?php } ?>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
|
||||
<?php include( $templates.'footer.tpl.php' ); ?>
|
142
picturelicious/templates/view.tpl.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php include( $templates.'header.tpl.php' ); ?>
|
||||
|
||||
<h1>
|
||||
» 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' ); ?>
|