1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
<?php namespace HashOver;
// Copyright (C) 2010-2018 Jacob Barkdull
// This file is part of HashOver.
//
// HashOver is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// HashOver is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with HashOver. If not, see <http://www.gnu.org/licenses/>.
//
//--------------------
//
// IMPORTANT NOTICE:
//
// Do not edit this file unless you know what you are doing. Instead,
// please use the HashOver administration panel to graphically adjust
// the settings, or create/edit the settings JSON file.
// Default and advanced HashOver settings
class Settings extends Secrets
{
// Primary settings
public $language = 'auto'; // UI language, for example 'en', 'de', etc. 'auto' to use system locale
public $theme = 'default'; // Comment Cascading Style Sheet (CSS)
public $usesModeration = false; // Whether comments must be approved before they appear to other visitors
public $pendsUserEdits = false; // Whether comments need to be approved again when edited
public $dataFormat = 'xml'; // Format comments will be stored in; options: xml, json, sql
public $defaultName = 'Anonymous'; // Default name to use when one isn't given
public $allowsImages = true; // Whether external image URLs wrapped in [img] tags are embedded
public $allowsLogin = true; // Whether users can login and logout (when false form cookies are still set)
public $allowsLikes = true; // Whether a "Like" link is displayed
public $allowsDislikes = false; // Whether a "Dislike" link is displayed; allowing Reddit-style voting
public $usesAjax = true; // Whether AJAX is used for posting, editing, and loading comments
public $collapsesInterface = false; // Whether the comment form, thread, and end links are all initially hidden
public $collapsesComments = true; // Whether to hide comments and display a link to show them
public $collapseLimit = 3; // Number of comments that aren't hidden
public $replyMode = 'thread'; // Whether to display replies as a 'thread' or as a 'stream'
public $streamDepth = 3; // In stream mode, the number of reply indentions to allow before the thread flattens
public $popularityThreshold = 5; // Minimum likes a comment needs to be popular
public $popularityLimit = 2; // Number of comments allowed to become popular
public $usesMarkdown = true; // Whether comments will be parsed for Markdown
// Date and Time settings
public $serverTimezone = 'America/Los_Angeles'; // Server timezone
public $usesUserTimezone = true; // Whether comment dates should use the user's timezone (JavaScript-mode)
public $usesShortDates = true; // Whether comment dates are shortened, for example "X days ago"
public $timeFormat = 'g:ia'; // Time format, use 'H:i' for 24-hour format (see: http://php.net/manual/en/function.date.php)
public $dateFormat = 'm/d/Y'; // Date format (see: http://php.net/manual/en/function.date.php)
// Field options, use true/false to enable/disable a field,
// use 'required' to require a field be properly filled
public $fieldOptions = array (
'name' => true,
'password' => false,
'email' => true,
'website' => false
);
// Behavior settings
public $displaysTitle = false; // Whether page title is shown or not
public $formPosition = 'top'; // Position for primary form; options: 'top' or 'bottom'
public $usesAutoLogin = true; // Whether a user's first comment automatically logs them in
public $showsReplyCount = false; // Whether to show reply count separately from total
public $countIncludesDeleted = true; // Whether comment counts should include deleted comments
public $iconMode = 'none'; // How to display avatar icons (either 'image', 'count' or 'none')
public $iconSize = 45; // Size of Gravatar icons in pixels
public $imageFormat = 'png'; // Format for icons and other images (use 'svg' for HDPI)
public $usesLabels = false; // Whether to display labels above inputs
public $usesCancelButtons = true; // Whether forms have "Cancel" buttons
public $appendsCss = false; // Whether to automatically add a CSS <link> element to the page <head>
public $appendsRss = false; // Whether a comment RSS feed link is displayed
// Technical settings
public $loginMethod = 'defaultLogin'; // Login method class for handling user login information
public $setsCookies = true; // Whether cookies are enabled
public $secureCookies = false; // Whether cookies set over secure HTTPS will only be transmitted over HTTPS
public $storesIpAddress = false; // Whether to store users' IP addresses
public $subscribesUser = true; // Whether to subscribe the user to e-mail notifications by default
public $allowsUserReplies = false; // Whether given e-mails are sent as reply-to address to users
public $noreplyEmail = 'info@edwinmattiacci.com'; // E-mail used when no e-mail is given
public $spamDatabase = 'remote'; // Whether to use a remote or local spam database
public $spamCheckModes = 'php'; // Perform IP spam check in 'json' or 'php' mode, or 'both'
public $gravatarDefault = 'custom'; // Gravatar theme to use ('custom', 'identicon', 'monsterid', 'wavatar', or 'retro')
public $gravatarForce = false; // Whether to force the themed Gravatar images instead of an avatar image
public $minifiesJavascript = false; // Whether JavaScript output should be minified
public $minifyLevel = 4; // How much to minify JavaScript code, options: 1, 2, 3, 4
public $enabledApi = array ('all'); // An array of enabled API. 'all' = fully-enabled, empty array = fully disabled
public $latestMax = 10; // Maximum number of comments to save as latest comments
public $latestTrimWidth = 100; // Number of characters to trim latest comments to, 0 for no trim
public $userDeletionsUnlink = false; // Whether user deleted files are actually unlinked from the filesystem
public $allowLocalMetadata = false; // Whether default metadata should be collected while running on a local server
// Types of images allowed to be embedded in comments
public $imageTypes = array (
'jpeg',
'jpg',
'png',
'gif'
);
// External domains allowed to remotely load HashOver scripts
public $allowedDomains = array (
// '*.example.com',
// '*.example.org',
// '*.example.net'
);
// General database options
public $databaseType = 'sqlite'; // Type of database, sqlite or mysql
public $databaseName = 'hashover-threads'; // Database name
// SQL database options
public $databaseHost = 'localhost'; // Database host name
public $databaseUser = 'root'; // Database login user
public $databasePassword = 'password'; // Database login password
public $databaseCharset = 'utf8'; // Database character set
// Automated settings
public $isMobile = false;
// Technical settings placeholders
public $rootDirectory;
public $httpRoot;
public $httpBackend;
public $httpImages;
public $cookieExpiration;
public $domain;
public function __construct ()
{
// Theme path
$this->themePath = 'themes/' . $this->theme;
// Set server timezone
date_default_timezone_set ($this->serverTimezone);
// Set encoding
mb_internal_encoding ('UTF-8');
// Get parent directory
$root_directory = dirname (dirname (__DIR__));
// Get HTTP parent directory
$document_root = realpath ($_SERVER['DOCUMENT_ROOT']);
$http_directory = mb_substr ($root_directory, mb_strlen ($document_root));
// Replace backslashes with forward slashes on Windows
if (DIRECTORY_SEPARATOR === '\\') {
$http_directory = str_replace ('\\', '/', $http_directory);
}
// Determine HTTP or HTTPS
$protocol = ($this->isHTTPS () ? 'https' : 'http') . '://';
// Technical settings
$this->rootDirectory = $root_directory; // Root directory for script
$this->httpRoot = $http_directory; // Root directory for HTTP
$this->httpBackend = $http_directory . '/backend'; // Backend directory for HTTP
$this->httpImages = $http_directory . '/images'; // Image directory for HTTP
$this->cookieExpiration = time () + 60 * 60 * 24 * 30; // Cookie expiration date
$this->domain = $_SERVER['HTTP_HOST']; // Domain name for refer checking & notifications
$this->absolutePath = $protocol . $this->domain; // Absolute path or remote access
// Load JSON settings
$this->jsonSettings ();
// Synchronize settings
$this->syncSettings ();
}
function isHTTPS ()
{
// The connection is HTTPS if server says so
if (!empty ($_SERVER['HTTPS']) and $_SERVER['HTTPS'] !== 'off') {
return true;
}
// Assume the connection is HTTPS on standard SSL port
if ($_SERVER['SERVER_PORT'] == 443) {
return true;
}
return false;
}
// Returns a server-side absolute file path
public function getAbsolutePath ($file)
{
return $this->rootDirectory . '/' . trim ($file, '/');
}
// Returns a client-side path for a file within the HashOver root
public function getHttpPath ($file)
{
return $this->httpRoot . '/' . trim ($file, '/');
}
// Returns a client-side path for a file within the backend directory
public function getBackendPath ($file)
{
return $this->httpBackend . '/' . trim ($file, '/');
}
// Returns a client-side path for a file within the images directory
public function getImagePath ($filename)
{
$path = $this->httpImages . '/' . trim ($filename, '/');
$path .= '.' . $this->imageFormat;
return $path;
}
// Returns a client-side path for a file within the configured theme
public function getThemePath ($file, $http = true)
{
// Path to the requested file in the configured theme
$theme_file = $this->themePath . '/' . $file;
// Use the same file from the default theme if it doesn't exist
if (!file_exists ($this->getAbsolutePath ($theme_file))) {
$theme_file = 'themes/default/' . $file;
}
// Convert the theme file path for HTTP use if told to
if ($http !== false) {
$theme_file = $this->getHttpPath ($theme_file);
}
return $theme_file;
}
public function jsonSettings ()
{
// JSON settings file path
$path = $this->getAbsolutePath ('config/settings.json');
// Do nothing if the JSON settings file doesn't exist
if (!file_exists ($path)) {
return;
}
// Get JSON data
$data = @file_get_contents ($path);
// Load and decode JSON settings file
$json_settings = @json_decode ($data, true);
// Return void on failure
if ($json_settings === null) {
return;
}
// Loop through each setting
foreach ($json_settings as $key => $value) {
// Convert setting name to camelCase
$title_case_key = ucwords (str_replace ('-', ' ', strtolower ($key)));
$setting = lcfirst (str_replace (' ', '', $title_case_key));
// Check if the JSON setting property exists in the defaults
if (property_exists ($this, $setting)) {
// Check if the JSON value is the same type as the default
if (gettype ($value) === gettype ($this->{$setting})) {
// Override default setting
$this->{$setting} = $value;
}
}
}
}
// Synchronizes specific settings after remote changes
public function syncSettings ()
{
// Theme path
$this->themePath = 'themes/' . $this->theme;
// Disable likes and dislikes if cookies are disabled
if ($this->setsCookies === false) {
$this->allowsLikes = false;
$this->allowsDislikes = false;
}
// Setup default field options
foreach (array ('name', 'password', 'email', 'website') as $field) {
if (!isset ($this->fieldOptions[$field])) {
$this->fieldOptions[$field] = true;
}
}
// Disable password if name is disabled
if ($this->fieldOptions['name'] === false) {
$this->fieldOptions['password'] = false;
}
// Disable login if name or password is disabled
if ($this->fieldOptions['name'] === false
or $this->fieldOptions['password'] === false)
{
$this->allowsLogin = false;
}
// Disable autologin if login is disabled
if ($this->allowsLogin === false) {
$this->usesAutoLogin = false;
}
// Backend directory for HTTP
$this->httpBackend = $this->httpRoot . '/backend';
// Image directory for HTTP
$this->httpImages = $this->httpRoot . '/images';
}
// Check if a given API format is enabled
public function apiStatus ($api)
{
// Check if the given API is enabled
if (is_array ($this->enabledApi)) {
// Return enabled if all available APIs are enabled
if (in_array ('all', $this->enabledApi)) {
return 'enabled';
}
// Return enabled if the given API is enabled
if (in_array ($api, $this->enabledApi)) {
return 'enabled';
}
}
// Otherwise, assume API is disabled by default
return 'disabled';
}
}
|