Codeigniter throws 520 error CloudFlare while using session - php

I am using Codeigniter with cloudflare and getting 520 error while storing user value in session during login.
Here is login function:
function check_login_submit($post_data) {
if ($post_data) {
$mob = trim($post_data['mob']);
$password = trim($post_data['password']);
$sql = "Select * from table where phone='$mob' and password='$password'";
$query = $this->db->query($sql);
$user = $query->row();
if ($query->num_rows() == 1) {
if ($user->status == 1)
{
$this->session->set_userdata('mem_id', $user->id);
$this->session->set_userdata('mem_last_login_date', $user->last_login_date);
$this->session->set_userdata('mem_created_on', $user->created_on);
//-- Update last login of successfull Login
$sql = "update table set last_login_date = NOW() where id=$user->id";
$query = $this->db->query($sql);
return TRUE;
}
}
else {
return FALSE;
}
}
}
If i will stop the storing value into session user data than it will working fine however with session cloudflare give me 502 error page.
Please advise
Thanks in advance for your time and support.

If anyone else runs into this problem, I came up with a solution that involves extending the core Session library that ultimately reduces the number of calls to sess_write() and by extension, _set_cookie().
MY_Session.php:
class MY_Session extends CI_Session {
function set_userdata($newdata = array(), $newval = '', $write_session = true)
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$this->userdata[$key] = $val;
}
}
// Do not write the session (set the cookies) unless explicitly specified
if ($write_session) {
$this->sess_write();
}
}
function set_flashdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$flashdata_key = $this->flashdata_key.':new:'.$key;
$this->set_userdata($flashdata_key, $val, false); // Do not update the cookie in the foreach
}
}
// Save the cookie now that all userdata has been set
$this->sess_write();
}
function _flashdata_mark()
{
$userdata = $this->all_userdata();
$newUserData = array();
$userDataToUnset = array();
foreach ($userdata as $name => $value)
{
$parts = explode(':new:', $name);
if (is_array($parts) && count($parts) === 2)
{
$new_name = $this->flashdata_key.':old:'.$parts[1];
$newUserData[$new_name] = $value;
$userDataToUnset[$name] = '';
// Cookies were originally set in this loop. Moved to the end of the function
}
}
// Save all changes outside of the loop
if (count($newUserData) > 0) {
$this->set_userdata($newUserData);
$this->unset_userdata($userDataToUnset);
}
}
}

A 520 error generally indicates that there are large cookies or headers being returned that hit proxy buffer limits on our end. A HAR file send to our support team will help us figure out what the issue is.

Related

PHP shopping cart session not updating after custom session handler incorporated into site

