소스 검색

doh.

master
Austin Gillmann 5 년 전
부모
커밋
e594331a15
No known key found for this signature in database GPG 키 ID: 5F5F18DA6D07B04D
11개의 변경된 파일1개의 추가작업 그리고 921개의 파일을 삭제
  1. +1
    -0
      .gitignore
  2. +0
    -21
      build/LICENSE
  3. +0
    -161
      build/README.md
  4. +0
    -241
      build/classes/Response.class.php
  5. +0
    -63
      build/classes/UploadException.class.php
  6. +0
    -32
      build/classes/UploadedFile.class.php
  7. +0
    -0
      build/faq.html
  8. +0
    -19
      build/grill.php
  9. +0
    -30
      build/includes/database.inc.php
  10. +0
    -118
      build/includes/settings.inc.php
  11. +0
    -236
      build/upload.php

+ 1
- 0
.gitignore 파일 보기

@@ -1,3 +1,4 @@
node_modules
dist
dist.zip
build

+ 0
- 21
build/LICENSE 파일 보기

@@ -1,21 +0,0 @@
Copyright (c) 2013, 2014, 2015 Eric Johansson <neku@pomf.se>
Copyright (c) 2013, 2014 Peter Lejeck <peter.lejeck@gmail.com>
Copyright (c) 2015 cenci0 <alchimist94@gmail.com>
Copyright (c) 2015, 2016, 2017 the Pantsu.cat developers <hostmaster@pantsu.cat> <hostmaster@pantsu.cat>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 0
- 161
build/README.md 파일 보기

