inital commit
This commit is contained in:
643
webroot/forum/inc/datahandlers/event.php
Normal file
643
webroot/forum/inc/datahandlers/event.php
Normal file
@@ -0,0 +1,643 @@
|
||||
<?php
|
||||
/**
|
||||
* MyBB 1.8
|
||||
* Copyright 2014 MyBB Group, All Rights Reserved
|
||||
*
|
||||
* Website: http://www.mybb.com
|
||||
* License: http://www.mybb.com/about/license
|
||||
*
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handling class, provides common structure to handle event data.
|
||||
*
|
||||
*/
|
||||
class EventDataHandler extends DataHandler
|
||||
{
|
||||
/**
|
||||
* The language file used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_file = 'datahandler_event';
|
||||
|
||||
/**
|
||||
* The prefix for the language variables used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_prefix = 'eventdata';
|
||||
|
||||
/**
|
||||
* Array of data inserted in to an event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $event_insert_data = array();
|
||||
|
||||
/**
|
||||
* Array of data used to update an event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $event_update_data = array();
|
||||
|
||||
/**
|
||||
* Event ID currently being manipulated by the datahandlers.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $eid = 0;
|
||||
|
||||
/**
|
||||
* Values to be returned after inserting/updating an event.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $return_values = array();
|
||||
|
||||
/**
|
||||
* Verifies if an event name is valid or not and attempts to fix it
|
||||
*
|
||||
* @return boolean True if valid, false if invalid.
|
||||
*/
|
||||
function verify_name()
|
||||
{
|
||||
$name = &$this->data['name'];
|
||||
$name = trim($name);
|
||||
if(!$name)
|
||||
{
|
||||
$this->set_error("missing_name");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if an event description is valid or not and attempts to fix it
|
||||
*
|
||||
* @return boolean True if valid, false if invalid.
|
||||
*/
|
||||
function verify_description()
|
||||
{
|
||||
$description = &$this->data['description'];
|
||||
$description = trim($description);
|
||||
if(!$description)
|
||||
{
|
||||
$this->set_error("missing_description");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if an event date is valid or not and attempts to fix it
|
||||
*
|
||||
* @return boolean True if valid, false if invalid.
|
||||
*/
|
||||
function verify_date()
|
||||
{
|
||||
$event = &$this->data;
|
||||
|
||||
// All types of events require a start date
|
||||
if(!$event['start_date']['day'] || !$event['start_date']['month'] || !$event['start_date']['year'])
|
||||
{
|
||||
$this->set_error("invalid_start_date");
|
||||
return false;
|
||||
}
|
||||
|
||||
$event['start_date']['day'] = (int)$event['start_date']['day'];
|
||||
$event['start_date']['month'] = (int)$event['start_date']['month'];
|
||||
$event['start_date']['year'] = (int)$event['start_date']['year'];
|
||||
|
||||
if($event['start_date']['day'] > date("t", mktime(0, 0, 0, $event['start_date']['month'], 1, $event['start_date']['year'])))
|
||||
{
|
||||
$this->set_error("invalid_start_date");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calendar events can only be within the next 5 years
|
||||
if($event['start_date']['year'] > date("Y") + 5)
|
||||
{
|
||||
$this->set_error("invalid_start_year");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check to see if the month is within 1 and 12
|
||||
if($event['start_date']['month'] > 12 || $event['start_date']['month'] < 1)
|
||||
{
|
||||
$this->set_error("invalid_start_month");
|
||||
return false;
|
||||
}
|
||||
|
||||
// For ranged events, we check the end date & times too
|
||||
if($event['type'] == "ranged")
|
||||
{
|
||||
if(!$event['end_date']['day'] || !$event['end_date']['month'] || !$event['end_date']['year'])
|
||||
{
|
||||
$this->set_error("invalid_end_date");
|
||||
return false;
|
||||
}
|
||||
|
||||
$event['end_date']['day'] = (int)$event['end_date']['day'];
|
||||
$event['end_date']['month'] = (int)$event['end_date']['month'];
|
||||
$event['end_date']['year'] = (int)$event['end_date']['year'];
|
||||
|
||||
if($event['end_date']['day'] > date("t", mktime(0, 0, 0, $event['end_date']['month'], 1, $event['end_date']['year'])))
|
||||
{
|
||||
$this->set_error("invalid_end_date");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calendar events can only be within the next 5 years
|
||||
if($event['end_date']['year'] > date("Y") + 5)
|
||||
{
|
||||
$this->set_error("invalid_end_year");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check to see if the month is within 1 and 12
|
||||
if($event['end_date']['month'] > 12 || $event['end_date']['month'] < 1)
|
||||
{
|
||||
$this->set_error("invalid_end_month");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate time input
|
||||
if($event['start_date']['time'] || $event['end_date']['time'])
|
||||
{
|
||||
if(($event['start_date']['time'] && !$event['end_date']['time']) || ($event['end_date']['time'] && !$event['start_date']['time']))
|
||||
{
|
||||
$this->set_error("cant_specify_one_time");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Begin start time validation
|
||||
$start_time = $this->verify_time($event['start_date']['time']);
|
||||
if(!is_array($start_time))
|
||||
{
|
||||
$this->set_error("start_time_invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
// End time validation
|
||||
$end_time = $this->verify_time($event['end_date']['time']);
|
||||
if(!is_array($end_time))
|
||||
{
|
||||
$this->set_error("end_time_invalid");
|
||||
return false;
|
||||
}
|
||||
$event['usingtime'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$start_time = array("hour" => 0, "min" => 0);
|
||||
$end_time = array("hour" => 23, "min" => 59);
|
||||
$event['usingtime'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists('timezone', $event))
|
||||
{
|
||||
$event['timezone'] = (float)$event['timezone'];
|
||||
if($event['timezone'] > 12 || $event['timezone'] < -12)
|
||||
{
|
||||
$this->set_error("invalid_timezone");
|
||||
return false;
|
||||
}
|
||||
$start_time['hour'] -= $event['timezone'];
|
||||
$end_time['hour'] -= $event['timezone'];
|
||||
}
|
||||
|
||||
if(!isset($start_time))
|
||||
{
|
||||
$start_time = array("hour" => 0, "min" => 0);
|
||||
}
|
||||
|
||||
$start_timestamp = gmmktime($start_time['hour'], $start_time['min'], 0, $event['start_date']['month'], $event['start_date']['day'], $event['start_date']['year']);
|
||||
|
||||
if($event['type'] == "ranged")
|
||||
{
|
||||
$end_timestamp = gmmktime($end_time['hour'], $end_time['min'], 0, $event['end_date']['month'], $event['end_date']['day'], $event['end_date']['year']);
|
||||
|
||||
if($end_timestamp <= $start_timestamp)
|
||||
{
|
||||
$this->set_error("end_in_past");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($end_timestamp))
|
||||
{
|
||||
$end_timestamp = 0;
|
||||
}
|
||||
|
||||
// Save our time stamps for saving
|
||||
$event['starttime'] = $start_timestamp;
|
||||
$event['endtime'] = $end_timestamp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $time
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
function verify_time($time)
|
||||
{
|
||||
preg_match('#^(0?[1-9]|1[012])\s?([:\.]?)\s?([0-5][0-9])?(\s?[ap]m)|([01][0-9]|2[0-3])\s?([:\.])\s?([0-5][0-9])$#i', $time, $matches);
|
||||
if(count($matches) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 24h time
|
||||
if(count($matches) == 8)
|
||||
{
|
||||
$hour = $matches[5];
|
||||
$min = $matches[7];
|
||||
}
|
||||
// 12 hour time
|
||||
else
|
||||
{
|
||||
$hour = $matches[1];
|
||||
$min = (int)$matches[3];
|
||||
$matches[4] = trim($matches[4]);
|
||||
if(my_strtolower($matches[4]) == "pm" && $hour != 12)
|
||||
{
|
||||
$hour += 12;
|
||||
}
|
||||
else if(my_strtolower($matches[4]) == "am" && $hour == 12)
|
||||
{
|
||||
$hour = 0;
|
||||
}
|
||||
}
|
||||
return array("hour" => $hour, "min" => $min);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function verify_repeats()
|
||||
{
|
||||
$event = &$this->data;
|
||||
|
||||
if(!is_array($event['repeats']) || !$event['repeats']['repeats'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!$event['endtime'])
|
||||
{
|
||||
$this->set_error("only_ranged_events_repeat");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($event['repeats']['repeats'])
|
||||
{
|
||||
case 1:
|
||||
$event['repeats']['days'] = (int)$event['repeats']['days'];
|
||||
if($event['repeats']['days'] <= 0)
|
||||
{
|
||||
$this->set_error("invalid_repeat_day_interval");
|
||||
return false;
|
||||
}
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
$event['repeats']['weeks'] = (int)$event['repeats']['weeks'];
|
||||
if($event['repeats']['weeks'] <= 0)
|
||||
{
|
||||
$this->set_error("invalid_repeat_week_interval");
|
||||
return false;
|
||||
}
|
||||
if(is_array($event['repeats']['days']) && count($event['repeats']['days']) == 0)
|
||||
{
|
||||
$this->set_error("invalid_repeat_weekly_days");
|
||||
return false;
|
||||
}
|
||||
asort($event['repeats']['days']);
|
||||
break;
|
||||
case 4:
|
||||
if($event['repeats']['day'])
|
||||
{
|
||||
$event['repeats']['day'] = (int)$event['repeats']['day'];
|
||||
if($event['repeats']['day'] <= 0 || $event['repeats']['day'] > 31)
|
||||
{
|
||||
$this->set_error("invalid_repeat_day_interval");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($event['repeats']['occurance'] != "last")
|
||||
{
|
||||
$event['repeats']['occurance'] = (int)$event['repeats']['occurance'];
|
||||
}
|
||||
$event['repeats']['weekday'] = (int)$event['repeats']['weekday'];
|
||||
}
|
||||
$event['repeats']['months'] = (int)$event['repeats']['months'];
|
||||
if($event['repeats']['months'] <= 0 || $event['repeats']['months'] > 12)
|
||||
{
|
||||
$this->set_error("invalid_repeat_month_interval");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if($event['repeats']['day'])
|
||||
{
|
||||
$event['repeats']['day'] = (int)$event['repeats']['day'];
|
||||
if($event['repeats']['day'] <= 0 || $event['repeats']['day'] > 31)
|
||||
{
|
||||
$this->set_error("invalid_repeat_day_interval");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($event['repeats']['occurance'] != "last")
|
||||
{
|
||||
$event['repeats']['occurance'] = (int)$event['repeats']['occurance'];
|
||||
}
|
||||
$event['repeats']['weekday'] = (int)$event['repeats']['weekday'];
|
||||
}
|
||||
$event['repeats']['month'] = (int)$event['repeats']['month'];
|
||||
if($event['repeats']['month'] <= 0 || $event['repeats']['month'] > 12)
|
||||
{
|
||||
$this->set_error("invalid_repeat_month_interval");
|
||||
return false;
|
||||
}
|
||||
$event['repeats']['years'] = (int)$event['repeats']['years'];
|
||||
if($event['repeats']['years'] <= 0 || $event['repeats']['years'] > 4)
|
||||
{
|
||||
$this->set_error("invalid_repeat_year_interval");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$event['repeats'] = array();
|
||||
}
|
||||
require_once MYBB_ROOT."inc/functions_calendar.php";
|
||||
$event['starttime_user'] = $event['starttime'];
|
||||
$event['endtime_user'] = $event['endtime'];
|
||||
$next_occurance = fetch_next_occurance($event, array('start' => $event['starttime'], 'end' => $event['endtime']), $event['starttime'], true);
|
||||
if($next_occurance > $event['endtime'])
|
||||
{
|
||||
$this->set_error("event_wont_occur");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an event.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function validate_event()
|
||||
{
|
||||
global $plugins;
|
||||
|
||||
$event = &$this->data;
|
||||
|
||||
if($this->method == "insert" || array_key_exists('name', $event))
|
||||
{
|
||||
$this->verify_name();
|
||||
}
|
||||
|
||||
if($this->method == "insert" || array_key_exists('description', $event))
|
||||
{
|
||||
$this->verify_description();
|
||||
}
|
||||
|
||||
if($this->method == "insert" || array_key_exists('start_date', $event) || array_key_exists('end_date', $event))
|
||||
{
|
||||
$this->verify_date();
|
||||
}
|
||||
|
||||
if(($this->method == "insert" && $event['endtime']) || array_key_exists('repeats', $event))
|
||||
{
|
||||
$this->verify_repeats();
|
||||
}
|
||||
|
||||
$plugins->run_hooks("datahandler_event_validate", $this);
|
||||
|
||||
// We are done validating, return.
|
||||
$this->set_validated(true);
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an event into the database.
|
||||
*
|
||||
* @return array Array of new event details, eid and private.
|
||||
*/
|
||||
function insert_event()
|
||||
{
|
||||
global $db, $mybb, $plugins;
|
||||
|
||||
// Yes, validating is required.
|
||||
if(!$this->get_validated())
|
||||
{
|
||||
die("The event needs to be validated before inserting it into the DB.");
|
||||
}
|
||||
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
die("The event is not valid.");
|
||||
}
|
||||
|
||||
$event = &$this->data;
|
||||
|
||||
$query = $db->simple_select("calendars", "*", "cid='".(int)$event['cid']."'");
|
||||
$calendar_moderation = $db->fetch_field($query, "moderation");
|
||||
if($calendar_moderation == 1 && (int)$event['private'] != 1)
|
||||
{
|
||||
$visible = 0;
|
||||
if($event['uid'] == $mybb->user['uid'])
|
||||
{
|
||||
$calendar_permissions = get_calendar_permissions($event['cid']);
|
||||
if($calendar_permissions['canbypasseventmod'] == 1)
|
||||
{
|
||||
$visible = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$visible = 1;
|
||||
}
|
||||
|
||||
// Prepare an array for insertion into the database.
|
||||
$this->event_insert_data = array(
|
||||
'cid' => (int)$event['cid'],
|
||||
'uid' => (int)$event['uid'],
|
||||
'name' => $db->escape_string($event['name']),
|
||||
'description' => $db->escape_string($event['description']),
|
||||
'visible' => $visible,
|
||||
'private' => (int)$event['private'],
|
||||
'dateline' => TIME_NOW,
|
||||
'starttime' => (int)$event['starttime'],
|
||||
'endtime' => (int)$event['endtime']
|
||||
);
|
||||
|
||||
if(isset($event['timezone']))
|
||||
{
|
||||
$this->event_insert_data['timezone'] = $db->escape_string((float)$event['timezone']);
|
||||
}
|
||||
|
||||
if(isset($event['ignoretimezone']))
|
||||
{
|
||||
$this->event_insert_data['ignoretimezone'] = (int)$event['ignoretimezone'];
|
||||
}
|
||||
|
||||
if(isset($event['usingtime']))
|
||||
{
|
||||
$this->event_insert_data['usingtime'] = (int)$event['usingtime'];
|
||||
}
|
||||
|
||||
if(isset($event['repeats']))
|
||||
{
|
||||
$this->event_insert_data['repeats'] = $db->escape_string(my_serialize($event['repeats']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->event_insert_data['repeats'] = '';
|
||||
}
|
||||
|
||||
$plugins->run_hooks("datahandler_event_insert", $this);
|
||||
|
||||
$this->eid = $db->insert_query("events", $this->event_insert_data);
|
||||
|
||||
// Return the event's eid and whether or not it is private.
|
||||
$this->return_values = array(
|
||||
'eid' => $this->eid,
|
||||
'private' => $event['private'],
|
||||
'visible' => $visible
|
||||
);
|
||||
|
||||
$plugins->run_hooks("datahandler_event_insert_end", $this);
|
||||
|
||||
return $this->return_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an event that is already in the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function update_event()
|
||||
{
|
||||
global $db, $plugins;
|
||||
|
||||
// Yes, validating is required.
|
||||
if(!$this->get_validated())
|
||||
{
|
||||
die("The event needs to be validated before inserting it into the DB.");
|
||||
}
|
||||
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
die("The event is not valid.");
|
||||
}
|
||||
|
||||
$event = &$this->data;
|
||||
|
||||
$this->eid = $event['eid'];
|
||||
|
||||
if(isset($event['cid']))
|
||||
{
|
||||
$this->event_update_data['cid'] = $db->escape_string($event['cid']);
|
||||
}
|
||||
|
||||
if(isset($event['name']))
|
||||
{
|
||||
$this->event_update_data['name'] = $db->escape_string($event['name']);
|
||||
}
|
||||
|
||||
if(isset($event['description']))
|
||||
{
|
||||
$this->event_update_data['description'] = $db->escape_string($event['description']);
|
||||
}
|
||||
|
||||
if(isset($event['starttime']))
|
||||
{
|
||||
$this->event_update_data['starttime'] = (int)$event['starttime'];
|
||||
$this->event_update_data['usingtime'] = (int)$event['usingtime'];
|
||||
}
|
||||
|
||||
if(isset($event['endtime']))
|
||||
{
|
||||
$this->event_update_data['endtime'] = (int)$event['endtime'];
|
||||
$this->event_update_data['usingtime'] = (int)$event['usingtime'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->event_update_data['endtime'] = 0;
|
||||
$this->event_update_data['usingtime'] = 0;
|
||||
}
|
||||
|
||||
if(isset($event['repeats']))
|
||||
{
|
||||
if(!empty($event['repeats']))
|
||||
{
|
||||
$event['repeats'] = my_serialize($event['repeats']);
|
||||
}
|
||||
$this->event_update_data['repeats'] = $db->escape_string($event['repeats']);
|
||||
}
|
||||
|
||||
if(isset($event['timezone']))
|
||||
{
|
||||
$this->event_update_data['timezone'] = $db->escape_string((float)$event['timezone']);
|
||||
}
|
||||
|
||||
if(isset($event['ignoretimezone']))
|
||||
{
|
||||
$this->event_update_data['ignoretimezone'] = (int)$event['ignoretimezone'];
|
||||
}
|
||||
|
||||
if(isset($event['private']))
|
||||
{
|
||||
$this->event_update_data['private'] = (int)$event['private'];
|
||||
}
|
||||
|
||||
if(isset($event['visible']))
|
||||
{
|
||||
$this->event_update_data['visible'] = $db->escape_string($event['visible']);
|
||||
}
|
||||
|
||||
if(isset($event['uid']))
|
||||
{
|
||||
$this->event_update_data['uid'] = (int)$event['uid'];
|
||||
}
|
||||
|
||||
$plugins->run_hooks("datahandler_event_update", $this);
|
||||
|
||||
$db->update_query("events", $this->event_update_data, "eid='".(int)$event['eid']."'");
|
||||
|
||||
// Return the event's eid and whether or not it is private.
|
||||
$this->return_values = array(
|
||||
'eid' => $event['eid'],
|
||||
'private' => $event['private']
|
||||
);
|
||||
|
||||
$plugins->run_hooks("datahandler_event_update_end", $this);
|
||||
|
||||
return $this->return_values;
|
||||
}
|
||||
}
|
||||
|
||||
8
webroot/forum/inc/datahandlers/index.html
Normal file
8
webroot/forum/inc/datahandlers/index.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
340
webroot/forum/inc/datahandlers/login.php
Normal file
340
webroot/forum/inc/datahandlers/login.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
/**
|
||||
* MyBB 1.8
|
||||
* Copyright 2014 MyBB Group, All Rights Reserved
|
||||
*
|
||||
* Website: http://www.mybb.com
|
||||
* License: http://www.mybb.com/about/license
|
||||
*
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Login handling class, provides common structure to handle login events.
|
||||
*
|
||||
*/
|
||||
class LoginDataHandler extends DataHandler
|
||||
{
|
||||
/**
|
||||
* The language file used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_file = 'datahandler_login';
|
||||
|
||||
/**
|
||||
* The prefix for the language variables used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_prefix = 'logindata';
|
||||
|
||||
/**
|
||||
* Array of data used via login events.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $login_data = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $captcha_verified = true;
|
||||
|
||||
/**
|
||||
* @var bool|captcha
|
||||
*/
|
||||
private $captcha = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $username_method = null;
|
||||
|
||||
/**
|
||||
* @param int $check_captcha
|
||||
*/
|
||||
function verify_attempts($check_captcha = 0)
|
||||
{
|
||||
global $db, $mybb;
|
||||
|
||||
$user = &$this->data;
|
||||
|
||||
if($check_captcha)
|
||||
{
|
||||
if(!isset($mybb->cookies['loginattempts']))
|
||||
{
|
||||
$mybb->cookies['loginattempts'] = 0;
|
||||
}
|
||||
if($mybb->settings['failedcaptchalogincount'] > 0 && ($user['loginattempts'] > $mybb->settings['failedcaptchalogincount'] || (int)$mybb->cookies['loginattempts'] > $mybb->settings['failedcaptchalogincount']))
|
||||
{
|
||||
$this->captcha_verified = false;
|
||||
$this->verify_captcha();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function verify_captcha()
|
||||
{
|
||||
global $db, $mybb;
|
||||
|
||||
$user = &$this->data;
|
||||
|
||||
if($user['imagestring'] || $mybb->settings['captchaimage'] != 1)
|
||||
{
|
||||
// Check their current captcha input - if correct, hide the captcha input area
|
||||
require_once MYBB_ROOT.'inc/class_captcha.php';
|
||||
$this->captcha = new captcha;
|
||||
|
||||
if($this->captcha->validate_captcha() == false)
|
||||
{
|
||||
// CAPTCHA validation failed
|
||||
foreach($this->captcha->get_errors() as $error)
|
||||
{
|
||||
$this->set_error($error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->captcha_verified = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if($mybb->input['quick_login'] == 1 && $mybb->input['quick_password'] && $mybb->input['quick_username'])
|
||||
{
|
||||
$this->set_error('regimagerequired');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('regimageinvalid');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function verify_username()
|
||||
{
|
||||
$this->get_login_data();
|
||||
|
||||
if(!$this->login_data['uid'])
|
||||
{
|
||||
$this->invalid_combination();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $strict
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function verify_password($strict = true)
|
||||
{
|
||||
global $db, $mybb, $plugins;
|
||||
|
||||
$this->get_login_data();
|
||||
|
||||
if(empty($this->login_data['username']))
|
||||
{
|
||||
// Username must be validated to apply a password to
|
||||
$this->invalid_combination();
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'this' => &$this,
|
||||
'strict' => &$strict,
|
||||
);
|
||||
|
||||
$plugins->run_hooks('datahandler_login_verify_password_start', $args);
|
||||
|
||||
$user = &$this->data;
|
||||
|
||||
if(!$this->login_data['uid'] || $this->login_data['uid'] && !$this->login_data['salt'] && $strict == false)
|
||||
{
|
||||
$this->invalid_combination();
|
||||
}
|
||||
|
||||
if($strict == true)
|
||||
{
|
||||
if(!$this->login_data['salt'])
|
||||
{
|
||||
// Generate a salt for this user and assume the password stored in db is a plain md5 password
|
||||
$password_fields = create_password($this->login_data['password']);
|
||||
$this->login_data = array_merge($this->login_data, $password_fields);
|
||||
$db->update_query("users", $password_fields, "uid = '{$this->login_data['uid']}'");
|
||||
}
|
||||
|
||||
if(!$this->login_data['loginkey'])
|
||||
{
|
||||
$this->login_data['loginkey'] = generate_loginkey();
|
||||
|
||||
$sql_array = array(
|
||||
"loginkey" => $this->login_data['loginkey']
|
||||
);
|
||||
|
||||
$db->update_query("users", $sql_array, "uid = '{$this->login_data['uid']}'");
|
||||
}
|
||||
}
|
||||
|
||||
$plugins->run_hooks('datahandler_login_verify_password_end', $args);
|
||||
|
||||
if(!verify_user_password($this->login_data, $user['password']))
|
||||
{
|
||||
$this->invalid_combination(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $show_login_attempts
|
||||
*/
|
||||
function invalid_combination($show_login_attempts = false)
|
||||
{
|
||||
global $db, $lang, $mybb;
|
||||
|
||||
// Don't show an error when the captcha was wrong!
|
||||
if(!$this->captcha_verified)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$login_text = '';
|
||||
if($show_login_attempts)
|
||||
{
|
||||
if($mybb->settings['failedlogincount'] != 0 && $mybb->settings['failedlogintext'] == 1 && $this->login_data['uid'] != 0)
|
||||
{
|
||||
$logins = login_attempt_check($this->login_data['uid'], false) + 1;
|
||||
$login_text = $lang->sprintf($lang->failed_login_again, $mybb->settings['failedlogincount'] - $logins);
|
||||
}
|
||||
}
|
||||
|
||||
switch($mybb->settings['username_method'])
|
||||
{
|
||||
case 1:
|
||||
$this->set_error('invalidpwordusernameemail', $login_text);
|
||||
break;
|
||||
case 2:
|
||||
$this->set_error('invalidpwordusernamecombo', $login_text);
|
||||
break;
|
||||
default:
|
||||
$this->set_error('invalidpwordusername', $login_text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function get_login_data()
|
||||
{
|
||||
global $db, $settings;
|
||||
|
||||
$user = &$this->data;
|
||||
|
||||
$options = array(
|
||||
'fields' => '*',
|
||||
'username_method' => (int)$settings['username_method']
|
||||
);
|
||||
|
||||
if($this->username_method !== null)
|
||||
{
|
||||
$options['username_method'] = (int)$this->username_method;
|
||||
}
|
||||
|
||||
$this->login_data = get_user_by_username($user['username'], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function validate_login()
|
||||
{
|
||||
global $plugins, $mybb;
|
||||
|
||||
$user = &$this->data;
|
||||
|
||||
$plugins->run_hooks('datahandler_login_validate_start', $this);
|
||||
|
||||
if(!defined('IN_ADMINCP'))
|
||||
{
|
||||
$this->verify_attempts($mybb->settings['captchaimage']);
|
||||
}
|
||||
|
||||
if(array_key_exists('username', $user))
|
||||
{
|
||||
$this->verify_username();
|
||||
}
|
||||
|
||||
if(array_key_exists('password', $user))
|
||||
{
|
||||
$this->verify_password();
|
||||
}
|
||||
|
||||
$plugins->run_hooks('datahandler_login_validate_end', $this);
|
||||
|
||||
$this->set_validated(true);
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true
|
||||
*/
|
||||
function complete_login()
|
||||
{
|
||||
global $plugins, $db, $mybb, $session;
|
||||
|
||||
$user = &$this->login_data;
|
||||
|
||||
$plugins->run_hooks('datahandler_login_complete_start', $this);
|
||||
|
||||
// Login to MyBB
|
||||
my_setcookie('loginattempts', 1);
|
||||
my_setcookie("sid", $session->sid, -1, true);
|
||||
|
||||
$ip_address = $db->escape_binary($session->packedip);
|
||||
$db->delete_query("sessions", "ip = {$ip_address} AND sid != '{$session->sid}'");
|
||||
|
||||
$newsession = array(
|
||||
"uid" => $user['uid'],
|
||||
);
|
||||
|
||||
$db->update_query("sessions", $newsession, "sid = '{$session->sid}'");
|
||||
$db->update_query("users", array("loginattempts" => 1), "uid = '{$user['uid']}'");
|
||||
|
||||
$remember = null;
|
||||
if(!isset($mybb->input['remember']) || $mybb->input['remember'] != "yes")
|
||||
{
|
||||
$remember = -1;
|
||||
}
|
||||
|
||||
my_setcookie("mybbuser", $user['uid']."_".$user['loginkey'], $remember, true, "lax");
|
||||
|
||||
if($this->captcha !== false)
|
||||
{
|
||||
$this->captcha->invalidate_captcha();
|
||||
}
|
||||
|
||||
$plugins->run_hooks('datahandler_login_complete_end', $this);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
772
webroot/forum/inc/datahandlers/pm.php
Normal file
772
webroot/forum/inc/datahandlers/pm.php
Normal file
@@ -0,0 +1,772 @@
|
||||
<?php
|
||||
/**
|
||||
* MyBB 1.8
|
||||
* Copyright 2014 MyBB Group, All Rights Reserved
|
||||
*
|
||||
* Website: http://www.mybb.com
|
||||
* License: http://www.mybb.com/about/license
|
||||
*
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
* PM handling class, provides common structure to handle private messaging data.
|
||||
*
|
||||
*/
|
||||
class PMDataHandler extends DataHandler
|
||||
{
|
||||
/**
|
||||
* The language file used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_file = 'datahandler_pm';
|
||||
|
||||
/**
|
||||
* The prefix for the language variables used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_prefix = 'pmdata';
|
||||
|
||||
/**
|
||||
* Array of data inserted in to a private message.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pm_insert_data = array();
|
||||
|
||||
/**
|
||||
* Array of data used to update a private message.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pm_update_data = array();
|
||||
|
||||
/**
|
||||
* PM ID currently being manipulated by the datahandlers.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $pmid = 0;
|
||||
|
||||
/**
|
||||
* Values to be returned after inserting a PM.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $return_values = array();
|
||||
|
||||
/**
|
||||
* Verifies a private message subject.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function verify_subject()
|
||||
{
|
||||
$subject = &$this->data['subject'];
|
||||
|
||||
// Subject is over 85 characters, too long.
|
||||
if(my_strlen($subject) > 85)
|
||||
{
|
||||
$this->set_error("too_long_subject");
|
||||
return false;
|
||||
}
|
||||
// No subject, apply the default [no subject]
|
||||
if(!trim_blank_chrs($subject))
|
||||
{
|
||||
$this->set_error("missing_subject");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if a message for a PM is valid.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function verify_message()
|
||||
{
|
||||
$message = &$this->data['message'];
|
||||
|
||||
// No message, return an error.
|
||||
if(trim_blank_chrs($message) == '')
|
||||
{
|
||||
$this->set_error("missing_message");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the length of message is beyond SQL limitation for 'text' field
|
||||
else if(strlen($message) > 65535)
|
||||
{
|
||||
$this->set_error("message_too_long", array('65535', strlen($message)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the specified sender is valid or not.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function verify_sender()
|
||||
{
|
||||
global $db, $mybb, $lang;
|
||||
|
||||
$pm = &$this->data;
|
||||
|
||||
// Return if we've already validated
|
||||
if(!empty($pm['sender']))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fetch the senders profile data.
|
||||
$sender = get_user($pm['fromid']);
|
||||
|
||||
// Collect user permissions for the sender.
|
||||
$sender_permissions = user_permissions($pm['fromid']);
|
||||
|
||||
// Check if the sender is over their quota or not - if they are, disable draft sending
|
||||
if(isset($pm['options']['savecopy']) && $pm['options']['savecopy'] != 0 && empty($pm['saveasdraft']))
|
||||
{
|
||||
if($sender_permissions['pmquota'] != 0 && $sender['totalpms'] >= $sender_permissions['pmquota'] && $this->admin_override != true)
|
||||
{
|
||||
$pm['options']['savecopy'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the sender information to the data.
|
||||
$pm['sender'] = array(
|
||||
"uid" => $sender['uid'],
|
||||
"username" => $sender['username']
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if an array of recipients for a private message are valid
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function verify_recipient()
|
||||
{
|
||||
global $cache, $db, $mybb, $lang;
|
||||
|
||||
$pm = &$this->data;
|
||||
|
||||
$recipients = array();
|
||||
|
||||
$invalid_recipients = array();
|
||||
// We have our recipient usernames but need to fetch user IDs
|
||||
if(array_key_exists("to", $pm))
|
||||
{
|
||||
foreach(array("to", "bcc") as $recipient_type)
|
||||
{
|
||||
if(!isset($pm[$recipient_type]))
|
||||
{
|
||||
$pm[$recipient_type] = array();
|
||||
}
|
||||
if(!is_array($pm[$recipient_type]))
|
||||
{
|
||||
$pm[$recipient_type] = array($pm[$recipient_type]);
|
||||
}
|
||||
|
||||
$pm[$recipient_type] = array_map('trim', $pm[$recipient_type]);
|
||||
$pm[$recipient_type] = array_filter($pm[$recipient_type]);
|
||||
|
||||
// No recipients? Skip query
|
||||
if(empty($pm[$recipient_type]))
|
||||
{
|
||||
if($recipient_type == 'to' && !$pm['saveasdraft'])
|
||||
{
|
||||
$this->set_error("no_recipients");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$recipientUsernames = array_map(array($db, 'escape_string'), $pm[$recipient_type]);
|
||||
$recipientUsernames = "'".implode("','", $recipientUsernames)."'";
|
||||
|
||||
$query = $db->simple_select('users', '*', 'username IN('.$recipientUsernames.')');
|
||||
|
||||
$validUsernames = array();
|
||||
|
||||
while($user = $db->fetch_array($query))
|
||||
{
|
||||
if($recipient_type == "bcc")
|
||||
{
|
||||
$user['bcc'] = 1;
|
||||
}
|
||||
|
||||
$recipients[] = $user;
|
||||
$validUsernames[] = $user['username'];
|
||||
}
|
||||
|
||||
foreach($pm[$recipient_type] as $username)
|
||||
{
|
||||
if(!in_array($username, $validUsernames))
|
||||
{
|
||||
$invalid_recipients[] = $username;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We have recipient IDs
|
||||
else
|
||||
{
|
||||
foreach(array("toid", "bccid") as $recipient_type)
|
||||
{
|
||||
if(!isset($pm[$recipient_type]))
|
||||
{
|
||||
$pm[$recipient_type] = array();
|
||||
}
|
||||
if(!is_array($pm[$recipient_type]))
|
||||
{
|
||||
$pm[$recipient_type] = array($pm[$recipient_type]);
|
||||
}
|
||||
$pm[$recipient_type] = array_map('intval', $pm[$recipient_type]);
|
||||
$pm[$recipient_type] = array_filter($pm[$recipient_type]);
|
||||
|
||||
// No recipients? Skip query
|
||||
if(empty($pm[$recipient_type]))
|
||||
{
|
||||
if($recipient_type == 'toid' && !$pm['saveasdraft'])
|
||||
{
|
||||
$this->set_error("no_recipients");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$recipientUids = "'".implode("','", $pm[$recipient_type])."'";
|
||||
|
||||
$query = $db->simple_select('users', '*', 'uid IN('.$recipientUids.')');
|
||||
|
||||
$validUids = array();
|
||||
|
||||
while($user = $db->fetch_array($query))
|
||||
{
|
||||
if($recipient_type == "bccid")
|
||||
{
|
||||
$user['bcc'] = 1;
|
||||
}
|
||||
|
||||
$recipients[] = $user;
|
||||
$validUids[] = $user['uid'];
|
||||
}
|
||||
|
||||
foreach($pm[$recipient_type] as $uid)
|
||||
{
|
||||
if(!in_array($uid, $validUids))
|
||||
{
|
||||
$invalid_recipients[] = $uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have one or more invalid recipients and we're not saving a draft, error
|
||||
if(count($invalid_recipients) > 0)
|
||||
{
|
||||
$invalid_recipients = implode($lang->comma, array_map("htmlspecialchars_uni", $invalid_recipients));
|
||||
$this->set_error("invalid_recipients", array($invalid_recipients));
|
||||
return false;
|
||||
}
|
||||
|
||||
$sender_permissions = user_permissions($pm['fromid']);
|
||||
|
||||
// Are we trying to send this message to more users than the permissions allow?
|
||||
if($sender_permissions['maxpmrecipients'] > 0 && count($recipients) > $sender_permissions['maxpmrecipients'] && $this->admin_override != true)
|
||||
{
|
||||
$this->set_error("too_many_recipients", array($sender_permissions['maxpmrecipients']));
|
||||
}
|
||||
|
||||
// Now we're done with that we loop through each recipient
|
||||
foreach($recipients as $user)
|
||||
{
|
||||
// Collect group permissions for this recipient.
|
||||
$recipient_permissions = user_permissions($user['uid']);
|
||||
|
||||
// See if the sender is on the recipients ignore list and that either
|
||||
// - admin_override is set or
|
||||
// - sender is an administrator
|
||||
if($this->admin_override != true && $sender_permissions['canoverridepm'] != 1)
|
||||
{
|
||||
if(!empty($user['ignorelist']) && strpos(','.$user['ignorelist'].',', ','.$pm['fromid'].',') !== false)
|
||||
{
|
||||
$this->set_error("recipient_is_ignoring", array(htmlspecialchars_uni($user['username'])));
|
||||
}
|
||||
|
||||
// Is the recipient only allowing private messages from their buddy list?
|
||||
if(empty($pm['saveasdraft']) && $mybb->settings['allowbuddyonly'] == 1 && $user['receivefrombuddy'] == 1 && !empty($user['buddylist']) && strpos(','.$user['buddylist'].',', ','.$pm['fromid'].',') === false)
|
||||
{
|
||||
$this->set_error('recipient_has_buddy_only', array(htmlspecialchars_uni($user['username'])));
|
||||
}
|
||||
|
||||
// Can the recipient actually receive private messages based on their permissions or user setting?
|
||||
if(($user['receivepms'] == 0 || $recipient_permissions['canusepms'] == 0) && empty($pm['saveasdraft']))
|
||||
{
|
||||
$this->set_error("recipient_pms_disabled", array(htmlspecialchars_uni($user['username'])));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the user has reached their private message quota - if they have, email them.
|
||||
if($recipient_permissions['pmquota'] != 0 && $user['totalpms'] >= $recipient_permissions['pmquota'] && $sender_permissions['cancp'] != 1 && empty($pm['saveasdraft']) && !$this->admin_override)
|
||||
{
|
||||
if(trim($user['language']) != '' && $lang->language_exists($user['language']))
|
||||
{
|
||||
$uselang = trim($user['language']);
|
||||
}
|
||||
elseif($mybb->settings['bblanguage'])
|
||||
{
|
||||
$uselang = $mybb->settings['bblanguage'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$uselang = "english";
|
||||
}
|
||||
if($uselang == $mybb->settings['bblanguage'] || !$uselang)
|
||||
{
|
||||
$emailsubject = $lang->emailsubject_reachedpmquota;
|
||||
$emailmessage = $lang->email_reachedpmquota;
|
||||
}
|
||||
else
|
||||
{
|
||||
$userlang = new MyLanguage;
|
||||
$userlang->set_path(MYBB_ROOT."inc/languages");
|
||||
$userlang->set_language($uselang);
|
||||
$userlang->load("messages");
|
||||
$emailsubject = $userlang->emailsubject_reachedpmquota;
|
||||
$emailmessage = $userlang->email_reachedpmquota;
|
||||
}
|
||||
$emailmessage = $lang->sprintf($emailmessage, $user['username'], $mybb->settings['bbname'], $mybb->settings['bburl']);
|
||||
$emailsubject = $lang->sprintf($emailsubject, $mybb->settings['bbname'], $pm['subject']);
|
||||
|
||||
$new_email = array(
|
||||
"mailto" => $db->escape_string($user['email']),
|
||||
"mailfrom" => '',
|
||||
"subject" => $db->escape_string($emailsubject),
|
||||
"message" => $db->escape_string($emailmessage),
|
||||
"headers" => ''
|
||||
);
|
||||
|
||||
$db->insert_query("mailqueue", $new_email);
|
||||
$cache->update_mailqueue();
|
||||
|
||||
if($this->admin_override != true)
|
||||
{
|
||||
$this->set_error("recipient_reached_quota", array(htmlspecialchars_uni($user['username'])));
|
||||
}
|
||||
}
|
||||
|
||||
// Everything looks good, assign some specifics about the recipient
|
||||
$pm['recipients'][$user['uid']] = array(
|
||||
"uid" => $user['uid'],
|
||||
"username" => $user['username'],
|
||||
"email" => $user['email'],
|
||||
"lastactive" => $user['lastactive'],
|
||||
"pmnotice" => $user['pmnotice'],
|
||||
"pmnotify" => $user['pmnotify'],
|
||||
"language" => $user['language']
|
||||
);
|
||||
|
||||
// If this recipient is defined as a BCC recipient, save it
|
||||
if(isset($user['bcc']) && $user['bcc'] == 1)
|
||||
{
|
||||
$pm['recipients'][$user['uid']]['bcc'] = 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the user is not flooding the system.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function verify_pm_flooding()
|
||||
{
|
||||
global $mybb, $db;
|
||||
|
||||
$pm = &$this->data;
|
||||
|
||||
// Check if post flooding is enabled within MyBB or if the admin override option is specified.
|
||||
if($mybb->settings['pmfloodsecs'] > 0 && $pm['fromid'] != 0 && $this->admin_override == false && !is_moderator(0, '', $pm['fromid']))
|
||||
{
|
||||
// Fetch the senders profile data.
|
||||
$sender = get_user($pm['fromid']);
|
||||
|
||||
// Calculate last post
|
||||
$query = $db->simple_select("privatemessages", "dateline", "fromid='".$db->escape_string($pm['fromid'])."' AND toid != '0'", array('order_by' => 'dateline', 'order_dir' => 'desc', 'limit' => 1));
|
||||
$sender['lastpm'] = $db->fetch_field($query, "dateline");
|
||||
|
||||
// A little bit of calculation magic and moderator status checking.
|
||||
if(TIME_NOW-$sender['lastpm'] <= $mybb->settings['pmfloodsecs'])
|
||||
{
|
||||
// Oops, user has been flooding - throw back error message.
|
||||
$time_to_wait = ($mybb->settings['pmfloodsecs'] - (TIME_NOW-$sender['lastpm'])) + 1;
|
||||
if($time_to_wait == 1)
|
||||
{
|
||||
$this->set_error("pm_flooding_one_second");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error("pm_flooding", array($time_to_wait));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All is well that ends well - return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the various 'options' for sending PMs are valid.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function verify_options()
|
||||
{
|
||||
$options = &$this->data['options'];
|
||||
|
||||
$this->verify_yesno_option($options, 'signature', 1);
|
||||
$this->verify_yesno_option($options, 'savecopy', 1);
|
||||
$this->verify_yesno_option($options, 'disablesmilies', 0);
|
||||
|
||||
// Requesting a read receipt?
|
||||
if(isset($options['readreceipt']) && $options['readreceipt'] == 1)
|
||||
{
|
||||
$options['readreceipt'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$options['readreceipt'] = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an entire private message.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_pm()
|
||||
{
|
||||
global $plugins;
|
||||
|
||||
$pm = &$this->data;
|
||||
|
||||
if(empty($pm['savedraft']))
|
||||
{
|
||||
$this->verify_pm_flooding();
|
||||
}
|
||||
|
||||
// Verify all PM assets.
|
||||
$this->verify_subject();
|
||||
|
||||
$this->verify_sender();
|
||||
|
||||
$this->verify_recipient();
|
||||
|
||||
$this->verify_message();
|
||||
|
||||
$this->verify_options();
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_validate", $this);
|
||||
|
||||
// Choose the appropriate folder to save in.
|
||||
if(!empty($pm['saveasdraft']))
|
||||
{
|
||||
$pm['folder'] = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
$pm['folder'] = 1;
|
||||
}
|
||||
|
||||
// We are done validating, return.
|
||||
$this->set_validated(true);
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new private message.
|
||||
*
|
||||
* @return array Array of PM useful data.
|
||||
*/
|
||||
function insert_pm()
|
||||
{
|
||||
global $cache, $db, $mybb, $plugins, $lang;
|
||||
|
||||
// Yes, validating is required.
|
||||
if(!$this->get_validated())
|
||||
{
|
||||
die("The PM needs to be validated before inserting it into the DB.");
|
||||
}
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
die("The PM is not valid.");
|
||||
}
|
||||
|
||||
// Assign data to common variable
|
||||
$pm = &$this->data;
|
||||
|
||||
if(empty($pm['pmid']))
|
||||
{
|
||||
$pm['pmid'] = 0;
|
||||
}
|
||||
$pm['pmid'] = (int)$pm['pmid'];
|
||||
|
||||
if(empty($pm['icon']) || $pm['icon'] < 0)
|
||||
{
|
||||
$pm['icon'] = 0;
|
||||
}
|
||||
|
||||
$uid = 0;
|
||||
|
||||
if(!is_array($pm['recipients']))
|
||||
{
|
||||
$recipient_list = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build recipient list
|
||||
foreach($pm['recipients'] as $recipient)
|
||||
{
|
||||
if(!empty($recipient['bcc']))
|
||||
{
|
||||
$recipient_list['bcc'][] = $recipient['uid'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$recipient_list['to'][] = $recipient['uid'];
|
||||
$uid = $recipient['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->pm_insert_data = array(
|
||||
'fromid' => (int)$pm['sender']['uid'],
|
||||
'folder' => $pm['folder'],
|
||||
'subject' => $db->escape_string($pm['subject']),
|
||||
'icon' => (int)$pm['icon'],
|
||||
'message' => $db->escape_string($pm['message']),
|
||||
'dateline' => TIME_NOW,
|
||||
'status' => 0,
|
||||
'includesig' => $pm['options']['signature'],
|
||||
'smilieoff' => $pm['options']['disablesmilies'],
|
||||
'receipt' => (int)$pm['options']['readreceipt'],
|
||||
'readtime' => 0,
|
||||
'recipients' => $db->escape_string(my_serialize($recipient_list)),
|
||||
'ipaddress' => $db->escape_binary($pm['ipaddress'])
|
||||
);
|
||||
|
||||
// Check if we're updating a draft or not.
|
||||
$query = $db->simple_select("privatemessages", "pmid, deletetime", "folder='3' AND uid='".(int)$pm['sender']['uid']."' AND pmid='{$pm['pmid']}'");
|
||||
$draftcheck = $db->fetch_array($query);
|
||||
|
||||
// This PM was previously a draft
|
||||
if($draftcheck['pmid'])
|
||||
{
|
||||
if($draftcheck['deletetime'])
|
||||
{
|
||||
// This draft was a reply to a PM
|
||||
$pm['pmid'] = $draftcheck['deletetime'];
|
||||
$pm['do'] = "reply";
|
||||
}
|
||||
|
||||
// Delete the old draft as we no longer need it
|
||||
$db->delete_query("privatemessages", "pmid='{$draftcheck['pmid']}'");
|
||||
}
|
||||
|
||||
// Saving this message as a draft
|
||||
if(!empty($pm['saveasdraft']))
|
||||
{
|
||||
$this->pm_insert_data['uid'] = $pm['sender']['uid'];
|
||||
|
||||
// If this is a reply, then piggyback into the deletetime to let us know in the future
|
||||
if($pm['do'] == "reply" || $pm['do'] == "replyall")
|
||||
{
|
||||
$this->pm_insert_data['deletetime'] = $pm['pmid'];
|
||||
}
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_updatedraft", $this);
|
||||
|
||||
$this->pmid = $db->insert_query("privatemessages", $this->pm_insert_data);
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_updatedraft_commit", $this);
|
||||
|
||||
// If this is a draft, end it here - below deals with complete messages
|
||||
return array(
|
||||
"draftsaved" => 1
|
||||
);
|
||||
}
|
||||
|
||||
$this->pmid = array();
|
||||
|
||||
// Save a copy of the PM for each of our recipients
|
||||
foreach($pm['recipients'] as $recipient)
|
||||
{
|
||||
// Send email notification of new PM if it is enabled for the recipient
|
||||
$query = $db->simple_select("privatemessages", "dateline", "uid='".$recipient['uid']."' AND folder='1'", array('order_by' => 'dateline', 'order_dir' => 'desc', 'limit' => 1));
|
||||
$lastpm = $db->fetch_array($query);
|
||||
if($recipient['pmnotify'] == 1 && $recipient['lastactive'] > $lastpm['dateline'])
|
||||
{
|
||||
if($recipient['language'] != "" && $lang->language_exists($recipient['language']))
|
||||
{
|
||||
$uselang = $recipient['language'];
|
||||
}
|
||||
elseif($mybb->settings['bblanguage'])
|
||||
{
|
||||
$uselang = $mybb->settings['bblanguage'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$uselang = "english";
|
||||
}
|
||||
if($uselang == $mybb->settings['bblanguage'] && !empty($lang->emailsubject_newpm))
|
||||
{
|
||||
$emailsubject = $lang->emailsubject_newpm;
|
||||
$emailmessage = $lang->email_newpm;
|
||||
}
|
||||
else
|
||||
{
|
||||
$userlang = new MyLanguage;
|
||||
$userlang->set_path(MYBB_ROOT."inc/languages");
|
||||
$userlang->set_language($uselang);
|
||||
$userlang->load("messages");
|
||||
$emailsubject = $userlang->emailsubject_newpm;
|
||||
$emailmessage = $userlang->email_newpm;
|
||||
}
|
||||
|
||||
if(!$pm['sender']['username'])
|
||||
{
|
||||
$pm['sender']['username'] = $lang->mybb_engine;
|
||||
}
|
||||
|
||||
require_once MYBB_ROOT.'inc/class_parser.php';
|
||||
$parser = new Postparser;
|
||||
|
||||
$parser_options = array(
|
||||
'me_username' => $pm['sender']['username'],
|
||||
'filter_badwords' => 1
|
||||
);
|
||||
|
||||
$pm['message'] = $parser->text_parse_message($pm['message'], $parser_options);
|
||||
|
||||
$emailmessage = $lang->sprintf($emailmessage, $recipient['username'], $pm['sender']['username'], $mybb->settings['bbname'], $mybb->settings['bburl'], $pm['message']);
|
||||
$emailsubject = $lang->sprintf($emailsubject, $mybb->settings['bbname'], $pm['subject']);
|
||||
|
||||
$new_email = array(
|
||||
"mailto" => $db->escape_string($recipient['email']),
|
||||
"mailfrom" => '',
|
||||
"subject" => $db->escape_string($emailsubject),
|
||||
"message" => $db->escape_string($emailmessage),
|
||||
"headers" => ''
|
||||
);
|
||||
|
||||
$db->insert_query("mailqueue", $new_email);
|
||||
$cache->update_mailqueue();
|
||||
}
|
||||
|
||||
$this->pm_insert_data['uid'] = $recipient['uid'];
|
||||
$this->pm_insert_data['toid'] = $recipient['uid'];
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert", $this);
|
||||
|
||||
$this->pmid[] = $db->insert_query("privatemessages", $this->pm_insert_data);
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_commit", $this);
|
||||
|
||||
// If PM noices/alerts are on, show!
|
||||
if($recipient['pmnotice'] == 1)
|
||||
{
|
||||
$updated_user = array(
|
||||
"pmnotice" => 2
|
||||
);
|
||||
$db->update_query("users", $updated_user, "uid='{$recipient['uid']}'");
|
||||
}
|
||||
|
||||
// Update private message count (total, new and unread) for recipient
|
||||
require_once MYBB_ROOT."/inc/functions_user.php";
|
||||
update_pm_count($recipient['uid'], 7, $recipient['lastactive']);
|
||||
}
|
||||
|
||||
// Are we replying or forwarding an existing PM?
|
||||
if($pm['pmid'])
|
||||
{
|
||||
if($pm['do'] == "reply" || $pm['do'] == "replyall")
|
||||
{
|
||||
$sql_array = array(
|
||||
'status' => 3,
|
||||
'statustime' => TIME_NOW
|
||||
);
|
||||
$db->update_query("privatemessages", $sql_array, "pmid={$pm['pmid']} AND uid={$pm['sender']['uid']}");
|
||||
}
|
||||
elseif($pm['do'] == "forward")
|
||||
{
|
||||
$sql_array = array(
|
||||
'status' => 4,
|
||||
'statustime' => TIME_NOW
|
||||
);
|
||||
$db->update_query("privatemessages", $sql_array, "pmid={$pm['pmid']} AND uid={$pm['sender']['uid']}");
|
||||
}
|
||||
}
|
||||
|
||||
// If we're saving a copy
|
||||
if($pm['options']['savecopy'] != 0)
|
||||
{
|
||||
if(isset($recipient_list['to']) && is_array($recipient_list['to']) && count($recipient_list['to']) == 1)
|
||||
{
|
||||
$this->pm_insert_data['toid'] = $uid;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->pm_insert_data['toid'] = 0;
|
||||
}
|
||||
$this->pm_insert_data['uid'] = (int)$pm['sender']['uid'];
|
||||
$this->pm_insert_data['folder'] = 2;
|
||||
$this->pm_insert_data['status'] = 1;
|
||||
$this->pm_insert_data['receipt'] = 0;
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_savedcopy", $this);
|
||||
|
||||
$db->insert_query("privatemessages", $this->pm_insert_data);
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_savedcopy_commit", $this);
|
||||
|
||||
// Because the sender saved a copy, update their total pm count
|
||||
require_once MYBB_ROOT."/inc/functions_user.php";
|
||||
update_pm_count($pm['sender']['uid'], 1);
|
||||
}
|
||||
|
||||
// Return back with appropriate data
|
||||
$this->return_values = array(
|
||||
"messagesent" => 1,
|
||||
"pmids" => $this->pmid
|
||||
);
|
||||
|
||||
$plugins->run_hooks("datahandler_pm_insert_end", $this);
|
||||
|
||||
return $this->return_values;
|
||||
}
|
||||
}
|
||||
1984
webroot/forum/inc/datahandlers/post.php
Normal file
1984
webroot/forum/inc/datahandlers/post.php
Normal file
File diff suppressed because it is too large
Load Diff
1861
webroot/forum/inc/datahandlers/user.php
Normal file
1861
webroot/forum/inc/datahandlers/user.php
Normal file
File diff suppressed because it is too large
Load Diff
741
webroot/forum/inc/datahandlers/warnings.php
Normal file
741
webroot/forum/inc/datahandlers/warnings.php
Normal file
@@ -0,0 +1,741 @@
|
||||
<?php
|
||||
/**
|
||||
* MyBB 1.8
|
||||
* Copyright 2014 MyBB Group, All Rights Reserved
|
||||
*
|
||||
* Website: http://www.mybb.com
|
||||
* License: http://www.mybb.com/about/license
|
||||
*
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Login handling class, provides common structure to handle login events.
|
||||
*
|
||||
*/
|
||||
class WarningsHandler extends DataHandler
|
||||
{
|
||||
/**
|
||||
* The language file used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_file = 'datahandler_warnings';
|
||||
|
||||
/**
|
||||
* The prefix for the language variables used in the data handler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language_prefix = 'warnings';
|
||||
|
||||
/**
|
||||
* The stored data for the warning being written.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $write_warning_data = array();
|
||||
|
||||
/**
|
||||
* The stored data for the warning being retrieved.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $read_warning_data = array();
|
||||
|
||||
/**
|
||||
* Friendly redirect action after inserting a new warning.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $friendly_action = '';
|
||||
|
||||
/**
|
||||
* Validate a warning user assets.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_user()
|
||||
{
|
||||
global $mybb;
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
$user = get_user($warning['uid']);
|
||||
|
||||
if(!$user['uid'])
|
||||
{
|
||||
$this->set_error('error_invalid_user');
|
||||
return false;
|
||||
}
|
||||
|
||||
if($user['uid'] == $mybb->user['uid'])
|
||||
{
|
||||
$this->set_error('error_cannot_warn_self');
|
||||
return false;
|
||||
}
|
||||
|
||||
if($user['warningpoints'] >= $mybb->settings['maxwarningpoints'])
|
||||
{
|
||||
$this->set_error('error_user_reached_max_warning');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a warning post.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_post()
|
||||
{
|
||||
$warning = &$this->data;
|
||||
|
||||
$post = get_post($warning['pid']);
|
||||
|
||||
if(!$post['pid'])
|
||||
{
|
||||
$this->set_error('error_invalid_post');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a warning notes.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_notes()
|
||||
{
|
||||
$warning = &$this->data;
|
||||
|
||||
if(!trim($warning['notes']))
|
||||
{
|
||||
$this->set_error('error_no_note');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate maximum warnings per day for current user.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_maximum()
|
||||
{
|
||||
global $mybb, $db, $lang;
|
||||
|
||||
if($mybb->usergroup['maxwarningsday'] != 0)
|
||||
{
|
||||
$timecut = TIME_NOW-60*60*24;
|
||||
$query = $db->simple_select("warnings", "COUNT(wid) AS given_today", "issuedby='{$mybb->user['uid']}' AND dateline>'$timecut'");
|
||||
$given_today = $db->fetch_field($query, "given_today");
|
||||
if($given_today >= $mybb->usergroup['maxwarningsday'])
|
||||
{
|
||||
$this->set_error('reached_max_warnings_day', array(my_number_format($mybb->usergroup['maxwarningsday'])));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate warnings type.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_type()
|
||||
{
|
||||
global $mybb, $db;
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
// Issuing a custom warning
|
||||
if($warning['type'] == 'custom')
|
||||
{
|
||||
if($mybb->settings['allowcustomwarnings'] == 0)
|
||||
{
|
||||
$this->set_error('error_cant_custom_warn');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$warning['custom_reason'])
|
||||
{
|
||||
$this->set_error('error_no_custom_reason');
|
||||
return false;
|
||||
}
|
||||
|
||||
$warning['title'] = $warning['custom_reason'];
|
||||
|
||||
if(!$warning['custom_points'] || $warning['custom_points'] > $mybb->settings['maxwarningpoints'] || $warning['custom_points'] < 0)
|
||||
{
|
||||
$this->set_error('error_invalid_custom_points', array(my_number_format($mybb->settings['maxwarningpoints'])));
|
||||
return false;
|
||||
}
|
||||
|
||||
$warning['points'] = round($warning['custom_points']);
|
||||
|
||||
// Build expiry date
|
||||
if($warning['expires_period'] == "hours")
|
||||
{
|
||||
$warning['expires'] = $warning['expires']*3600 + TIME_NOW;
|
||||
}
|
||||
else if($warning['expires_period'] == "days")
|
||||
{
|
||||
$warning['expires'] = $warning['expires']*86400 + TIME_NOW;
|
||||
}
|
||||
else if($warning['expires_period'] == "weeks")
|
||||
{
|
||||
$warning['expires'] = $warning['expires']*604800 + TIME_NOW;
|
||||
}
|
||||
else if($warning['expires_period'] == "months")
|
||||
{
|
||||
$warning['expires'] = $warning['expires']*2592000 + TIME_NOW;
|
||||
}
|
||||
else if($warning['expires_period'] == "never")
|
||||
{
|
||||
$warning['expires'] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unkown expires_period
|
||||
$this->set_error('error_invalid_expires_period');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Using a predefined warning type
|
||||
else
|
||||
{
|
||||
$query = $db->simple_select("warningtypes", "*", "tid='".(int)$warning['type']."'");
|
||||
$this->warning_type = $db->fetch_array($query);
|
||||
|
||||
if(!$this->warning_type)
|
||||
{
|
||||
$this->set_error('error_invalid_type');
|
||||
return false;
|
||||
}
|
||||
|
||||
$warning['points'] = $this->warning_type['points'];
|
||||
$warning['title'] = '';
|
||||
$warning['expires'] = 0;
|
||||
|
||||
if($this->warning_type['expirationtime'])
|
||||
{
|
||||
$warning['expires'] = TIME_NOW+$this->warning_type['expirationtime'];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a warning.
|
||||
*
|
||||
* @return boolean True when valid, false when invalid.
|
||||
*/
|
||||
function validate_warning()
|
||||
{
|
||||
global $plugins;
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
// Verify all warning assets.
|
||||
$this->validate_user();
|
||||
$this->validate_maximum();
|
||||
$this->validate_notes();
|
||||
|
||||
if(array_key_exists('pid', $warning))
|
||||
{
|
||||
$this->validate_post();
|
||||
}
|
||||
if(array_key_exists('type', $warning))
|
||||
{
|
||||
$this->validate_type();
|
||||
}
|
||||
|
||||
$plugins->run_hooks("datahandler_warnings_validate_warning", $this);
|
||||
|
||||
// We are done validating, return.
|
||||
$this->set_validated(true);
|
||||
|
||||
if(count($this->get_errors()) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a valid warning from the DB engine.
|
||||
*
|
||||
* @param int $wid
|
||||
* @return array|bool array when valid, boolean false when invalid.
|
||||
*/
|
||||
function get($wid)
|
||||
{
|
||||
global $db;
|
||||
|
||||
$wid = (int)$wid;
|
||||
if($wid <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $db->simple_select("warnings", "*", "wid='".$wid."'");
|
||||
$this->read_warning_data = $db->fetch_array($query);
|
||||
|
||||
if(!$this->read_warning_data['wid'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->read_warning_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expire old warnings in the database.
|
||||
*
|
||||
* @return boolean True when finished.
|
||||
*/
|
||||
function expire_warnings()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$users = array();
|
||||
|
||||
$query = $db->query("
|
||||
SELECT w.wid, w.uid, w.points, u.warningpoints
|
||||
FROM ".TABLE_PREFIX."warnings w
|
||||
LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=w.uid)
|
||||
WHERE expires<".TIME_NOW." AND expires!=0 AND expired!=1
|
||||
");
|
||||
while($warning = $db->fetch_array($query))
|
||||
{
|
||||
$updated_warning = array(
|
||||
"expired" => 1
|
||||
);
|
||||
$db->update_query("warnings", $updated_warning, "wid='{$warning['wid']}'");
|
||||
|
||||
if(array_key_exists($warning['uid'], $users))
|
||||
{
|
||||
$users[$warning['uid']] -= $warning['points'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$users[$warning['uid']] = $warning['warningpoints']-$warning['points'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach($users as $uid => $warningpoints)
|
||||
{
|
||||
if($warningpoints < 0)
|
||||
{
|
||||
$warningpoints = 0;
|
||||
}
|
||||
|
||||
$updated_user = array(
|
||||
"warningpoints" => (int)$warningpoints
|
||||
);
|
||||
$db->update_query("users", $updated_user, "uid='".(int)$uid."'");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an user warning details.
|
||||
*
|
||||
* @return array Updated user details.
|
||||
*/
|
||||
function update_user($method='insert')
|
||||
{
|
||||
global $db, $mybb, $lang, $cache, $groupscache;
|
||||
|
||||
if($mybb->settings['maxwarningpoints'] < 1)
|
||||
{
|
||||
$mybb->settings['maxwarningpoints'] = 10;
|
||||
}
|
||||
|
||||
if(!is_array($groupscache))
|
||||
{
|
||||
$groupscache = $cache->read("usergroups");
|
||||
}
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
$user = get_user($warning['uid']);
|
||||
|
||||
if($method == 'insert')
|
||||
{
|
||||
// Build warning level & ensure it doesn't go over 100.
|
||||
$current_level = round($user['warningpoints']/$mybb->settings['maxwarningpoints']*100);
|
||||
$this->new_warning_level = round(($user['warningpoints']+$warning['points'])/$mybb->settings['maxwarningpoints']*100);
|
||||
if($this->new_warning_level > 100)
|
||||
{
|
||||
$this->new_warning_level = 100;
|
||||
}
|
||||
|
||||
// Update user
|
||||
$this->updated_user = array(
|
||||
"warningpoints" => $user['warningpoints']+$warning['points']
|
||||
);
|
||||
|
||||
// Fetch warning level
|
||||
$query = $db->simple_select("warninglevels", "*", "percentage<={$this->new_warning_level}", array("order_by" => "percentage", "order_dir" => "desc"));
|
||||
$new_level = $db->fetch_array($query);
|
||||
|
||||
if($new_level['lid'])
|
||||
{
|
||||
$expiration = 0;
|
||||
$action = my_unserialize($new_level['action']);
|
||||
|
||||
if($action['length'] > 0)
|
||||
{
|
||||
$expiration = TIME_NOW+$action['length'];
|
||||
}
|
||||
|
||||
switch($action['type'])
|
||||
{
|
||||
// Ban the user for a specified time
|
||||
case 1:
|
||||
// Fetch any previous bans for this user
|
||||
$query = $db->simple_select("banned", "*", "uid='{$user['uid']}' AND gid='{$action['usergroup']}' AND lifted>".TIME_NOW);
|
||||
$existing_ban = $db->fetch_array($query);
|
||||
|
||||
// Only perform if no previous ban or new ban expires later than existing ban
|
||||
if(($expiration > $existing_ban['lifted'] && $existing_ban['lifted'] != 0) || $expiration == 0 || !$existing_ban['uid'])
|
||||
{
|
||||
if(!$warning['title'])
|
||||
{
|
||||
$warning['title'] = $this->warning_type['title'];
|
||||
}
|
||||
|
||||
// Never lift the ban?
|
||||
if($action['length'] <= 0)
|
||||
{
|
||||
$bantime = '---';
|
||||
}
|
||||
else
|
||||
{
|
||||
$bantimes = fetch_ban_times();
|
||||
foreach($bantimes as $date => $string)
|
||||
{
|
||||
if($date == '---')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$time = 0;
|
||||
list($day, $month, $year) = explode('-', $date);
|
||||
if($day > 0)
|
||||
{
|
||||
$time += 60*60*24*$day;
|
||||
}
|
||||
|
||||
if($month > 0)
|
||||
{
|
||||
$time += 60*60*24*30*$month;
|
||||
}
|
||||
|
||||
if($year > 0)
|
||||
{
|
||||
$time += 60*60*24*365*$year;
|
||||
}
|
||||
|
||||
if($time == $action['length'])
|
||||
{
|
||||
$bantime = $date;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$new_ban = array(
|
||||
"uid" => $user['uid'],
|
||||
"gid" => $action['usergroup'],
|
||||
"oldgroup" => $user['usergroup'],
|
||||
"oldadditionalgroups" => $user['additionalgroups'],
|
||||
"olddisplaygroup" => $user['displaygroup'],
|
||||
"admin" => $mybb->user['uid'],
|
||||
"dateline" => TIME_NOW,
|
||||
"bantime" => $db->escape_string($bantime),
|
||||
"lifted" => $expiration,
|
||||
"reason" => $db->escape_string($warning['title'])
|
||||
);
|
||||
// Delete old ban for this user, taking details
|
||||
if($existing_ban['uid'])
|
||||
{
|
||||
$db->delete_query("banned", "uid='{$user['uid']}' AND gid='{$action['usergroup']}'");
|
||||
// Override new ban details with old group info
|
||||
$new_ban['oldgroup'] = $existing_ban['oldgroup'];
|
||||
$new_ban['oldadditionalgroups'] = $existing_ban['oldadditionalgroups'];
|
||||
$new_ban['olddisplaygroup'] = $existing_ban['olddisplaygroup'];
|
||||
}
|
||||
|
||||
$period = $lang->expiration_never;
|
||||
$ban_length = fetch_friendly_expiration($action['length']);
|
||||
|
||||
if($ban_length['time'])
|
||||
{
|
||||
$lang_str = "expiration_".$ban_length['period'];
|
||||
$period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str);
|
||||
}
|
||||
|
||||
$group_name = $groupscache[$action['usergroup']]['title'];
|
||||
$this->friendly_action = $lang->sprintf($lang->redirect_warned_banned, $group_name, $period);
|
||||
|
||||
$db->insert_query("banned", $new_ban);
|
||||
$this->updated_user['usergroup'] = $action['usergroup'];
|
||||
$this->updated_user['additionalgroups'] = '';
|
||||
$this->updated_user['displaygroup'] = 0;
|
||||
}
|
||||
break;
|
||||
// Suspend posting privileges
|
||||
case 2:
|
||||
// Only perform if the expiration time is greater than the users current suspension period
|
||||
if($expiration == 0 || $expiration > $user['suspensiontime'])
|
||||
{
|
||||
if(($user['suspensiontime'] != 0 && $user['suspendposting']) || !$user['suspendposting'])
|
||||
{
|
||||
$period = $lang->expiration_never;
|
||||
$ban_length = fetch_friendly_expiration($action['length']);
|
||||
|
||||
if($ban_length['time'])
|
||||
{
|
||||
$lang_str = "expiration_".$ban_length['period'];
|
||||
$period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str);
|
||||
}
|
||||
|
||||
$this->friendly_action = $lang->sprintf($lang->redirect_warned_suspended, $period);
|
||||
|
||||
$this->updated_user['suspensiontime'] = $expiration;
|
||||
$this->updated_user['suspendposting'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Moderate new posts
|
||||
case 3:
|
||||
// Only perform if the expiration time is greater than the users current suspension period
|
||||
if($expiration == 0 || $expiration > $user['moderationtime'])
|
||||
{
|
||||
if(($user['moderationtime'] != 0 && $user['moderateposts']) || !$user['suspendposting'])
|
||||
{
|
||||
$period = $lang->expiration_never;
|
||||
$ban_length = fetch_friendly_expiration($action['length']);
|
||||
|
||||
if($ban_length['time'])
|
||||
{
|
||||
$lang_str = "expiration_".$ban_length['period'];
|
||||
$period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str);
|
||||
}
|
||||
|
||||
$this->friendly_action = $lang->sprintf($lang->redirect_warned_moderate, $period);
|
||||
|
||||
$this->updated_user['moderationtime'] = $expiration;
|
||||
$this->updated_user['moderateposts'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Warning is still active, lower users point count
|
||||
if($warning['expired'] != 1)
|
||||
{
|
||||
$new_warning_points = $user['warningpoints']-$warning['points'];
|
||||
if($new_warning_points < 0)
|
||||
{
|
||||
$new_warning_points = 0;
|
||||
}
|
||||
|
||||
$this->updated_user = array(
|
||||
"warningpoints" => $new_warning_points
|
||||
);
|
||||
|
||||
|
||||
// check if we need to revoke any consequences with this warning
|
||||
$current_level = round($user['warningpoints']/$mybb->settings['maxwarningpoints']*100);
|
||||
$this->new_warning_level = round($new_warning_points/$mybb->settings['maxwarningpoints']*100);
|
||||
$query = $db->simple_select("warninglevels", "action", "percentage>{$this->new_warning_level} AND percentage<=$current_level");
|
||||
if($db->num_rows($query))
|
||||
{
|
||||
// we have some warning levels we need to revoke
|
||||
$max_expiration_times = $check_levels = array();
|
||||
find_warnlevels_to_check($query, $max_expiration_times, $check_levels);
|
||||
|
||||
// now check warning levels already applied to this user to see if we need to lower any expiration times
|
||||
$query = $db->simple_select("warninglevels", "action", "percentage<={$this->new_warning_level}");
|
||||
$lower_expiration_times = $lower_levels = array();
|
||||
find_warnlevels_to_check($query, $lower_expiration_times, $lower_levels);
|
||||
|
||||
// now that we've got all the info, do necessary stuff
|
||||
for($i = 1; $i <= 3; ++$i)
|
||||
{
|
||||
if($check_levels[$i])
|
||||
{
|
||||
switch($i)
|
||||
{
|
||||
case 1: // Ban
|
||||
// we'll have to resort to letting the admin/mod remove the ban manually, since there's an issue if stacked bans are in force...
|
||||
continue 2;
|
||||
case 2: // Revoke posting
|
||||
$current_expiry_field = 'suspensiontime';
|
||||
$current_inforce_field = 'suspendposting';
|
||||
break;
|
||||
case 3:
|
||||
$current_expiry_field = 'moderationtime';
|
||||
$current_inforce_field = 'moderateposts';
|
||||
break;
|
||||
}
|
||||
|
||||
// if the thing isn't in force, don't bother with trying to update anything
|
||||
if(!$user[$current_inforce_field])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if($lower_levels[$i])
|
||||
{
|
||||
// lessen the expiration time if necessary
|
||||
|
||||
if(!$lower_expiration_times[$i])
|
||||
{
|
||||
// doesn't expire - enforce this
|
||||
$this->updated_user[$current_expiry_field] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if($max_expiration_times[$i])
|
||||
{
|
||||
// if the old level did have an expiry time...
|
||||
if($max_expiration_times[$i] <= $lower_expiration_times[$i])
|
||||
{
|
||||
// if the lower expiration time is actually higher than the upper expiration time -> skip
|
||||
continue;
|
||||
}
|
||||
// both new and old max expiry times aren't infinite, so we can take a difference
|
||||
$expire_offset = ($lower_expiration_times[$i] - $max_expiration_times[$i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the old level never expired, not much we can do but try to estimate a new expiry time... which will just happen to be starting from today...
|
||||
$expire_offset = TIME_NOW + $lower_expiration_times[$i];
|
||||
// if the user's expiry time is already less than what we're going to set it to, skip
|
||||
if($user[$current_expiry_field] <= $expire_offset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->updated_user[$current_expiry_field] = $user[$current_expiry_field] + $expire_offset;
|
||||
// double-check if it's expired already
|
||||
if($this->updated_user[$current_expiry_field] < TIME_NOW)
|
||||
{
|
||||
$this->updated_user[$current_expiry_field] = 0;
|
||||
$this->updated_user[$current_inforce_field] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there's no lower level for this type - remove the consequence entirely
|
||||
$this->updated_user[$current_expiry_field] = 0;
|
||||
$this->updated_user[$current_inforce_field] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save updated details
|
||||
$db->update_query("users", $this->updated_user, "uid='{$user['uid']}'");
|
||||
|
||||
$mybb->cache->update_moderators();
|
||||
|
||||
return $this->updated_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a warning into the database
|
||||
*
|
||||
* @return array Warning database details.
|
||||
*/
|
||||
function insert_warning()
|
||||
{
|
||||
global $db, $mybb, $plugins;
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
$this->write_warning_data = array(
|
||||
"uid" => (int)$warning['uid'],
|
||||
"tid" => (int)$warning['type'],
|
||||
"pid" => (int)$warning['pid'],
|
||||
"title" => $db->escape_string($warning['title']),
|
||||
"points" => (int)$warning['points'],
|
||||
"dateline" => TIME_NOW,
|
||||
"issuedby" => $mybb->user['uid'],
|
||||
"expires" => (int)$warning['expires'],
|
||||
"expired" => 0,
|
||||
"revokereason" => '',
|
||||
"notes" => $db->escape_string($warning['notes'])
|
||||
);
|
||||
|
||||
$this->write_warning_data['wid'] = $db->insert_query("warnings", $this->write_warning_data);
|
||||
|
||||
$this->update_user();
|
||||
|
||||
$plugins->run_hooks("datahandler_warnings_insert_warning", $this);
|
||||
|
||||
return $this->write_warning_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a warning in the database
|
||||
*
|
||||
* @return array Warning database details.
|
||||
*/
|
||||
function update_warning()
|
||||
{
|
||||
global $db, $mybb, $plugins;
|
||||
|
||||
$warning = &$this->data;
|
||||
|
||||
$warning['wid'] = (int)$warning['wid'];
|
||||
if($warning['wid'] <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->write_warning_data = array(
|
||||
"expired" => 1,
|
||||
"daterevoked" => TIME_NOW,
|
||||
"revokedby" => $mybb->user['uid'],
|
||||
"revokereason" => $db->escape_string($warning['reason'])
|
||||
);
|
||||
|
||||
$plugins->run_hooks("datahandler_warnings_update_warning", $this);
|
||||
|
||||
$db->update_query("warnings", $this->write_warning_data, "wid='{$warning['wid']}'");
|
||||
|
||||
$this->update_user('update');
|
||||
|
||||
return $this->write_warning_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user