i am putting together a basic site with a basic shopping cart, we plan to store sensitive information in the sessions in the future so getting this sorted now is a smart choice.
Everything works fine without the custom session handler, for some context the session handling code is below:
function decrypt($edata, $password) {
$data = base64_decode($edata);
$salt = substr($data, 0, 16);
$ct = substr($data, 16);
$rounds = 3; // depends on key length
$data00 = $password.$salt;
$hash = array();
$hash[0] = hash('sha256', $data00, true);
$result = $hash[0];
for ($i = 1; $i < $rounds; $i++) {
$hash[$i] = hash('sha256', $hash[$i - 1].$data00, true);
$result .= $hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32,16);
return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv);
}
function encrypt($data, $password) {
// Set a random salt
$salt = openssl_random_pseudo_bytes(16);
$salted = '';
$dx = '';
// Salt the key(32) and iv(16) = 48
while (strlen($salted) < 48) {
$dx = hash('sha256', $dx.$password.$salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32,16);
$encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv);
return base64_encode($salt . $encrypted_data);
}
class SecureSessionHandler extends SessionHandler {
protected $name, $cookie;
private $key;
public function __construct($key, $name = 'MY_SESSION', $cookie = [])
{
$this->key = $key;
$this->name = $name;
$this->cookie = $cookie;
$this->cookie += [
'lifetime' => 0,
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true
];
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-
cbc'));
$this->setup();
}
private function setup()
{
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_name($this->name);
session_set_cookie_params(
$this->cookie['lifetime'],
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
}
public function start()
{
if (session_id() === '') {
if (session_start()) {
return mt_rand(45, 99) === 55 ? $this->refresh() : true; // 1/5
}
}
return false;
}
public function forget()
{
if (session_id() === '') {
return false;
}
$_SESSION = [];
setcookie(
$this->name,
'',
time() - 42000,
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
return session_destroy();
}
public function refresh()
{
return session_regenerate_id(false);
}
public function write($id, $data)
{
$data = encrypt($data, $this->key);
return parent::write($id, $data);
}
public function read($id)
{
$data = parent::read($id);
if (!$data) {
return "";
} else {
return decrypt($data, $this->key);
}
}
public function isExpired($ttl = 30)
{
$last = isset($_SESSION['_last_activity'])
? $_SESSION['_last_activity']
: false;
if ($last !== false && time() - $last > $ttl * 60) {
return true;
}
$_SESSION['_last_activity'] = time();
return false;
}
public function isFingerprint()
{
$hash = md5(
$_SERVER['HTTP_USER_AGENT'] .
(ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0'))
);
if (isset($_SESSION['_fingerprint'])) {
return $_SESSION['_fingerprint'] === $hash;
}
$_SESSION['_fingerprint'] = $hash;
return true;
}
public function isValid()
{
return ! $this->isExpired() && $this->isFingerprint();
}
public function get($name)
{
$parsed = explode('.', $name);
$result = $_SESSION;
while ($parsed) {
$next = array_shift($parsed);
if (isset($result[$next])) {
$result = $result[$next];
} else {
return null;
}
}
return $result;
}
public function put($name, $value)
{
$parsed = explode('.', $name);
$session =& $_SESSION;
while (count($parsed) > 1) {
$next = array_shift($parsed);
if ( ! isset($session[$next]) || ! is_array($session[$next])) {
$session[$next] = [];
}
$session =& $session[$next];
}
$session[array_shift($parsed)] = $value;
}
}
$key = file_get_contents('./key.pem', FILE_USE_INCLUDE_PATH);
$session = new SecureSessionHandler($key);
ini_set('session.save_handler', 'files');
session_set_save_handler($session, true);
session_save_path(__DIR__ . '/sessions');
$session->start('cheese');
if ( ! $session->isValid(5)) {
$session->destroy('cheese');
}
There is the full session handler and encryption/decryption method, everything works fine overall but the problem is when going through my shopping cart code and changing all the $_SESSION variables into the $session->get objects, i managed to replace every $_SESSION then the last one i need to change throws a fatal error:
changing " $_SESSION['cart_contents'] = $this->cart_contents;"
to "$session->get('cart_contents') = $this->cart_contents;"
results in:
Fatal error: Can't use method return value in write context in C:\xampp\htdocs\teck\Cart.php on line 375
The rest of the important code is mentioned below, i made sure nothing was left out, its better to have a long post with all details than getting flamed for a small post with a question missing all details lol.
The page that you can adjust the quantity on is viewcart.php, the code thats important from this page is below:
<input type="number" class="form-control text-center" value="<?php echo
$item["qty"]; ?>" onchange="updateCartItem(this, '<?php echo
$item["rowid"]; ?>')">
and the script on the same page (viewcart.php) that throws the alert is below:
<script>
function updateCartItem(obj,id){
$.get("cartAction.php", {action:"updateCartItem", id:id, qty:obj.value},
function(data){
if(data == 'ok'){
location.reload();
}else{
alert('Cart update failed, please try again.');
}
});
}
</script>
Now finally cartaction.php, the code for the action "updatecartitem" is below:
}elseif($_REQUEST['action'] == 'updateCartItem' && !empty($_REQUEST['id']))
{
$itemData = array(
'rowid' => $_REQUEST['id'],
'qty' => $_REQUEST['qty']
);
$updateItem = $cart->update($itemData);
echo $updateItem?'ok':'err';die;
}
The update function thats in cart.php:
public function update($item = array()){
if (!is_array($item) OR count($item) === 0){
return FALSE;
}else{
if (!isset($item['rowid'], $this->cart_contents[$item['rowid']])){
return FALSE;
}else{
// prep the quantity
if(isset($item['qty'])){
$item['qty'] = filter_var($item['qty'],
FILTER_VALIDATE_INT);
// remove the item from the cart, if quantity is zero
if ($item['qty'] == 0){
unset($this->cart_contents[$item['rowid']]);
return TRUE;
}
}
// find updatable keys
$keys = array_intersect(array_keys($this-
>cart_contents[$item['rowid']]), array_keys($item));
// prep the price
if(isset($item['price'])){
$item['price'] = filter_var($item['price'],
FILTER_VALIDATE_FLOAT);
}
// product id & name shouldn't be changed
foreach(array_diff($keys, array('id', 'name')) as $key){
$this->cart_contents[$item['rowid']][$key] = $item[$key];
}
// save cart data
$this->save_cart();
return TRUE;
}
}
}
And last but not least the save_cart function in cart.php also:
protected function save_cart(){
$this->cart_contents['total_items'] = $this->cart_contents['cart_total']
= 0;
foreach ($this->cart_contents as $key => $val){
// make sure the array contains the proper indexes
if(!is_array($val) OR !isset($val['price'], $val['qty'])){
continue;
}
$this->cart_contents['cart_total'] += ($val['price'] * $val['qty']);
$this->cart_contents['total_items'] += $val['qty'];
$this->cart_contents[$key]['subtotal'] = ($this->cart_contents[$key]
['price'] * $this->cart_contents[$key]['qty']);
}
global $key;
global $session;
// if cart empty, delete it from the session
if(count($this->cart_contents) <= 2){
$session->forget();
return FALSE;
}else{
// original code below
$_SESSION['cart_contents'] = $this->cart_contents;
// code below is what i think will clear everything up but throws the
// error.
$session->get('cart_contents') = $this->cart_contents;
return TRUE;
}
}
The cart code above is in the same file as the session handler,
A bit more of an explanation, with " $_SESSION['cart_contents'] = $this->cart_contents;" (the original code),
i press the button +1 to add extra item into cart, the text field increases 1, and the error alert pops up saying "Cart update failed, please try again", i click ok and the alert goes away and nothing happens, the item qty in the text box stays updated but the actual real cart qty doesnt update until i refresh the page or click a link.
With the standard session handler in place this doesnt happen, everything works perfectly.
Is it a must that i change this $_SESSION['cart_contents'] variable to $session->get('cart_contents')?
I should be able to change that script alert to update the cart properly without throwing the alert but will my custom session handler work flawlessly if i leave that one session variable?
Im very sorry for the long post but i wanted to make sure everything is as clear as possible for other people to also understand if they are having similar problems.
The code does seem quite messy from this point of view but if you were to go over the entire site everything would make much more sense.
I have been on php for about 2 months max now trying my best to pick up as much as possible so please bear with me, obviously most of the code is not as clean as it should be, but this is production.
I have spent the past 3-4 days on this session handler, i really dont want to discard it and just go back to the standard _session.
All & any advice is welcome, constructive criticism will be taken lightly!
I really appreciate the time you have taken to go through this, Thanks for your effort!
You are getting the error at line
$session->get('cart_contents') = $this->cart_contents;
Here I assume the get function returns a reference. So if you want to store $this->cart_contents to the reference variable then you must use $$.
e.g $temp = $session->get('cart_contents');
and use $$temp = $this->cart_contents;
Or if you want to assign $this->cart_contents to the cart values then you must use
$this->cart_contents = $session->get('cart_contents');
You cant just use get method and assign a value to it.
Not much i could really do apart from keep researching, what ive done to get it working is below, but can someone please let me know if this will make my custom sessionhandler not work as intended?
i changed the updateCartItem function so there is no if statement just straight calls the function then reloads the page.
<script>
function updateCartItem(obj,id){
$.get("cartAction.php", {action:"updateCartItem", id:id, qty:obj.value},
function(data){
location.reload();
});
}</script>
This works fine with the save_cart function as below:
protected function save_cart(){
$this->cart_contents['total_items'] = $this->cart_contents['cart_total']
= 0;
foreach ($this->cart_contents as $key => $val){
// make sure the array contains the proper indexes
if(!is_array($val) OR !isset($val['price'], $val['qty'])){
continue;
}
$this->cart_contents['cart_total'] += ($val['price'] * $val['qty']);
$this->cart_contents['total_items'] += $val['qty'];
$this->cart_contents[$key]['subtotal'] = ($this->cart_contents[$key]
['price'] * $this->cart_contents[$key]['qty']);
}
global $key;
global $session;
// if cart empty, delete it from the session
if(count($this->cart_contents) <= 2){
$session->forget();
return FALSE;
}else{
$_SESSION['cart_contents'] = $this->cart_contents;
return TRUE;
}
}
BUT! Shouldnt the $_SESSION variable be replaced with my custom session handler call? ($session->get('cart_contents') = $this->cart_contents;) Obviously il get the error if i change it :(
Everything seems to work fine with the sessions, but will this create a weak point in my session security? And i should be able to use the if statement in the updateCartItem script! There must be a way to use the customsessionhandler call instead of "$_SESSION['cart_contents']".

How do I modify an existing file to add the ability to unlink a specific file from a folder?

Thank you StackOverflow experts for looking at my question.
First, It is possible this question has been asked before but my situation is a bit unique. So, please hear me out.
When our users want to edit an existing record, they would also like to have the ability to delete an existing pdf file if one exists before adding a new one.
To display an existing file, I use this code.
<td class="td_input_form">
<?php
// if the BidIDFile is empty,
if(empty($result["BidIDFile"]))
{
//then show file upload field for Bid File
echo '<input type="file" name="BidIDFile[]" size="50">';
}
else
{
// Bid file already upload, show checkbox to delete it.
echo '<input type="checkbox" name="delete[]" value="'.$result["BidIDFile"].'"> (delete)
'.$result["BidIDFile"].'';
}
</td>
Then to delete this file, I use the following code:
// Connect to SQL Server database
include("connections/Connect.php");
// Connect to SQL Server database
include("connections/Connect.php");
$strsID = isset($_GET["Id"]) ? $_GET["Id"] : null;
if(isset($_POST['delete']))
{
// whilelisted table columns
$fileColumnsInTable = array( 'BidIDFile', 'TabSheet', 'SignInSheet', 'XConnect',
'Addend1', 'Addend2','Addend3','Addend4','Addend5', 'Addend6');
$fileColumns = array();
foreach ($_POST['delete'] as $fileColumn)
{
if(in_array($fileColumn, $fileColumnsInTable))
$fileColumns[] = $fileColumn;
}
// get the file paths for each file to be deleted
$stmts = "SELECT " . implode(', ', $fileColumns) . " FROM bids WHERE ID = ? ";
$querys = sqlsrv_query( $conn, $stmts, array($strsID));
$files = sqlsrv_fetch_array($querys,SQLSRV_FETCH_ROW);
// loop over the files returned by the query
foreach ($files as $file )
{
//delete file
unlink($file);
}
// now remove the values from the table
$stmts = "UPDATE bids SET " . impload(' = '', ', $fields) . " WHERE ID = ? ";
$querys = sqlsrv_query( $conn, $stmts, array($strsID));
This works fine. However, the edit file points to an existing file with an INSERT and UPDATE operation in this one file (great thanks to rasclatt) and I am having problem integrating the two together.
Can someone please help with integrating the two files into one?
Thanks in advance for your assistance.
Here is the INSERT and UPDATE file:
<?php
error_reporting(E_ALL);
class ProcessBid
{
public $data;
public $statement;
public $where_vals;
protected $keyname;
protected $conn;
public function __construct($conn = false)
{
$this->conn = $conn;
}
public function SaveData($request = array(),$skip = false,$keyname = 'post')
{
$this->keyname = $keyname;
$this->data[$this->keyname] = $this->FilterRequest($request,$skip);
return $this;
}
public function FilterRequest($request = array(), $skip = false)
{
// See how many post variables are being sent
if(count($request) > 0) {
// Loop through post
foreach($request as $key => $value) {
// Use the skip
if($skip == false || (is_array($skip) && !in_array($key,$skip))) {
// Create insert values
$vals['vals'][] = "'".ms_escape_string($value)."'";
// Create insert columns
$vals['cols'][] = "".str_replace("txt","",$key)."";
// For good measure, create an update string
$vals['update'][] = "".str_replace("txt","",$key)."".' = '."'".ms_escape_string($value)."'";
// For modern day binding, you can use this array
$vals['bind']['cols'][] = "".$key."";
$vals['bind']['cols_bind'][] = ":".$key;
$vals['bind']['vals'][":".$key] = $value;
$vals['bind']['update'][] = "".$key.' = :'.$key;
}
}
}
return (isset($vals))? $vals:false;
}
public function AddFiles($name = 'item')
{
// If the files array has been set
if(isset($_FILES[$name]['name']) && !empty($_FILES[$name]['name'])) {
// Remove empties
$_FILES[$name]['name'] = array_filter($_FILES[$name]['name']);
$_FILES[$name]['type'] = array_filter($_FILES[$name]['type']);
$_FILES[$name]['size'] = array_filter($_FILES[$name]['size']);
$_FILES[$name]['tmp_name'] = array_filter($_FILES[$name]['tmp_name']);
// we need to differentiate our type array names
$use_name = ($name == 'item')? 'Addend':$name;
// To start at Addendum1, create an $a value of 1
$a = 1;
if(!empty($_FILES[$name]['tmp_name'])) {
foreach($_FILES[$name]['name'] as $i => $value ) {
$file_name = ms_escape_string($_FILES[$name]['name'][$i]);
$file_size = $_FILES[$name]['size'][$i];
$file_tmp = $_FILES[$name]['tmp_name'][$i];
$file_type = $_FILES[$name]['type'][$i];
if(move_uploaded_file($_FILES[$name]['tmp_name'][$i], $this->target.$file_name)) {
// Format the key values for addendum
if($name == 'item')
$arr[$use_name.$a] = $file_name;
// Format the key values for others
else
$arr[$use_name] = $file_name;
$sql = $this->FilterRequest($arr);
// Auto increment the $a value
$a++;
}
}
}
}
if(isset($sql) && (isset($i) && $i == (count($_FILES[$name]['tmp_name'])-1)))
$this->data[$name] = $sql;
return $this;
}
public function SaveFolder($target = '../uploads/')
{
$this->target = $target;
// Makes the folder if not already made.
if(!is_dir($this->target))
mkdir($this->target,0755,true);
return $this;
}
public function where($array = array())
{
$this->where_vals = NULL;
if(is_array($array) && !empty($array)) {
foreach($array as $key => $value) {
$this->where_vals[] = $key." = '".ms_escape_string($value)."'";
}
}
return $this;
}
public function UpdateQuery()
{
$this->data = array_filter($this->data);
if(empty($this->data)) {
$this->statement = false;
return $this;
}
if(isset($this->data) && !empty($this->data)) {
foreach($this->data as $name => $arr) {
$update[] = implode(",",$arr['update']);
}
}
$vars = (isset($update) && is_array($update))? implode(",",$update):"";
// Check that both columns and values are set
$this->statement = (isset($update) && !empty($update))? "update bids set ".implode(",",$update):false;
if(isset($this->where_vals) && !empty($this->where_vals)) {
$this->statement .= " where ".implode(" and ",$this->where_vals);
}
return $this;
}
public function SelectQuery($select = "*",$table = 'bids')
{
$stmt = (is_array($select) && !empty($select))? implode(",",$select):$select;
$this->statement = "select ".$stmt." from ".$table;
return $this;
}
public function InsertQuery($table = 'bids')
{
$this->data = array_filter($this->data);
if(empty($this->data)) {
$this->statement = false;
return $this;
}
$this->statement = "insert into ".$table;
if(isset($this->data) && !empty($this->data)) {
foreach($this->data as $name => $arr) {
$insert['cols'][] = implode(",",$arr['cols']);
$insert['vals'][] = implode(",",$arr['vals']);
}
}
$this->statement .= '(';
$this->statement .= (isset($insert['cols']) && is_array($insert['cols']))? implode(",",$insert['cols']):"";
$this->statement .= ") VALUES (";
$this->statement .= (isset($insert['vals']) && is_array($insert['vals']))? implode(",",$insert['vals']):"";
$this->statement .= ")";
return $this;
}
}
include("../Connections/Connect.php");
function render_error($settings = array("title"=>"Failed","body"=>"Sorry, your submission failed. Please go back and fill out all required information."))
{ ?>
<h2><?php echo (isset($settings['title']))? $settings['title']:"Error"; ?></h2>
<p><?php echo (isset($settings['body']))? $settings['body']:"An unknown error occurred."; ?></p>
<?php
}
// this function is used to sanitize code against sql injection attack.
function ms_escape_string($data)
{
if(!isset($data) || empty($data))
return "";
if(is_numeric($data))
return $data;
$non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
$non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
$non_displayables[] = '/[\x00-\x08]/'; // 00-08
$non_displayables[] = '/\x0b/'; // 11
$non_displayables[] = '/\x0c/'; // 12
$non_displayables[] = '/[\x0e-\x1f]/'; // 14-31
foreach($non_displayables as $regex)
$data = preg_replace($regex,'',$data);
$data = str_replace("'","''",$data);
return $data;
}
// New bid save engine is required for both sql statement generations
$BidSet = new ProcessBid($conn);
$strId = null;
if(isset($_POST["Id"]))
{
$strId = $_POST["Id"];
//echo $strId;
}
If ($strId == "") {
//echo "This is an insert statement";
// This will generate an insert query
$insert = $BidSet->SaveData($_POST)
->SaveFolder('../uploads/')
->AddFiles('BidIDFile')
->AddFiles('item')
->AddFiles('SignInSheet')
->AddFiles('TabSheet')
->AddFiles('Xcontract')
->InsertQuery()
->statement;
// Check that statement is not empty
if($insert != false) {
sqlsrv_query($conn,$insert);
render_error(array("title"=>"Bid Successfully Saved!","body"=>'Go back to Solicitation screen'));
$err = false;
}
//echo '<pre>';
//print_r($insert);
// echo '</pre>';
}
else
{
//echo "This is an update statement";
// This will generate an update query
$update = $BidSet->SaveData($_POST,array("Id"))
->SaveFolder('../uploads/')
->AddFiles('BidIDFile')
->AddFiles('item')
->AddFiles('SignInSheet')
->AddFiles('TabSheet')
->AddFiles('Xcontract')
->where(array("Id"=>$_POST["Id"]))
->UpdateQuery()
->statement;
//echo '<pre>';
//print_r($update);
//echo '</pre>';
// Check that statement is not empty
if($update != false) {
sqlsrv_query($conn,$update);
render_error(array("title"=>"Bid Successfully Saved!","body"=>'Go back to admin screen'));
$err = false;
}
}
// This will post an error if the query fails
if((isset($err) && $err == true) || !isset($err))
render_error(); ?>

Moodle php - where does moodle check if the provided enrolment key matches the course's predefined enrollment key?

I am creating a moodle website. I already setup my courses with their specific enrolment keys, etc. But I want to know in what .php file and where in that file (in the moodle files), does Moodle check if the enrollment key entered by the user matches what I set as the enrolment key for the course...
Thanks for your help!
UPDATE--------
I did as Russell England suggested, but when I go to the page where I type my enrolment key, the page isn't loading or the page is redirected to my moodle homepage. My table that I store the enrolment keys is user_enrolment_keys.
Here is the updated validation function:
public function validation($data, $files) {
global $DB, $CFG, $USER;
$errors = parent::validation($data, $files);
$instance = $this->instance;
if ($this->toomany) {
$errors['notice'] = get_string('error');
return $errors;
}
//--------Russell's suggestion--------------
if ($instance->password) {
$params = array('user_email' => $USER->email, 'course_id' => $instance->courseid, 'enrolment_key' => $data['enrolpassword']);
if (!$DB->record_exists('user_enrolment_keys', $params)) {
$errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
return $errors;
}
}
//What I tried last (did not work either)...
/*$uemail = $USER->email;
$userscoursekey = 'testing';
$connecty = mysqli_connect("localhost", "...", "...", "...");
mysql_select_db('user_enrolment_keys', $connecty);
$var2 = $instance->courseid;
$resulty = mysqli_query($connecty, "SELECT * FROM user_enrolment_keys WHERE user_email='$uemail' AND course_id='$var2'");
$numrows = $resulty->num_rows;
if($numrows > 0)
{
while($row = mysqli_fetch_assoc($resulty))
{
$userscoursekey = $row['enrolment_key'];
}
}
$instance->password = $userscoursekey;
my_sqli_close($connecty); //Close the database connection.*/
if ($instance->password) {
if ($data['enrolpassword'] !== $instance->password) {
if ($instance->customint1) {
$groups = $DB->get_records('groups', array('courseid'=>$instance->courseid), 'id ASC', 'id, enrolmentkey');
$found = false;
foreach ($groups as $group) {
if (empty($group->enrolmentkey)) {
continue;
}
if ($group->enrolmentkey === $data['enrolpassword']) {
$found = true;
break;
}
}
if (!$found) {
// We can not hint because there are probably multiple passwords.
$errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
}
} else {
$plugin = enrol_get_plugin('self');
if ($plugin->get_config('showhint')) {
$hint = core_text::substr($instance->password, 0, 1);
$errors['enrolpassword'] = get_string('passwordinvalidhint', 'enrol_self', $hint);
} else {
$errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
}
}
}
}
return $errors;
// END DEFAULT BLOCK
}
Its validated in the custom self enrolment form
In the function validation() in the file /enrol/self/locallib.php it checks if the password matches and displays an error if not.
UPDATE:
I would probably do this in the validation function
Add the $USER variable at the top
global $DB, $CFG, $USER;
Then check if the user, course and password combination exists in your newly created licence table ;)
$params = array('userid' => $USER->id, 'courseid' => $instance->courseid, 'password' => $data['enrolpassword']);
if (!$DB->record_exists('local_licence_table', $params)) {
$errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
return $errors;
}

Return in foreach showing only 1st value

I have problem. In my function, return shows only first player from server. I wanted to show all players from server, but i cant get this working. Here is my code:
function players() {
require_once "inc/SampQueryAPI.php";
$query = new SampQueryAPI('uh1.ownserv.pl', 25052); // Zmień dane obok! //
if($query->isOnline())
{
$aInformation = $query->getInfo();
$aServerRules = $query->getRules();
$aPlayers = $query->getDetailedPlayers();
if(!is_array($aPlayers) || count($aPlayers) == 0)
{
return 'Brak graczy online';
}
else
{
foreach($aPlayers as $sValue)
{
$playerid = $sValue['playerid'];
$playername = htmlentities($sValue['nickname']);
$playerscore = $sValue['score'];
$playerping = $sValue['ping'];
return '<li>'.$playername.' (ID: '.$playerid.'), Punkty ('.$playerscore.'), Ping ('.$playerping.')</li>';
}
}
}
}
You're returning from within your loop.
Instead, you should concatenate the results for each iteration and then return that concatenated string outside the loop.
e.g.
$result = "";
foreach($aPlayers as $sValue) {
# add to $result...
}
return $result
function players() {
require_once "inc/SampQueryAPI.php";
$query = new SampQueryAPI('uh1.ownserv.pl', 25052); // Zmień dane obok! //
if($query->isOnline())
{
$aInformation = $query->getInfo();
$aServerRules = $query->getRules();
$aPlayers = $query->getDetailedPlayers();
if(!is_array($aPlayers) || count($aPlayers) == 0)
{
return 'Brak graczy online';
}
else
{
$ret = '';
foreach($aPlayers as $sValue)
{
$playerid = $sValue['playerid'];
$playername = htmlentities($sValue['nickname']);
$playerscore = $sValue['score'];
$playerping = $sValue['ping'];
$ret .= '<li>'.$playername.' (ID: '.$playerid.'), Punkty ('.$playerscore.'), Ping ('.$playerping.')</li>';
}
return $ret;
}
}
}
In a function you can only return ONE value.
Try creating a list of players and return the list when all records have been added to it.
In your case, list of players will result in an array of players

How to unenroll user from a course with php

Using Moodle 1.9, I have successfully been able to enroll a user via php with
$user = get_record("user", "id", $mqval['id']);
$course = get_record("course", "id", $cid);
if ( ! enrol_into_course($course, $user, 'manuel')) {
} else {
//echo 'success';
}
Now I want to unenroll the user the same way. I tried using unenrol_user, which didn't work. I also tried role_unassign but with no success.
//get instance that can unenrol
$enrols = enrol_get_plugins(true);
$enrolinstances = enrol_get_instances($courseid, true);
$unenrolled = false;
foreach ($enrolinstances as $instance) {
if (!$unenrolled and $enrols[$instance->enrol]->allow_unenrol($instance)) {
$unenrolinstance = $instance;
$unenrolled = true;
}
}
//unenrol the user in every course he's in
$enrolledusercourses = enrol_get_users_courses($userid);
foreach ($enrolledcourses as $course) {
//unenrol the user
$enrols[$unenrolinstance->enrol]->unenrol_user($unenrolinstance, $userid, $roleid);
}
I have modified above code and its working.
//unenrol the user in every course he's in
$enrols = enrol_get_plugins(true);
$enrolledusercourses = enrol_get_users_courses($user->id);
foreach ($enrolledusercourses as $course) {
//unenrol the user
$courseid = $course->id;
$enrolinstances = enrol_get_instances($courseid, true);
$unenrolled = false;
foreach ($enrolinstances as $instance) {
if (!$unenrolled and $enrols[$instance->enrol]->allow_unenrol($instance)) {
$unenrolinstance = $instance;
$unenrolled = true;
}
}
$enrols[$unenrolinstance->enrol]->unenrol_user($unenrolinstance, $user->id, $user->rollid);
}

Categories