it's not dead!!!

This commit is contained in:
flash 2016-07-26 19:29:53 +02:00
parent 888b22f14a
commit 8f84d1eedc
69 changed files with 585 additions and 577 deletions

19
.gitignore vendored
View file

@ -1,9 +1,16 @@
BingSiteAuth.xml
google*.html
/config/config.ini
/cache/*
!/cache/.sakura
# Libraries
/vendor
/node_modules
# Configuration
/config/config.ini
# Cache
/cache/*
!/cache/.gitkeep
# OS specific shit
[Tt]humbs.db
Desktop.ini
[Dd]esktop.ini
$RECYCLE.BIN/
.DS_Store

70
app/Config.php Normal file
View file

@ -0,0 +1,70 @@
<?php
/**
* Holds the configuration manager.
*
* @package Sakura
*/
namespace Sakura;
/**
* Handles the configuration settings of Sakura.
*
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Config
{
/**
* Storage for the parsed config file
*
* @var array
*/
private static $config = [];
/**
* Initialiser, parses the configuration.
*
* @param string $path Path to the configuration file.
*/
public static function init($path)
{
// Check if the configuration file exists
if (!file_exists($path)) {
throw new Exception('Configuration file does not exist');
}
// Attempt to load the configuration file
$config = parse_ini_file($path, true);
if (is_array($config)) {
self::$config = $config;
} else {
throw new Exception('Failed to parse configuration');
}
}
/**
* Get a value from the configuration.
*
* @param string $key Configuration section.
* @param string $subkey Configuration key.
*
* @return array|string Configuration value.
*/
public static function get($section, $key = null)
{
// Check if the key that we're looking for exists
if (array_key_exists($section, self::$config)) {
if ($key) {
// If we also have a subkey return the proper data
return self::$config[$section][$key];
}
// else we just return the default value
return self::$config[$section];
}
throw new Exception("Couldn't find configuration value");
}
}

View file

@ -22,7 +22,7 @@ class ServeCommand extends Command
$document_root = addslashes(ROOT . 'public/');
$router_proxy = addslashes(ROOT . 'server.php');
$php_dir = PHP_BINDIR;
$host = Config::local('dev', 'host');
$host = config('dev.host');
exec("{$php_dir}/php -S {$host} -t {$document_root} {$router_proxy}");
}

View file