@@ -1,161 +0,0 @@
# Pomf
[![Build
Status](https://travis-ci.org/pomf/pomf.svg?branch=master)](https://travis-ci.org/pomf/pomf)
[![Dependency
Status](https://david-dm.org/pomf/pomf.svg)](https://david-dm.org/pomf/pomf)
[![devDependency
Status](https://david-dm.org/pomf/pomf/dev-status.svg)](https://david-dm.org/pomf/pomf#info=devDependencies)
[![MIT
licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/pomf/pomf/master/LICENSE)

Pomf is a simple file uploading and sharing platform.

## Features

- One click uploading, no registration required
- A minimal, modern web interface
- Drag & drop supported
- Upload API with multiple response choices
- JSON
- HTML
- Text
- CSV
- Supports [ShareX](https://getsharex.com/) and other screenshot tools

### Demo

See the real world example at [Pantsu.cat](https://pantsu.cat/).

## Requirements

Original development environment is Nginx + PHP5.5 + MySQL, but is confirmed to
work with Apache 2.4 and newer PHP versions. Should work with any other
PDO-compatible database.

## Install

For the purposes of this guide, we won't cover setting up Nginx, PHP, MySQL,
Node, or NPM. So we'll just assume you already have them all running well.

### Compiling

Assuming you already have Node and NPM working, compilation is easy. Use the
following shell code:
```bash
git clone https://github.com/pomf/pomf
cd pomf/
make
make install
```
OR
```bash
make install DESTDIR=/desired/path/for/site
```
After this, the pomf site is now compressed and set up inside `dist/`, or, if specified, `DESTDIR`.

## Configuring

Front-end related settings, such as the name of the site, and maximum allowable
file size, are found in `templates/site_variables.json`. Changes made here will
only take effect after rebuilding the site pages. This may be done by running
`make` from the root of the site directory.

Back-end related settings, such as database configuration, and path for uploaded files, are found in `static/php/includes/settings.inc.php`. Changes made here take effect immediately.

If you intend to allow uploading files larger than 2 MB, you may also need to
increase POST size limits in `php.ini` and webserver configuration. For PHP,
modify `upload_max_filesize` and `post_max_size` values. The configuration
option for nginx webserver is `client_max_body_size`.

Example nginx configs can be found in confs/.

## Using SQLite as DB engine

We need to create the SQLite database before it may be used by pomf.
Fortunately, this is incredibly simple.

First create a directory for the database, e.g. `mkdir /var/db/pomf`.
Then, create a new SQLite database from the schema, e.g. `sqlite3 /var/db/pomf/pomf.sq3 -init /home/pomf/sqlite_schema.sql`.
Then, finally, ensure the permissions are correct, e.g.
```bash
chown nginx:nginx /var/db/pomf
chmod 0750 /var/db/pomf
chmod 0640 /var/db/pomf/pomf.sq3
```

Finally, edit `php/includes/settings.inc.php` to indicate this is the database engine you would like to use. Make the changes outlined below
```php
define('POMF_DB_CONN', '[stuff]'); ---> define('POMF_DB_CONN', 'sqlite:/var/db/pomf/pomf.sq3');`
define('POMF_DB_USER', '[stuff]'); ---> define('POMF_DB_USER', null);
define('POMF_DB_PASS', '[stuff]'); ---> define('POMF_DB_PASS', null);
```

*NOTE: The directory where the SQLite database is stored, must be writable by the web server user*

### Apache

If you are running Apache and want to compress your output when serving files,
add to your `.htaccess` file:

AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/x-javascript application/json

Remember to enable `deflate_module` and `filter_module` modules in your Apache
configuration file.

### Migrating from MySQL to SQLite

For older versions of Pomf you may want to migrate to SQLite. Fortunately, it is incredibly simple to migrate your database. This may be done on a live server, and should require zero downtime.

_If doing this on a live server, you way wish to work in a subdirectory (or vhost, or equivelant), so that any complications or mistakes do not affect your main site.
If you choose not to do so, know that mistakes in the changes outlined below, will only temporarily impact **uploading**, causing **Server error** to be displayed. None of these steps are destructive, and are easily reverted._

Run the following commands as root, to dump your database, and make a SQLite database with the contents.
```bash
mkdir /var/db/pomf
wget -O /tmp/m2s https://github.com/dumblob/mysql2sqlite/raw/master/mysql2sqlite.sh
mysqldump -u OLD_DB_USER -p OLD_DB_PASS pomf | sh /tmp/m2s | sqlite3 /var/db/pomf/sq3
rm /tmp/m2s
chown -R nginx:nginx /var/db/pomf #replace user as appropriate
chmod 0750 /var/db/pomf && chmod 0640 /var/db/pomf/sq3
```
Edit the file `php/includes/settings.inc.php`, in the subdirectory you just made, making the changes outlined below.
```php
define('POMF_DB_CONN', '[stuff]'); ---> define('POMF_DB_CONN', 'sqlite:/var/db/pomf/pomf.sq3');`
define('POMF_DB_USER', '[stuff]'); ---> define('POMF_DB_USER', null);
define('POMF_DB_PASS', '[stuff]'); ---> define('POMF_DB_PASS', null);
```

Then, run `make` to rebuild the website pages, and copy the new `settings.inc.php` file into place.

All done! You may disable or uninstall MySQL if you wish.

## Getting help

The Pomf community gathers on IRC. You can also email the maintainer for help.

- IRC (users): `#pomfret` on Rizon (`irc.rizon.net`)
- Email: <hostmaster@pantsu.cat>

## Contributing

We'd really like if you can take some time to make sure your coding style is
consistent with the project. Pomf follows [PHP
PSR-2](http://www.php-fig.org/psr/psr-2/) and [Airbnb JavaScript
(ES5)](https://github.com/airbnb/javascript/tree/master/es5) (`airbnb/legacy`)
coding style guides. We use ESLint and PHPCS tools to enforce these standards.

You can also help by sending us feature requests or writing documentation and
tests.

Thanks!

## Credits

Pomf was created by Eric Johansson and Peter Lejeck for
[Pomf.se](http://pomf.se/). The software is currently maintained by the
community.

## License

Pomf is free software, and is released under the terms of the Expat license. See
`LICENSE`.

+ 0
- 241
build/classes/Response.class.php 파일 보기

@@ -1,241 +0,0 @@
<?php
/**
* The Response class is a do-it-all for getting responses out in different
* formats.
*
* @todo Create sub-classes to split and extend this god object.
*/
class Response
{
/**
* Indicates response type used for routing.
*
* Valid strings are 'csv', 'html', 'json' and 'text'.
*
* @var string $type Response type
*/
private $type;

/**
* Indicates requested response type.
*
* Valid strings are 'csv', 'html', 'json', 'gyazo' and 'text'.
*
* @param string|null $response_type Response type
*/
public function __construct($response_type = null)
{
switch ($response_type) {
case 'csv':
header('Content-Type: text/csv; charset=UTF-8');
$this->type = $response_type;
break;
case 'html':
header('Content-Type: text/html; charset=UTF-8');
$this->type = $response_type;
break;
case 'json':
header('Content-Type: application/json; charset=UTF-8');
$this->type = $response_type;
break;
case 'gyazo':
header('Content-Type: text/plain; charset=UTF-8');
$this->type = 'text';
break;
case 'text':
header('Content-Type: text/plain; charset=UTF-8');
$this->type = $response_type;
break;
default:
header('Content-Type: application/json; charset=UTF-8');
$this->type = 'json';
$this->error(400, 'Invalid response type. Valid options are: csv, html, json, text.');
break;
}
}

/**
* Routes error messages depending on response type.
*
* @param int $code HTTP status code number.
* @param int $desc Descriptive error message.
* @return void
*/
public function error($code, $desc)
{
$response = null;

switch ($this->type) {
case 'csv':
$response = $this->csvError($desc);
break;
case 'html':
$response = $this->htmlError($code, $desc);
break;
case 'json':
$response = $this->jsonError($code, $desc);
break;
case 'text':
$response = $this->textError($code, $desc);
break;
}

http_response_code(500); // "500 Internal Server Error"
echo $response;
}

/**
* Routes success messages depending on response type.
*
* @param mixed[] $files
* @return void
*/
public function send($files)
{
$response = null;

switch ($this->type) {
case 'csv':
$response = $this->csvSuccess($files);
break;
case 'html':
$response = $this->htmlSuccess($files);
break;
case 'json':
$response = $this->jsonSuccess($files);
break;
case 'text':
$response = $this->textSuccess($files);
break;
}

http_response_code(200); // "200 OK". Success.
echo $response;
}

/**
* Indicates with CSV body the request was invalid.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param int $description Descriptive error message.
* @return string Error message in CSV format.
*/
private static function csvError($description)
{
return '"error"'."\r\n"."\"$description\""."\r\n";
}

/**
* Indicates with CSV body the request was successful.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param mixed[] $files
* @return string Success message in CSV format.
*/
private static function csvSuccess($files)
{
$result = '"name","url","hash","size"'."\r\n";
foreach ($files as $file) {
$result .= '"'.$file['name'].'"'.','.
'"'.$file['url'].'"'.','.
'"'.$file['hash'].'"'.','.
'"'.$file['size'].'"'."\r\n";
}

return $result;
}

/**
* Indicates with HTML body the request was invalid.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param int $code HTTP status code number.
* @param int $description Descriptive error message.
* @return string Error message in HTML format.
*/
private static function htmlError($code, $description)
{
return '<p>ERROR: ('.$code.') '.$description.'</p>';
}

/**
* Indicates with HTML body the request was successful.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param mixed[] $files
* @return string Success message in HTML format.
*/
private static function htmlSuccess($files)
{
$result = '';

foreach ($files as $file) {
$result .= '<a href="'.$file['url'].'">'.$file['url'].'</a><br>';
}

return $result;
}

/**
* Indicates with JSON body the request was invalid.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param int $code HTTP status code number.
* @param int $description Descriptive error message.
* @return string Error message in pretty-printed JSON format.
*/
private static function jsonError($code, $description)
{
return json_encode(array(
'success' => false,
'errorcode' => $code,
'description' => $description,
), JSON_PRETTY_PRINT);
}

/**
* Indicates with JSON body the request was successful.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param mixed[] $files
* @return string Success message in pretty-printed JSON format.
*/
private static function jsonSuccess($files)
{
return json_encode(array(
'success' => true,
'files' => $files,
), JSON_PRETTY_PRINT);
}

/**
* Indicates with plain text body the request was invalid.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param int $code HTTP status code number.
* @param int $description Descriptive error message.
* @return string Error message in plain text format.
*/
private static function textError($code, $description)
{
return 'ERROR: ('.$code.') '.$description;
}

/**
* Indicates with plain text body the request was successful.
*
* @deprecated 2.1.0 Will be renamed to camelCase format.
* @param mixed[] $files
* @return string Success message in plain text format.
*/
private static function textSuccess($files)
{
$result = '';

foreach ($files as $file) {
$result .= $file['url']."\n";
}

return $result;
}
}

+ 0
- 63
build/classes/UploadException.class.php 파일 보기

@@ -1,63 +0,0 @@
<?php

/**
* Returns a human readable error description for file upload errors.
*
* @author Dan Brown <danbrown@php.net>
* @author Michiel Thalen
* @copyright Copyright © 1997 - 2016 by the PHP Documentation Group
* @license
* UploadException is licensed under a Creative Commons Attribution 3.0 License
* or later.
*
* Based on a work at
* https://secure.php.net/manual/en/features.file-upload.errors.php#89374.
*
* You should have received a copy of the Creative Commons Attribution 3.0
* License with this program. If not, see
* <https://creativecommons.org/licenses/by/3.0/>.
*/


class UploadException extends Exception
{
public function __construct($code)
{
$message = $this->codeToMessage($code);
parent::__construct($message, 500);
}

private function codeToMessage($code)
{
switch ($code) {
case UPLOAD_ERR_INI_SIZE:
$message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
break;
case UPLOAD_ERR_FORM_SIZE:
$message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was '.
'specified in the HTML form';
break;
case UPLOAD_ERR_PARTIAL:
$message = 'The uploaded file was only partially uploaded';
break;
case UPLOAD_ERR_NO_FILE:
$message = 'No file was uploaded';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$message = 'Missing a temporary folder';
break;
case UPLOAD_ERR_CANT_WRITE:
$message = 'Failed to write file to disk';
break;
case UPLOAD_ERR_EXTENSION:
$message = 'File upload stopped by extension';
break;

default:
$message = 'Unknown upload error';
break;
}

return $message;
}
}

+ 0
- 32
build/classes/UploadedFile.class.php 파일 보기

@@ -1,32 +0,0 @@
<?php

class UploadedFile
{
/* Public attributes */
public $name;
public $mime;
public $size;
public $tempfile;
public $error;

/**
* SHA-1 checksum
*
* @var string 40 digit hexadecimal hash (160 bits)
*/
private $sha1;

/**
* Generates the SHA-1 or returns the cached SHA-1 hash for the file.
*
* @return string|false $sha1
*/
public function getSha1()
{
if (!$this->sha1) {
$this->sha1 = sha1_file($this->tempfile);
}

return $this->sha1;
}
}

+ 0
- 0
build/faq.html 파일 보기


+ 0
- 19
build/grill.php 파일 보기

@@ -1,19 +0,0 @@
<?php

// Array of image paths, feel free to add/remove to/from this list
$images = array(
'img/2.png',
'img/3.png',
'img/4.png',
'img/5.png',
'img/6.png',
'img/7.png',
'img/8.png',
'img/9.png',
'img/10.png',
);

// Redirect to a random image from the above array using status code "303 See Other"
if (headers_sent() === false) {
header('Location: '.$images[array_rand($images)], true, 303);
}

+ 0
- 30
build/includes/database.inc.php 파일 보기

@@ -1,30 +0,0 @@
<?php

/**
* Prepares a PDO connection between Pomf and a database server.
*
* @copyright Copyright (c) 2013 Peter Lejeck <peter.lejeck@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

require_once 'settings.inc.php';

/* NOTE: we don't have to unref the PDO because we're not long-running */
$db = new PDO(POMF_DB_CONN, POMF_DB_USER, POMF_DB_PASS);

+ 0
- 118
build/includes/settings.inc.php 파일 보기

@@ -1,118 +0,0 @@
<?php

/**
* User configurable settings for Pomf.
*
* @copyright Copyright (c) 2013, 2014 Peter Lejeck <peter.lejeck@gmail.com>
* @copyright Copyright (c) 2015 cenci0 <alchimist94@gmail.com>
* @copyright Copyright (c) 2015, 2016, 2017 the Pantsu.cat developers <hostmaster@pantsu.cat>
* <hostmaster@pantsu.cat>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/**
* PDO connection socket
*
* Database connection to use for communication. Currently, MySQL is the only
* DSN prefix supported.
*
* @see http://php.net/manual/en/ref.pdo-mysql.connection.php PHP manual for
* PDO_MYSQL DSN.
* @param string POMF_DB_CONN DSN:host|unix_socket=hostname|path;dbname=database
*/
define('POMF_DB_CONN', 'mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=pomf');

/**
* PDO database login credentials
*/

/** @param string POMF_DB_NAME Database username */
define('POMF_DB_USER', 'pomf');
/** @param string POMF_DB_PASS Database password */
define('POMF_DB_PASS', '');

/**
* File system location where to store uploaded files
*
* @param string Path to directory with trailing delimiter
*/
define('POMF_FILES_ROOT', '/mnt/pantsu/http/files/');

/**
* Maximum number of iterations while generating a new filename
*
* Pomf uses an algorithm to generate random filenames. Sometimes a file may
* exist under a randomly generated filename, so we count tries and keep trying.
* If this value is exceeded, we give up trying to generate a new filename.
*
* @param int POMF_FILES_RETRIES Number of attempts to retry
*/
define('POMF_FILES_RETRIES', 15);

/**
* The length of generated filename (without file extension)
*
* @param int POMF_FILES_LENGTH Number of random alphabetical ASCII characters
* to use
*/
define('POMF_FILES_LENGTH', 6);

/**
* URI to prepend to links for uploaded files
*
* @param string POMF_URL URI with trailing delimiter
*/
define('POMF_URL', 'https://i.pantsu.cat/');

/**
* URI for filename generation
*
* @param string characters to be used in generateName()
*/
define('ID_CHARSET', 'abcdefghijklmnopqrstuvwxyz');


/**
* Filtered mime types
* @param string[] $FILTER_MIME allowed/blocked mime types
*/
$FILTER_MIME = array();
/**
* Filter mode: whitelist (true) or blacklist (false)
* @param bool $FILTER_MODE mime type filter mode
*/
$FILTER_MODE = false;
/**
* Double dot file extensions
*
* Pomf keeps the last file extension for the uploaded file. In other words, an
* uploaded file with `.tar.gz` extension will be given a random filename which
* ends in `.gz` unless configured here to ignore discards for `.tar.gz`.
*
* @param string[] $doubledots Array of double dot file extensions strings
* without the first prefixing dot
*/
$doubledots = array_map('strrev', array(
'tar.gz',
'tar.bz',
'tar.bz2',
'tar.xz',
'user.js',
));

+ 0
- 236
build/upload.php 파일 보기

@@ -1,236 +0,0 @@
<?php
session_start();

/**
* Handles POST uploads, generates filenames, moves files around and commits
* uploaded metadata to database.
*/

require_once 'classes/Response.class.php';
require_once 'classes/UploadException.class.php';
require_once 'classes/UploadedFile.class.php';
require_once 'includes/database.inc.php';

/**
* Generates a random name for the file, retrying until we get an unused one.
*
* @param UploadedFile $file
*
* @return string
*/
function generateName($file)
{
global $db;
global $doubledots;

// We start at N retries, and --N until we give up
$tries = POMF_FILES_RETRIES;
$length = POMF_FILES_LENGTH;
$ext = pathinfo($file->name, PATHINFO_EXTENSION);

// Check if extension is a double-dot extension and, if true, override $ext
$revname = strrev($file->name);
foreach ($doubledots as $ddot) {
if (stripos($revname, $ddot) === 0) {
$ext = strrev($ddot);
}
}

do {
// Iterate until we reach the maximum number of retries
if ($tries-- === 0) {
throw new Exception(
'Gave up trying to find an unused name',
500
); // HTTP status code "500 Internal Server Error"
}

$chars = ID_CHARSET;
$name = '';
for ($i = 0; $i < $length; ++$i) {
$name .= $chars[mt_rand(0, strlen($chars))];
}

// Add the extension to the file name
if (isset($ext) && $ext !== '') {
$name .= '.'.$ext;
}

// Check if a file with the same name does already exist in the database
$q = $db->prepare('SELECT COUNT(filename) FROM files WHERE filename = (:name)');
$q->bindValue(':name', $name, PDO::PARAM_STR);
$q->execute();
$result = $q->fetchColumn();
// If it does, generate a new name
} while ($result > 0);

return $name;
}

/**
* Handles the uploading and db entry for a file.
*
* @param UploadedFile $file
*
* @return array
*/
function uploadFile($file)
{
global $db;
global $FILTER_MODE;
global $FILTER_MIME;

// Handle file errors
if ($file->error) {
throw new UploadException($file->error);
}

// Check if mime type is blocked
if (!empty($FILTER_MIME)) {
if ($FILTER_MODE == true) { //whitelist mode
if (!in_array($file->mime, $FILTER_MIME)) {
throw new UploadException(UPLOAD_ERR_EXTENSION);
}
} else { //blacklist mode
if (in_array($file->mime, $FILTER_MIME)) {
throw new UploadException(UPLOAD_ERR_EXTENSION);
}
}
}


// Check if a file with the same hash and size (a file which is the same)
// does already exist in the database; if it does, return the proper link
// and data. PHP deletes the temporary file just uploaded automatically.
$q = $db->prepare('SELECT filename, COUNT(*) AS count FROM files WHERE hash = (:hash) '.
'AND size = (:size)');
$q->bindValue(':hash', $file->getSha1(), PDO::PARAM_STR);
$q->bindValue(':size', $file->size, PDO::PARAM_INT);
$q->execute();
$result = $q->fetch();
if ($result['count'] > 0) {
return array(
'hash' => $file->getSha1(),
'name' => $file->name,
'url' => POMF_URL.rawurlencode($result['filename']),
'size' => $file->size,
);
}

// Generate a name for the file
$newname = generateName($file);

// Store the file's full file path in memory
$uploadFile = POMF_FILES_ROOT . $newname;

// Attempt to move it to the static directory
if (!move_uploaded_file($file->tempfile, $uploadFile)) {
throw new Exception(
'Failed to move file to destination',
500
); // HTTP status code "500 Internal Server Error"
}

// Need to change permissions for the new file to make it world readable
if (!chmod($uploadFile, 0644)) {
throw new Exception(
'Failed to change file permissions',
500
); // HTTP status code "500 Internal Server Error"
}

// Add it to the database
if (empty($_SESSION['id'])) {
// Query if user is NOT logged in
$q = $db->prepare('INSERT INTO files (hash, originalname, filename, size, date, ' .
'expire, delid) VALUES (:hash, :orig, :name, :size, :date, ' .
':exp, :del)');
} else {
// Query if user is logged in (insert user id together with other data)
$q = $db->prepare('INSERT INTO files (hash, originalname, filename, size, date, ' .
'expire, delid, user) VALUES (:hash, :orig, :name, :size, :date, ' .
':exp, :del, :user)');
$q->bindValue(':user', $_SESSION['id'], PDO::PARAM_INT);
}

// Common parameters binding
$q->bindValue(':hash', $file->getSha1(), PDO::PARAM_STR);
$q->bindValue(':orig', strip_tags($file->name), PDO::PARAM_STR);
$q->bindValue(':name', $newname, PDO::PARAM_STR);
$q->bindValue(':size', $file->size, PDO::PARAM_INT);
$q->bindValue(':date', date('Y-m-d'), PDO::PARAM_STR);
$q->bindValue(':exp', null, PDO::PARAM_STR);
$q->bindValue(':del', sha1($file->tempfile), PDO::PARAM_STR);
$q->execute();

return array(
'hash' => $file->getSha1(),
'name' => $file->name,
'url' => POMF_URL.rawurlencode($newname),
'size' => $file->size,
);
}

/**
* Reorder files array by file.
*
* @param $_FILES
*
* @return array
*/
function diverseArray($files)
{
$result = array();

foreach ($files as $key1 => $value1) {
foreach ($value1 as $key2 => $value2) {
$result[$key2][$key1] = $value2;
}
}

return $result;
}

/**
* Reorganize the $_FILES array into something saner.
*
* @param $_FILES
*
* @return array
*/
function refiles($files)
{
$result = array();
$files = diverseArray($files);

foreach ($files as $file) {
$f = new UploadedFile();
$f->name = $file['name'];
$f->mime = $file['type'];
$f->size = $file['size'];
$f->tempfile = $file['tmp_name'];
$f->error = $file['error'];
//$f->expire = $file['expire'];
$result[] = $f;
}

return $result;
}

$type = isset($_GET['output']) ? $_GET['output'] : 'json';
$response = new Response($type);

if (isset($_FILES['files'])) {
$uploads = refiles($_FILES['files']);

try {
foreach ($uploads as $upload) {
$res[] = uploadFile($upload);
}
$response->send($res);
} catch (Exception $e) {
$response->error($e->getCode(), $e->getMessage());
}
} else {
$response->error(400, 'No input file(s)');
}

불러오는 중...
취소
저장