/data/core/classes/Database/DB.php
$this->_error = false;
if ($this->_statement = $this->_pdo->prepare($sql)) {
$x = 1;
foreach ($params as $param) {
// Convert "true" and "false" to 1 and 0 so that query params can be more fluent
if (is_bool($param)) {
$param = $param ? 1 : 0;
}
$this->_statement->bindValue(
$x,
$param,
is_int($param)
? PDO::PARAM_INT
: PDO::PARAM_STR
);
$x++;
}
$this->_query_recorder->pushQuery($sql, $params);
if ($this->_statement->execute()) {
// Only fetch the results if this is a SELECT query.
if ($isSelect || str_starts_with(strtoupper(ltrim($sql)), 'SELECT')) {
$this->_results = $this->_statement->fetchAll(PDO::FETCH_OBJ);
}
$this->_count = $this->_statement->rowCount();
} else {
print_r($this->_pdo->errorInfo());
$this->_error = true;
}
} else {
$this->_results = [];
}
return $this;
}
/**
* Execute some SQL action (which uses a where clause) on the database.
*
* @param string $action The action to perform (SELECT, DELETE).
/data/core/classes/Core/User.php
]);
Session::delete($this->_admSessionName);
Cookie::delete($this->_cookieName . '_adm');
}
/**
* Get the user's groups.
*
* @return array<int, Group> Their groups.
*/
public function getGroups(): array
{
if (isset($this->_groups)) {
return $this->_groups;
}
if (isset(self::$_group_cache[$this->data()->id])) {
$this->_groups = self::$_group_cache[$this->data()->id];
} else {
$groups_query = $this->_db->query('SELECT nl2_groups.* FROM nl2_users_groups INNER JOIN nl2_groups ON group_id = nl2_groups.id WHERE user_id = ? AND deleted = 0 ORDER BY `order`', [$this->data()->id]);
if ($groups_query->count()) {
foreach ($groups_query->results() as $item) {
$this->_groups[$item->id] = new Group($item);
}
} else {
$this->_groups = [];
}
self::$_group_cache[$this->data()->id] = $this->_groups;
}
if (!count($this->_groups)) {
// Get default group
// TODO: Use PRE_VALIDATED_DEFAULT ?
$default_group = Group::find(1, 'default_group');
$default_group_id = $default_group->id ?? 1;
$this->addGroup($default_group_id);
}
/data/core/classes/Core/User.php
} else {
$data_obj->uuid = '';
}
return AvatarSource::getAvatarFromUserData($data_obj, $this->hasPermission('usercp.gif_avatar'), $size, $full);
}
/**
* Does the user have a specific permission in any of their groups?
*
* @param string $permission Permission node to check recursively for.
*
* @return bool Whether they inherit this permission or not.
*/
public function hasPermission(string $permission): bool
{
if (!$this->exists()) {
return false;
}
foreach ($this->getGroups() as $group) {
$permissions = json_decode($group->permissions, true) ?? [];
if (isset($permissions['administrator']) && $permissions['administrator'] == 1) {
return true;
}
if (isset($permissions[$permission]) && $permissions[$permission] == 1) {
return true;
}
}
return false;
}
public function getActiveSessions(): array
{
return DB::getInstance()->query(
'SELECT * FROM nl2_users_session WHERE user_id = ? AND active = 1 ORDER BY last_seen DESC',
[
$this->data()->id,
/data/core/classes/Core/User.php
* @param int $size Size of image to render in pixels.
* @param bool $full Whether to use full site URL or not, for external loading - ie discord webhooks.
*
* @return string URL to their avatar image.
*/
public function getAvatar(int $size = 128, bool $full = false): string
{
$data_obj = new stdClass();
// Convert UserData object to stdClass so we can dynamically add the 'uuid' property
foreach (get_object_vars($this->data()) as $key => $value) {
$data_obj->{$key} = $value;
}
$integrationUser = $this->getIntegration('Minecraft');
if ($integrationUser != null) {
$data_obj->uuid = $integrationUser->data()->identifier;
} else {
$data_obj->uuid = '';
}
return AvatarSource::getAvatarFromUserData($data_obj, $this->hasPermission('usercp.gif_avatar'), $size, $full);
}
/**
* Does the user have a specific permission in any of their groups?
*
* @param string $permission Permission node to check recursively for.
*
* @return bool Whether they inherit this permission or not.
*/
public function hasPermission(string $permission): bool
{
if (!$this->exists()) {
return false;
}
foreach ($this->getGroups() as $group) {
$permissions = json_decode($group->permissions, true) ?? [];
if (isset($permissions['administrator']) && $permissions['administrator'] == 1) {
return true;
/data/cache/templates_c/fdef5dbd06dd76349dff94823e93ea8449b5def0_0.file.members.tpl.php
<div class="px-5 py-4">
<h4 class="text-sm font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">
<?php echo $_smarty_tpl->tpl_vars['NEW_MEMBERS']->value;?>
</h4>
<div class="mt-4 grid grid-cols-6 gap-2" id="new-members-grid">
<?php
$_from = $_smarty_tpl->smarty->ext->_foreach->init($_smarty_tpl, $_smarty_tpl->tpl_vars['NEW_MEMBERS_VALUE']->value, 'member');
$_smarty_tpl->tpl_vars['member']->do_else = true;
if ($_from !== null) foreach ($_from as $_smarty_tpl->tpl_vars['member']->value) {
$_smarty_tpl->tpl_vars['member']->do_else = false;
?>
<a class="block"
href="<?php echo $_smarty_tpl->tpl_vars['member']->value->getProfileUrl();?>
"
data-poload="<?php echo $_smarty_tpl->tpl_vars['USER_INFO_URL']->value;
echo $_smarty_tpl->tpl_vars['member']->value->data()->id;?>
">
<img class="h-10 w-10 rounded-full ring-1 ring-slate-200 hover:ring-2 hover:ring-indigo-500/40 dark:ring-slate-800"
src="<?php echo $_smarty_tpl->tpl_vars['member']->value->getAvatar();?>
"
alt="<?php echo $_smarty_tpl->tpl_vars['member']->value->getDisplayname();?>
">
</a>
<?php
}
$_smarty_tpl->smarty->ext->_foreach->restore($_smarty_tpl, 1);?>
</div>
</div>
</section>
</aside>
<main class="lg:col-span-8">
<?php if ($_smarty_tpl->tpl_vars['VIEWING_LIST']->value == "group" || smarty_modifier_count($_smarty_tpl->tpl_vars['MEMBER_LISTS_VIEWING']->value)) {?>
<section class="rounded-2xl border border-slate-200 bg-white p-5 shadow-soft dark:border-slate-800 dark:bg-slate-900">
<?php if ($_smarty_tpl->tpl_vars['VIEWING_LIST']->value == "group") {?>
<div class="flex items-center justify-between gap-3">
<h3 class="text-lg font-semibold text-slate-900 dark:text-slate-100">
<?php echo $_smarty_tpl->tpl_vars['VIEWING_GROUP']->value['name'];?>
/data/vendor/smarty/smarty/libs/sysplugins/smarty_template_resource_base.php
*
* @throws \Exception
*/
public function getRenderedTemplateCode(Smarty_Internal_Template $_template, $unifunc = null)
{
$smarty = &$_template->smarty;
$_template->isRenderingCache = $this->isCache;
$level = ob_get_level();
try {
if (!isset($unifunc)) {
$unifunc = $this->unifunc;
}
if (empty($unifunc) || !function_exists($unifunc)) {
throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'");
}
if ($_template->startRenderCallbacks) {
foreach ($_template->startRenderCallbacks as $callback) {
call_user_func($callback, $_template);
}
}
$unifunc($_template);
foreach ($_template->endRenderCallbacks as $callback) {
call_user_func($callback, $_template);
}
$_template->isRenderingCache = false;
} catch (Exception $e) {
$_template->isRenderingCache = false;
while (ob_get_level() > $level) {
ob_end_clean();
}
if (isset($smarty->security_policy)) {
$smarty->security_policy->endTemplate();
}
throw $e;
}
}
/**
* Get compiled time stamp
*
* @return int
/data/vendor/smarty/smarty/libs/sysplugins/smarty_template_compiled.php
if (!$_template->source->exists) {
$type = $_template->source->isConfig ? 'config' : 'template';
throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'");
}
if ($_template->smarty->debugging) {
if (!isset($_template->smarty->_debug)) {
$_template->smarty->_debug = new Smarty_Internal_Debug();
}
$_template->smarty->_debug->start_render($_template);
}
if (!$this->processed) {
$this->process($_template);
}
if (isset($_template->cached)) {
$_template->cached->file_dependency =
array_merge($_template->cached->file_dependency, $this->file_dependency);
}
if ($_template->source->handler->uncompiled) {
$_template->source->handler->renderUncompiled($_template->source, $_template);
} else {
$this->getRenderedTemplateCode($_template);
}
if ($_template->caching && $this->has_nocache_code) {
$_template->cached->hashes[ $this->nocache_hash ] = true;
}
if ($_template->smarty->debugging) {
$_template->smarty->_debug->end_render($_template);
}
}
/**
* load compiled template or compile from source
*
* @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
*
* @throws Exception
*/
public function process(Smarty_Internal_Template $_smarty_tpl)
{
$source = &$_smarty_tpl->source;
$smarty = &$_smarty_tpl->smarty;
/data/vendor/smarty/smarty/libs/sysplugins/smarty_internal_template.php
"Unable to load template '{$this->source->type}:{$this->source->name}'" .
($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" : '')
);
}
// disable caching for evaluated code
if ($this->source->handler->recompiled) {
$this->caching = Smarty::CACHING_OFF;
}
// read from cache or render
if ($this->caching === Smarty::CACHING_LIFETIME_CURRENT || $this->caching === Smarty::CACHING_LIFETIME_SAVED) {
if (!isset($this->cached) || $this->cached->cache_id !== $this->cache_id
|| $this->cached->compile_id !== $this->compile_id
) {
$this->loadCached(true);
}
$this->cached->render($this, $no_output_filter);
} else {
if (!isset($this->compiled) || $this->compiled->compile_id !== $this->compile_id) {
$this->loadCompiled(true);
}
$this->compiled->render($this);
}
// display or fetch
if ($display) {
if ($this->caching && $this->smarty->cache_modified_check) {
$this->smarty->ext->_cacheModify->cacheModifiedCheck(
$this->cached,
$this,
isset($content) ? $content : ob_get_clean()
);
} else {
if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled)
&& !$no_output_filter && (isset($this->smarty->autoload_filters[ 'output' ])
|| isset($this->smarty->registered_filters[ 'output' ]))
) {
echo $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
} else {
echo ob_get_clean();
}
}
if ($this->smarty->debugging) {
/data/vendor/smarty/smarty/libs/sysplugins/smarty_internal_templatebase.php
if ($template->caching) {
// return cache status of template
if (!isset($template->cached)) {
$template->loadCached();
}
$result = $template->cached->isCached($template);
Smarty_Internal_Template::$isCacheTplObj[ $template->_getTemplateId() ] = $template;
} else {
return false;
}
} else {
if ($saveVars) {
$savedTplVars = $template->tpl_vars;
$savedConfigVars = $template->config_vars;
}
ob_start();
$template->_mergeVars();
if (!empty(Smarty::$global_tpl_vars)) {
$template->tpl_vars = array_merge(Smarty::$global_tpl_vars, $template->tpl_vars);
}
$result = $template->render(false, $function);
$template->_cleanUp();
if ($saveVars) {
$template->tpl_vars = $savedTplVars;
$template->config_vars = $savedConfigVars;
} else {
if (!$function && !isset(Smarty_Internal_Template::$tplObjCache[ $template->templateId ])) {
$template->parent = null;
$template->tpl_vars = $template->config_vars = array();
Smarty_Internal_Template::$tplObjCache[ $template->templateId ] = $template;
}
}
}
if (isset($errorHandler)) {
$errorHandler->deactivate();
}
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);
}
/data/vendor/smarty/smarty/libs/sysplugins/smarty_internal_templatebase.php
* universal cache
*
* @var array()
*/
public $_cache = array();
/**
* fetches a rendered Smarty template
*
* @param string $template the resource handle of the template file or template object
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
* @param object $parent next higher level of Smarty variables
*
* @throws Exception
* @throws SmartyException
* @return string rendered template output
*/
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
$result = $this->_execute($template, $cache_id, $compile_id, $parent, 0);
return $result === null ? ob_get_clean() : $result;
}
/**
* displays a Smarty template
*
* @param string $template the resource handle of the template file or template object
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
* @param object $parent next higher level of Smarty variables
*
* @throws \Exception
* @throws \SmartyException
*/
public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
// display template
$this->_execute($template, $cache_id, $compile_id, $parent, 1);
}
/data/core/classes/Templates/SmartyTemplateEngine.php
DebugBarHelper::getInstance()->addSmartyCollector($smarty);
}
$this->_securityPolicy = $securityPolicy;
$this->_smarty = $smarty;
parent::__construct();
}
public function render(string $templateFile): void
{
echo $this->fetch($templateFile);
}
public function fetch(string $templateFile): string
{
$templateFile = str_replace('.tpl', '', $templateFile);
$this->_smarty->assign($this->getVariables());
return $this->_smarty->fetch("$templateFile.tpl");
}
public function clearCache(): void
{
$this->_smarty->clearAllCache();
}
/**
* Add an extra directory to the Smarty security policy.
*
* @param string $dir Directory to add to policy
* @return void
*/
public function addSecurityPolicyDirectory(string $dir): void
{
$this->_securityPolicy->secure_dir = [...$this->_securityPolicy->secure_dir, $dir];
$this->_smarty->enableSecurity($this->_securityPolicy);
}
}
/data/core/classes/Templates/SmartyTemplateEngine.php
'array_key_exists',
];
$securityPolicy->secure_dir = [ROOT_PATH . '/custom/templates', ROOT_PATH . '/custom/panel_templates'];
$smarty->enableSecurity($securityPolicy);
$smarty->setCompileDir(ROOT_PATH . '/cache/templates_c');
$smarty->setTemplateDir($dir);
if (defined('PHPDEBUGBAR')) {
DebugBarHelper::getInstance()->addSmartyCollector($smarty);
}
$this->_securityPolicy = $securityPolicy;
$this->_smarty = $smarty;
parent::__construct();
}
public function render(string $templateFile): void
{
echo $this->fetch($templateFile);
}
public function fetch(string $templateFile): string
{
$templateFile = str_replace('.tpl', '', $templateFile);
$this->_smarty->assign($this->getVariables());
return $this->_smarty->fetch("$templateFile.tpl");
}
public function clearCache(): void
{
$this->_smarty->clearAllCache();
}
/**
* Add an extra directory to the Smarty security policy.
*
* @param string $dir Directory to add to policy
/data/core/classes/Templates/TemplateBase.php
{
[$css, $js] = $this->assets()->compile();
// Put the assets at the start of the arrays, so they load first (SBAdmin requires JQuery first, etc.)
array_unshift($this->_css, ...$css);
array_unshift($this->_js, ...$js);
$this->_engine->addVariables([
'TEMPLATE_CSS' => $this->getCSS(),
'TEMPLATE_JS' => $this->getJS(),
]);
if (defined('PHPDEBUGBAR') && PHPDEBUGBAR) {
$debugBar = DebugBarHelper::getInstance()->getDebugBar()->getJavascriptRenderer();
$this->_engine->addVariables([
'DEBUGBAR_JS' => $debugBar->renderHead(),
'DEBUGBAR_HTML' => $debugBar->render(),
]);
}
$this->_engine->render($template);
}
/**
* Get all internal CSS styles.
*
* @return array Array of strings of CSS.
*/
public function getCSS(): array
{
return $this->_css;
}
/**
* Get all internal JS code.
*
* @return array Array of strings of JS.
*/
public function getJS(): array
{
return $this->_js;
/data/modules/Members/pages/members.php
'FIND_MEMBER' => $members_language->get('members', 'find_member'),
'NAME' => $members_language->get('members', 'name'),
'SEARCH_URL' => URL::build('/queries/users'),
'NO_RESULTS_HEADER' => $members_language->get('members', 'no_results_header'),
'NO_RESULTS_TEXT' => $members_language->get('members', 'no_results_text'),
'VIEW_GROUP' => $members_language->get('members', 'view_group'),
'GROUP' => $members_language->get('members', 'group'),
'NO_MEMBERS_FOUND' => $members_language->get('members', 'no_members'),
'NO_OVERVIEW_LISTS_ENABLED' => $members_language->get('members', 'no_overview_lists_enabled'),
]);
// Load modules + template
Module::loadPage($user, $pages, $cache, $smarty, [$navigation, $cc_nav, $staffcp_nav], $widgets, $template);
$template->onPageLoad();
require ROOT_PATH . '/core/templates/navbar.php';
require ROOT_PATH . '/core/templates/footer.php';
// Display template
$template->displayTemplate('members/members');
/data/index.php
require(ROOT_PATH . '/modules/Core/pages/index.php');
}
}
die;
}
$route = rtrim(strtok($_GET['route'], '?'), '/');
$all_pages = $pages->returnPages();
if (array_key_exists($route, $all_pages)) {
$pages->setActivePage($all_pages[$route]);
if (isset($all_pages[$route]['custom'])) {
require(implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', 'Core', 'pages', 'custom.php']));
die;
}
$path = implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', $all_pages[$route]['module'], $all_pages[$route]['file']]);
if (file_exists($path)) {
require($path);
die;
}
} else {
// Use recursion to check - might have URL parameters in path
$path_array = explode('/', $route);
for ($i = count($path_array) - 2; $i > 0; $i--) {
$new_path = '/';
for ($n = 1; $n <= $i; $n++) {
$new_path .= $path_array[$n] . '/';
}
$new_path = rtrim($new_path, '/');
if (array_key_exists($new_path, $all_pages)) {
$path = implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', $all_pages[$new_path]['module'], $all_pages[$new_path]['file']]);
if (file_exists($path)) {
$pages->setActivePage($all_pages[$new_path]);
require($path);
/data/core/classes/Core/User.php
SELECT nl2_groups.* FROM nl2_users_groups INNER JOIN nl2_groups ON group_id = nl2_groups.id WHERE user_id = '2' AND deleted = 0 ORDER BY `order`;
]);
Session::delete($this->_admSessionName);
Cookie::delete($this->_cookieName . '_adm');
}
/**
* Get the user's groups.
*
* @return array<int, Group> Their groups.
*/
public function getGroups(): array
{
if (isset($this->_groups)) {
return $this->_groups;
}
if (isset(self::$_group_cache[$this->data()->id])) {
$this->_groups = self::$_group_cache[$this->data()->id];
} else {
$groups_query = $this->_db->query('SELECT nl2_groups.* FROM nl2_users_groups INNER JOIN nl2_groups ON group_id = nl2_groups.id WHERE user_id = ? AND deleted = 0 ORDER BY `order`', [$this->data()->id]);
if ($groups_query->count()) {
foreach ($groups_query->results() as $item) {
$this->_groups[$item->id] = new Group($item);
}
} else {
$this->_groups = [];
}
self::$_group_cache[$this->data()->id] = $this->_groups;
}
if (!count($this->_groups)) {
// Get default group
// TODO: Use PRE_VALIDATED_DEFAULT ?
$default_group = Group::find(1, 'default_group');
$default_group_id = $default_group->id ?? 1;
$this->addGroup($default_group_id);
}
/data/core/classes/Core/User.php
SELECT nl2_users_integrations.*, nl2_integrations.name as integration_name FROM nl2_users_integrations LEFT JOIN nl2_integrations ON integration_id=nl2_integrations.id WHERE user_id = '2';
return $this->_groups;
}
/**
* Get the user's integrations.
*
* @return IntegrationUser[] Their integrations.
*/
public function getIntegrations(): array
{
if (isset($this->_integrations)) {
return $this->_integrations;
}
$integrations = Integrations::getInstance();
if (isset(self::$_integration_cache[$this->data()->id])) {
$integrations_query = self::$_integration_cache[$this->data()->id];
} else {
$integrations_query = $this->_db->query('SELECT nl2_users_integrations.*, nl2_integrations.name as integration_name FROM nl2_users_integrations LEFT JOIN nl2_integrations ON integration_id=nl2_integrations.id WHERE user_id = ?', [$this->data()->id]);
if ($integrations_query->count()) {
$integrations_query = $integrations_query->results();
} else {
$integrations_query = [];
}
self::$_integration_cache[$this->data()->id] = $integrations_query;
}
$integrations_list = [];
foreach ($integrations_query as $item) {
$integration = $integrations->getIntegration($item->integration_name);
if ($integration != null) {
$integrationUser = new IntegrationUser($integration, $this->data()->id, 'user_id', $item);
$integrations_list[$item->integration_name] = $integrationUser;
}
}
return $this->_integrations = $integrations_list;
}
/data/modules/Lists/module.php
SELECT * FROM nl2_lists WHERE link_location IS NOT NULL;
mkdir(ROOT_PATH . '/uploads/lists_banners');
}
public function onUninstall() {
PhinxAdapter::rollback($this->getName(), __DIR__ . '/includes/migrations');
}
public function onEnable() {
PhinxAdapter::migrate($this->getName(), __DIR__ . '/includes/migrations');
mkdir(ROOT_PATH . '/uploads/lists_icons');
mkdir(ROOT_PATH . '/uploads/lists_images');
mkdir(ROOT_PATH . '/uploads/lists_banners');
}
public function onDisable() {
// No actions necessary
}
public function onPageLoad($user, $pages, $cache, $smarty, $navs, $widgets, $template) {
$lists = DB::getInstance()->query('SELECT * FROM nl2_lists WHERE link_location IS NOT NULL');
if ($lists->count()) {
foreach ($lists->results() as $list) {
// Check cache first
$cache->setCache('navbar_order');
if (!$cache->isCached('lists-' . $list->id . '_order')){
$order = 5;
$cache->store('lists-' . $list->id . '_order', 5);
} else {
$order = $cache->retrieve('lists-' . $list->id . '_order');
}
$cache->setCache('navbar_icons');
if (!$cache->isCached('lists-' . $list->id . '_icon'))
$icon = '';
else
$icon = $cache->retrieve('lists-' . $list->id . '_icon');
switch ($list->link_location) {
case 1:
// Navbar
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_referrals';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_credits';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_spent';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_purchases';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'highest_forum_reaction_scores';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_posts';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'staff_members';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'registered_members';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/modules/Members/classes/MemberListProvider.php
SELECT user_id, COUNT(user_id) AS `count` FROM nl2_users_trophies INNER JOIN nl2_users ON nl2_users.id=user_id GROUP BY user_id ORDER BY `count` DESC;
'count' => $count_column ? $row->{$count_column} : null,
],
$overview
? []
: [
'group_html' => $member->getAllGroupHtml(),
'metadata' => MemberListManager::getInstance()->getMemberMetadata($member),
],
);
}
return $list_members;
}
/**
* Determine the total number of members in this list.
* @return int The total number of members in this list
*/
public function getMemberCount(): int {
[$sql, $id_column] = $this->generator();
$rows = DB::getInstance()->query($sql)->results();
if (Settings::get('member_list_hide_banned', false, 'Members')) {
$rows = $this->filterBanned($rows, $id_column);
}
return count($rows);
}
/**
* Filter out banned users from a list of members.
*
* @param array $rows Rows returned from the member list query
* @param string $id_column The name of the column in each row containing the user ID
* @return array The rows with banned users filtered out
*/
private function filterBanned(array $rows, string $id_column): array {
$ids = implode(',', array_map(static fn ($row) => $row->{$id_column}, $rows));
if (empty($ids)) {
return [];
}
/data/core/classes/DTO/Group.php
SELECT * FROM nl2_groups WHERE `id` = '4';
* @return array<int, Group>
*/
public static function all(): array
{
$rows = DB::getInstance()->query('SELECT * FROM nl2_groups ORDER BY `order`')->results();
$fields = [];
foreach ($rows as $row) {
$fields[$row->id] = new Group($row);
}
return $fields;
}
/**
* @param string $value
* @param string $column
* @return Group|null
*/
public static function find(string $value, string $column = 'id'): ?Group
{
$row = DB::getInstance()->get('groups', [$column, $value])->first();
return $row
? new Group($row)
: null;
}
}
/data/core/classes/DTO/Group.php
SELECT * FROM nl2_groups WHERE `id` = '3';
* @return array<int, Group>
*/
public static function all(): array
{
$rows = DB::getInstance()->query('SELECT * FROM nl2_groups ORDER BY `order`')->results();
$fields = [];
foreach ($rows as $row) {
$fields[$row->id] = new Group($row);
}
return $fields;
}
/**
* @param string $value
* @param string $column
* @return Group|null
*/
public static function find(string $value, string $column = 'id'): ?Group
{
$row = DB::getInstance()->get('groups', [$column, $value])->first();
return $row
? new Group($row)
: null;
}
}
/data/core/classes/DTO/Group.php
SELECT * FROM nl2_groups WHERE `id` = '2';
* @return array<int, Group>
*/
public static function all(): array
{
$rows = DB::getInstance()->query('SELECT * FROM nl2_groups ORDER BY `order`')->results();
$fields = [];
foreach ($rows as $row) {
$fields[$row->id] = new Group($row);
}
return $fields;
}
/**
* @param string $value
* @param string $column
* @return Group|null
*/
public static function find(string $value, string $column = 'id'): ?Group
{
$row = DB::getInstance()->get('groups', [$column, $value])->first();
return $row
? new Group($row)
: null;
}
}
/data/core/classes/DTO/Group.php
SELECT * FROM nl2_groups WHERE `id` = '1';
* @return array<int, Group>
*/
public static function all(): array
{
$rows = DB::getInstance()->query('SELECT * FROM nl2_groups ORDER BY `order`')->results();
$fields = [];
foreach ($rows as $row) {
$fields[$row->id] = new Group($row);
}
return $fields;
}
/**
* @param string $value
* @param string $column
* @return Group|null
*/
public static function find(string $value, string $column = 'id'): ?Group
{
$row = DB::getInstance()->get('groups', [$column, $value])->first();
return $row
? new Group($row)
: null;
}
}
/data/core/classes/Core/User.php
SELECT * FROM nl2_users WHERE `id` = '1';
}
/**
* Find a user by unique identifier (username, ID, email, etc).
* Loads instance variables for this class.
*
* @param string $value Unique identifier.
* @param string $field What column to check for their unique identifier in.
*
* @return bool True/false on success or failure respectfully.
*/
private function find(string $value, string $field = 'id'): bool
{
if (isset(self::$_user_cache["$value.$field"])) {
$this->_data = self::$_user_cache["$value.$field"];
return true;
}
if ($field !== 'hash') {
$data = $this->_db->get('users', [$field, $value]);
} else {
$data = $this->_db->query(
<<<'SQL'
SELECT
nl2_users.*
FROM nl2_users
LEFT JOIN nl2_users_session
ON nl2_users.id = nl2_users_session.user_id
WHERE
nl2_users_session.hash = ?
AND nl2_users_session.active = 1
AND (
nl2_users_session.expires_at IS NULL
OR nl2_users_session.expires_at > ?
)
SQL,
[
$value,
time(),
]
/data/core/classes/Core/User.php
SELECT * FROM nl2_users WHERE `id` = '2';
}
/**
* Find a user by unique identifier (username, ID, email, etc).
* Loads instance variables for this class.
*
* @param string $value Unique identifier.
* @param string $field What column to check for their unique identifier in.
*
* @return bool True/false on success or failure respectfully.
*/
private function find(string $value, string $field = 'id'): bool
{
if (isset(self::$_user_cache["$value.$field"])) {
$this->_data = self::$_user_cache["$value.$field"];
return true;
}
if ($field !== 'hash') {
$data = $this->_db->get('users', [$field, $value]);
} else {
$data = $this->_db->query(
<<<'SQL'
SELECT
nl2_users.*
FROM nl2_users
LEFT JOIN nl2_users_session
ON nl2_users.id = nl2_users_session.user_id
WHERE
nl2_users_session.hash = ?
AND nl2_users_session.active = 1
AND (
nl2_users_session.expires_at IS NULL
OR nl2_users_session.expires_at > ?
)
SQL,
[
$value,
time(),
]
/data/modules/Members/pages/members.php
SELECT id FROM nl2_users ORDER BY joined DESC LIMIT 12;
$lists_viewing = [];
} else {
$viewing_list = $_GET['list'] ?? 'overview';
if ($viewing_list !== 'overview'
&& (!MemberListManager::getInstance()->listExists($viewing_list) || !MemberListManager::getInstance()->getList($viewing_list)->isEnabled())
) {
Redirect::to(URL::build('/members'));
}
$lists_viewing = $viewing_list === 'overview'
? array_filter(MemberListManager::getInstance()->allEnabledLists(), static fn (MemberListProvider $list) => $list->displayOnOverview())
: [MemberListManager::getInstance()->getList($viewing_list)];
}
// TODO handle this in MemberListManager and cache it using UserRegisteredEvent
$new_members = [];
if (Settings::get('member_list_hide_banned', false, 'Members')) {
$query = DB::getInstance()->query('SELECT id FROM nl2_users WHERE isbanned = 0 ORDER BY joined DESC LIMIT 12');
} else {
$query = DB::getInstance()->query('SELECT id FROM nl2_users ORDER BY joined DESC LIMIT 12');
}
foreach ($query->results() as $new_member) {
$new_members[] = new User($new_member->id);
}
if (isset($error)) {
$template->getEngine()->addVariables([
'ERROR_TITLE' => $language->get('general', 'error'),
'ERROR' => $error,
]);
}
$groups = [];
foreach (json_decode(Settings::get('member_list_viewable_groups', '{}', 'Members'), true) as $group_id) {
$group = Group::find($group_id);
if (!$group) {
continue;
}
$groups[] = [
'id' => $group->id,
/data/core/classes/Core/Settings.php
SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = 'Members';
$cache_name = $module !== null ? $module : 'core';
self::$_cached_settings[$cache_name] = $cache;
}
/**
* Get a setting from the database table `nl2_settings`.
*
* @param string $setting Setting to check.
* @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null.
* @param string $module Module name to keep settings separate from other modules. Set module
* to 'Core' for global settings.
* @return ?string Setting from DB or $fallback.
*/
public static function get(string $setting, ?string $fallback = null, string $module = 'core'): ?string
{
if (!self::hasSettingsCache($module)) {
// Load all settings for this module and store it as a dictionary
if ($module === 'core') {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL')->results();
} else {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = ?', [$module])->results();
}
$cache = [];
foreach ($result as $row) {
$cache[$row->name] = $row->value;
}
self::setSettingsCache($module, $cache);
}
$cache = &self::getSettingsCache($module);
return $cache[$setting] ?? $fallback;
}
/**
* Modify a setting in the database table `nl2_settings`.
*
* @param string $setting Setting name.
* @param string|null $new_value New setting value, or null to delete
* @param string $module Module name to keep settings separate from other modules. Set module
/data/modules/Members/classes/MemberListProvider.php
SELECT * FROM nl2_member_lists WHERE `name` = 'most_trophies';
public function displayOnOverview(): bool {
return $this->_display_on_overview;
}
/**
* @return string A URL to this specific member list page
*/
public function url(): string {
return URL::build('/members', 'list=' . $this->getName());
}
/**
* Determine whether the member list provider is enabled or not. Will automatically enable the member list if it is not already enabled.
* @return bool Whether the member list provider is enabled
*/
public function isEnabled(): bool {
if (isset($this->_enabled)) {
return $this->_enabled;
}
$enabled = DB::getInstance()->get('member_lists', ['name', $this->getName()])->first()->enabled;
if ($enabled === null) {
DB::getInstance()->insert('member_lists', [
'name' => $this->getName(),
'friendly_name' => $this->getFriendlyName(),
'module' => $this->getModule(),
'enabled' => true,
]);
return true;
}
return $this->_enabled = $enabled;
}
/**
* Get the information needed to generate the member list.
*
* @return array An array containing the SQL query to run, the column name of the user ID, and optionally the
* column name of the "count" value for this list. Count values are used to display the number of posts, likes, etc.
*/
/data/core/templates/frontend_init.php
SELECT * FROM nl2_page_descriptions WHERE `page` = '/members';
$default_group = $cache->retrieve('default_group');
} else {
try {
$default_group = Group::find(1, 'default_group')->id;
} catch (Exception $e) {
$default_group = 1;
}
$cache->store('default_group', $default_group);
}
}
// Page metadata
if (isset($_GET['route']) && $_GET['route'] != '/') {
$route = rtrim($_GET['route'], '/');
} else {
$route = '/';
}
if (!defined('PAGE_DESCRIPTION')) {
$page_metadata = DB::getInstance()->get('page_descriptions', ['page', $route]);
if ($page_metadata->count()) {
$page_metadata = $page_metadata->first();
$template->getEngine()->addVariables([
'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), addslashes(strip_tags($page_metadata->description))),
'PAGE_KEYWORDS' => addslashes(strip_tags($page_metadata->tags)),
]);
$og_image = $page_metadata->image;
if ($og_image) {
$template->getEngine()->addVariable('OG_IMAGE', rtrim(URL::getSelfURL(), '/') . $og_image);
}
} else {
$template->getEngine()->addVariables([
'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), addslashes(strip_tags(Settings::get('default_meta_description', '')))),
'PAGE_KEYWORDS' => addslashes(strip_tags(Settings::get('default_meta_keywords', ''))),
]);
}
} else {
$template->getEngine()->addVariables([
'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), addslashes(strip_tags(PAGE_DESCRIPTION))),
/data/core/init.php
SELECT * FROM nl2_groups WHERE `default_group` = '1';
: [DiscordHook::class, 'execute'],
'events' => json_decode($hook->events, true),
];
}
$cache->store('hooks', $hook_array);
}
}
}
EventHandler::registerWebhooks($hook_array);
// Get IP
$ip = HttpUtils::getRemoteAddress();
// Define default group pre validation
$cache->setCache('pre_validation_default');
$group_id = null;
if ($cache->isCached('pre_validation_default')) {
$group_id = $cache->retrieve('pre_validation_default');
} else {
$group_id = DB::getInstance()->get('groups', ['default_group', '1'])->results();
$group_id = $group_id[0]->id;
}
define('PRE_VALIDATED_DEFAULT', $group_id);
// Perform tasks if the user is logged in
if ($user->isLoggedIn()) {
Debugging::setCanViewDetailedError($user->hasPermission('admincp.errors'));
Debugging::setCanGenerateDebugLink($user->hasPermission('admincp.core.debugging'));
// Ensure a user is not banned
if ($user->data()->isbanned == 1) {
$user->logout();
Session::flash('home_error', $language->get('user', 'you_have_been_banned'));
Redirect::to(URL::build('/'));
}
// Is the IP address banned?
$ip_bans = DB::getInstance()->get('ip_bans', ['ip', $ip])->results();
if (count($ip_bans)) {
/data/core/init.php
SELECT * FROM nl2_hooks WHERE `id` <> '0';
|| str_contains($_GET['route'], 'store/listener')
)) {
// Can continue as normal
} else {
require(ROOT_PATH . '/core/includes/maintenance.php');
die;
}
} else {
// Display notice to admin stating maintenance mode is enabled
define('BYPASS_MAINTENANCE', true);
}
}
// Webhooks
$hook_array = [];
if (Util::isModuleEnabled('Discord Integration')) {
$cache->setCache('hooks');
if ($cache->isCached('hooks')) {
$hook_array = $cache->retrieve('hooks');
} else {
$hooks = DB::getInstance()->get('hooks', ['id', '<>', 0])->results();
if (count($hooks)) {
foreach ($hooks as $hook) {
if ($hook->action != 1 && $hook->action != 2) {
continue;
}
// TODO: more extendable webhook system, #2676
if ($hook->action == 2 && !class_exists(DiscordHook::class)) {
continue;
}
$hook_array[] = [
'id' => $hook->id,
'url' => Output::getClean($hook->url),
'action' => $hook->action == 1
? [WebHook::class, 'execute']
: [DiscordHook::class, 'execute'],
'events' => json_decode($hook->events, true),
];
}
/data/core/classes/Core/Settings.php
SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = 'Referrals';
$cache_name = $module !== null ? $module : 'core';
self::$_cached_settings[$cache_name] = $cache;
}
/**
* Get a setting from the database table `nl2_settings`.
*
* @param string $setting Setting to check.
* @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null.
* @param string $module Module name to keep settings separate from other modules. Set module
* to 'Core' for global settings.
* @return ?string Setting from DB or $fallback.
*/
public static function get(string $setting, ?string $fallback = null, string $module = 'core'): ?string
{
if (!self::hasSettingsCache($module)) {
// Load all settings for this module and store it as a dictionary
if ($module === 'core') {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL')->results();
} else {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = ?', [$module])->results();
}
$cache = [];
foreach ($result as $row) {
$cache[$row->name] = $row->value;
}
self::setSettingsCache($module, $cache);
}
$cache = &self::getSettingsCache($module);
return $cache[$setting] ?? $fallback;
}
/**
* Modify a setting in the database table `nl2_settings`.
*
* @param string $setting Setting name.
* @param string|null $new_value New setting value, or null to delete
* @param string $module Module name to keep settings separate from other modules. Set module
/data/modules/Referrals/module.php
SELECT id, custom_url FROM nl2_referrals WHERE disabled = 0 AND custom_url IS NOT NULL;
// Check if module version changed
$cache->setCache('referrals_module_cache');
if (!$cache->isCached('module_version')) {
$cache->store('module_version', $module_version);
} else {
if ($module_version != $cache->retrieve('module_version')) {
// Version have changed, Perform actions
$this->initialiseUpdate($cache->retrieve('module_version'));
$cache->store('module_version', $module_version);
if ($cache->isCached('update_check')) {
$cache->erase('update_check');
}
}
}
try {
// Define URLs which belong to this module
$referrals = $this->_db->query('SELECT id, custom_url FROM nl2_referrals WHERE disabled = 0 AND custom_url IS NOT NULL');
if ($referrals->count()) {
foreach ($referrals->results() as $referral) {
$pages->add('Referrals', '/' . $referral->custom_url, 'pages/referral.php');
}
}
} catch (Exception $e) {
// Database tables don't exist yet
}
// Events
EventHandler::registerEvent(ReferralRegistrationEvent::class);
// Listeners
EventHandler::registerListener(UserRegisteredEvent::class, [RegistrationListener::class, 'registration']);
EventHandler::registerListener(UserValidatedEvent::class, [RegistrationListener::class, 'userValidated']);
EventHandler::registerListener(DiscordWebhookFormatterEvent::class, [RegistrationListener::class, 'discordEmbedFormatter']);
// Store integration
$percentage = Settings::get('store_sale_percentage', '0', 'Referrals');
/data/core/classes/Core/Settings.php
SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = 'Store';
$cache_name = $module !== null ? $module : 'core';
self::$_cached_settings[$cache_name] = $cache;
}
/**
* Get a setting from the database table `nl2_settings`.
*
* @param string $setting Setting to check.
* @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null.
* @param string $module Module name to keep settings separate from other modules. Set module
* to 'Core' for global settings.
* @return ?string Setting from DB or $fallback.
*/
public static function get(string $setting, ?string $fallback = null, string $module = 'core'): ?string
{
if (!self::hasSettingsCache($module)) {
// Load all settings for this module and store it as a dictionary
if ($module === 'core') {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL')->results();
} else {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = ?', [$module])->results();
}
$cache = [];
foreach ($result as $row) {
$cache[$row->name] = $row->value;
}
self::setSettingsCache($module, $cache);
}
$cache = &self::getSettingsCache($module);
return $cache[$setting] ?? $fallback;
}
/**
* Modify a setting in the database table `nl2_settings`.
*
* @param string $setting Setting name.
* @param string|null $new_value New setting value, or null to delete
* @param string $module Module name to keep settings separate from other modules. Set module
/data/core/classes/Integrations/IntegrationBase.php
SELECT * FROM nl2_integrations WHERE name = 'Discord';
* @author Partydragen
* @version 2.1.0
* @license MIT
*/
abstract class IntegrationBase
{
private DB $_db;
private IntegrationData $_data;
protected string $_icon;
private array $_errors = [];
protected Language $_language;
protected ?string $_settings = null;
protected string $_name;
protected ?int $_order;
public function __construct()
{
$this->_db = DB::getInstance();
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]);
if ($integration->count()) {
$integration = $integration->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
} else {
// Register integration to database
$this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [
$this->_name,
]);
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
}
}
/**
* Get the name of this integration.
/data/modules/Lists/module.php
SELECT * FROM `nl2_lists_submissions` WHERE `vanity_url` IS NOT NULL;
Lists::getInstance()->registerProviderConnection(new DiscordConnection());
Lists::getInstance()->registerProviderConnection(new NamelessMCConnection());
Lists::getInstance()->registerProviderConnection(new BF2142Connection());
EventHandler::registerEvent(ListSubmissionCreatedEvent::class);
// Store Listener
EventHandler::registerListener(PaymentCompletedEvent::class, [StorePaymentListener::class, 'paymentCompleted']);
// Register page for each lists
$lists = DB::getInstance()->query('SELECT * FROM nl2_lists WHERE provider IS NOT NULL AND url IS NOT NULL');
if ($lists->count()) {
foreach ($lists->results() as $list) {
// Register page
$pages->add('Lists', $list->url, 'pages/submissions.php', 'lists-' . $list->id, true);
$pages->add('Lists', $list->url . '/new', 'pages/new_submission.php', 'lists-' . $list->id);
}
}
// Register page for each submission that has own vanity url
$submissions = DB::getInstance()->query('SELECT * FROM `nl2_lists_submissions` WHERE `vanity_url` IS NOT NULL');
foreach ($submissions->results() as $submission) {
$pages->add('Lists', '/' . $submission->vanity_url, 'pages/submission.php');
}
}
public function onInstall() {
PhinxAdapter::migrate($this->getName(), __DIR__ . '/includes/migrations');
mkdir(ROOT_PATH . '/uploads/lists_icons');
mkdir(ROOT_PATH . '/uploads/lists_images');
mkdir(ROOT_PATH . '/uploads/lists_banners');
}
public function onUninstall() {
PhinxAdapter::rollback($this->getName(), __DIR__ . '/includes/migrations');
}
public function onEnable() {
PhinxAdapter::migrate($this->getName(), __DIR__ . '/includes/migrations');
/data/modules/Lists/module.php
SELECT * FROM nl2_lists WHERE provider IS NOT NULL AND url IS NOT NULL;
$pages->add('Lists', '/panel/lists/settings', 'pages/panel/settings.php');
$pages->add('Lists', '/panel/lists', 'pages/panel/lists.php');
$pages->add('Lists', '/panel/lists/tags', 'pages/panel/tags.php');
$pages->add('Lists', '/queries/querysubmissions', 'queries/querysubmissions.php');
// Register provider connections
Lists::getInstance()->registerProviderConnection(new DefaultConnection());
Lists::getInstance()->registerProviderConnection(new MinecraftConnection());
Lists::getInstance()->registerProviderConnection(new VotifierConnection());
Lists::getInstance()->registerProviderConnection(new MCStatisticsConnection());
Lists::getInstance()->registerProviderConnection(new DiscordConnection());
Lists::getInstance()->registerProviderConnection(new NamelessMCConnection());
Lists::getInstance()->registerProviderConnection(new BF2142Connection());
EventHandler::registerEvent(ListSubmissionCreatedEvent::class);
// Store Listener
EventHandler::registerListener(PaymentCompletedEvent::class, [StorePaymentListener::class, 'paymentCompleted']);
// Register page for each lists
$lists = DB::getInstance()->query('SELECT * FROM nl2_lists WHERE provider IS NOT NULL AND url IS NOT NULL');
if ($lists->count()) {
foreach ($lists->results() as $list) {
// Register page
$pages->add('Lists', $list->url, 'pages/submissions.php', 'lists-' . $list->id, true);
$pages->add('Lists', $list->url . '/new', 'pages/new_submission.php', 'lists-' . $list->id);
}
}
// Register page for each submission that has own vanity url
$submissions = DB::getInstance()->query('SELECT * FROM `nl2_lists_submissions` WHERE `vanity_url` IS NOT NULL');
foreach ($submissions->results() as $submission) {
$pages->add('Lists', '/' . $submission->vanity_url, 'pages/submission.php');
}
}
public function onInstall() {
PhinxAdapter::migrate($this->getName(), __DIR__ . '/includes/migrations');
mkdir(ROOT_PATH . '/uploads/lists_icons');
mkdir(ROOT_PATH . '/uploads/lists_images');
/data/core/classes/Database/PhinxAdapter.php
SELECT version, migration_name FROM nl2_phinxlog_lists;
if (!$migrationDir) {
$migrationDir = __DIR__ . '/../../migrations';
}
$migration_files = array_map(
static function ($file_name) {
[$version, $migration_name] = explode('_', $file_name, 2);
$migration_name = str_replace(['.php', '_'], '', ucwords($migration_name, '_'));
return $version . '_' . $migration_name;
},
array_filter(scandir($migrationDir), static function ($file_name) {
// Pattern that matches Phinx migration file names (eg: 20230403000000_create_stroopwafel_table.php)
return preg_match('/^\d{14}_\w+\.php$/', $file_name);
}),
);
$migration_database_entries = array_map(static function ($row) {
return $row->version . '_' . $row->migration_name;
}, DB::getInstance()->query("SELECT version, migration_name FROM $table")->results());
$missing = array_diff($migration_files, $migration_database_entries);
$extra = array_diff($migration_database_entries, $migration_files);
if ($returnResults) {
return [
'missing' => count($missing),
'extra' => count($extra),
];
}
// Likely a pull from the repo dev branch or migrations
// weren't run during an upgrade script.
if (($missing_count = count($missing)) > 0) {
echo "There are $missing_count migrations files which have not been executed:" . '<br>';
foreach ($missing as $missing_migration) {
echo " - $missing_migration" . '<br>';
}
}
/data/core/classes/Core/Module.php
SELECT * FROM nl2_modules WHERE `name` = 'Core';
/**
* Get this module's ID.
*
* @return int The ID for the module
*/
public function getId(): int
{
return DB::getInstance()->query('SELECT `id` FROM nl2_modules WHERE `name` = ?', [$this->_name])->first()->id;
}
/**
* Get a module ID from name.
*
* @param string $name Module name
*
* @return ?int Module ID
*/
public static function getIdFromName(string $name): ?int
{
$query = DB::getInstance()->get('modules', ['name', $name]);
if ($query->count()) {
return $query->first()->id;
}
return null;
}
/**
* Get a module name from ID.
*
* @param int $id Module ID
*
* @return ?string Module name
*/
public static function getNameFromId(int $id): ?string
{
$query = DB::getInstance()->get('modules', ['id', $id]);
if ($query->count()) {
/data/core/classes/Integrations/IntegrationBase.php
SELECT * FROM nl2_integrations WHERE name = 'Google';
* @author Partydragen
* @version 2.1.0
* @license MIT
*/
abstract class IntegrationBase
{
private DB $_db;
private IntegrationData $_data;
protected string $_icon;
private array $_errors = [];
protected Language $_language;
protected ?string $_settings = null;
protected string $_name;
protected ?int $_order;
public function __construct()
{
$this->_db = DB::getInstance();
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]);
if ($integration->count()) {
$integration = $integration->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
} else {
// Register integration to database
$this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [
$this->_name,
]);
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
}
}
/**
* Get the name of this integration.
/data/core/classes/Integrations/IntegrationBase.php
SELECT * FROM nl2_integrations WHERE name = 'Minecraft';
* @author Partydragen
* @version 2.1.0
* @license MIT
*/
abstract class IntegrationBase
{
private DB $_db;
private IntegrationData $_data;
protected string $_icon;
private array $_errors = [];
protected Language $_language;
protected ?string $_settings = null;
protected string $_name;
protected ?int $_order;
public function __construct()
{
$this->_db = DB::getInstance();
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]);
if ($integration->count()) {
$integration = $integration->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
} else {
// Register integration to database
$this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [
$this->_name,
]);
$integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first();
$this->_data = new IntegrationData($integration);
$this->_order = $integration->order;
}
}
/**
* Get the name of this integration.
/data/modules/Core/module.php
SELECT * FROM nl2_custom_pages_permissions WHERE `group_id` = '0';
$navigation->add(
$custom_page->id,
Output::getClean($custom_page->title),
(is_null($redirect)) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect,
'footer', $custom_page->target ? '_blank' : null,
2000,
$custom_page->icon
);
break;
}
break 2;
}
break;
}
}
}
}
}
} else {
$custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', 0])->results();
if (count($custom_page_permissions)) {
foreach ($custom_pages as $custom_page) {
$redirect = null;
if ($custom_page->redirect == 1) {
$redirect = Output::getClean($custom_page->link);
}
$pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic);
foreach ($custom_page_permissions as $permission) {
if ($permission->page_id == $custom_page->id) {
if ($permission->view == 1) {
// Check cache for order
if (!$cache->isCached($custom_page->id . '_order')) {
// Create cache entry now
$page_order = 200;
$cache->store($custom_page->id . '_order', 200);
} else {
$page_order = $cache->retrieve($custom_page->id . '_order');
/data/modules/Core/module.php
SELECT * FROM nl2_custom_pages WHERE `id` <> '0';
}
// "More" dropdown
$cache->setCache('navbar_icons');
if ($cache->isCached('more_dropdown_icon')) {
$icon = $cache->retrieve('more_dropdown_icon');
} else {
$icon = '';
}
$cache->setCache('navbar_order');
if ($cache->isCached('more_dropdown_order')) {
$order = $cache->retrieve('more_dropdown_order');
} else {
$order = 2500;
}
$navigation->addDropdown('more_dropdown', $language->get('general', 'more'), 'top', $order, $icon);
// Custom pages
$custom_pages = DB::getInstance()->get('custom_pages', ['id', '<>', 0])->results();
if (count($custom_pages)) {
$more = [];
$cache->setCache('navbar_order');
if ($user->isLoggedIn()) {
// Check all groups
$user_groups = $user->getAllGroupIds();
foreach ($custom_pages as $custom_page) {
$redirect = null;
// Get redirect URL if enabled
if ($custom_page->redirect == 1) {
$redirect = $custom_page->link;
}
$pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic);
foreach ($user_groups as $user_group) {
$custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', $user_group])->results();
/data/core/classes/Core/Settings.php
SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL;
private static function setSettingsCache(?string $module, array $cache): void
{
$cache_name = $module !== null ? $module : 'core';
self::$_cached_settings[$cache_name] = $cache;
}
/**
* Get a setting from the database table `nl2_settings`.
*
* @param string $setting Setting to check.
* @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null.
* @param string $module Module name to keep settings separate from other modules. Set module
* to 'Core' for global settings.
* @return ?string Setting from DB or $fallback.
*/
public static function get(string $setting, ?string $fallback = null, string $module = 'core'): ?string
{
if (!self::hasSettingsCache($module)) {
// Load all settings for this module and store it as a dictionary
if ($module === 'core') {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL')->results();
} else {
$result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = ?', [$module])->results();
}
$cache = [];
foreach ($result as $row) {
$cache[$row->name] = $row->value;
}
self::setSettingsCache($module, $cache);
}
$cache = &self::getSettingsCache($module);
return $cache[$setting] ?? $fallback;
}
/**
* Modify a setting in the database table `nl2_settings`.
*
* @param string $setting Setting name.