@ -94,14 +94,6 @@ class AuthController extends Controller
// Preliminarily set login to failed
$redirect = Router::route('auth.login');
// Check if authentication is disallowed
if (Config::get('lock_authentication')) {
$message = 'Logging in is disabled for security checkups! Try again later.';
Template::vars(compact('message', 'redirect'));
return Template::render('global/information');
}
// Get request variables
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : null;
$password = isset($_REQUEST['password']) ? $_REQUEST['password'] : null;
@ -175,20 +167,20 @@ class AuthController extends Controller
// Generate a session key
$sessionKey = $session->create($remember);
$cookiePrefix = config('cookie.prefix');
// User ID cookie
setcookie(
Config::get('cookie_prefix') . 'id',
"{$cookiePrefix}id",
$user->id,
time() + 604800,
Config::get('cookie_path')
time() + 604800
);
// Session ID cookie
setcookie(
Config::get('cookie_prefix') . 'session',
"{$cookiePrefix}session",
$sessionKey,
time() + 604800,
Config::get('cookie_path')
time() + 604800
);
$this->touchRateLimit($user->id, true);
@ -240,7 +232,7 @@ class AuthController extends Controller
$redirect = Router::route('auth.register');
// Check if authentication is disallowed
if (Config::get('lock_authentication') || Config::get('disable_registration')) {
if (config('user.disable_registration')) {
$message = 'Registration is disabled for security checkups! Try again later.';
Template::vars(compact('message', 'redirect'));
@ -261,43 +253,10 @@ class AuthController extends Controller
$username = isset($_POST['username']) ? $_POST['username'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : null;
$terms = isset($_POST['tos']);
// Append username and email to the redirection url
$redirect .= "?username={$username}&email={$email}";
// Check if the user agreed to the ToS
if (!$terms) {
$message = 'You are required to agree to the Terms of Service.';
Template::vars(compact('message', 'redirect'));
return Template::render('global/information');
}
// Check if we require a captcha
if (Config::get('recaptcha')) {
// Get secret key from the config
$secret = Config::get('recaptcha_private');
// Attempt to verify the captcha
$response = Net::fetch("https://google.com/recaptcha/api/siteverify?secret={$secret}&response={$captcha}");
// Attempt to decode as json
if ($response) {
$response = json_decode($response);
}
if (!$response || !$response->success) {
$message = 'Captcha verification failed, please try again.';
Template::vars(compact('message', 'redirect'));
return Template::render('global/information');
}
}
// Attempt to get account data
$user = User::construct(clean_string($username, true, true));
@ -312,7 +271,7 @@ class AuthController extends Controller
}
// Username too short
if (strlen($username) < Config::get('username_min_length')) {
if (strlen($username) < config('user.name_min')) {
$message = 'Your name must be at least 3 characters long.';
Template::vars(compact('message', 'redirect'));
@ -321,7 +280,7 @@ class AuthController extends Controller
}
// Username too long
if (strlen($username) > Config::get('username_max_length')) {
if (strlen($username) > config('user.name_max')) {
$message = 'Your name can\'t be longer than 16 characters.';
Template::vars(compact('message', 'redirect'));
@ -360,7 +319,7 @@ class AuthController extends Controller
}
// Check password entropy
if (password_entropy($password) < Config::get('min_entropy')) {
if (password_entropy($password) < config('user.pass_min_entropy')) {
$message = 'Your password is too weak, try adding some special characters.';
Template::vars(compact('message', 'redirect'));
@ -369,8 +328,8 @@ class AuthController extends Controller
}
// Set a few variables
$requireActive = Config::get('require_activation');
$ranks = $requireActive ? [1] : [2];
$requireActive = config('user.require_activation');
$ranks = $requireActive ? [config('rank.inactive')] : [config('rank.regular')];
// Create the user
$user = User::create($username, $password, $email, $ranks);
@ -385,7 +344,7 @@ class AuthController extends Controller
$redirect = Router::route('auth.login');
$message = $requireActive
? 'Your registration went through! An activation e-mail has been sent.'
: 'Your registration went through! Welcome to ' . Config::get('sitename') . '!';
: 'Your registration went through! Welcome to ' . config('general.name') . '!';
Template::vars(compact('message', 'redirect'));
@ -439,8 +398,8 @@ class AuthController extends Controller
}
// Get the ids for deactivated and default user ranks
$rankDefault = Config::get('default_rank_id');
$rankDeactive = Config::get('deactive_rank_id');
$rankDefault = config('rank.regular');
$rankDeactive = config('rank.inactive');
// Add normal user, remove deactivated and set normal as default
$user->addRanks([$rankDefault]);
@ -448,7 +407,7 @@ class AuthController extends Controller
$user->removeRanks([$rankDeactive]);
$redirect = Router::route('auth.login');
$message = "Your account is activated, welcome to " . Config::get('sitename') . "!";
$message = "Your account is activated, welcome to " . config('general.name') . "!";
Template::vars(compact('message', 'redirect'));
@ -475,15 +434,6 @@ class AuthController extends Controller
// Preliminarily set registration to failed
$redirect = Router::route('auth.reactivate');
// Check if authentication is disallowed
if (Config::get('lock_authentication')) {
$message = "You can't request a reactivation at this time, sorry!";
Template::vars(compact('message', 'redirect'));
return Template::render('global/information');
}
// Validate session
if (!isset($_POST['session']) || $_POST['session'] != session_id()) {
$message = "Your session expired, refreshing the page will most likely fix this!";
@ -555,15 +505,6 @@ class AuthController extends Controller
// Preliminarily set action to failed
$redirect = Router::route('main.index');
// Check if authentication is disallowed
if (Config::get('lock_authentication')) {
$message = "You can't request a reactivation at this time, sorry!";
Template::vars(compact('message', 'redirect'));
return Template::render('global/information');
}
// Validate session
if (!isset($_POST['session']) || $_POST['session'] != session_id()) {
$message = "Your session expired, refreshing the page will most likely fix this!";
@ -603,7 +544,7 @@ class AuthController extends Controller
if ($key && $password) {
// Check password entropy
if (password_entropy($password) < Config::get('min_entropy')) {
if (password_entropy($password) < config('user.pass_min_entropy')) {
$message = "Your password doesn't meet the strength requirements!";
Template::vars(compact('message', 'redirect'));
@ -661,11 +602,11 @@ class AuthController extends Controller
// Generate activation key
$activate = ActionCode::generate('ACTIVATE', $user->id);
$siteName = Config::get('sitename');
$baseUrl = "http://" . Config::get('url_main');
$siteName = config('general.name');
$baseUrl = "http://{$_SERVER['HTTP_HOST']}";
$activateLink = Router::route('auth.activate') . "?u={$user->id}&k={$activate}";
$profileLink = Router::route('user.profile', $user->id);
$signature = Config::get('mail_signature');
$signature = config('mail.signature');
// Build the e-mail
$message = "Welcome to {$siteName}!\r\n\r\n"
@ -696,10 +637,10 @@ class AuthController extends Controller
// Generate the verification key
$verk = ActionCode::generate('LOST_PASS', $user->id);
$siteName = Config::get('sitename');
$baseUrl = "http://" . Config::get('url_main');
$siteName = config('general.name');
$baseUrl = "http://{$_SERVER['HTTP_HOST']}";
$reactivateLink = Router::route('auth.resetpassword') . "?u={$user->id}&k={$verk}";
$signature = Config::get('mail_signature');
$signature = config('mail.signature');
// Build the e-mail
$message = "Hello {$user->username},\r\n\r\n"

View file

@ -39,8 +39,8 @@ class CommentsController extends Controller
// Checks
$text = $_POST['text'] ?? '';
$length = strlen($text);
$tooShort = $length < Config::get('comment_min_length');
$tooLong = $length > Config::get('comment_max_length');
$tooShort = $length < config('comments.min_length');
$tooLong = $length > config('comments.max_length');
if ($tooShort || $tooLong) {
$fill = $tooShort ? "short" : "long";

View file

@ -46,9 +46,9 @@ class FileController extends Controller
public function avatar($id = 0)
{
$noAvatar = ROOT . str_replace(
'{{ TPL }}',
'%tplname%',
Template::$name,
Config::get('no_avatar_img')
config('user.avatar_none')
);
$none = [
'name' => basename($noAvatar),
@ -57,9 +57,9 @@ class FileController extends Controller
];
$deactivePath = ROOT . str_replace(
'{{ TPL }}',
'%tplname%',
Template::$name,
Config::get('deactivated_avatar_img')
config('user.avatar_inactive')
);
$deactive = [
'name' => basename($deactivePath),
@ -68,9 +68,9 @@ class FileController extends Controller
];
$bannedPath = ROOT . str_replace(
'{{ TPL }}',
'%tplname%',
Template::$name,
Config::get('banned_avatar_img')
config('user.avatar_ban')
);
$banned = [
'name' => basename($bannedPath),
@ -108,7 +108,7 @@ class FileController extends Controller
*/
public function background($id = 0)
{
$noBg = ROOT . Config::get('no_background_img');
$noBg = ROOT . "public/content/pixel.png";
$none = [
'name' => basename($noBg),
'data' => file_get_contents($noBg),
@ -143,7 +143,7 @@ class FileController extends Controller
*/
public function header($id = 0)
{
$noHeader = ROOT . Config::get('no_header_img');
$noHeader = ROOT . "public/content/pixel.png";
$none = [
'name' => basename($noHeader),
'data' => file_get_contents($noHeader),

View file

@ -36,7 +36,7 @@ class ForumController extends Controller
{
// Get the most active threads
$activeThreadsIds = DB::table('posts')
->where('forum_id', '!=', Config::get('forum_trash_id'))
->where('forum_id', '!=', config('forum.trash'))
->groupBy('topic_id')
->orderByRaw('COUNT(*) DESC')
->limit(10)
@ -70,7 +70,7 @@ class ForumController extends Controller
// Get the latest posts
$latestPostsIds = DB::table('posts')
->where('forum_id', '!=', Config::get('forum_trash_id'))
->where('forum_id', '!=', config('forum.trash'))
->orderBy('post_id', 'desc')
->limit(10)
->get(['post_id']);
@ -102,7 +102,7 @@ class ForumController extends Controller
// Get the most active poster
$activePosterId = DB::table('posts')
->where('forum_id', '!=', Config::get('forum_trash_id'))
->where('forum_id', '!=', config('forum.trash'))
->where('post_time', '>', time() - (24 * 60 * 60))
->groupBy('poster_id')
->orderByRaw('COUNT(*) DESC')
@ -378,7 +378,7 @@ class ForumController extends Controller
case 'delete':
// Get the id of the trash forum
$trash = Config::get('forum_trash_id');
$trash = config('forum.trash');
// Check if we're operating from the trash
if ($thread->forum == $trash) {
@ -547,8 +547,8 @@ class ForumController extends Controller
// Length
$length = strlen($text);
$minLen = Config::get('forum_text_min');
$maxLen = Config::get('forum_text_max');
$minLen = config('forum.min_post_length');
$maxLen = config('forum.max_post_length');
$tooShort = $length < $minLen;
$tooLong = $length > $maxLen;
@ -624,10 +624,10 @@ class ForumController extends Controller
// Length
$titleLength = strlen($title);
$textLength = strlen($text);
$titleMin = Config::get('forum_title_min');
$titleMax = Config::get('forum_title_max');
$textMin = Config::get('forum_text_min');
$textMax = Config::get('forum_text_max');
$titleMin = config('forum.min_title_length');
$titleMax = config('forum.max_title_length');
$textMin = config('forum.min_post_length');
$textMax = config('forum.max_post_length');
// Checks
$titleTooShort = $titleLength < $titleMin;
@ -740,10 +740,10 @@ class ForumController extends Controller
// Length
$titleLength = strlen($title);
$textLength = strlen($text);
$titleMin = Config::get('forum_title_min');
$titleMax = Config::get('forum_title_max');
$textMin = Config::get('forum_text_min');
$textMax = Config::get('forum_text_max');
$titleMin = config('forum.min_title_length');
$titleMax = config('forum.max_title_length');
$textMin = config('forum.min_post_length');
$textMax = config('forum.max_post_length');
// Checks
$titleTooShort = $title !== null

View file

@ -30,15 +30,14 @@ class MetaController extends Controller
{
// Get the newest user
$newestUserId = DB::table('users')
->where('rank_main', '!=', Config::get('restricted_rank_id'))
->where('rank_main', '!=', Config::get('deactive_rank_id'))
->whereNotIn('rank_main', [config('rank.banned'), config('rank.inactive')])
->orderBy('user_id', 'desc')
->limit(1)
->get(['user_id']);
$newestUser = User::construct($newestUserId ? $newestUserId[0]->user_id : 0);
// Get all the currently online users
$timeRange = time() - Config::get('max_online_time');
$timeRange = time() - 120;
// Create a storage variable
$onlineUsers = [];
@ -61,23 +60,23 @@ class MetaController extends Controller
}
// Get news
$news = new Category(Config::get('site_news_category'));
$news = new Category(config('general.news'));
// Merge index specific stuff with the global render data
Template::vars([
'news' => $news->posts(Config::get('front_page_news_posts')),
'news' => $news->posts(3),
'stats' => [
'userCount' => DB::table('users')
->where('password_algo', '!=', 'disabled')
->whereNotIn('rank_main', [Config::get('deactive_rank_id'), Config::get('restricted_rank_id')])
->whereNotIn('rank_main', [config('rank.banned'), config('rank.inactive')])
->count(),
'newestUser' => $newestUser,
'lastRegDate' => date_diff(
date_create(date('Y-m-d', $newestUser->registered)),
date_create(date('Y-m-d'))
)->format('%a'),
'topicCount' => DB::table('topics')->where('forum_id', '!=', Config::get('forum_trash_id'))->count(),
'postCount' => DB::table('posts')->where('forum_id', '!=', Config::get('forum_trash_id'))->count(),
'topicCount' => DB::table('topics')->where('forum_id', '!=', config('forum.trash'))->count(),
'postCount' => DB::table('posts')->where('forum_id', '!=', config('forum.trash'))->count(),
'onlineUsers' => $onlineUsers,
],
]);
@ -112,6 +111,7 @@ class MetaController extends Controller
/**
* Handles the info pages.
* Deprecate this!!
*
* @param string $id The page ID from the database.
*

View file

@ -25,7 +25,7 @@ class NewsController extends Controller
// Check if the category is set
if ($category === '') {
// Fetch the default category from the config
$category = Config::get('site_news_category');
$category = config('general.news');
}
// Create the category object

View file

@ -43,8 +43,8 @@ class PremiumController extends Controller
*/
public function index()
{
$price = Config::get('premium_price_per_month');
$amountLimit = Config::get('premium_amount_max');
$price = config('premium.price_per_month');
$amountLimit = config('premium.max_months_at_once');
Template::vars(compact('price', 'amountLimit'));
@ -75,7 +75,7 @@ class PremiumController extends Controller
}
// Fetch the limit
$amountLimit = Config::get('premium_amount_max');
$amountLimit = config('premium.max_months_at_once');
// Check months
if ($months < 1
@ -88,10 +88,10 @@ class PremiumController extends Controller
return Template::render('global/information');
}
$pricePerMonth = Config::get('premium_price_per_month');
$pricePerMonth = config('premium.price_per_month');
$total = number_format($pricePerMonth * $months, 2, '.', '');
$siteName = Config::get('sitename');
$siteName = config('general.name');
$multiMonths = $months !== 1 ? 's' : '';
$siteUrl = 'http'

View file

@ -109,14 +109,14 @@ class AccountController extends Controller
}
// Check if the username is too short
if (strlen($username_clean) < Config::get('username_min_length')) {
if (strlen($username_clean) < config('user.name_min')) {
$message = "This username is too short!";
Template::vars(compact('redirect', 'message'));
return Template::render('global/information');
}
// Check if the username is too long
if (strlen($username_clean) > Config::get('username_max_length')) {
if (strlen($username_clean) > config('user.name_max')) {
$message = "This username is too long!";
Template::vars(compact('redirect', 'message'));
return Template::render('global/information');
@ -125,7 +125,7 @@ class AccountController extends Controller
// Check if this username hasn't been used in the last amount of days set in the config
$getOld = DB::table('username_history')
->where('username_old_clean', $username_clean)
->where('change_time', '>', (Config::get('old_username_reserve') * 24 * 60 * 60))
->where('change_time', '>', (config('user.name_reserve') * 24 * 60 * 60))
->orderBy('change_id', 'desc')
->get();
@ -249,7 +249,7 @@ class AccountController extends Controller
}
// Check password entropy
if (password_entropy($password) < Config::get('min_entropy')) {
if (password_entropy($password) < config('user.pass_min_entropy')) {
$message = "Your password isn't strong enough!";
Template::vars(compact('redirect', 'message'));
return Template::render('global/information');
@ -282,10 +282,11 @@ class AccountController extends Controller
$mode = $_POST['mode'] ?? null;
$locked = [
Config::get('deactive_rank_id'),
Config::get('default_rank_id'),
Config::get('premium_rank_id'),
Config::get('restricted_rank_id'),
config('rank.inactive'),
config('rank.regular'),
config('rank.premium'),
config('rank.alumni'),
config('rank.banned'),
];
if ($session && $rank && $mode) {

View file

@ -63,11 +63,13 @@ class AppearanceController extends Controller
return "Please upload a valid image!";
}
$confp = $mode === 'header' ? 'cover' : $mode;
// Check dimensions
$minWidth = Config::get("{$mode}_min_width");
$minHeight = Config::get("{$mode}_min_height");
$maxWidth = Config::get("{$mode}_max_width");
$maxHeight = Config::get("{$mode}_max_height");
$minWidth = config("file.{$confp}.min_width");
$minHeight = config("file.{$confp}.min_height");
$maxWidth = config("file.{$confp}.max_width");
$maxHeight = config("file.{$confp}.max_height");
if ($meta[0] < $minWidth
|| $meta[1] < $minHeight
@ -78,7 +80,7 @@ class AppearanceController extends Controller
}
// Check file size
$maxFileSize = Config::get("{$mode}_max_fsize");
$maxFileSize = config("file.{$confp}.max_file_size");
if (filesize($tmpName) > $maxFileSize) {
$maxSizeFmt = byte_symbol($maxFileSize);

View file

@ -93,10 +93,10 @@ class UserController extends Controller
}
// Get the active rank
$rank = array_key_exists($rank, $ranks) ? $rank : ($rank ? 0 : intval(Config::get('default_rank_id')));
$rank = array_key_exists($rank, $ranks) ? $rank : ($rank ? 0 : intval(config("rank.regular")));
// Get members per page
$membersPerPage = Config::get('members_per_page');
$membersPerPage = 30;
// Set parse variables
Template::vars(compact('ranks', 'rank', 'membersPerPage'));

View file

@ -8,7 +8,6 @@
namespace Sakura\Forum;
use Sakura\BBcode;
use Sakura\Config;
use Sakura\DB;
use Sakura\Exception;
use Sakura\Net;
@ -196,14 +195,6 @@ class Post
*/
public function update()
{
// Check if the data meets the requirements
if (strlen($this->subject) < Config::get('forum_title_min')
|| strlen($this->subject) > Config::get('forum_title_max')
|| strlen($this->text) < Config::get('forum_text_min')
|| strlen($this->text) > Config::get('forum_text_max')) {
return null;
}
// Create a thread object
$thread = new Thread($this->thread);

View file

@ -45,8 +45,8 @@ class Payments
try {
self::$paypal = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
Config::get('paypal_client_id'),
Config::get('paypal_secret')
config("paypal.client_id"),
config("paypal.secret_id")
)
);
} catch (\Exception $e) {
@ -55,7 +55,7 @@ class Payments
// Set the configuration
self::$paypal->setConfig([
'mode' => Config::get('paypal_mode'),
'mode' => config("paypal.mode"),
]);
return true;

View file

@ -65,7 +65,7 @@ class Template
self::$name = $name;
// Set reources path
self::$resources = Config::get('content_path') . '/data/' . self::$name;
self::$resources = '/content/data/' . self::$name;
// Reinitialise
self::init();
@ -83,8 +83,8 @@ class Template
$twigEnv = [];
// Enable caching
if (Config::get('enable_tpl_cache')) {
$twigEnv['cache'] = ROOT . 'cache/twig';
if (config("performance.template_cache")) {
$twigEnv['cache'] = ROOT . config("performance.cache_dir") . 'twig';
}
// And now actually initialise the templating engine
@ -99,13 +99,7 @@ class Template
}));
// Add config function
self::$engine->addFunction(new Twig_SimpleFunction('config', function ($name, $local = false) {
if ($local) {
$name = explode('.', $name);
return Config::local($name[0], $name[1]);
}
return Config::get($name);
}));
self::$engine->addFunction(new Twig_SimpleFunction('config', 'config'));
// Add resource function
self::$engine->addFunction(new Twig_SimpleFunction('resource', function ($path = "") {

View file

@ -445,7 +445,7 @@ class User
}
// Otherwise use the standard method
return $this->lastOnline > (time() - Config::get('max_online_time'));
return $this->lastOnline > (time() - 120);
}
/**
@ -965,8 +965,8 @@ class User
public function isPremium()
{
// Get rank IDs from the db
$premiumRank = (int) Config::get('premium_rank_id');
$defaultRank = (int) Config::get('default_rank_id');
$premiumRank = (int) config('rank.premium');
$defaultRank = (int) config('rank.regular');
// Fetch expiration date
$expire = $this->premiumInfo()->expire;

View file

View file

@ -22,7 +22,7 @@
},
"autoload": {
"psr-4": {
"Sakura\\": "libraries/"
"Sakura\\": "app/"
},
"files": [
"utility.php"

341
composer.lock generated
View file

@ -4,32 +4,37 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "74d0e0231a20998b63636505d174d1d2",
"hash": "765ea465939a65048ac736e4fbc6c167",
"content-hash": "1af681873ad63e53d42dfd445d67b388",
"packages": [
{
"name": "corneltek/class-template",
"version": "2.1.2",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/c9s/ClassTemplate.git",
"reference": "4bdb46a6b1a5245118e7bf08b4cdacdfdaadb77b"
"reference": "31a6281e5664b00a3f9dd6141f112c908e9a29e9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/c9s/ClassTemplate/zipball/4bdb46a6b1a5245118e7bf08b4cdacdfdaadb77b",
"reference": "4bdb46a6b1a5245118e7bf08b4cdacdfdaadb77b",
"url": "https://api.github.com/repos/c9s/ClassTemplate/zipball/31a6281e5664b00a3f9dd6141f112c908e9a29e9",
"reference": "31a6281e5664b00a3f9dd6141f112c908e9a29e9",
"shasum": ""
},
"require": {
"corneltek/codegen": "^2",
"corneltek/codegen": "^3.0.0",
"php": ">=5.3.0",
"twig/twig": "^1"
"twig/twig": "^1.22"
},
"require-dev": {
"corneltek/phpunit-testmore": "dev-master"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"ClassTemplate\\": "src/ClassTemplate/"
@ -48,40 +53,45 @@
],
"description": "Class template Utilities",
"homepage": "http://github.com/c9s/ClassTemplate",
"time": "2015-09-06 05:04:14"
"time": "2016-06-10 16:07:48"
},
{
"name": "corneltek/cliframework",
"version": "2.8.1",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/c9s/CLIFramework.git",
"reference": "7ca1239bb032f5cd1d746974954adde0233900ce"
"reference": "b776b4619aa4df24e3112d4e0535972276be80fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/c9s/CLIFramework/zipball/7ca1239bb032f5cd1d746974954adde0233900ce",
"reference": "7ca1239bb032f5cd1d746974954adde0233900ce",
"url": "https://api.github.com/repos/c9s/CLIFramework/zipball/b776b4619aa4df24e3112d4e0535972276be80fd",
"reference": "b776b4619aa4df24e3112d4e0535972276be80fd",
"shasum": ""
},
"require": {
"corneltek/class-template": "^2",
"corneltek/codegen": "^2",
"corneltek/getoptionkit": "^2",
"corneltek/universal": ">= 1.4",
"corneltek/class-template": "^3.0.0",
"corneltek/codegen": "^3.0.0",
"corneltek/getoptionkit": "^2.4",
"corneltek/universal": "^1.7",
"php": ">=5.3.0",
"pimple/pimple": "*",
"symfony/class-loader": "^2.7",
"symfony/finder": "^2.7"
"symfony/class-loader": "^2.8|3.0",
"symfony/finder": "^2.8|3.0"
},
"require-dev": {
"corneltek/phpunit-testmore": "dev-master",
"satooshi/php-coveralls": "dev-master"
"satooshi/php-coveralls": "^1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"CLIFramework\\": "src/CLIFramework/"
"CLIFramework\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -105,26 +115,26 @@
"getopt",
"zsh"
],
"time": "2015-11-07 11:01:47"
"time": "2016-06-11 12:24:41"
},
{
"name": "corneltek/codegen",
"version": "2.7.1",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/c9s/CodeGen.git",
"reference": "b2a1835b4a0c63cb5f1c1c0a44176adbbfd46dcd"
"reference": "b7e7abb5d3eb339c30b751ff30c6b7caa3641880"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/c9s/CodeGen/zipball/b2a1835b4a0c63cb5f1c1c0a44176adbbfd46dcd",
"reference": "b2a1835b4a0c63cb5f1c1c0a44176adbbfd46dcd",
"url": "https://api.github.com/repos/c9s/CodeGen/zipball/b7e7abb5d3eb339c30b751ff30c6b7caa3641880",
"reference": "b7e7abb5d3eb339c30b751ff30c6b7caa3641880",
"shasum": ""
},
"require": {
"doctrine/inflector": "*",
"php": ">=5.3.0",
"twig/twig": "^1 >=1.21"
"twig/twig": "^1.21"
},
"require-dev": {
"corneltek/phpunit-testmore": "dev-master"
@ -132,7 +142,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8.x-dev"
"dev-master": "3.0.x-dev"
}
},
"autoload": {
@ -147,26 +157,25 @@
"authors": [
{
"name": "Yo-An Lin",
"email": "yoanlin93@gmail.com",
"homepage": "http://c9s.me"
"email": "yoanlin93@gmail.com"
}
],
"description": "PHP Code Generation Library",
"homepage": "http://github.com/c9s/CodeGen",
"time": "2016-03-26 07:10:40"
"time": "2016-06-10 15:32:20"
},
{
"name": "corneltek/getoptionkit",
"version": "2.2.5",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/c9s/GetOptionKit.git",
"reference": "977b11bf1f44a02398ecfc96cf2fc913cb9f017b"
"reference": "076cc41051d6417bf9304fe92f8d9793edac9910"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/c9s/GetOptionKit/zipball/977b11bf1f44a02398ecfc96cf2fc913cb9f017b",
"reference": "977b11bf1f44a02398ecfc96cf2fc913cb9f017b",
"url": "https://api.github.com/repos/c9s/GetOptionKit/zipball/076cc41051d6417bf9304fe92f8d9793edac9910",
"reference": "076cc41051d6417bf9304fe92f8d9793edac9910",
"shasum": ""
},
"require": {
@ -174,12 +183,17 @@
},
"require-dev": {
"corneltek/phpunit-testmore": "dev-master",
"satooshi/php-coveralls": "dev-master"
"satooshi/php-coveralls": "^1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5.x-dev"
}
},
"autoload": {
"psr-4": {
"GetOptionKit\\": "src/GetOptionKit/"
"GetOptionKit\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -189,26 +203,25 @@
"authors": [
{
"name": "Yo-An Lin",
"email": "cornelius.howl@gmail.com",
"homepage": "http://c9s.me"
"email": "cornelius.howl@gmail.com"
}
],
"description": "Powerful command-line option toolkit",
"homepage": "http://github.com/c9s/GetOptionKit",
"time": "2016-02-16 10:41:32"
"time": "2016-07-18 07:44:29"
},
{
"name": "corneltek/universal",
"version": "1.7.2",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/c9s/Universal.git",
"reference": "7815546cc524f6eac84d8f7620510e9277252d78"
"url": "https://github.com/corneltek/Universal.git",
"reference": "7b69d656be18d6b1d01a5a672141c80b43b5c2f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/c9s/Universal/zipball/7815546cc524f6eac84d8f7620510e9277252d78",
"reference": "7815546cc524f6eac84d8f7620510e9277252d78",
"url": "https://api.github.com/repos/corneltek/Universal/zipball/7b69d656be18d6b1d01a5a672141c80b43b5c2f3",
"reference": "7b69d656be18d6b1d01a5a672141c80b43b5c2f3",
"shasum": ""
},
"require": {
@ -216,9 +229,14 @@
},
"require-dev": {
"corneltek/phpunit-testmore": "dev-master",
"satooshi/php-coveralls": "dev-master"
"satooshi/php-coveralls": "^1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Universal\\": "src/Universal/"
@ -231,13 +249,12 @@
"authors": [
{
"name": "Yo-An Lin",
"email": "cornelius.howl@gmail.com",
"homepage": "http://c9s.me"
"email": "yoanlin93@gmail.com"
}
],
"description": "Universal library for PHP",
"homepage": "http://github.com/c9s/Universal",
"time": "2015-11-07 10:32:02"
"homepage": "http://github.com/corneltek/Universal",
"time": "2016-06-11 11:51:45"
},
{
"name": "doctrine/annotations",
@ -710,16 +727,16 @@
},
{
"name": "illuminate/container",
"version": "v5.2.28",
"version": "v5.2.37",
"source": {
"type": "git",
"url": "https://github.com/illuminate/container.git",
"reference": "1e156f8017490f5583ab161030bf839c77c95e54"
"reference": "7ec395833738b9059f829348ddc9a59d0118ac88"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/1e156f8017490f5583ab161030bf839c77c95e54",
"reference": "1e156f8017490f5583ab161030bf839c77c95e54",
"url": "https://api.github.com/repos/illuminate/container/zipball/7ec395833738b9059f829348ddc9a59d0118ac88",
"reference": "7ec395833738b9059f829348ddc9a59d0118ac88",
"shasum": ""
},
"require": {
@ -749,20 +766,20 @@
],
"description": "The Illuminate Container package.",
"homepage": "http://laravel.com",
"time": "2016-03-16 17:19:17"
"time": "2016-05-29 02:18:23"
},
{
"name": "illuminate/contracts",
"version": "v5.2.28",
"version": "v5.2.37",
"source": {
"type": "git",
"url": "https://github.com/illuminate/contracts.git",
"reference": "411b851962c211078ade7664a6976e77a78cd2a5"
"reference": "f4f44d7c6d20404da8dfc655bd3d6dd788dfdce5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/411b851962c211078ade7664a6976e77a78cd2a5",
"reference": "411b851962c211078ade7664a6976e77a78cd2a5",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/f4f44d7c6d20404da8dfc655bd3d6dd788dfdce5",
"reference": "f4f44d7c6d20404da8dfc655bd3d6dd788dfdce5",
"shasum": ""
},
"require": {
@ -791,20 +808,20 @@
],
"description": "The Illuminate Contracts package.",
"homepage": "http://laravel.com",
"time": "2016-03-07 20:37:17"
"time": "2016-05-31 21:36:13"
},
{
"name": "illuminate/database",
"version": "v5.2.28",
"version": "v5.2.37",
"source": {
"type": "git",
"url": "https://github.com/illuminate/database.git",
"reference": "1ea9f36cef011a80b1623ea3566d57017e7913bc"
"reference": "c0746930dc6a6ff9b72945152609d61a3b3829c6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/database/zipball/1ea9f36cef011a80b1623ea3566d57017e7913bc",
"reference": "1ea9f36cef011a80b1623ea3566d57017e7913bc",
"url": "https://api.github.com/repos/illuminate/database/zipball/c0746930dc6a6ff9b72945152609d61a3b3829c6",
"reference": "c0746930dc6a6ff9b72945152609d61a3b3829c6",
"shasum": ""
},
"require": {
@ -851,20 +868,20 @@
"orm",
"sql"
],
"time": "2016-04-01 18:17:22"
"time": "2016-06-06 13:12:46"
},
{
"name": "illuminate/support",
"version": "v5.2.28",
"version": "v5.2.37",
"source": {
"type": "git",
"url": "https://github.com/illuminate/support.git",
"reference": "e4aa03c5f26db752e838354a7d71b85e6138f4ec"
"reference": "6e86ac2b4e3d0c42c2dc846dbac3e74d378a812b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/e4aa03c5f26db752e838354a7d71b85e6138f4ec",
"reference": "e4aa03c5f26db752e838354a7d71b85e6138f4ec",
"url": "https://api.github.com/repos/illuminate/support/zipball/6e86ac2b4e3d0c42c2dc846dbac3e74d378a812b",
"reference": "6e86ac2b4e3d0c42c2dc846dbac3e74d378a812b",
"shasum": ""
},
"require": {
@ -907,7 +924,7 @@
],
"description": "The Illuminate Support package.",
"homepage": "http://laravel.com",
"time": "2016-03-30 18:18:45"
"time": "2016-05-30 02:40:53"
},
{
"name": "jbbcode/jbbcode",
@ -1052,22 +1069,23 @@
},
{
"name": "paypal/rest-api-sdk-php",
"version": "v1.6.4",
"version": "1.7.4",
"source": {
"type": "git",
"url": "https://github.com/paypal/PayPal-PHP-SDK.git",
"reference": "06837d290c4906578cfd92786412dff330a1429c"
"reference": "d62e8db407827229c6c7aabfa54792d0113b99e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paypal/PayPal-PHP-SDK/zipball/06837d290c4906578cfd92786412dff330a1429c",
"reference": "06837d290c4906578cfd92786412dff330a1429c",
"url": "https://api.github.com/repos/paypal/PayPal-PHP-SDK/zipball/d62e8db407827229c6c7aabfa54792d0113b99e4",
"reference": "d62e8db407827229c6c7aabfa54792d0113b99e4",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"php": ">=5.3.0"
"php": ">=5.3.0",
"psr/log": "1.0.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
@ -1096,20 +1114,20 @@
"rest",
"sdk"
],
"time": "2016-01-20 17:45:52"
"time": "2016-07-15 20:42:18"
},
{
"name": "phpmailer/phpmailer",
"version": "v5.2.14",
"version": "v5.2.16",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "e774bc9152de85547336e22b8926189e582ece95"
"reference": "1d85f9ef3ecfc42bbc4f3c70d5e37ca9a65f629a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e774bc9152de85547336e22b8926189e582ece95",
"reference": "e774bc9152de85547336e22b8926189e582ece95",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/1d85f9ef3ecfc42bbc4f3c70d5e37ca9a65f629a",
"reference": "1d85f9ef3ecfc42bbc4f3c70d5e37ca9a65f629a",
"shasum": ""
},
"require": {
@ -1120,8 +1138,7 @@
"phpunit/phpunit": "4.7.*"
},
"suggest": {
"league/oauth2-client": "Needed for XOAUTH2 authentication",
"league/oauth2-google": "Needed for Gmail XOAUTH2"
"league/oauth2-google": "Needed for Google XOAUTH2 authentication"
},
"type": "library",
"autoload": {
@ -1157,7 +1174,7 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2015-11-01 10:15:28"
"time": "2016-06-06 09:09:37"
},
{
"name": "phroute/phroute",
@ -1250,30 +1267,67 @@
"time": "2015-09-11 15:10:35"
},
{
"name": "symfony/class-loader",
"version": "v2.8.4",
"name": "psr/log",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
"reference": "7d362c22710980730d46a5d039e788946a2938cb"
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/7d362c22710980730d46a5d039e788946a2938cb",
"reference": "7d362c22710980730d46a5d039e788946a2938cb",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2012-12-21 11:40:51"
},
{
"name": "symfony/class-loader",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
"reference": "05ad69969796955102e42b12d13ad73fc6dadaaf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/05ad69969796955102e42b12d13ad73fc6dadaaf",
"reference": "05ad69969796955102e42b12d13ad73fc6dadaaf",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-apcu": "~1.1"
"php": ">=5.5.9"
},
"require-dev": {
"symfony/finder": "~2.0,>=2.0.5|~3.0.0"
"symfony/finder": "~2.8|~3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
"dev-master": "3.0-dev"
}
},
"autoload": {
@ -1300,29 +1354,29 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
"time": "2016-03-10 19:33:53"
"time": "2015-11-26 07:02:09"
},
{
"name": "symfony/finder",
"version": "v2.8.4",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1"
"reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1",
"reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1",
"url": "https://api.github.com/repos/symfony/finder/zipball/3577eb98dba90721d1a0a3edfc6956ab8b1aecee",
"reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
"dev-master": "3.0-dev"
}
},
"autoload": {
@ -1349,73 +1403,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2016-03-10 10:53:53"
},
{
"name": "symfony/polyfill-apcu",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-apcu.git",
"reference": "0c901e4e65a2f7ece68f0fd249b56d6ad3adc214"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/0c901e4e65a2f7ece68f0fd249b56d6ad3adc214",
"reference": "0c901e4e65a2f7ece68f0fd249b56d6ad3adc214",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting apcu_* functions to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"apcu",
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2016-03-03 16:49:40"
"time": "2015-10-30 23:35:59"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.1.1",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "1289d16209491b584839022f29257ad859b8532d"
"reference": "dff51f72b0706335131b00a7f49606168c582594"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
"reference": "1289d16209491b584839022f29257ad859b8532d",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
"reference": "dff51f72b0706335131b00a7f49606168c582594",
"shasum": ""
},
"require": {
@ -1427,7 +1428,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
"dev-master": "1.2-dev"
}
},
"autoload": {
@ -1461,20 +1462,20 @@
"portable",
"shim"
],
"time": "2016-01-20 09:13:37"
"time": "2016-05-18 14:26:46"
},
{
"name": "symfony/translation",
"version": "v3.0.4",
"version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2"
"reference": "d63a94528530c3ea5ff46924c8001cec4a398609"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/f7a07af51ea067745a521dab1e3152044a2fb1f2",
"reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2",
"url": "https://api.github.com/repos/symfony/translation/zipball/d63a94528530c3ea5ff46924c8001cec4a398609",
"reference": "d63a94528530c3ea5ff46924c8001cec4a398609",
"shasum": ""
},
"require": {
@ -1498,7 +1499,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-master": "3.1-dev"
}
},
"autoload": {
@ -1525,20 +1526,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2016-03-25 01:41:20"
"time": "2016-06-29 05:41:56"
},
{
"name": "twig/twig",
"version": "v1.24.0",
"version": "v1.24.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
"reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
"shasum": ""
},
"require": {
@ -1586,7 +1587,7 @@
"keywords": [
"templating"
],
"time": "2016-01-25 21:22:18"
"time": "2016-05-30 09:11:59"
}
],
"packages-dev": [],

View file

@ -1,34 +1,173 @@
; Example Sakura configuration
; Rename this file to config.ini after you're done editing.
; Database configuration according to https://laravel.com/docs/5.2/database#introduction
; Put some here in advance, uncomment the one you need.
[database]
driver = mysql
;; mysql
;driver = mysql
;host = localhost
;port = 3306
;username = sakura
;password = password
;prefix = sakura_
;database = sakura-development
;charset = utf8
;collation = utf8_unicode_ci
host = localhost
;; sqlite
;driver = sqlite
;database = sakura.sq3
;prefix = sakura_
port = 3306
;; postgres
;driver = pgsql
;host = localhost
;port = 5432
;username = sakura
;password = password
;prefix = sakura_
;database = sakura-development
;charset = utf8
;schema = public
username = sakura
; General site settings
[general]
; Name of the site
name = Sakura
password = "password"
; Design used by the site, must be a folder in templates/
design = yuuno
; Category to be used for site news
news = site-news
; Cover to be used when no other one is specified
cover =
; Close the site for maintenance
maintenance = false
; Cookie settings
[cookie]
prefix = sakura_
database = sakura-development
; Performance settings
[performance]
; Compress output using gzip, recommended to turn this off while debugging
compression = true
charset = utf8
; Cache directory
cache_dir = cache/
collation = utf8_unicode_ci
; Enable template caching
template_cache = true
; Development mode settings
; Development specific settings
[dev]
; Show detailed error logs in browser
show_errors = true
show_errors = false
; Show a small version of the changelog loaded from sakura.flash.moe
show_changelog = true
show_changelog = false
; Host for the mahou serve command
host = localhost:8000
; Mailing settings
[mail]
contact_address = sakura@localhost
signature = Sakura | http://localhost/
; SMTP settings
[mail.smtp]
auth = false
from = sakura-noreply@localhost
name = Sakura
reply_to = sakura-admin@localhost
reply_name = Administrator
username =
password =
server =
port = 25
secure = true
; File settings
[file]
upload_dir = uploads/
; Avatar requirements
[file.avatar]
max_file_size = 2097152
max_height = 512
max_width = 512
; Background requirements
[file.background]
max_file_size = 5242880
max_height = 1440
max_width = 2560
; Cover requirements
[file.cover]
max_file_size = 2097152
max_height = 500
max_width = 2048
; User settings
[user]
; Avatars
avatar_ban = public/content/data/%tplname%/images/banned-av.png
avatar_none = public/content/data/%tplname%/images/no-av.png
avatar_inactive = public/content/data/%tplname%/images/deactivated-av.png
; Username constraints
name_min = 3
name_max = 16
; Disable registration, just in case
disable_registration = false
; Require the user to click a link in an e-mail sent to them
require_activation = true
; Minimum entropy value a password needs to have
pass_min_entropy = 1
; How long a username should be reserved in days
name_reserve = 90
; How long a user should be inactive till another person can use their name
name_takeover = 365
; Premium settings
[premium]
max_months_at_once = 24
price_per_month = 2.00
price_unit = EUR
; Paypal settings
[paypal]
mode = sandbox
client_id =
secret_id =
; Ranks ids
[rank]
inactive = 1
regular = 2
premium = 8
alumni = 9
banned = 10
; Forum settings
[forum]
max_post_length = 60000
min_post_length = 1
max_title_length = 128
min_title_length = 4
; Id of the trash forum
trash = 19
; Comment settings
[comments]
min_length = 500
min_length = 1

13
gulpfile.js Normal file
View file

@ -0,0 +1,13 @@
var
elixir = require('laravel-elixir'),
elixirTypscript = require('elixir-typescript'),
nodePath = '../../../node_modules/';
elixir(function(mix) {
mix
.less('app.less')
.typescript('**/*.ts', 'public/js/app.js')
.scripts([
nodePath + 'turbolinks/dist/turbolinks.js'
], 'public/js/libs.js');
});

View file

@ -1,148 +0,0 @@
<?php
/**
* Holds the configuration manager.
*
* @package Sakura
*/
namespace Sakura;
/**
* Handles both the local and database stored configuration sides of Sakura.
*
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Config
{
/**
* Container for the parsed local configuration.
*
* @var array
*/
private static $local = [];
/**
* Cache for the configuration stored in the database.
*
* @var array
*/
private static $database = [];
/**
* Initialiser, parses the local configuration.
*
* @param string $local Path to the configuration file.
*/
public static function init($local)
{
// Check if the configuration file exists
if (!file_exists($local)) {
trigger_error('Local configuration file does not exist', E_USER_ERROR);
}
// Attempt to load the configuration file
$local = parse_ini_file($local, true);
// Check if $local is an array and then store it in $local
if (is_array($local)) {
self::$local = $local;
} else {
// Otherwise trigger an error
trigger_error(
'Failed to load local configuration file,' .
' check the structure of the file to see if you made mistake somewhere',
E_USER_ERROR
);
}
}
/**
* Get a value from the local configuration file.
*
* @param string $key Configuration section.
* @param string $subkey Configuration key.
*
* @return array|string Configuration value.
*/
public static function local($key, $subkey = null)
{
// Check if the key that we're looking for exists
if (array_key_exists($key, self::$local)) {
if ($subkey) {
// If we also have a subkey return the proper data
return self::$local[$key][$subkey];
}
// else we just return the default value
return self::$local[$key];
}
// If it doesn't exist trigger an error to avoid explosions
trigger_error(
'Unable to get local configuration value "' . $key . '"',
E_USER_ERROR
);
return null;
}
/**
* Get a configuration value from the database.
*
* @param string $key Configuration key.
* @param string $default Value that gets used when the value doesn't exist.
*
* @return string Configuration value.
*/
public static function get($key, $default = null)
{
// Check if the key that we're looking for exists
if (array_key_exists($key, self::$database)) {
// Then return the value
return self::$database[$key];
} else {
// Get the record from the database
$value = DB::table('config')
->where('config_name', $key)
->get();
// Check if it exists
if ($value) {
self::$database[$key] = $value[0]->config_value;
return self::$database[$key];
}
}
// If we fell all the way down here set the bundled default value
Config::set($key, $default);
// And then return default that value
return $default;
}
public static function set($key, $value)
{
// Unset the cached copy
if (array_key_exists($key, self::$database)) {
unset(self::$database[$key]);
}
// Check if the value already exists
$exists = DB::table('config')
->where('config_name', $key)
->count();
// If it exists run an update
if ($exists) {
DB::table('config')
->where('config_name', $key)
->update(['config_value' => $value]);
} else {
DB::table('config')
->insert(['config_name' => $key, 'config_value' => $value]);
}
// Return the value
return $value;
}
}

15
package.json Normal file
View file

@ -0,0 +1,15 @@
{
"private": true,
"scripts": {
"prod": "gulp --production",
"dev": "gulp watch"
},
"devDependencies": {
"gulp": "^3.9.1",
"laravel-elixir": "^5.0.0",
"elixir-typescript": "^2.0.0"
},
"dependencies": {
"turbolinks": "^5.0.0"
}
}

Binary file not shown.

View file

@ -30,15 +30,11 @@ Router::filter('loginCheck', function () {
// Maintenance check
Router::filter('maintenance', function () {
if (Config::get('site_closed')) {
if (config('general.maintenance')) {
ActiveUser::$session->destroy();
http_response_code(503);
$message = Config::get('site_closed_reason');
Template::vars(compact('message'));
return Template::render('global/maintenance');
}
});

View file

@ -1,6 +1,6 @@
<?php
/*
* Sakura Community Management System
* Community Management System
* (c) 2013-2016 Julian van de Groep <http://flash.moe>
*/
@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', 20160425);
define('SAKURA_VERSION', 20160726);
// Define Sakura Path
define('ROOT', __DIR__ . '/');
@ -43,42 +43,19 @@ Config::init(ROOT . 'config/config.ini');
set_error_handler('error_handler');
// Change error reporting according to the dev configuration
error_reporting(Config::local('dev', 'show_errors') ? -1 : 0);
error_reporting(config('dev.show_errors') ? -1 : 0);
// Create a new database capsule
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule = new DB;
// Add the connection
$capsule->addConnection(Config::local('database'));
$capsule->addConnection(config('database'));
// Make the capsule globally accessible
$capsule->setAsGlobal();
// Check if we the system has a cron service
if (Config::get('no_cron_service')) {
// If not do an "asynchronous" call to the cron.php script
if (Config::get('no_cron_last') < (time() - Config::get('no_cron_interval'))) {
$phpDir = PHP_BINDIR;
$cronPath = ROOT . 'cron.php';
// Check OS
if (substr(strtolower(PHP_OS), 0, 3) == 'win') {
$cronPath = addslashes($cronPath);
pclose(popen("start /B {$phpDir}\php.exe {$cronPath}", 'r'));
} else {
pclose(popen("{$phpDir}/php {$cronPath} > /dev/null 2>/dev/null &", 'r'));
}
unset($phpDir, $cronPath);
// Update last execution time
Config::set('no_cron_last', time());
}
}
// Start output buffering
ob_start(Config::get('use_gzip') ? 'ob_gzhandler' : null);
ob_start(config('performance.compression') ? 'ob_gzhandler' : null);
// Initialise the router
Router::init();
@ -87,15 +64,14 @@ Router::init();
include_once ROOT . 'routes.php';
// Initialise the current session
$cookiePrefix = Config::get('cookie_prefix');
ActiveUser::init(
intval($_COOKIE["{$cookiePrefix}id"] ?? 0),
$_COOKIE["{$cookiePrefix}session"] ?? ''
);
$cookiePrefix = config('cookie.prefix');
// ActiveUser::init(
// intval($_COOKIE["{$cookiePrefix}id"] ?? 0),
// $_COOKIE["{$cookiePrefix}session"] ?? ''
// );
if (!defined('SAKURA_NO_TPL')) {
// Start templating engine
Template::set(Config::get('site_style'));
Template::set(config('general.design'));
// Set base page rendering data
Template::vars([
@ -104,6 +80,5 @@ if (!defined('SAKURA_NO_TPL')) {
'post' => $_POST,
'server' => $_SERVER,
'request' => $_REQUEST,
'session' => $_SESSION,
//'session' => $_SESSION,
]);
}

View file

@ -6,10 +6,24 @@
use Sakura\Config;
use Sakura\Net;
// Sort of aias for Config::get
function config($value)
{
$split = explode('.', $value);
$key = array_pop($split);
$section = implode('.', $split);
try {
return Config::get($section, $key);
} catch (Exception $e) {
return Config::get($value);
}
}
function clean_string($string, $lower = false, $noSpecial = false, $replaceSpecial = '')
{
// Run common sanitisation function over string
$string = htmlentities($string, ENT_NOQUOTES | ENT_HTML401, Config::get('charset'));
$string = htmlentities($string, ENT_NOQUOTES | ENT_HTML401, 'utf-8');
$string = stripslashes($string);
$string = strip_tags($string);
@ -65,23 +79,20 @@ function get_country_code()
function get_country_name($code)
{
// Catch XX
if (strtolower($code) === 'xx') {
return 'Unknown';
}
switch (strtolower($code)) {
case "xx":
return "Unknown";
// Catch proxy
if (strtolower($code) === 'a1') {
return 'Anonymous Proxy';
}
case "a1":
return "Anonymous Proxy";
// Catch proxy
if (strtolower($code) === 'a2') {
return 'Satellite Provider';
}
case "a2":
return "Satellite Provider";
default:
return locale_get_display_region("-{$code}", 'en');
}
}
function password_entropy($password)
{
@ -121,28 +132,28 @@ function send_mail($to, $subject, $body)
$mail->isSMTP();
// Set the SMTP server host
$mail->Host = Config::get('smtp_server');
$mail->Host = config('mail.smtp.server');
// Do we require authentication?
$mail->SMTPAuth = Config::get('smtp_auth');
$mail->SMTPAuth = config('mail.smtp.auth');
// Do we encrypt as well?
$mail->SMTPSecure = Config::get('smtp_secure');
$mail->SMTPSecure = config('mail.smtp.secure');
// Set the port to the SMTP server
$mail->Port = Config::get('smtp_port');
$mail->Port = config('mail.smtp.port');
// If authentication is required log in as well
if (Config::get('smtp_auth')) {
$mail->Username = Config::get('smtp_username');
$mail->Password = base64_decode(Config::get('smtp_password'));
if (config('mail.smtp.auth')) {
$mail->Username = config('mail.smtp.username');
$mail->Password = config('mail.smtp.password');
}
// Add a reply-to header
$mail->addReplyTo(Config::get('smtp_replyto_mail'), Config::get('smtp_replyto_name'));
$mail->addReplyTo(config('mail.smtp.reply_to'), config('mail.smtp.reply_name'));
// Set a from address as well
$mail->setFrom(Config::get('smtp_from_email'), Config::get('smtp_from_name'));
$mail->setFrom(config('mail.smtp.from'), config('mail.smtp.name'));
// Set the addressee
foreach ($to as $email => $name) {
@ -202,7 +213,7 @@ function error_handler($errno, $errstr, $errfile, $errline)
ob_end_clean();
// Check for dev mode
$detailed = Config::local('dev', 'show_errors');
$detailed = config('dev.show_errors');
// Build page
$errorPage = '<!DOCTYPE html>