From 179473460979103172b09bfa87850f3ca72f6be8 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 4 May 2016 13:26:29 +1000 Subject: [PATCH 01/16] Move from SHA1 to Bcrypt. Some PSR2 formatting fixes. Remove enabled grouping --- application/core/GoCart.php | 567 ++++++------------ application/libraries/Auth.php | 134 ++--- .../controllers/AdminCategories.php | 114 ++-- .../modules/categories/models/Categories.php | 90 +-- .../categories/views/admin/categories.php | 22 +- .../categories/views/admin/category_form.php | 8 +- .../customers/controllers/AdminCustomers.php | 142 ++--- .../modules/customers/models/Customers.php | 63 +- .../modules/login/controllers/AdminLogin.php | 56 +- .../modules/login/controllers/Login.php | 98 ++- application/modules/login/models/Login.php | 73 +-- .../my_account/controllers/MyAccount.php | 54 +- application/modules/orders/models/Orders.php | 134 ++--- .../products/controllers/AdminProducts.php | 262 +++----- .../modules/products/models/Products.php | 198 +++--- .../views/admin/giftcard_product_form.php | 73 ++- .../products/views/admin/product_form.php | 4 +- .../modules/products/views/admin/products.php | 2 +- .../modules/users/controllers/AdminUsers.php | 49 +- install/database.sql | 8 +- 20 files changed, 775 insertions(+), 1376 deletions(-) diff --git a/application/core/GoCart.php b/application/core/GoCart.php index 397b9cc..4eb42bb 100644 --- a/application/core/GoCart.php +++ b/application/core/GoCart.php @@ -9,7 +9,8 @@ * @link http://gocartdv.com */ -class GoCart { +class GoCart +{ protected $cart; protected $customer; @@ -50,10 +51,8 @@ public function saveCart() public function addGiftCard($giftCard) { - foreach($this->items as $item) - { - if($item->description == $giftCard->code && $item->type == 'gift card') - { + foreach ($this->items as $item) { + if ($item->description == $giftCard->code && $item->type == 'gift card') { return ['success'=>false, 'error'=>lang('gift_card_already_applied')]; } } @@ -68,37 +67,28 @@ public function addCoupon($code) { //get the coupon $coupon = \CI::Coupons()->getCouponByCode($code); - if(!$coupon) - { + if (!$coupon) { return json_encode(['error'=>lang('invalid_coupon_code')]); } //is coupon valid - if(\CI::Coupons()->isValid($coupon)) - { - //does the coupon apply to any products? - if($this->isCouponApplied($coupon)) - { + if (\CI::Coupons()->isValid($coupon)) { + //does the coupon apply to any products? + if ($this->isCouponApplied($coupon)) { return json_encode(['error'=>lang('coupon_already_applied')]); - } - else - { + } else { $item = (object)['product_id'=>0, 'shippable'=>0, 'track_stock'=>0, 'taxable'=>0, 'fixed_quantity'=>1, 'type'=>'coupon', 'name'=>lang('coupon'), 'price'=>0, 'total_price'=>0, 'description'=>$coupon->code, 'excerpt' => json_encode($coupon)]; $this->insertItem(['product'=>$item]); return json_encode(['message'=>lang('coupon_applied')]); } - } - else - { + } else { return json_encode(['error'=>lang('coupon_invalid')]); } } public function isCouponApplied($coupon) { - foreach($this->items as $item) - { - if($item->type == 'coupon' && $item->description == $coupon->code) - { + foreach ($this->items as $item) { + if ($item->type == 'coupon' && $item->description == $coupon->code) { return true; } } @@ -108,19 +98,15 @@ public function isCouponApplied($coupon) private function getCouponTimesAvailable($coupon) { $timesAvailable = -1; - if($coupon->max_uses > 0 && $coupon->max_product_instances > 0) - { - $timesAvailable = min( ($coupon->max_uses - $coupon->num_uses),$coupon->max_product_instances ); //maximum times supported per order & max uses in genreral - } elseif ($coupon->max_uses == 0 && $coupon->max_product_instances > 0) - { + if ($coupon->max_uses > 0 && $coupon->max_product_instances > 0) { + $timesAvailable = min(($coupon->max_uses - $coupon->num_uses), $coupon->max_product_instances); //maximum times supported per order & max uses in genreral + } elseif ($coupon->max_uses == 0 && $coupon->max_product_instances > 0) { $timesAvailable = $coupon->max_product_instances; - } elseif($coupon->max_uses > 0 && $coupon->max_product_instances == 0) - { + } elseif ($coupon->max_uses > 0 && $coupon->max_product_instances == 0) { $usesLeft = max($coupon->max_uses - $coupon->num_uses, 0); //if there are more than 0 return -1 so the coupon can be used on the whole order - if($usesLeft == 0) - { + if ($usesLeft == 0) { $timesAvailable = 0; } } @@ -132,14 +118,10 @@ private function calculateCouponDiscounts() { $coupons = []; $discounts = []; - for($i=0; $iitems); $i++) - { - if($this->items[$i]->type == 'coupon') - { + for ($i=0; $iitems); $i++) { + if ($this->items[$i]->type == 'coupon') { $coupons[] = $this->items[$i]; - } - elseif($this->items[$i]->type == 'product') - { + } elseif ($this->items[$i]->type == 'product') { //remove all discounts $this->items[$i]->coupon_code = ''; $this->items[$i]->coupon_discount = ''; @@ -148,10 +130,8 @@ private function calculateCouponDiscounts() } $couponsByCode = []; - if(count($coupons) > 0) - { - foreach($coupons as $code) - { + if (count($coupons) > 0) { + foreach ($coupons as $code) { $coupon = \CI::Coupons()->getCouponByCode($code->description); $couponsByCode[$coupon->code] = $coupon; @@ -160,32 +140,24 @@ private function calculateCouponDiscounts() //store the timesAvailable with the coupon to access shortly $couponsByCode[$coupon->code]->timesAvailable = $timesAvailable; - for($i=0; $i < count($this->items); $i++) - { - if($coupon->whole_order_coupon || in_array($this->items[$i]->product_id, $coupon->product_list)) - { - if($this->items[$i]->type == 'product') - { - if($timesAvailable < 0) - { + for ($i=0; $i < count($this->items); $i++) { + if ($coupon->whole_order_coupon || in_array($this->items[$i]->product_id, $coupon->product_list)) { + if ($this->items[$i]->type == 'product') { + if ($timesAvailable < 0) { $quantity = $this->items[$i]->quantity; - } - else - { + } else { $quantity = min($this->items[$i]->quantity, $timesAvailable); } - $key = json_encode(['code'=>$coupon->code, 'itemId'=>$this->items[$i]->id]); + $key = json_encode(['code'=>$coupon->code, 'itemId'=>$this->items[$i]->id]); - if($coupon->reduction_type == 'percent') - { + if ($coupon->reduction_type == 'percent') { $percent = ($coupon->reduction_amount/100); $discount = $this->items[$i]->total_price * $percent; $discounts[$key] = $discount * $quantity; - } - else //fixed - { + } else //fixed + { $discounts[$key] = $coupon->reduction_amount * $quantity; } } @@ -197,8 +169,7 @@ private function calculateCouponDiscounts() //sort descending arsort($discounts); - foreach($discounts as $key => $discount) - { + foreach ($discounts as $key => $discount) { $key = json_decode($key); $code = $key->code; @@ -206,36 +177,27 @@ private function calculateCouponDiscounts() $coupon = $couponsByCode[$code]; - for($i=0; $iitems); $i++) - { - if($this->items[$i]->id == $item) - { - if($coupon->timesAvailable < 0) - { + for ($i=0; $iitems); $i++) { + if ($this->items[$i]->id == $item) { + if ($coupon->timesAvailable < 0) { $quantity = $this->items[$i]->quantity; - } - else - { + } else { $quantity = min($this->items[$i]->quantity, $coupon->timesAvailable); } - $discount = 0; // reset discount + $discount = 0; // reset discount - if($coupon->reduction_type == 'percent') - { + if ($coupon->reduction_type == 'percent') { $percent = ($coupon->reduction_amount/100); $discount = $this->items[$i]->total_price * $percent; - } - else //fixed - { + } else //fixed + { $discount = $coupon->reduction_amount; } - if(($this->items[$i]->coupon_discount * $this->items[$i]->coupon_discount_quantity) < ($quantity * $discount)) - { + if (($this->items[$i]->coupon_discount * $this->items[$i]->coupon_discount_quantity) < ($quantity * $discount)) { //consider adding the previous availability back to the other coupon - if(!empty($this->items[$i]->coupon_code) && $couponsByCode[$this->items[$i]->coupon_code]->timesAvailable >= 0) - { + if (!empty($this->items[$i]->coupon_code) && $couponsByCode[$this->items[$i]->coupon_code]->timesAvailable >= 0) { $couponsByCode[$this->items[$i]->coupon_code]->timesAvailable += $this->items[$i]->coupon_discount_quantity; } // else could go here but if it's less than 0 it's an infinite use coupon @@ -245,15 +207,13 @@ private function calculateCouponDiscounts() $couponsByCode[$code]->timesAvailable -= $quantity; } - } + } } } //loop through and resave all items. - for($i=0; $iitems); $i++) - { - if($this->items[$i]->type == 'product') - { + for ($i=0; $iitems); $i++) { + if ($this->items[$i]->type == 'product') { $this->insertItem(['product'=>$this->items[$i], 'quantity'=>$this->items[$i]->quantity]); } } @@ -264,35 +224,24 @@ private function calculateGiftCardDiscounts() $total = 0; $giftCards = []; - foreach($this->items as $item) - { - if($item->type != 'gift card') //gift card - { - if(isset($item->coupon_discount)) - { + foreach ($this->items as $item) { + if ($item->type != 'gift card') { //gift card + if (isset($item->coupon_discount)) { $total += ($item->total_price * $item->quantity) - ($item->coupon_discount * $item->coupon_discount_quantity); - } - else - { + } else { $total += ($item->total_price * $item->quantity); } - } - else - { + } else { $giftCards[] = $item; } } $total = round($total, 2); - foreach($giftCards as $giftCard) - { - //find out how much can be applied - if($total > $giftCard->price) - { + foreach ($giftCards as $giftCard) { + //find out how much can be applied + if ($total > $giftCard->price) { $giftCard->total_price = -($giftCard->price); - } - else - { + } else { $giftCard->total_price = -($total); } @@ -323,14 +272,11 @@ public function getCustomer() public function getCart($refresh = false) { - if($refresh) - { + if ($refresh) { $this->customer = CI::Login()->customer(); - $this->cart = CI::Orders()->getCustomerCart($this->customer->id); - if(!$this->cart) - { - //create a new cart + if (empty($this->cart)) { + //create a new cart CI::Orders()->saveOrder(['status' => 'cart', 'customer_id' => $this->customer->id]); $this->cart = CI::Orders()->getCustomerCart($this->customer->id); } @@ -342,8 +288,7 @@ public function getCart($refresh = false) public function getCartItems($refresh = false) { - if($refresh || empty($this->items)) - { + if ($refresh || empty($this->items)) { $this->items = CI::Orders()->getItems($this->cart->id); } @@ -352,10 +297,8 @@ public function getCartItems($refresh = false) public function getCartItem($id) { - foreach($this->items as $item) - { - if($item->id == $id) - { + foreach ($this->items as $item) { + if ($item->id == $id) { return $item; } } @@ -370,15 +313,14 @@ private function cleanProduct($product) //remove the following fields $remove = ['id', 'primary_category', 'quantity', 'related_products', 'google_feed', 'seo_title', 'meta']; - foreach($remove as $r) - { + foreach ($remove as $r) { unset($product->$r); } return $product; } - public function insertItem($data=[]) + public function insertItem($data = []) { $product = false; $quantity = 1; @@ -388,12 +330,10 @@ public function insertItem($data=[]) extract($data); - if(is_int($product)) - { + if (is_int($product)) { $product = \CI::Products()->getProduct($product); - if(!$product) - { + if (!$product) { return json_encode(['error'=>lang('error_product_not_found')]); } @@ -405,20 +345,16 @@ public function insertItem($data=[]) } $update = false; - if(empty($product->hash)) - { + if (empty($product->hash)) { $product->hash = md5(json_encode($product).json_encode($postedOptions)); //set defaults for new items $product->coupon_discount = 0; $product->coupon_discount_quantity = 0; $product->coupon_code = ''; - } - else - { - if(!$combine) - { - //this is an update + } else { + if (!$combine) { + //this is an update $update = true; } @@ -431,55 +367,42 @@ public function insertItem($data=[]) $this->getCartItems(); // refresh the cart items - foreach($this->items as $item) - { - if(intval($item->product_id) == intval($product->product_id)) - { - if($item->hash != $product->hash) //if the hashes match, skip this step (this is an update) - { + foreach ($this->items as $item) { + if (intval($item->product_id) == intval($product->product_id)) { + if ($item->hash != $product->hash) { //if the hashes match, skip this step (this is an update) $qty_count = $qty_count + $item->quantity; } } - if($item->hash == $product->hash && !$update) //if this is an update skip this step - { - //if the item is already in the cart, send back a message + if ($item->hash == $product->hash && !$update) { //if this is an update skip this step + //if the item is already in the cart, send back a message return json_encode(['message'=>lang('item_already_added')]); } } - if(!config_item('allow_os_purchase') && (bool)$product->track_stock) - { + if (!config_item('allow_os_purchase') && (bool)$product->track_stock) { $stock = \CI::Products()->getProduct($product->product_id); - if($stock->quantity < $qty_count) - { + if ($stock->quantity < $qty_count) { return json_encode(['error'=>sprintf(lang('not_enough_stock'), $stock->name, $stock->quantity)]); } } - if (!$quantity || $quantity <= 0 || $product->fixed_quantity==1) - { + if (!$quantity || $quantity <= 0 || $product->fixed_quantity==1) { $product->quantity = 1; - } - else - { + } else { $product->quantity = $quantity; } //create save options array here for use later. $saveOptions = []; - if(!$update && $product->product_id) // if not an update or non-product, try and run the options - { - //set the base "total_price" - if($product->saleprice > 0) - { + if (!$update && $product->product_id) { // if not an update or non-product, try and run the options + //set the base "total_price" + if ($product->saleprice > 0) { $product->total_price = $product->saleprice; - } - else - { + } else { $product->total_price = $product->price; } @@ -492,39 +415,30 @@ public function insertItem($data=[]) $optionError = false; $optionErrorMessage = lang('option_error').'
'; - foreach($productOptions as $productOption) - { - // are we missing any required values? + foreach ($productOptions as $productOption) { + // are we missing any required values? $optionValue = false; - if(!empty($postedOptions[$productOption->id])) - { + if (!empty($postedOptions[$productOption->id])) { $optionValue = $postedOptions[$productOption->id]; } - if((int)$productOption->required && empty($optionValue)) - { + if ((int)$productOption->required && empty($optionValue)) { $optionError = true; $optionErrorMessage .= "- ". $productOption->name .'
'; continue; // don't bother processing this particular option any further } - if(empty($optionValue)) - { - //empty? Move along, nothing to see here. + if (empty($optionValue)) { + //empty? Move along, nothing to see here. continue; } //create options to save to the database in case we get past the errors - if($productOption->type == 'checklist') - { - if(is_array($optionValue)) - { - foreach($optionValue as $ov) - { - foreach($productOption->values as $productOptionValue) - { - if($productOptionValue->id == $ov) - { + if ($productOption->type == 'checklist') { + if (is_array($optionValue)) { + foreach ($optionValue as $ov) { + foreach ($productOption->values as $productOptionValue) { + if ($productOptionValue->id == $ov) { $saveOptions[] = [ 'option_name'=>$productOption->name, 'value'=>$productOptionValue->value, @@ -537,29 +451,23 @@ public function insertItem($data=[]) } } } - } - else //every other form type we support + } else //every other form type we support { $saveOption = []; - if($productOption->type == 'textfield' || $productOption->type == 'textarea') - { + if ($productOption->type == 'textfield' || $productOption->type == 'textarea') { $productOptionValue = $productOption->values[0]; $productOptionValue->value = $optionValue; - } - else //radios and checkboxes + } else //radios and checkboxes { - foreach($productOption->values as $ov) - { - if($ov->id == $optionValue) - { + foreach ($productOption->values as $ov) { + if ($ov->id == $optionValue) { $productOptionValue = $ov; break; } } $saveOption['value'] = $optionValue; } - if(isset($productOptionValue)) - { + if (isset($productOptionValue)) { $saveOption['option_name'] = $productOption->name; $saveOption['price'] = $productOptionValue->price; $saveOption['weight'] = $productOptionValue->weight; @@ -575,8 +483,7 @@ public function insertItem($data=[]) } } - if($optionError) - { + if ($optionError) { return json_encode(['error'=>$optionErrorMessage]); } } @@ -585,33 +492,25 @@ public function insertItem($data=[]) $product_id = \CI::Orders()->saveItem((array)$product); //save the options if we have them - foreach($saveOptions as $saveOption) - { + foreach ($saveOptions as $saveOption) { $saveOption['order_item_id'] = $product_id; $saveOption['order_id'] = $this->cart->id; \CI::Orders()->saveItemOption($saveOption); } - if($update) - { - foreach($this->items as $key => $item) - { - if($item->id == $product_id) - { + if ($update) { + foreach ($this->items as $key => $item) { + if ($item->id == $product_id) { $this->items[$key] = $product; } } - } - else - { + } else { $product->id = $product_id; $this->items[] = $product; //update file downloads - if($downloads) - { - foreach($downloads as $file) - { + if ($downloads) { + foreach ($downloads as $file) { \CI::Orders()->saveOrderItemFile(['order_id'=>$this->cart->id, 'order_item_id'=>$product->id, 'file_id'=>$file->file_id]); } } @@ -620,12 +519,9 @@ public function insertItem($data=[]) //get current item count $itemCount = $this->totalItems(); - if($update) - { + if ($update) { return json_encode(['message'=>lang('cart_updated'), 'itemCount'=>$itemCount]); - } - else - { + } else { return json_encode(['message'=>lang('item_added_to_cart'), 'itemCount'=>$itemCount]); } } @@ -636,21 +532,14 @@ public function checkInventory() $errors = []; //if we do not allow overstock sale, then check stock otherwise return an empty array - if(!config_item('allow_os_purchase')) - { - foreach($this->items as $item) - { - if($item->type == 'product') - { + if (!config_item('allow_os_purchase')) { + foreach ($this->items as $item) { + if ($item->type == 'product') { $stock = \CI::Products()->getProduct($item->product_id); - if((bool)$stock->track_stock && $stock->quantity < $item->quantity) - { - if ($stock->quantity < 1) - { + if ((bool)$stock->track_stock && $stock->quantity < $item->quantity) { + if ($stock->quantity < 1) { $errors[$item->id] = lang('this_item_is_out_of_stock'); //completely out of stock. - } - else - { + } else { $errors[$item->id] = str_replace('{quantity}', $stock->quantity, lang('not_enough_stock_quantity')); } } @@ -664,23 +553,19 @@ function checkCoupons() { $errors = []; $coupons = []; - for($i=0; $iitems); $i++) - { - if($this->items[$i]->type == 'coupon') - { + for ($i=0; $iitems); $i++) { + if ($this->items[$i]->type == 'coupon') { $coupons[] = $this->items[$i]; } } - foreach($coupons as $code) - { + foreach ($coupons as $code) { $coupon = \CI::Coupons()->getCouponByCode($code->description); - if(!\CI::Coupons()->isValid($coupon)) - { - //coupon is no longer valid - $errors[] = json_encode(['error'=>str_replace('{coupon_code}', $code->description,lang('coupon_code_no_longer_valid'))]); + if (!\CI::Coupons()->isValid($coupon)) { + //coupon is no longer valid + $errors[] = json_encode(['error'=>str_replace('{coupon_code}', $code->description, lang('coupon_code_no_longer_valid'))]); //remove the coupon $this->removeItem($code->id); } @@ -690,103 +575,82 @@ function checkCoupons() } // double check the order before saving - public function checkOrder() { + public function checkOrder() + { //start tracking errors $errors = []; $cart = new stdClass(); $addresses = \CI::Customers()->get_address_list($this->customer->id); - foreach($addresses as $address) - { - if($address['id'] == $this->cart->shipping_address_id) - { + foreach ($addresses as $address) { + if ($address['id'] == $this->cart->shipping_address_id) { $cart->shippingAddress = (object)$address; } - if($address['id'] == $this->cart->billing_address_id) - { + if ($address['id'] == $this->cart->billing_address_id) { $cart->billingAddress = (object)$address; } } //check shipping - if($this->orderRequiresShipping()) - { - if(!$this->getShippingMethod()) - { + if ($this->orderRequiresShipping()) { + if (!$this->getShippingMethod()) { $errors['shipping'] = lang('error_choose_shipping'); } - if(empty($cart->shippingAddress)) - { + if (empty($cart->shippingAddress)) { $errors['shippingAddress'] = lang('error_shipping_address'); } } - if(empty($cart->billingAddress)) - { + if (empty($cart->billingAddress)) { $errors['billingAddress'] = lang('error_billing_address'); } //check coupons $checkCoupons = $this->checkCoupons(); - if(!empty($checkCoupons)) - { + if (!empty($checkCoupons)) { $errors['coupons'] = $checkCoupons; } //check the inventory of our products $inventory = $this->checkInventory(); - if(!empty($inventory)) - { + if (!empty($inventory)) { $errors['inventory'] = $inventory; } //if we have errors, return them - if(!empty($errors)) - { + if (!empty($errors)) { return $errors; } } function submitOrder($transaction = false) { - foreach ($this->items as $item) - { - if($item->type == 'gift card') - { + foreach ($this->items as $item) { + if ($item->type == 'gift card') { //touch giftcard \CI::GiftCards()->updateAmountUsed($item->description, $item->total_price); continue; - } - elseif($item->type == 'coupon') - { + } elseif ($item->type == 'coupon') { //touch coupon \CI::Coupons()->touchCoupon($item->description); continue; - } - elseif($item->type == 'product') - { + } elseif ($item->type == 'product') { //update inventory - if($item->track_stock) - { + if ($item->track_stock) { \CI::Products()->touchInventory($item->product_id, $item->quantity); } //if this is a giftcard purchase, generate it and send it where it needs to go. - if($item->is_giftcard) - { - //process giftcard + if ($item->is_giftcard) { + //process giftcard $options = CI::Orders()->getItemOptions(GC::getCart()->id); $giftCard = []; - foreach($options[$item->id] as $option) - { - if($option->option_name == 'gift_card_amount') - { + foreach ($options[$item->id] as $option) { + if ($option->option_name == 'gift_card_amount') { $giftCard[$option->option_name] = $option->price; - } - else - { + } else { $giftCard[$option->option_name] = $option->value; } } @@ -801,8 +665,7 @@ function submitOrder($transaction = false) } } } - if(!$transaction) - { + if (!$transaction) { $transaction = $this->transaction(); } @@ -833,8 +696,7 @@ function submitOrder($transaction = false) public function transaction($transaction = false) { //no transaction provided? create a new one and return it. - if(!$transaction) - { + if (!$transaction) { $order_number = str_replace('.', '-', microtime(true)).$this->cart->id; $transaction = [ 'order_id' => $this->cart->id, @@ -845,28 +707,21 @@ public function transaction($transaction = false) \CI::db()->insert('transactions', $transaction); $transaction['id'] = \CI::db()->insert_id(); - return (object)$transaction; - } - else - { + return (object)$transaction; + } else { //we have a transaction, update it with the response - \CI::db()->where('id',$transaction->id)->update('transactions', (array)$transaction); + \CI::db()->where('id', $transaction->id)->update('transactions', (array)$transaction); } } public function getTaxableTotal() { $total = 0; - foreach($this->items as $item) - { - if($item->taxable) - { - if(isset($item->coupon_discount)) - { + foreach ($this->items as $item) { + if ($item->taxable) { + if (isset($item->coupon_discount)) { $total += ($item->total_price * $item->quantity) - ($item->coupon_discount * $item->coupon_discount_quantity); - } - else - { + } else { $total += ($item->total_price * $item->quantity); } } @@ -878,10 +733,8 @@ public function getTaxableTotal() public function getSubtotal() { $total = 0; - foreach($this->items as $item) - { - if($item->type == 'product') - { + foreach ($this->items as $item) { + if ($item->type == 'product') { $total += ($item->total_price * $item->quantity) - ($item->coupon_discount * $item->coupon_discount_quantity); } } @@ -894,10 +747,8 @@ public function getSubtotal() public function getTotalWeight() { $total = 0; - foreach($this->items as $item) - { - if($item->type == 'product') - { + foreach ($this->items as $item) { + if ($item->type == 'product') { $total += ($item->total_weight * $item->quantity); } } @@ -908,14 +759,10 @@ public function getTotalWeight() public function getGrandTotal() { $total = 0; - foreach($this->items as $item) - { - if(isset($item->coupon_discount)) - { + foreach ($this->items as $item) { + if (isset($item->coupon_discount)) { $math = ($item->total_price * $item->quantity) - ($item->coupon_discount * $item->coupon_discount_quantity); - } - else - { + } else { $math = ($item->total_price * $item->quantity); } $total = $total+$math; @@ -932,8 +779,7 @@ public function setTaxes() //remove any existing tax charges $this->removeItemsOfType('tax'); - if($tax > 0) - { + if ($tax > 0) { $item = (object)['product_id'=>0, 'shippable'=>0, 'taxable'=>0, 'track_stock'=>0, 'fixed_quantity'=>1, 'type'=>'tax', 'name'=>lang('taxes'), 'total_price'=>$tax]; $this->insertItem(['product'=>$item]); } @@ -946,8 +792,7 @@ public function setShippingMethod($key, $rate, $hash) $shipping = (object)['product_id'=>0, 'shippable'=>0, 'taxable'=>0, 'fixed_quantity'=>1, 'type'=>'shipping', 'name'=>$key, 'total_price'=>$rate, 'description'=>$hash]; - if(config_item('tax_shipping')) - { + if (config_item('tax_shipping')) { $shipping->taxable = 1; } @@ -956,10 +801,8 @@ public function setShippingMethod($key, $rate, $hash) public function getShippingMethod() { - foreach($this->items as $item) - { - if($item->type == 'shipping') - { + foreach ($this->items as $item) { + if ($item->type == 'shipping') { return $item; } } @@ -968,10 +811,8 @@ public function getShippingMethod() public function orderRequiresShipping() { - foreach($this->items as $item) - { - if((bool)$item->shippable) - { + foreach ($this->items as $item) { + if ((bool)$item->shippable) { return true; } } @@ -983,8 +824,7 @@ public function getShippingMethodOptions() global $shippingModules; $rates = []; - foreach($shippingModules as $shippingModule) - { + foreach ($shippingModules as $shippingModule) { $className = '\GoCart\Controller\\'.$shippingModule['class']; $rates = $rates+(new $className)->rates(); } @@ -993,29 +833,22 @@ public function getShippingMethodOptions() public function testShippingMethodValidity() { - if(!$this->orderRequiresShipping()) - { - //if shipping is not required, then remove any shipping methods. + if (!$this->orderRequiresShipping()) { + //if shipping is not required, then remove any shipping methods. $this->removeItemsOfType('shipping'); - } - else - { + } else { $shippingExists = false; $shippingMethod = $this->getShippingMethod(); - if(is_object($shippingMethod)) - { + if (is_object($shippingMethod)) { $shippingMethods = $this->getShippingMethodOptions(); - foreach($shippingMethods as $key=>$rate) - { - $hash = md5( json_encode(['key'=>$key, 'rate'=>$rate]) ); - if($hash == $shippingMethod->description) - { + foreach ($shippingMethods as $key => $rate) { + $hash = md5(json_encode(['key'=>$key, 'rate'=>$rate])); + if ($hash == $shippingMethod->description) { $shippingExists = true; } } } - if(!$shippingExists) - { + if (!$shippingExists) { $this->removeItemsOfType('shipping'); } } @@ -1023,10 +856,8 @@ public function testShippingMethodValidity() public function removeItemsOfType($type) { - foreach($this->items as $item) - { - if($item->type == $type) - { + foreach ($this->items as $item) { + if ($item->type == $type) { $this->removeItem($item->id); } } @@ -1036,10 +867,8 @@ public function removeItem($id) { CI::Orders()->removeItem($this->cart->id, $id); - for($i=0; $i < count($this->items); $i++) - { - if($this->items[$i]->id == $id) - { + for ($i=0; $i < count($this->items); $i++) { + if ($this->items[$i]->id == $id) { unset($this->items[$i]); } } @@ -1052,10 +881,8 @@ public function totalItems() { $count = 0; - foreach($this->items as $item) - { - if($item->type == 'product') - { + foreach ($this->items as $item) { + if ($item->type == 'product') { $count += $item->quantity; } } @@ -1070,18 +897,13 @@ public function repriceItems() $options = CI::Orders()->getItemOptions(GC::getCart()->id); - foreach($this->items as $item) - { - - if($item->type == 'product') - { - + foreach ($this->items as $item) { + if ($item->type == 'product') { //grab the product from the database $product = \CI::Products()->getProduct($item->product_id); - if(empty($product)) - { - //product can no longer be found. remove it + if (empty($product)) { + //product can no longer be found. remove it $this->removeItem($item->id); continue; } @@ -1091,31 +913,26 @@ public function repriceItems() $totalPrice = 0; - if($product->{'saleprice_'.$this->customer->group_id} > 0) - { - //if it's on sale, give it the sale price + if ($product->{'saleprice_'.$this->customer->group_id} > 0) { + //if it's on sale, give it the sale price $totalPrice = $product->{'saleprice_'.$this->customer->group_id}; - } - else - { + } else { //not on sale give it the normal price $totalPrice = $product->{'price_'.$this->customer->group_id}; } - if(isset($options[$item->id])) - { - foreach($options[$item->id] as $option) - { + if (isset($options[$item->id])) { + foreach ($options[$item->id] as $option) { $totalPrice += $option->price; } } - $product->id = $item->id; - $product->hash = $item->hash; + $product->id = $item->id; + $product->hash = $item->hash; - $product->total_price = $totalPrice; //updated price + $product->total_price = $totalPrice; //updated price - \CI::Orders()->saveItem((array)$product); + \CI::Orders()->saveItem((array)$product); } } $this->getCart(true); // refresh the cart and items just one more time. diff --git a/application/libraries/Auth.php b/application/libraries/Auth.php index 68d1a07..bafece5 100644 --- a/application/libraries/Auth.php +++ b/application/libraries/Auth.php @@ -1,8 +1,10 @@ -logout(); return false; } // echo $result->access; - if ($access) - { - if ($access == $result->access) - { + if ($access) { + if ($access == $result->access) { return true; - } - else - { - if ($redirect) - { + } else { + if ($redirect) { redirect($redirect); - } - elseif($defaultRedirect) - { + } elseif ($defaultRedirect) { redirect('admin'); - } - else - { + } else { return false; } } @@ -66,68 +58,57 @@ public function isLoggedIn($redirect = false, $defaultRedirect = true) $admin = CI::session()->userdata('admin'); - if (!$admin) - { - //check the cookie - if(isset($_COOKIE['GoCartAdmin'])) - { - //the cookie is there, lets log the customer back in. - if($_COOKIE['GoCartAdmin']) - { + if (!$admin) { + //check the cookie + if (isset($_COOKIE['GoCartAdmin'])) { + //the cookie is there, lets log the customer back in. + if ($_COOKIE['GoCartAdmin']) { $result = CI::db()->select('*, sha1(username+password) as hash')->get('admin')->row_array(); - if($result) - { - //unset these 2 fields + if ($result) { + //unset these 2 fields unset($result['password']); unset($result['hash']); CI::session()->set_userdata(['admin'=>$result]); - if ($redirect) - { + if ($redirect) { CI::session()->set_flashdata('redirect', $redirect); } - if ($defaultRedirect) - { + if ($defaultRedirect) { redirect(CI::uri()->uri_string()); } } } } - if($redirect && $defaultRedirect) - redirect('admin/login'); + if ($redirect && $defaultRedirect) { + redirect('admin/login'); + } return false; - } - else - { + } else { return true; } } /* this function does the logging in. */ - public function login_admin($username, $password, $remember=false) + public function login_admin($username, $password, $remember = false) { // make sure the username doesn't go into the query as false or 0 - if(!$username) - { + if (!$username) { return false; } CI::db()->select('*'); CI::db()->where('username', $username); - CI::db()->where('password', sha1($password)); CI::db()->limit(1); $result = CI::db()->get('admin'); $result = $result->row_array(); - if (sizeof($result) > 0) - { - if($remember) - { + if (password_verify($password, $result['password']) == true && sizeof($result) > 0) { + if ($remember) { //generate a remember cookie $loginCred = sha1($username.$result['password']); $this->generateCookie($loginCred, strtotime('+6 months')); //remember the user for 6 months @@ -141,9 +122,7 @@ public function login_admin($username, $password, $remember=false) CI::session()->set_userdata(['admin'=>$result]); return true; - } - else - { + } else { return false; } } @@ -169,21 +148,18 @@ public function logout() public function resetPassword($username) { $admin = $this->getAdminByUsername($username); - if ($admin) - { + if ($admin) { CI::load()->helper('string'); CI::load()->library('email'); $newPassword = random_string('alnum', 8); - $admin['password'] = sha1($newPassword); + $admin['password'] = password_hash($newPassword, PASSWORD_DEFAULT); $this->save($admin); - \GoCart\Emails::resetPassword($newPassword,$admin['email']); + \GoCart\Emails::resetPassword($newPassword, $admin['email']); return true; - } - else - { + } else { return false; } } @@ -200,12 +176,9 @@ private function getAdminByUsername($username) $result = CI::db()->get('admin'); $result = $result->row_array(); - if (sizeof($result) > 0) - { - return $result; - } - else - { + if (sizeof($result) > 0) { + return $result; + } else { return false; } } @@ -215,13 +188,10 @@ private function getAdminByUsername($username) */ public function save($admin) { - if ($admin['id']) - { + if ($admin['id']) { CI::db()->where('id', $admin['id']); CI::db()->update('admin', $admin); - } - else - { + } else { CI::db()->insert('admin', $admin); } } @@ -263,51 +233,41 @@ public function checkId($str) CI::db()->where('id', $str); $count = CI::db()->count_all_results(); - if ($count > 0) - { + if ($count > 0) { return true; - } - else - { + } else { return false; } } - public function check_username($str, $id=false) + public function check_username($str, $id = false) { CI::db()->select('username'); CI::db()->from('admin'); CI::db()->where('username', $str); - if ($id) - { + if ($id) { CI::db()->where('id !=', $id); } $count = CI::db()->count_all_results(); - if ($count > 0) - { + if ($count > 0) { return true; - } - else - { + } else { return false; } } public function delete($id) { - if ($this->checkId($id)) - { + if ($this->checkId($id)) { $admin = $this->getAdmin($id); CI::db()->where('id', $id); CI::db()->limit(1); CI::db()->delete('admin'); return $admin->firstname.' '.$admin->lastname.' has been removed.'; - } - else - { + } else { return 'The admin could not be found.'; } } -} \ No newline at end of file +} diff --git a/application/modules/categories/controllers/AdminCategories.php b/application/modules/categories/controllers/AdminCategories.php index 1587786..c785c73 100644 --- a/application/modules/categories/controllers/AdminCategories.php +++ b/application/modules/categories/controllers/AdminCategories.php @@ -1,4 +1,5 @@ check_access('Admin', true); @@ -63,21 +66,18 @@ function form($id = false) $data['parent_id'] = 0; $data['error'] = ''; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = ''; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = ''; } //create the photos array for later use $data['photos'] = []; - if ($id) - { + if ($id) { $category = \CI::Categories()->find($id); //if the category does not exist, redirect them to the category list with an error - if (!$category) - { + if (!$category) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/categories'); } @@ -96,9 +96,8 @@ function form($id = false) $data['image'] = $category->image; $data['seo_title'] = $category->seo_title; $data['meta'] = $category->meta; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = $category->{'enabled_'.$group->id}; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = $category->{'enabled'.$group->id}; } } @@ -113,41 +112,31 @@ function form($id = false) \CI::form_validation()->set_rules('seo_title', 'lang:seo_title', 'trim'); \CI::form_validation()->set_rules('meta', 'lang:meta', 'trim'); - foreach($data['groups'] as $group) - { - \CI::form_validation()->set_rules('enabled_'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); + foreach ($data['groups'] as $group) { + \CI::form_validation()->set_rules('enabled'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); } // validate the form - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('category_form', $data); - } - else - { + } else { $uploaded = \CI::upload()->do_upload('image'); - if ($id) - { - //delete the original file if another is uploaded - if($uploaded) - { - - if($data['image'] != '') - { + if ($id) { + //delete the original file if another is uploaded + if ($uploaded) { + if ($data['image'] != '') { $file = []; $file[] = 'uploads/images/full/'.$data['image']; $file[] = 'uploads/images/medium/'.$data['image']; $file[] = 'uploads/images/small/'.$data['image']; $file[] = 'uploads/images/thumbnails/'.$data['image']; - foreach($file as $f) - { - //delete the existing file if needed - if(file_exists($f)) - { + foreach ($file as $f) { + //delete the existing file if needed + if (file_exists($f)) { unlink($f); } } @@ -156,18 +145,14 @@ function form($id = false) } - if(!$uploaded) - { + if (!$uploaded) { $data['error'] = \CI::upload()->display_errors(); - if($_FILES['image']['error'] != 4) - { + if ($_FILES['image']['error'] != 4) { $data['error'] .= \CI::upload()->display_errors(); $this->view('category_form', $data); return; //end script here if there is an error } - } - else - { + } else { $image = \CI::upload()->data(); $save['image'] = $image['file_name']; @@ -177,7 +162,7 @@ function form($id = false) $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/full/'.$save['image']; $config['new_image'] = 'uploads/images/medium/'.$save['image']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 600; $config['height'] = 500; \CI::image_lib()->initialize($config); @@ -188,10 +173,10 @@ function form($id = false) $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/medium/'.$save['image']; $config['new_image'] = 'uploads/images/small/'.$save['image']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 300; $config['height'] = 300; - \CI::image_lib()->initialize($config); + \CI::image_lib()->initialize($config); \CI::image_lib()->resize(); \CI::image_lib()->clear(); @@ -199,11 +184,11 @@ function form($id = false) $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/small/'.$save['image']; $config['new_image'] = 'uploads/images/thumbnails/'.$save['image']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 150; $config['height'] = 150; - \CI::image_lib()->initialize($config); - \CI::image_lib()->resize(); + \CI::image_lib()->initialize($config); + \CI::image_lib()->resize(); \CI::image_lib()->clear(); } @@ -213,19 +198,15 @@ function form($id = false) $slug = \CI::input()->post('slug'); //if it's empty assign the name field - if(empty($slug) || $slug=='') - { + if (empty($slug) || $slug=='') { $slug = \CI::input()->post('name'); } - $slug = url_title(convert_accented_characters($slug), 'dash', TRUE); + $slug = url_title(convert_accented_characters($slug), 'dash', true); - if($id) - { + if ($id) { $slug = \CI::Categories()->validate_slug($slug, $category->id); - } - else - { + } else { $slug = \CI::Categories()->validate_slug($slug); } @@ -238,9 +219,8 @@ function form($id = false) $save['seo_title'] = \CI::input()->post('seo_title'); $save['meta'] = \CI::input()->post('meta'); $save['slug'] = $slug; - foreach($data['groups'] as $group) - { - $save['enabled_'.$group->id] = \CI::input()->post('enabled_'.$group->id); + foreach ($data['groups'] as $group) { + $save['enabled'.$group->id] = \CI::input()->post('enabled'.$group->id); } $category_id = \CI::Categories()->save($save); @@ -257,21 +237,17 @@ function delete($id) $category = \CI::Categories()->find($id); //if the category does not exist, redirect them to the customer list with an error - if ($category) - { - if($category->image != '') - { + if ($category) { + if ($category->image != '') { $file = []; $file[] = 'uploads/images/full/'.$category->image; $file[] = 'uploads/images/medium/'.$category->image; $file[] = 'uploads/images/small/'.$category->image; $file[] = 'uploads/images/thumbnails/'.$category->image; - foreach($file as $f) - { - //delete the existing file if needed - if(file_exists($f)) - { + foreach ($file as $f) { + //delete the existing file if needed + if (file_exists($f)) { unlink($f); } } @@ -281,10 +257,8 @@ function delete($id) \CI::session()->set_flashdata('message', lang('message_delete_category')); redirect('admin/categories'); - } - else - { + } else { \CI::session()->set_flashdata('error', lang('error_not_found')); } } -} \ No newline at end of file +} diff --git a/application/modules/categories/models/Categories.php b/application/modules/categories/models/Categories.php index ed08a85..9da8b7d 100644 --- a/application/modules/categories/models/Categories.php +++ b/application/modules/categories/models/Categories.php @@ -9,7 +9,7 @@ * @link http://gocartdv.com */ -Class Categories +class Categories { var $tiered; @@ -23,22 +23,17 @@ public function __construct() public function tier($parent_id) { - if(isset($this->tiered[$parent_id])) - { + if (isset($this->tiered[$parent_id])) { return $this->tiered[$parent_id]; - } - else - { + } else { return false; } } public function getBySlug($slug) { - foreach($this->tiered['all'] as $c) - { - if($c->slug == $slug) - { + foreach ($this->tiered['all'] as $c) { + if ($c->slug == $slug) { return $c; break; } @@ -52,8 +47,7 @@ public function get($slug, $sort, $direction, $page, $products_per_page) $category = $this->getBySlug($slug); //if the category does not exist return false - if(!$category || !$category->{'enabled_'.$this->customer->group_id}) - { + if (!$category || !$category->{'enabled'.$this->customer->group_id}) { return false; } @@ -71,8 +65,7 @@ public function get($slug, $sort, $direction, $page, $products_per_page) public function get_categories($parent = false) { - if ($parent !== false) - { + if ($parent !== false) { CI::db()->where('parent_id', $parent); } CI::db()->select('id'); @@ -83,8 +76,7 @@ public function get_categories($parent = false) $result = CI::db()->get('categories'); $categories = []; - foreach($result->result() as $cat) - { + foreach ($result->result() as $cat) { $categories[] = $this->find($cat->id); } @@ -93,14 +85,12 @@ public function get_categories($parent = false) public function get_categories_tiered($admin = false) { - if(!$admin && !empty($this->tiered)) - { + if (!$admin && !empty($this->tiered)) { return $this->tiered; } - if(!$admin) - { - CI::db()->where('enabled_'.$this->customer->group_id, 1); + if (!$admin && !empty($this->customer->group_id)) { + CI::db()->where('enabled'); } CI::db()->order_by('sequence'); @@ -109,10 +99,10 @@ public function get_categories_tiered($admin = false) $results = []; $results['all'] = []; - foreach($categories as $category) { + foreach ($categories as $category) { // Set a class to active, so we can highlight our current category - if(CI::uri()->segment(2) == $category->slug && CI::uri()->segment(1) == 'category') { + if (CI::uri()->segment(2) == $category->slug && CI::uri()->segment(1) == 'category') { $category->active = true; } else { $category->active = false; @@ -121,8 +111,7 @@ public function get_categories_tiered($admin = false) $results[$category->parent_id][$category->id] = $category; } - if(!$admin) - { + if (!$admin) { $this->tiered = $results; } @@ -133,19 +122,15 @@ public function getCategoryOptionsMenu($hideId = false) { $cats = $this->get_categories_tiered(true); $options = [-1 => lang('hidden'), 0 => lang('top_level_category')]; - $listCategories = function($parent_id, $sub='') use (&$options, $cats, &$listCategories, $hideId) { + $listCategories = function ($parent_id, $sub = '') use (&$options, $cats, &$listCategories, $hideId) { - if(isset($cats[$parent_id])) - { - foreach ($cats[$parent_id] as $cat) - { + if (isset($cats[$parent_id])) { + foreach ($cats[$parent_id] as $cat) { //if this matches the hide id, skip it and all it's children - if(!$hideId || $cat->id != $hideId) - { + if (!$hideId || $cat->id != $hideId) { $options[$cat->id] = $sub.$cat->name; - if (isset($cats[$cat->id]) && sizeof($cats[$cat->id]) > 0) - { + if (isset($cats[$cat->id]) && sizeof($cats[$cat->id]) > 0) { $sub2 = str_replace('→ ', ' ', $sub); $sub2 .= '   → '; $listCategories($cat->id, $sub2); @@ -179,12 +164,11 @@ public function get_category_products_admin($id) $result = $result->result(); $contents = []; - foreach ($result as $product) - { + foreach ($result as $product) { $result2 = CI::db()->get_where('products', array('id'=>$product->product_id)); $result2 = $result2->row(); - $contents[] = $result2; + $contents[] = $result2; } return $contents; @@ -198,8 +182,7 @@ public function get_category_products($id, $limit, $offset) $contents = []; $count = 1; - foreach ($result as $product) - { + foreach ($result as $product) { $result2 = CI::db()->get_where('products', array('id'=>$product->product_id)); $result2 = $result2->row(); @@ -212,15 +195,12 @@ public function get_category_products($id, $limit, $offset) public function save($category) { - if ($category['id']) - { + if ($category['id']) { CI::db()->where('id', $category['id']); CI::db()->update('categories', $category); return $category['id']; - } - else - { + } else { CI::db()->insert('categories', $category); return CI::db()->insert_id(); } @@ -243,33 +223,25 @@ public function delete($id) * check if slug already exists */ - public function validate_slug($slug, $id=false, $counter=false) + public function validate_slug($slug, $id = false, $counter = false) { CI::db()->select('slug'); CI::db()->from('categories'); CI::db()->where('slug', $slug.$counter); - if ($id) - { + if ($id) { CI::db()->where('id !=', $id); } $count = CI::db()->count_all_results(); - if ($count > 0) - { - if(!$counter) - { + if ($count > 0) { + if (!$counter) { $counter = 1; - } - else - { + } else { $counter++; } return $this->validate_slug($slug, $id, $counter); - } - else - { + } else { return $slug.$counter; } } - -} \ No newline at end of file +} diff --git a/application/modules/categories/views/admin/categories.php b/application/modules/categories/views/admin/categories.php index d707be1..adde9f4 100644 --- a/application/modules/categories/views/admin/categories.php +++ b/application/modules/categories/views/admin/categories.php @@ -16,7 +16,7 @@ function areyousure() - + name;?> @@ -25,14 +25,15 @@ function areyousure() '.lang('no_categories').'':''?> + foreach ($cats[$parent_id] as $cat) :?> ':'';?> name; ?> - - {'enabled_'.$group->id} == '1') ? lang('enabled') : lang('disabled'); ?> + + {'enabled'.$group->id} == '1') ? lang('enabled') : lang('disabled'); ?>
@@ -42,8 +43,7 @@ function list_categories($parent_id, $cats, $groups, $sub='', $hidden=false) { id]) && sizeof($cats[$cat->id]) > 0) - { + if (isset($cats[$cat->id]) && sizeof($cats[$cat->id]) > 0) { $sub2 = str_replace('→ ', ' ', $sub); $sub2 .= '   → '; list_categories($cat->id, $cats, $groups, $sub2, $hidden); @@ -51,16 +51,14 @@ function list_categories($parent_id, $cats, $groups, $sub='', $hidden=false) { endforeach; } - if(isset($categories[-1])) - { + if (isset($categories[-1])) { list_categories(-1, $categories, $groups, '', true); } - if(isset($categories[0])) - { + if (isset($categories[0])) { list_categories(0, $categories, $groups); } ?> - \ No newline at end of file + diff --git a/application/modules/categories/views/admin/category_form.php b/application/modules/categories/views/admin/category_form.php index c7324f6..4dd9a04 100644 --- a/application/modules/categories/views/admin/category_form.php +++ b/application/modules/categories/views/admin/category_form.php @@ -27,7 +27,7 @@ 'image', 'class'=>'form-control'));?>
- +
current
@@ -35,11 +35,11 @@
- +
name;?>
- id, [1 => lang('enabled'), 0 => lang('disabled')], assign_value('enabled_'.$group->id,${'enabled_'.$group->id}), 'class="form-control"'); ?> + id, [1 => lang('enabled'), 0 => lang('disabled')], assign_value('enabled'.$group->id, ${'enabled'.$group->id}), 'class="form-control"'); ?>
@@ -82,4 +82,4 @@ $('form').submit(function() { $('.btn .btn-primary').attr('disabled', true).addClass('disabled'); }); - \ No newline at end of file + diff --git a/application/modules/customers/controllers/AdminCustomers.php b/application/modules/customers/controllers/AdminCustomers.php index 03b8ff7..e1b8b6d 100644 --- a/application/modules/customers/controllers/AdminCustomers.php +++ b/application/modules/customers/controllers/AdminCustomers.php @@ -1,4 +1,5 @@ model(array('Customers', 'Locations')); @@ -22,13 +24,13 @@ public function __construct() \CI::lang()->load('customers'); } - public function index($field='lastname', $by='ASC', $page=0) + public function index($field = 'lastname', $by = 'ASC', $page = 0) { //we're going to use flash data and redirect() after form submissions to stop people from refreshing and duplicating submissions //\CI::session()->set_flashdata('message', 'this is our message'); $data['page_title'] = lang('customers'); - $data['customers'] = \CI::Customers()->get_customers(50,$page, $field, $by); + $data['customers'] = \CI::Customers()->get_customers(50, $page, $field, $by); \CI::load()->library('pagination'); @@ -96,19 +98,16 @@ public function form($id = false) // get group list $groups = \CI::Customers()->get_groups(); - foreach($groups as $group) - { + foreach ($groups as $group) { $group_list[$group->id] = $group->name; } $data['group_list'] = $group_list; - if ($id) - { + if ($id) { $this->customer_id = $id; $customer = \CI::Customers()->get_customer($id); //if the customer does not exist, redirect them to the customer list with an error - if (!$customer) - { + if (!$customer) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/customers'); } @@ -127,16 +126,13 @@ public function form($id = false) \CI::form_validation()->set_rules('firstname', 'lang:firstname', 'trim|required|max_length[32]'); \CI::form_validation()->set_rules('lastname', 'lang:lastname', 'trim|required|max_length[32]'); - \CI::form_validation()->set_rules('email', 'lang:email', ['trim', 'required', 'valid_email', 'max_length[128]', ['email_callable', function($str) { + \CI::form_validation()->set_rules('email', 'lang:email', ['trim', 'required', 'valid_email', 'max_length[128]', ['email_callable', function ($str) { $email = \CI::Customers()->check_email($str, $this->customer_id); - if ($email) - { + if ($email) { \CI::form_validation()->set_message('email_callable', lang('error_email_in_use')); - return FALSE; - } - else - { - return TRUE; + return false; + } else { + return true; } }]]); \CI::form_validation()->set_rules('phone', 'lang:phone', 'trim|required|max_length[32]'); @@ -146,19 +142,15 @@ public function form($id = false) \CI::form_validation()->set_rules('email_subscribe', 'email_subscribe', 'numeric|max_length[1]'); //if this is a new account require a password, or if they have entered either a password or a password confirmation - if (\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '' || !$id) - { - \CI::form_validation()->set_rules('password', 'lang:password', 'required|min_length[6]|sha1'); - \CI::form_validation()->set_rules('confirm', 'lang:confirm_password', 'required|sha1|matches[password]'); + if (\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '' || !$id) { + \CI::form_validation()->set_rules('password', 'lang:password', 'required|min_length[6]'); + \CI::form_validation()->set_rules('confirm', 'lang:confirm_password', 'required|matches[password]'); } - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('customer_form', $data); - } - else - { + } else { $save['id'] = $id; $save['group_id'] = \CI::input()->post('group_id'); $save['firstname'] = \CI::input()->post('firstname'); @@ -170,8 +162,7 @@ public function form($id = false) $save['email_subscribe'] = (bool)\CI::input()->post('email_subscribe'); - if (\CI::input()->post('password') != '' || !$id) - { + if (\CI::input()->post('password') != '' || !$id) { $save['password'] = \CI::input()->post('password'); } @@ -189,8 +180,7 @@ public function addresses($id = false) $data['customer'] = \CI::Customers()->get_customer($id); //if the customer does not exist, redirect them to the customer list with an error - if (!$data['customer']) - { + if (!$data['customer']) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/customers'); } @@ -204,26 +194,20 @@ public function addresses($id = false) public function delete($id = false) { - if ($id) - { + if ($id) { $customer = \CI::Customers()->get_customer($id); //if the customer does not exist, redirect them to the customer list with an error - if (!$customer) - { + if (!$customer) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/customers'); - } - else - { + } else { //if the customer is legit, delete them \CI::Customers()->delete($id); \CI::session()->set_flashdata('message', lang('message_customer_deleted')); redirect('admin/customers'); } - } - else - { + } else { //if they do not provide an id send them to the customer list page with an error \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/customers'); @@ -239,7 +223,7 @@ public function groups() $this->view('customer_groups', $data); } - public function groupForm($id=0) + public function groupForm($id = 0) { \CI::load()->helper('form'); \CI::load()->library('form_validation'); @@ -250,8 +234,7 @@ public function groupForm($id=0) $data['id'] = ''; $data['name'] = ''; - if($id) - { + if ($id) { $group = \CI::Customers()->get_group($id); $data['id'] = $group->id; @@ -260,14 +243,10 @@ public function groupForm($id=0) \CI::form_validation()->set_rules('name', 'lang:group_name', 'trim|required|max_length[50]'); - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('customer_group_form', $data); - } - else - { - if($id) - { + } else { + if ($id) { $save['id'] = $id; } @@ -284,8 +263,7 @@ public function groupForm($id=0) public function deleteGroup($id) { - if(empty($id)) - { + if (empty($id)) { return; } @@ -323,8 +301,7 @@ public function addressForm($customer_id, $id = false) //get the countries list for the dropdown $data['countries_menu'] = \CI::Locations()->get_countries_menu(); - if($id) - { + if ($id) { $address = \CI::Customers()->get_address($id); //fully escape the address @@ -334,9 +311,7 @@ public function addressForm($customer_id, $id = false) $data = array_merge($data, $address); $data['zones_menu'] = \CI::Locations()->get_zones_menu($data['country_id']); - } - else - { + } else { //if there is no set ID, the get the zones of the first country in the countries menu $country_keys = array_keys($data['countries_menu']); $data['zones_menu'] = \CI::Locations()->get_zones_menu(array_shift($country_keys)); @@ -354,12 +329,9 @@ public function addressForm($customer_id, $id = false) \CI::form_validation()->set_rules('zone_id', 'lang:state', 'trim|required'); \CI::form_validation()->set_rules('zip', 'lang:zip', 'trim|required|max_length[32]'); - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('customer_address_form', $data); - } - else - { + } else { $a['customer_id'] = $customer_id; // this is needed for new records $a['id'] = (empty($id))?'':$id; @@ -382,7 +354,7 @@ public function addressForm($customer_id, $id = false) $a['field_data']['zone'] = $zone->code; // save the state for output formatted addresses $a['field_data']['country'] = $country->name; // some shipping libraries require country name - $a['field_data']['country_code'] = $country->iso_code_2; // some shipping libraries require the code + $a['field_data']['country_code'] = $country->iso_code_2; // some shipping libraries require the code \CI::Customers()->save_address($a); \CI::session()->set_flashdata('message', lang('message_saved_address')); @@ -394,54 +366,38 @@ public function addressForm($customer_id, $id = false) public function deleteAddress($customer_id = false, $id = false) { - if ($id) - { + if ($id) { $address = \CI::Customers()->get_address($id); //if the customer does not exist, redirect them to the customer list with an error - if (!$address) - { + if (!$address) { \CI::session()->set_flashdata('error', lang('error_address_not_found')); - if($customer_id) - { + if ($customer_id) { redirect('admin/customers/addresses/'.$customer_id); - } - else - { + } else { redirect('admin/customers'); } - } - else - { + } else { //if the customer is legit, delete them - \CI::Customers()->delete_address($id, $customer_id); + \CI::Customers()->delete_address($id, $customer_id); \CI::session()->set_flashdata('message', lang('message_address_deleted')); - if($customer_id) - { + if ($customer_id) { redirect('admin/customers/addresses/'.$customer_id); - } - else - { + } else { redirect('admin/customers'); } } - } - else - { + } else { //if they do not provide an id send them to the customer list page with an error \CI::session()->set_flashdata('error', lang('error_address_not_found')); - if($customer_id) - { + if ($customer_id) { redirect('admin/customers/addresses/'.$customer_id); - } - else - { + } else { redirect('admin/customers'); } } } - -} \ No newline at end of file +} diff --git a/application/modules/customers/models/Customers.php b/application/modules/customers/models/Customers.php index 691dab8..a585584 100644 --- a/application/modules/customers/models/Customers.php +++ b/application/modules/customers/models/Customers.php @@ -1,5 +1,5 @@ where('is_guest', 0)->order_by($order_by, $direction); - if($limit>0) - { + if ($limit>0) { CI::db()->limit($limit, $offset); } @@ -31,7 +30,7 @@ public function get_customers($limit=0, $offset=0, $order_by='id', $direction='D return $result->result(); } - public function get_customer_export($limit=0, $offset=0, $order_by='id', $direction='DESC') + public function get_customer_export($limit = 0, $offset = 0, $order_by = 'id', $direction = 'DESC') { return CI::db()->where('is_guest', 0)->get('customers')->result(); } @@ -75,25 +74,21 @@ public function get_address($address_id) public function save_address($data) { - if(!empty($data['id'])) - { - /*************************** + if (!empty($data['id'])) { + /*************************** when saving an address that already exists, make sure it's not in use before updating it. if it is in use, set the previous instance to deleted and insert the changes as a new record ****************************/ $used = CI::db()->where('shipping_address_id', $data['id'])->or_where('billing_address_id', $data['id'])->count_all_results('orders'); - if($used > 0) - { + if ($used > 0) { CI::db()->where('id', $data['id']); CI::db()->update('customers_address_bank', ['deleted'=>1]); $data['id'] = false;// set ID to false CI::db()->insert('customers_address_bank', $data); return CI::db()->insert_id(); - } - else - { + } else { CI::db()->where('id', $data['id']); CI::db()->update('customers_address_bank', $data); return $data['id']; @@ -113,14 +108,11 @@ public function delete_address($id, $customer_id) public function save($customer) { - if($customer['id']) - { + if ($customer['id']) { CI::db()->where('id', $customer['id']); CI::db()->update('customers', $customer); return $customer['id']; - } - else - { + } else { CI::db()->insert('customers', $customer); return CI::db()->insert_id(); } @@ -152,8 +144,7 @@ public function delete($id) CI::db()->select('id'); $result = CI::db()->get_where('orders', array('customer_id'=>$id)); $result = $result->result(); - foreach ($result as $order) - { + foreach ($result as $order) { CI::db()->where('order_id', $order->id); CI::db()->delete('order_items'); } @@ -163,23 +154,19 @@ public function delete($id) CI::db()->delete('orders'); } - public function check_email($str, $id=false) + public function check_email($str, $id = false) { CI::db()->select('email'); CI::db()->from('customers'); CI::db()->where('is_guest', 0)->where('email', $str); - if ($id) - { + if ($id) { CI::db()->where('id !=', $id); } $count = CI::db()->count_all_results(); - if ($count > 0) - { + if ($count > 0) { return true; - } - else - { + } else { return false; } } @@ -188,21 +175,18 @@ public function reset_password($email) { CI::load()->library('encrypt'); $customer = $this->get_customer_by_email($email); - if ($customer) - { + if ($customer) { CI::load()->helper('string'); CI::load()->library('email'); $newPassword = random_string('alnum', 8); - $customer['password'] = sha1($newPassword); + $customer['password'] = password_hash($newPassword, PASSWORD_DEFAULT); $this->save($customer); GoCart\Emails::resetPasswordCustomer($newPassword, $email); return true; - } - else - { + } else { return false; } } @@ -232,8 +216,7 @@ public function delete_group($id) public function save_group($data) { - if(!empty($data['id'])) - { + if (!empty($data['id'])) { CI::db()->where('id', $data['id'])->update('customer_groups', $data); return $data['id']; } else { @@ -243,18 +226,18 @@ public function save_group($data) //create the new fields. CI::load()->dbforge(); $fields = [ - 'enabled_'.$groupId=>[ + 'enabled'.$groupId=>[ 'type'=>'TINYINT', 'constraint'=>'1', 'default'=>'1' ], 'price_'.$groupId=>[ - 'type'=>'DECIMAL', + 'type'=>'DECIMAL', 'constraint'=>'10,2', 'default'=>'0.00' ], 'saleprice_'.$groupId=>[ - 'type'=>'DECIMAL', + 'type'=>'DECIMAL', 'constraint'=>'10,2', 'default'=>'0.00' ] @@ -263,7 +246,7 @@ public function save_group($data) CI::dbforge()->add_column('order_items', $fields); $fields = [ - 'enabled_'.$groupId=>[ + 'enabled'.$groupId=>[ 'type'=>'TINYINT', 'constraint'=>'1', 'default'=>'1' diff --git a/application/modules/login/controllers/AdminLogin.php b/application/modules/login/controllers/AdminLogin.php index a128916..0607bef 100644 --- a/application/modules/login/controllers/AdminLogin.php +++ b/application/modules/login/controllers/AdminLogin.php @@ -1,4 +1,5 @@ isLoggedIn(false, false); - if ($redirect) - { + if ($redirect) { redirect('admin/dashboard'); } \CI::load()->helper('form'); $data['redirect'] = \CI::session()->flashdata('redirect'); $submitted = \CI::input()->post('submitted'); - if ($submitted) - { + if ($submitted) { $username = \CI::input()->post('username'); $password = \CI::input()->post('password'); $remember = \CI::input()->post('remember'); $redirect = \CI::input()->post('redirect'); $login = \CI::auth()->login_admin($username, $password, $remember); - if ($login) - { - if ($redirect == '') - { + if ($login) { + if ($redirect == '') { $redirect = 'admin/dashboard'; } redirect($redirect); - } - else - { + } else { //this adds the redirect back to flash data if they provide an incorrect credentials \CI::session()->set_flashdata('redirect', $redirect); \CI::session()->set_flashdata('error', lang('error_authentication_failed')); @@ -60,39 +56,34 @@ public function forgotPassword() { //redirect if the user is already logged in $redirect = \CI::auth()->isLoggedIn(false, false); - if ($redirect) - { + if ($redirect) { redirect('admin/dashboard'); } - \CI::form_validation()->set_rules('username', 'lang:username', + \CI::form_validation()->set_rules( + 'username', + 'lang:username', ['trim', 'required', - ['username_callable', function($str) - { + ['username_callable', function ($str) { + $success = \CI::auth()->resetPassword($str); - if(!$success) - { - \CI::form_validation()->set_message('username_callable', lang('username_doesnt_exist')); - return FALSE; - } - else - { - //user does exist. and the password is reset. - return TRUE; - } + if (!$success) { + \CI::form_validation()->set_message('username_callable', lang('username_doesnt_exist')); + return false; + } else { + //user does exist. and the password is reset. + return true; } + } ] ] ); - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->views->show('admin/header'); $this->views->show('admin/forgot_password'); $this->views->show('admin/footer'); - } - else - { + } else { \CI::session()->set_flashdata('message', lang('password_reset_message')); redirect('admin/login'); } @@ -107,5 +98,4 @@ public function logout() \CI::session()->set_flashdata('message', lang('message_logged_out')); redirect('admin/login'); } - } diff --git a/application/modules/login/controllers/Login.php b/application/modules/login/controllers/Login.php index bbbfc07..f808783 100644 --- a/application/modules/login/controllers/Login.php +++ b/application/modules/login/controllers/Login.php @@ -1,4 +1,5 @@ customer = \CI::Login()->customer(); } - public function login($redirect= '') + public function login($redirect = '') { //find out if they're already logged in - if (\CI::Login()->isLoggedIn(false, false)) - { - + if (\CI::Login()->isLoggedIn(false, false)) { redirect($redirect); } \CI::load()->library('form_validation'); \CI::form_validation()->set_rules('email', 'lang:address_email', ['trim','required','valid_email']); - \CI::form_validation()->set_rules('password', 'Password', ['required', ['check_login_callable', function($str){ + \CI::form_validation()->set_rules('password', 'Password', ['required', ['check_login_callable', function ($str) { $email = \CI::input()->post('email'); $password = \CI::input()->post('password'); $remember = \CI::input()->post('remember'); - $login = \CI::Login()->loginCustomer($email, sha1($password), $remember); - if(!$login) - { + $login = \CI::Login()->loginCustomer($email, $password, $remember); + if (!$login) { \CI::form_validation()->set_message('check_login_callable', lang('login_failed')); return false; } }]]); - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('login', ['redirect'=>$redirect, 'loginErrors'=>\CI::form_validation()->get_error_array()]); - } - else - { + } else { redirect($redirect); } } @@ -63,30 +59,24 @@ public function forgotPassword() $data['page_title'] = lang('forgot_password'); \CI::form_validation()->set_rules('email', 'lang:address_email', ['trim', 'required', 'valid_email', - ['email_callable', function($str) - { + ['email_callable', function ($str) { + $reset = \CI::Customers()->reset_password($str); - if(!$reset) - { - \CI::form_validation()->set_message('email_callable', lang('error_no_account_record')); - return FALSE; - } - else - { - //user does exist. and the password is reset. - return TRUE; - } + if (!$reset) { + \CI::form_validation()->set_message('email_callable', lang('error_no_account_record')); + return false; + } else { + //user does exist. and the password is reset. + return true; } + } ] ]); - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('forgot_password', $data); - } - else - { + } else { \CI::session()->set_flashdata('message', lang('message_new_password')); redirect('login'); } @@ -96,8 +86,7 @@ public function register() { $redirect = \CI::Login()->isLoggedIn(false, false); //if they are logged in, we send them back to the my_account by default - if ($redirect) - { + if ($redirect) { redirect('my-account'); } @@ -122,7 +111,7 @@ public function register() \CI::form_validation()->set_rules('company', 'lang:account_company', 'trim|max_length[128]'); \CI::form_validation()->set_rules('firstname', 'lang:account_firstname', 'trim|required|max_length[32]'); \CI::form_validation()->set_rules('lastname', 'lang:account_lastname', 'trim|required|max_length[32]'); - \CI::form_validation()->set_rules('email', 'lang:account_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function($str){ + \CI::form_validation()->set_rules('email', 'lang:account_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function ($str) { return $this->check_email($str); }]]); \CI::form_validation()->set_rules('phone', 'lang:account_phone', 'trim|required|max_length[32]'); @@ -131,24 +120,20 @@ public function register() \CI::form_validation()->set_rules('confirm', 'lang:account_confirm', 'required|matches[password]'); - if (\CI::form_validation()->run() == FALSE) - { - //if they have submitted the form already and it has returned with errors, reset the redirect - if (\CI::input()->post('submitted')) - { + if (\CI::form_validation()->run() == false) { + //if they have submitted the form already and it has returned with errors, reset the redirect + if (\CI::input()->post('submitted')) { $data['redirect'] = \CI::input()->post('redirect'); } - // load other page content + // load other page content //\CI::load()->model('banner_model'); \CI::load()->helper('directory'); $data['registrationErrors'] = \CI::form_validation()->get_error_array(); $this->view('login', $data); - } - else - { + } else { $save['id'] = false; $save['firstname'] = \CI::input()->post('firstname'); $save['lastname'] = \CI::input()->post('lastname'); @@ -158,13 +143,12 @@ public function register() $save['active'] = (bool)config_item('new_customer_status'); $save['email_subscribe'] = intval((bool)\CI::input()->post('email_subscribe')); - $save['password'] = sha1(\CI::input()->post('password')); + $save['password'] = password_hash(\CI::input()->post('password'), PASSWORD_DEFAULT); $redirect = \CI::input()->post('redirect'); //if we don't have a value for redirect - if ($redirect == '') - { + if ($redirect == '') { $redirect = 'my-account'; } @@ -179,20 +163,17 @@ public function register() $twig = new \Twig_Environment($loader); //if they're automatically activated log them in and send them where they need to go - if($save['active']) - { - \CI::session()->set_flashdata('message', $twig->render( lang('registration_thanks'), $save) ); + if ($save['active']) { + \CI::session()->set_flashdata('message', $twig->render(lang('registration_thanks'), $save)); //lets automatically log them in \CI::Login()->loginCustomer($save['email'], $save['password']); //to redirect them, if there is no redirect, the it should redirect to the homepage. redirect($redirect); - } - else - { + } else { //redirect to the login page if they need to wait for activation - \CI::session()->set_flashdata('message', $twig->render( lang('registration_awaiting_activation'), $save) ); + \CI::session()->set_flashdata('message', $twig->render(lang('registration_awaiting_activation'), $save)); redirect('login'); } } @@ -202,14 +183,11 @@ public function check_email($str) { $email = \CI::Customers()->check_email($str); - if ($email) - { + if ($email) { \CI::form_validation()->set_message('check_email_callable', lang('error_email')); - return FALSE; - } - else - { - return TRUE; + return false; + } else { + return true; } } } diff --git a/application/modules/login/models/Login.php b/application/modules/login/models/Login.php index a30306e..baafcc5 100644 --- a/application/modules/login/models/Login.php +++ b/application/modules/login/models/Login.php @@ -1,33 +1,27 @@ userdata('customer'); - if(empty($customer)) - { - //If we don't have a customer, check for a cookie. - if(isset($_COOKIE['GoCartCustomer'])) - { - //the cookie is there, lets log the customer back in. + if (empty($customer)) { + //If we don't have a customer, check for a cookie. + if (isset($_COOKIE['GoCartCustomer'])) { + //the cookie is there, lets log the customer back in. $info = $this->aes256Decrypt(base64_decode($_COOKIE['GoCartCustomer'])); $cred = json_decode($info); - if(is_object($cred)) - { + if (is_object($cred)) { $this->loginCustomer($cred->email, $cred->password, true); - if( ! $this->isLoggedIn() ) - { - // cookie data isn't letting us login. + if (! $this->isLoggedIn()) { + // cookie data isn't letting us login. $this->logoutCustomer(); $this->createGuest(); } } - } - else - { + } else { //cookie is empty $this->logoutCustomer(); $this->createGuest(); @@ -53,29 +47,24 @@ private function generateCookie($data, $expire) setcookie('GoCartCustomer', $data, $expire, '/', $_SERVER['HTTP_HOST'], config_item('ssl_support'), true); } - public function loginCustomer($email, $password, $remember=false) + public function loginCustomer($email, $password, $remember = false) { $customer = CI::db()->where('is_guest', 0)-> where('email', $email)-> where('active', 1)-> - where('password', $password)-> limit(1)-> get('customers')->row(); - if ($customer && !(bool)$customer->is_guest) - { - // Set up any group discount - if($customer->group_id != 0) - { + if ($customer && !(bool)$customer->is_guest && password_verify($password, $customer->password) == true) { + // Set up any group discount + if ($customer->group_id != 0) { $group = CI::Customers()->get_group($customer->group_id); - if($group) // group might not exist - { + if ($group) { // group might not exist $customer->group = $group; } } - if($remember) - { + if ($remember) { $loginCred = json_encode(array('email'=>$customer->email, 'password'=>$customer->password)); $loginCred = base64_encode($this->aes256Encrypt($loginCred)); //remember the user for 6 months @@ -83,16 +72,13 @@ public function loginCustomer($email, $password, $remember=false) } //combine cart items - if($this->customer()) - { + if ($this->customer()) { $oldCustomer = $this->customer(); CI::session()->set_userdata('customer', $customer); \GC::combineCart($oldCustomer); // send the logged-in customer data } return true; - } - else - { + } else { return false; } } @@ -104,24 +90,17 @@ public function isLoggedIn($redirect = false, $default_redirect = 'login') $customer = CI::session()->userdata('customer'); - if(!$customer) - { + if (!$customer) { return false; } - if($customer->is_guest == 1) - { - if($redirect) - { + if (isset($customer->is_guest) && $customer->is_guest == 1) { + if ($redirect) { redirect($default_redirect); - } - else - { + } else { return false; } - } - else - { + } else { return true; } } @@ -137,8 +116,7 @@ private function createGuest() private function aes256Encrypt($data) { $key = config_item('encryption_key'); - if(32 !== strlen($key)) - { + if (32 !== strlen($key)) { $key = hash('SHA256', $key, true); } $padding = 16 - (strlen($data) % 16); @@ -149,12 +127,11 @@ private function aes256Encrypt($data) private function aes256Decrypt($data) { $key = config_item('encryption_key'); - if(32 !== strlen($key)) - { + if (32 !== strlen($key)) { $key = hash('SHA256', $key, true); } $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16)); $padding = ord($data[strlen($data) - 1]); return substr($data, 0, -$padding); } -} \ No newline at end of file +} diff --git a/application/modules/my_account/controllers/MyAccount.php b/application/modules/my_account/controllers/MyAccount.php index d7de19e..58c2fcc 100644 --- a/application/modules/my_account/controllers/MyAccount.php +++ b/application/modules/my_account/controllers/MyAccount.php @@ -1,4 +1,5 @@ customer = \CI::Login()->customer(); } - public function index($offset=0) + public function index($offset = 0) { //make sure they're logged in \CI::Login()->isLoggedIn('my-account'); @@ -76,30 +78,24 @@ public function index($offset=0) \CI::form_validation()->set_rules('company', 'lang:address_company', 'trim|max_length[128]'); \CI::form_validation()->set_rules('firstname', 'lang:address_firstname', 'trim|required|max_length[32]'); \CI::form_validation()->set_rules('lastname', 'lang:address_lastname', 'trim|required|max_length[32]'); - \CI::form_validation()->set_rules('email', 'lang:address_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function($str){ + \CI::form_validation()->set_rules('email', 'lang:address_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function ($str) { return $this->check_email($str); }]]); \CI::form_validation()->set_rules('phone', 'lang:address_phone', 'trim|required|max_length[32]'); \CI::form_validation()->set_rules('email_subscribe', 'lang:account_newsletter_subscribe', 'trim|numeric|max_length[1]'); - if(\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '') - { - \CI::form_validation()->set_rules('password', 'Password', 'required|min_length[6]|sha1'); + if (\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '') { + \CI::form_validation()->set_rules('password', 'Password', 'required|min_length[6]'); \CI::form_validation()->set_rules('confirm', 'Confirm Password', 'required|matches[password]'); - } - else - { + } else { \CI::form_validation()->set_rules('password', 'Password'); \CI::form_validation()->set_rules('confirm', 'Confirm Password'); } - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('my_account', $data); - } - else - { + } else { $customer = []; $customer['id'] = $this->customer->id; $customer['company'] = \CI::input()->post('company'); @@ -108,8 +104,7 @@ public function index($offset=0) $customer['email'] = \CI::input()->post('email'); $customer['phone'] = \CI::input()->post('phone'); $customer['email_subscribe'] = intval((bool)\CI::input()->post('email_subscribe')); - if(\CI::input()->post('password') != '') - { + if (\CI::input()->post('password') != '') { $customer['password'] = \CI::input()->post('password'); } @@ -125,23 +120,17 @@ public function index($offset=0) public function check_email($str) { - if(!empty($this->customer->id)) - { + if (!empty($this->customer->id)) { $email = \CI::Customers()->check_email($str, $this->customer->id); - } - else - { + } else { $email = \CI::Customers()->check_email($str); } - if ($email) - { + if ($email) { \CI::form_validation()->set_message('check_email_callable', lang('error_email')); - return FALSE; - } - else - { - return TRUE; + return false; + } else { + return true; } } @@ -150,16 +139,13 @@ public function download($link) $filedata = \CI::DigitalProducts()->get_file_info_by_link($link); // missing file (bad link) - if(!$filedata) - { + if (!$filedata) { show_404(); } // validate download counter - if($filedata->max_downloads > 0) - { - if(intval($filedata->downloads) >= intval($filedata->max_downloads)) - { + if ($filedata->max_downloads > 0) { + if (intval($filedata->downloads) >= intval($filedata->max_downloads)) { show_404(); } } diff --git a/application/modules/orders/models/Orders.php b/application/modules/orders/models/Orders.php index 8c3ad00..7a23ba1 100644 --- a/application/modules/orders/models/Orders.php +++ b/application/modules/orders/models/Orders.php @@ -1,12 +1,11 @@ month] = $val->total; } return $return; @@ -77,8 +76,7 @@ public function getSalesYears() CI::db()->group_by('YEAR(ordered_on)'); $records = CI::db()->get('orders')->result(); $years = []; - foreach($records as $r) - { + foreach ($records as $r) { $years[] = $r->year; } return $years; @@ -88,8 +86,7 @@ private function getAddressSelect() { $fields = \CI::db()->list_fields('customers_address_bank'); $select = ''; - foreach($fields as $field) - { + foreach ($fields as $field) { $select .= ', shipping.'.$field.' as shipping_'.$field.', billing.'.$field.' as billing_'.$field.' '; } @@ -101,16 +98,14 @@ private function getOrderSearchLike($str) //support multiple words $term = explode(' ', $str); - foreach($term as $t) - { + foreach ($term as $t) { $not = ''; $operator = 'OR'; - if(substr($t,0,1) == '-') - { + if (substr($t, 0, 1) == '-') { $not = 'NOT '; $operator = 'AND'; //trim the - sign off - $t = substr($t,1,strlen($t)); + $t = substr($t, 1, strlen($t)); } $like = ''; @@ -126,7 +121,7 @@ private function getOrderSearchLike($str) } } - public function getOrders($search=false, $sort_by='', $sort_order='DESC', $limit=0, $offset=0) + public function getOrders($search = false, $sort_by = '', $sort_order = 'DESC', $limit = 0, $offset = 0) { $select = 'orders.*'.$this->getAddressSelect(); @@ -135,33 +130,27 @@ public function getOrders($search=false, $sort_by='', $sort_order='DESC', $limit \CI::db()->select($select)->join('customers_address_bank as shipping', 'shipping.id = orders.shipping_address_id', 'left'); \CI::db()->join('customers_address_bank as billing', 'billing.id = orders.billing_address_id', 'left'); - if ($search) - { - if(!empty($search->term)) - { + if ($search) { + if (!empty($search->term)) { $this->getOrderSearchLike($search->term); } - if(!empty($search->start_date)) - { - CI::db()->where('ordered_on >=',$search->start_date); + if (!empty($search->start_date)) { + CI::db()->where('ordered_on >=', $search->start_date); } - if(!empty($search->end_date)) - { - //increase by 1 day to make this include the final day + if (!empty($search->end_date)) { + //increase by 1 day to make this include the final day //I tried <= but it did not public function. Any ideas why? $search->end_date = date('Y-m-d', strtotime($search->end_date)+86400); - CI::db()->where('ordered_on <',$search->end_date); + CI::db()->where('ordered_on <', $search->end_date); } } - if($limit>0) - { + if ($limit>0) { CI::db()->limit($limit, $offset); } - if(!empty($sort_by)) - { + if (!empty($sort_by)) { CI::db()->order_by($sort_by, $sort_order); } @@ -170,25 +159,21 @@ public function getOrders($search=false, $sort_by='', $sort_order='DESC', $limit return CI::db()->get('orders')->result(); } - public function getOrderCount($search=false) + public function getOrderCount($search = false) { \CI::db()->join('customers_address_bank as shipping', 'shipping.id = orders.shipping_address_id', 'left'); \CI::db()->join('customers_address_bank as billing', 'billing.id = orders.billing_address_id', 'left'); - if ($search) - { - if(!empty($search->term)) - { + if ($search) { + if (!empty($search->term)) { $this->getOrderSearchLike($search->term); } - if(!empty($search->start_date)) - { - CI::db()->where('ordered_on >=',$search->start_date); + if (!empty($search->start_date)) { + CI::db()->where('ordered_on >=', $search->start_date); } - if(!empty($search->end_date)) - { - CI::db()->where('ordered_on <',$search->end_date); + if (!empty($search->end_date)) { + CI::db()->where('ordered_on <', $search->end_date); } } @@ -196,7 +181,7 @@ public function getOrderCount($search=false) } //get an individual customers orders - public function getCustomerOrders($id, $offset=0) + public function getCustomerOrders($id, $offset = 0) { CI::db()->order_by('ordered_on', 'DESC'); CI::db()->where(['customer_id' => $id, 'status !=' => 'cart']); @@ -221,8 +206,7 @@ public function getOrder($orderNumber) { $fields = \CI::db()->list_fields('customers_address_bank'); $select = 'orders.*, customers.*, orders.id as id '; - foreach($fields as $field) - { + foreach ($fields as $field) { $select .= ', shipping.'.$field.' as shipping_'.$field.', billing.'.$field.' as billing_'.$field.' '; } \CI::db()->select($select)->join('customers', 'customers.id = orders.customer_id', 'left')->join('customers_address_bank as shipping', 'shipping.id = orders.shipping_address_id', 'left')->join('customers_address_bank as billing', 'billing.id = orders.billing_address_id', 'left'); @@ -231,8 +215,7 @@ public function getOrder($orderNumber) $result = \CI::db()->get('orders'); $order = $result->row(); - if(!$order) - { + if (!$order) { return false; } $order->items = $this->getItems($order->id); @@ -256,10 +239,8 @@ public function getItemFiles($id) $files = CI::db()->select('*, order_item_files.id as id')->where('order_id', $id)->join('digital_products', 'digital_products.id = order_item_files.file_id')->get('order_item_files')->result(); $return = []; - foreach($files as $file) - { - if(!isset($return[$file->order_item_id])) - { + foreach ($files as $file) { + if (!isset($return[$file->order_item_id])) { $return[$file->order_item_id] = []; } @@ -275,10 +256,8 @@ public function getItemOptions($order_id) $return =[]; - foreach($optionValues as $optionValue) - { - if(!isset($return[$optionValue->order_item_id])) - { + foreach ($optionValues as $optionValue) { + if (!isset($return[$optionValue->order_item_id])) { $return[$optionValue->order_item_id] = []; } $return[$optionValue->order_item_id][] = $optionValue; @@ -296,13 +275,10 @@ public function removeItem($order_id, $id) function saveOrderItemFile($file) { - if(!empty($file['id'])) - { + if (!empty($file['id'])) { CI::db()->where('id', $file['id']); CI::db()->update('order_item_files', $file); - } - else - { + } else { CI::db()->insert('order_item_files', $file); } } @@ -330,14 +306,11 @@ public function delete($id) public function saveItem($data) { - if (isset($data['id'])) - { + if (isset($data['id'])) { CI::db()->where('id', $data['id']); CI::db()->update('order_items', $data); return $data['id']; - } - else - { + } else { CI::db()->insert('order_items', $data); return CI::db()->insert_id(); } @@ -345,14 +318,11 @@ public function saveItem($data) public function saveItemOption($data) { - if (isset($data['id'])) - { + if (isset($data['id'])) { CI::db()->where('id', $data['id']); CI::db()->update('order_item_options', $data); return $data['id']; - } - else - { + } else { CI::db()->insert('order_item_options', $data); return CI::db()->insert_id(); } @@ -361,10 +331,10 @@ public function saveItemOption($data) public function moveOrderItems($oldId, $newId) { //move order items - CI::db()->where('order_id', $oldId)->set('order_id',$newId)->update('order_items'); + CI::db()->where('order_id', $oldId)->set('order_id', $newId)->update('order_items'); //move order item options - CI::db()->where('order_id', $oldId)->set('order_id',$newId)->update('order_item_options'); + CI::db()->where('order_id', $oldId)->set('order_id', $newId)->update('order_item_options'); } public function savePaymentInfo($info) @@ -379,26 +349,21 @@ public function getPaymentInfo($order_id) public function saveOrder($data, $contents = false) { - if (isset($data['id'])) - { + if (isset($data['id'])) { CI::db()->where('id', $data['id']); CI::db()->update('orders', $data); $id = $data['id']; - } - else - { + } else { CI::db()->insert('orders', $data); $id = CI::db()->insert_id(); } //if there are items being submitted with this order add them now - if($contents) - { - // clear existing order items + if ($contents) { + // clear existing order items CI::db()->where('order_id', $id)->delete('order_items'); // update order items - foreach($contents as $item) - { + foreach ($contents as $item) { $save = []; $save['contents'] = $item; @@ -414,19 +379,16 @@ public function saveOrder($data, $contents = false) public function getBestSellers($start, $end) { - if(!empty($start)) - { + if (!empty($start)) { CI::db()->where('ordered_on >=', $start); } - if(!empty($end)) - { - CI::db()->where('ordered_on <', $end); + if (!empty($end)) { + CI::db()->where('ordered_on <', $end); } // just fetch a list of order id's - $orders = CI::db()->select('sum(quantity) as quantity_sold, order_items.name as name, sku')->group_by('product_id')->order_by('quantity_sold', 'DESC')->where('status !=','cart')->where('order_items.type', 'product')->join('order_items', 'order_items.order_id = orders.id')->get('orders')->result(); + $orders = CI::db()->select('sum(quantity) as quantity_sold, order_items.name as name, sku')->group_by('product_id')->order_by('quantity_sold', 'DESC')->where('status !=', 'cart')->where('order_items.type', 'product')->join('order_items', 'order_items.order_id = orders.id')->get('orders')->result(); return $orders; } - } diff --git a/application/modules/products/controllers/AdminProducts.php b/application/modules/products/controllers/AdminProducts.php index 607b17e..949bc62 100644 --- a/application/modules/products/controllers/AdminProducts.php +++ b/application/modules/products/controllers/AdminProducts.php @@ -1,4 +1,5 @@ load('products'); } - public function index($rows=100, $order_by="name", $sort_order="ASC", $code=0, $page=0) + public function index($rows = 100, $order_by = "name", $sort_order = "ASC", $code = 0, $page = 0) { $data['groups'] = \CI::Customers()->get_groups(); $data['page_title'] = lang('products'); @@ -35,14 +37,11 @@ public function index($rows=100, $order_by="name", $sort_order="ASC", $code=0, $ $post = \CI::input()->post(null, false); \CI::load()->model('Search'); - if($post) - { + if ($post) { $term = json_encode($post); $code = \CI::Search()->recordTerm($term); $data['code'] = $code; - } - elseif ($code) - { + } elseif ($code) { $term = \CI::Search()->getTerm($code); } @@ -99,18 +98,14 @@ public function product_autocomplete() $name = trim(\CI::input()->post('name')); $limit = \CI::input()->post('limit'); - if(empty($name)) - { + if (empty($name)) { echo json_encode([]); - } - else - { + } else { $results = \CI::Products()->product_autocomplete($name, $limit); $return = []; - foreach($results as $r) - { + foreach ($results as $r) { $return[$r->id] = $r->name; } echo json_encode($return); @@ -122,14 +117,12 @@ public function bulk_save() { $products = \CI::input()->post('product'); - if(!$products) - { + if (!$products) { \CI::session()->set_flashdata('error', lang('error_bulk_no_products')); redirect('admin/products'); } - foreach($products as $id=>$product) - { + foreach ($products as $id => $product) { $product['id'] = $id; \CI::Products()->save($product); } @@ -175,9 +168,8 @@ public function form($id = false, $duplicate = false) $data['product_files'] = []; $data['productOptions'] = []; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = ''; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = ''; $data['price_'.$group->id] = ''; $data['saleprice_'.$group->id] = ''; } @@ -186,12 +178,10 @@ public function form($id = false, $duplicate = false) //create the photos array for later use $data['photos'] = []; - if ($id) - { - // get the existing file associations and create a format we can read from the form to set the checkboxes + if ($id) { + // get the existing file associations and create a format we can read from the form to set the checkboxes $pr_files = \CI::DigitalProducts()->getAssociationsByProduct($id); - foreach($pr_files as $f) - { + foreach ($pr_files as $f) { $data['product_files'][] = $f->file_id; } @@ -200,8 +190,7 @@ public function form($id = false, $duplicate = false) $product = \CI::Products()->find($id, true); //if the product does not exist, redirect them to the product list with an error - if (!$product) - { + if (!$product) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/products'); } @@ -227,20 +216,16 @@ public function form($id = false, $duplicate = false) $data['taxable'] = $product->taxable; $data['fixed_quantity'] = $product->fixed_quantity; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = $product->{'enabled_'.$group->id}; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = $product->{'enabled'.$group->id}; $data['price_'.$group->id] = $product->{'price_'.$group->id}; $data['saleprice_'.$group->id] = $product->{'saleprice_'.$group->id}; } //make sure we haven't submitted the form yet before we pull in the images/related products from the database - if(!\CI::input()->post('submit')) - { - + if (!\CI::input()->post('submit')) { $data['product_categories'] = []; - foreach($product->categories as $product_category) - { + foreach ($product->categories as $product_category) { $data['product_categories'][] = $product_category->id; } @@ -250,12 +235,10 @@ public function form($id = false, $duplicate = false) } //if $data['related_products'] is not an array, make it one. - if(!is_array($data['related_products'])) - { + if (!is_array($data['related_products'])) { $data['related_products'] = []; } - if(!is_array($data['product_categories'])) - { + if (!is_array($data['product_categories'])) { $data['product_categories'] = []; } @@ -278,9 +261,8 @@ public function form($id = false, $duplicate = false) \CI::form_validation()->set_rules('taxable', 'lang:taxable', 'trim|numeric'); \CI::form_validation()->set_rules('fixed_quantity', 'lang:fixed_quantity', 'trim|numeric'); - foreach($data['groups'] as $group) - { - \CI::form_validation()->set_rules('enabled_'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); + foreach ($data['groups'] as $group) { + \CI::form_validation()->set_rules('enabled'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); \CI::form_validation()->set_rules('price_'.$group->id, lang('price').'('.$group->name.')', 'trim|numeric|floatval'); \CI::form_validation()->set_rules('saleprice_'.$group->id, lang('saleprice').'('.$group->name.')', 'trim|numeric|floatval'); } @@ -293,13 +275,11 @@ public function form($id = false, $duplicate = false) submit button has a value, so we can see when it's posted */ - if($duplicate) - { + if ($duplicate) { $data['id'] = false; } - if(\CI::input()->post('submit')) - { - //reset the product options that were submitted in the post + if (\CI::input()->post('submit')) { + //reset the product options that were submitted in the post $data['ProductOptions'] = \CI::input()->post('option'); $data['related_products'] = \CI::input()->post('related_products'); $data['product_categories'] = \CI::input()->post('categories'); @@ -308,24 +288,20 @@ public function form($id = false, $duplicate = false) } - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('product_form', $data); - } - else - { + } else { \CI::load()->helper('text'); //first check the slug field $slug = \CI::input()->post('slug'); //if it's empty assign the name field - if(empty($slug) || $slug=='') - { + if (empty($slug) || $slug=='') { $slug = \CI::input()->post('name'); } - $slug = url_title(convert_accented_characters($slug), '-', TRUE); + $slug = url_title(convert_accented_characters($slug), '-', true); //validate the slug $slug = ($id) ? \CI::Products()->validate_slug($slug, $product->id) : \CI::Products()->validate_slug($slug); @@ -347,9 +323,8 @@ public function form($id = false, $duplicate = false) $post_images = \CI::input()->post('images'); - foreach($data['groups'] as $group) - { - $save['enabled_'.$group->id] = \CI::input()->post('enabled_'.$group->id); + foreach ($data['groups'] as $group) { + $save['enabled'.$group->id] = \CI::input()->post('enabled'.$group->id); $save['price_'.$group->id] = \CI::input()->post('price_'.$group->id); $save['saleprice_'.$group->id] = \CI::input()->post('saleprice_'.$group->id); } @@ -357,14 +332,10 @@ public function form($id = false, $duplicate = false) $save['slug'] = $slug; - if($primary = \CI::input()->post('primary_image')) - { - if($post_images) - { - foreach($post_images as $key => &$pi) - { - if($primary == $key) - { + if ($primary = \CI::input()->post('primary_image')) { + if ($post_images) { + foreach ($post_images as $key => &$pi) { + if ($primary == $key) { $pi['primary'] = true; continue; } @@ -376,43 +347,32 @@ public function form($id = false, $duplicate = false) $save['images'] = json_encode($post_images); - if(\CI::input()->post('related_products')) - { + if (\CI::input()->post('related_products')) { $save['related_products'] = json_encode(\CI::input()->post('related_products')); - } - else - { + } else { $save['related_products'] = ''; } //save categories $categories = \CI::input()->post('categories'); - if(!$categories) - { + if (!$categories) { $categories = []; } //(\CI::input()->post('primary_category')) ? \CI::input()->post('primary_category') : 0; - if(!\CI::input()->post('primary_category') && $categories) - { + if (!\CI::input()->post('primary_category') && $categories) { $save['primary_category'] = $categories[0]; - } - elseif(!\CI::input()->post('primary_category') && !$categories) - { + } elseif (!\CI::input()->post('primary_category') && !$categories) { $save['primary_category'] = 0; - } - else - { + } else { $save['primary_category'] = \CI::input()->post('primary_category'); } // format options $options = []; - if(\CI::input()->post('option')) - { - foreach (\CI::input()->post('option') as $option) - { + if (\CI::input()->post('option')) { + foreach (\CI::input()->post('option') as $option) { $options[] = $option; } @@ -426,10 +386,8 @@ public function form($id = false, $duplicate = false) \CI::DigitalProducts()->disassociate(false, $product_id); // save new $downloads = \CI::input()->post('downloads'); - if(is_array($downloads)) - { - foreach($downloads as $d) - { + if (is_array($downloads)) { + foreach ($downloads as $d) { \CI::DigitalProducts()->associate($d, $product_id); } } @@ -469,24 +427,20 @@ public function giftCardForm($id = false, $duplicate = false) $data['product_categories'] = []; $data['product_files'] = []; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = ''; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = ''; } //create the photos array for later use $data['photos'] = []; - if ($id) - { - - // get product & options data + if ($id) { + // get product & options data $data['ProductOptions'] = \CI::ProductOptions()->getProductOptions($id); $product = \CI::Products()->find($id, true); //if the product does not exist, redirect them to the product list with an error - if (!$product) - { + if (!$product) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/products'); } @@ -508,18 +462,14 @@ public function giftCardForm($id = false, $duplicate = false) $data['taxable'] = $product->taxable; $data['fixed_quantity'] = $product->fixed_quantity; $data['is_giftcard'] = $product->is_giftcard; - foreach($data['groups'] as $group) - { - $data['enabled_'.$group->id] = $product->{'enabled_'.$group->id}; + foreach ($data['groups'] as $group) { + $data['enabled'.$group->id] = $product->{'enabled'.$group->id}; } //make sure we haven't submitted the form yet before we pull in the images/related products from the database - if(!\CI::input()->post('submit')) - { - + if (!\CI::input()->post('submit')) { $data['product_categories'] = []; - foreach($product->categories as $product_category) - { + foreach ($product->categories as $product_category) { $data['product_categories'][] = $product_category->id; } @@ -528,8 +478,7 @@ public function giftCardForm($id = false, $duplicate = false) } } - if(!is_array($data['product_categories'])) - { + if (!is_array($data['product_categories'])) { $data['product_categories'] = []; } @@ -549,9 +498,8 @@ public function giftCardForm($id = false, $duplicate = false) \CI::form_validation()->set_rules('fixed_quantity', 'lang:fixed_quantity', 'trim|numeric'); \CI::form_validation()->set_rules('option[giftcard_values]', 'lang:giftcard_values', 'required'); - foreach($data['groups'] as $group) - { - \CI::form_validation()->set_rules('enabled_'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); + foreach ($data['groups'] as $group) { + \CI::form_validation()->set_rules('enabled'.$group->id, lang('enabled').'('.$group->name.')', 'trim|numeric'); } /* if we've posted already, get the photo stuff and organize it @@ -561,37 +509,31 @@ public function giftCardForm($id = false, $duplicate = false) submit button has a value, so we can see when it's posted */ - if($duplicate) - { + if ($duplicate) { $data['id'] = false; } - if(\CI::input()->post('submit')) - { - //reset the product options that were submitted in the post + if (\CI::input()->post('submit')) { + //reset the product options that were submitted in the post $data['ProductOptions'] = \CI::input()->post('option'); $data['product_categories'] = \CI::input()->post('categories'); $data['images'] = \CI::input()->post('images'); } - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('giftcard_product_form', $data); - } - else - { + } else { \CI::load()->helper('text'); //first check the slug field $slug = \CI::input()->post('slug'); //if it's empty assign the name field - if(empty($slug) || $slug=='') - { + if (empty($slug) || $slug=='') { $slug = \CI::input()->post('name'); } - $slug = url_title(convert_accented_characters($slug), '-', TRUE); + $slug = url_title(convert_accented_characters($slug), '-', true); //validate the slug $slug = ($id) ? \CI::Products()->validate_slug($slug, $product->id) : \CI::Products()->validate_slug($slug); @@ -605,9 +547,8 @@ public function giftCardForm($id = false, $duplicate = false) $save['description'] = \CI::input()->post('description'); $save['excerpt'] = \CI::input()->post('excerpt'); - foreach($data['groups'] as $group) - { - $save['enabled_'.$group->id] = \CI::input()->post('enabled_'.$group->id); + foreach ($data['groups'] as $group) { + $save['enabled'.$group->id] = \CI::input()->post('enabled'.$group->id); $save['price_'.$group->id] = '0.00'; $save['saleprice_'.$group->id] = '0.00'; } @@ -620,14 +561,10 @@ public function giftCardForm($id = false, $duplicate = false) $save['slug'] = $slug; - if($primary = \CI::input()->post('primary_image')) - { - if($post_images) - { - foreach($post_images as $key => &$pi) - { - if($primary == $key) - { + if ($primary = \CI::input()->post('primary_image')) { + if ($post_images) { + foreach ($post_images as $key => &$pi) { + if ($primary == $key) { $pi['primary'] = true; continue; } @@ -639,33 +576,24 @@ public function giftCardForm($id = false, $duplicate = false) $save['images'] = json_encode($post_images); - if(\CI::input()->post('related_products')) - { + if (\CI::input()->post('related_products')) { $save['related_products'] = json_encode(\CI::input()->post('related_products')); - } - else - { + } else { $save['related_products'] = ''; } //save categories $categories = \CI::input()->post('categories'); - if(!$categories) - { + if (!$categories) { $categories = []; } //(\CI::input()->post('primary_category')) ? \CI::input()->post('primary_category') : 0; - if(!\CI::input()->post('primary_category') && $categories) - { + if (!\CI::input()->post('primary_category') && $categories) { $save['primary_category'] = $categories[0]; - } - elseif(!\CI::input()->post('primary_category') && !$categories) - { + } elseif (!\CI::input()->post('primary_category') && !$categories) { $save['primary_category'] = 0; - } - else - { + } else { $save['primary_category'] = \CI::input()->post('primary_category'); } @@ -721,10 +649,8 @@ public function giftCardForm($id = false, $duplicate = false) $giftcard_values = []; $postedValues = \CI::input()->post('option[giftcard_values]'); - if($postedValues) - { - foreach($postedValues as $giftcard_value) - { + if ($postedValues) { + foreach ($postedValues as $giftcard_value) { array_push($giftcard_values, ['name'=> 'beginning_amount', 'value' => $giftcard_value, 'weight'=>'', 'price' => $giftcard_value]); } } @@ -771,8 +697,7 @@ public function product_image_upload() \CI::load()->library('upload', $config); - if ( \CI::upload()->do_upload()) - { + if (\CI::upload()->do_upload()) { $upload_data = \CI::upload()->data(); \CI::load()->library('image_lib'); @@ -780,7 +705,7 @@ public function product_image_upload() $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/full/'.$upload_data['file_name']; $config['new_image'] = 'uploads/images/medium/'.$upload_data['file_name']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 600; $config['height'] = 500; \CI::image_lib()->initialize($config); @@ -791,7 +716,7 @@ public function product_image_upload() $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/medium/'.$upload_data['file_name']; $config['new_image'] = 'uploads/images/small/'.$upload_data['file_name']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 235; $config['height'] = 235; \CI::image_lib()->initialize($config); @@ -802,7 +727,7 @@ public function product_image_upload() $config['image_library'] = 'gd2'; $config['source_image'] = 'uploads/images/small/'.$upload_data['file_name']; $config['new_image'] = 'uploads/images/thumbnails/'.$upload_data['file_name']; - $config['maintain_ratio'] = TRUE; + $config['maintain_ratio'] = true; $config['width'] = 150; $config['height'] = 150; \CI::image_lib()->initialize($config); @@ -812,8 +737,7 @@ public function product_image_upload() $data['file_name'] = $upload_data['file_name']; } - if(\CI::upload()->display_errors() != '') - { + if (\CI::upload()->display_errors() != '') { $data['error'] = \CI::upload()->display_errors(); } $this->partial('iframe/product_image_uploader', $data); @@ -821,17 +745,13 @@ public function product_image_upload() public function delete($id = false) { - if ($id) - { + if ($id) { $product = \CI::Products()->find($id); //if the product does not exist, redirect them to the customer list with an error - if (!$product) - { + if (!$product) { \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/products'); - } - else - { + } else { //if the product is legit, delete them \CI::Products()->delete_product($id); @@ -839,9 +759,7 @@ public function delete($id = false) \CI::session()->set_flashdata('message', lang('message_deleted_product')); redirect('admin/products'); } - } - else - { + } else { //if they do not provide an id send them to the product list page with an error \CI::session()->set_flashdata('error', lang('error_not_found')); redirect('admin/products'); diff --git a/application/modules/products/models/Products.php b/application/modules/products/models/Products.php index b91bc8d..55b1fd7 100644 --- a/application/modules/products/models/Products.php +++ b/application/modules/products/models/Products.php @@ -9,7 +9,7 @@ * @link http://gocartdv.com */ -Class Products extends CI_Model +class Products extends CI_Model { public function __construct() { @@ -22,7 +22,7 @@ public function getProduct($id) $this->customer = \GC::getCustomer(); //find the product - $product = CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price')->where('id', $id)->where('enabled_'.$this->customer->group_id, '1')->get('products')->row(); + $product = CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price')->where('id', $id)->where('enabled'.$this->customer->group_id, '1')->get('products')->row(); $product = $this->processImageDecoding($product); return $product; } @@ -35,85 +35,71 @@ public function product_autocomplete($name, $limit) public function touchInventory($id, $quantity) { $product = $this->getProduct($id); - if(!$product) - { + if (!$product) { return false; } CI::db()->where('id', $id)->update('products', ['quantity' => ($product->quantity - $quantity)]); } - public function products($data=[], $return_count=false) + public function products($data = [], $return_count = false) { - if(empty($data)) - { - //if nothing is provided return the whole shabang + if (empty($data)) { + //if nothing is provided return the whole shabang CI::db()->order_by('name', 'ASC'); $result = CI::db()->get('products'); return $result->result(); - } - else - { + } else { //grab the limit - if(!empty($data['rows'])) - { + if (!empty($data['rows'])) { CI::db()->limit($data['rows']); } //grab the page - if(!empty($data['page'])) - { + if (!empty($data['page'])) { CI::db()->offset($data['page']); } //do we order by something other than category_id? - if(!empty($data['order_by'])) - { - //if we have an order_by then we must have a direction otherwise KABOOM + if (!empty($data['order_by'])) { + //if we have an order_by then we must have a direction otherwise KABOOM CI::db()->order_by($data['order_by'], $data['sort_order']); } //do we have a search submitted? - if(!empty($data['term'])) - { + if (!empty($data['term'])) { $search = json_decode($data['term']); //if we are searching dig through some basic fields - if(!empty($search->term)) - { + if (!empty($search->term)) { CI::db()->like('name', $search->term); CI::db()->or_like('description', $search->term); CI::db()->or_like('excerpt', $search->term); CI::db()->or_like('sku', $search->term); } - if(!empty($search->category_id)) - { - //lets do some joins to get the proper category products + if (!empty($search->category_id)) { + //lets do some joins to get the proper category products CI::db()->join('category_products', 'category_products.product_id=products.id', 'right'); CI::db()->where('category_products.category_id', $search->category_id); CI::db()->order_by('sequence', 'ASC'); } } - if($return_count) - { + if ($return_count) { return CI::db()->count_all_results('products'); - } - else - { + } else { return CI::db()->get('products')->result(); } } } - public function getProducts($category_id = false, $limit = false, $offset = false, $by=false, $sort=false) + public function getProducts($category_id = false, $limit = false, $offset = false, $by = false, $sort = false) { //if we are provided a category_id, then get products according to category - if ($category_id) - { - CI::db()->select('category_products.*, products.*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price, LEAST(IFNULL(NULLIF(saleprice_'.$this->customer->group_id.', 0), price_'.$this->customer->group_id.'), price_'.$this->customer->group_id.') as sort_price', false)->from('category_products')->join('products', 'category_products.product_id=products.id')->where(array('category_id'=>$category_id, 'enabled_'.$this->customer->group_id=>1)); + if ($category_id) { + CI::db()->select('category_products.*, products.*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price, LEAST(IFNULL(NULLIF(saleprice_'.$this->customer->group_id.', 0), price_'.$this->customer->group_id.'), price_'.$this->customer->group_id.') as sort_price', false)->from('category_products')->join('products', 'category_products.product_id=products.id')->where(array('category_id'=>$category_id, 'enabled'.$this->customer->group_id=>1)); CI::db()->order_by($by, $sort); @@ -121,14 +107,11 @@ public function getProducts($category_id = false, $limit = false, $offset = fals $products = []; - foreach($result as $product) - { + foreach ($result as $product) { $products[] = $this->processImageDecoding($product); } return $products; - } - else - { + } else { //sort by alphabetically by default return CI::db()->order_by('name', 'ASC')->get('products')->result(); } @@ -141,36 +124,31 @@ public function count_all_products() public function count_products($id) { - return CI::db()->select('product_id')->from('category_products')->join('products', 'category_products.product_id=products.id')->where(array('category_id'=>$id, 'enabled_'.$this->customer->group_id=>1))->count_all_results(); + return CI::db()->select('product_id')->from('category_products')->join('products', 'category_products.product_id=products.id')->where(array('category_id'=>$id, 'enabled'.$this->customer->group_id=>1))->count_all_results(); } - public function slug($slug, $related=true) + public function slug($slug, $related = true) { - $result = CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price')->get_where('products', array('slug'=>$slug, 'enabled_'.$this->customer->group_id=>1))->row(); + $result = CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price')->get_where('products', array('slug'=>$slug, 'enabled'.$this->customer->group_id=>1))->row(); - if(!$result) - { + if (!$result) { return false; } $related = json_decode($result->related_products); - if(!empty($related)) - { - //build the where + if (!empty($related)) { + //build the where $where = []; - foreach($related as $r) - { + foreach ($related as $r) { $where[] = '`id` = '.$r; } CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price'); CI::db()->where('('.implode(' OR ', $where).')', null); - CI::db()->where('enabled_'.$this->customer->group_id, 1); + CI::db()->where('enabled'.$this->customer->group_id, 1); $result->related_products = CI::db()->get('products')->result(); - } - else - { + } else { $result->related_products = []; } $result->categories = $this->getProductCategories($result->id); @@ -178,33 +156,27 @@ public function slug($slug, $related=true) return $result; } - public function find($id, $related=true) + public function find($id, $related = true) { $result = CI::db()->get_where('products', array('id'=>$id))->row(); - if(!$result) - { + if (!$result) { return false; } - if($related) - { + if ($related) { $relatedItems = json_decode($result->related_products); - if(!empty($relatedItems)) - { - //build the where + if (!empty($relatedItems)) { + //build the where $where = []; - foreach($relatedItems as $r) - { + foreach ($relatedItems as $r) { $where[] = '`id` = '.$r; } CI::db()->where('('.implode(' OR ', $where).')', null); - CI::db()->where('enabled_'.$this->customer->group_id, 1); + CI::db()->where('enabled'.$this->customer->group_id, 1); $result->related_products = CI::db()->get('products')->result(); - } - else - { + } else { $result->related_products = []; } } @@ -219,32 +191,26 @@ public function getProductCategories($id) return CI::db()->where('product_id', $id)->join('categories', 'category_id = categories.id')->get('category_products')->result(); } - public function save($product, $options=false, $categories=false) + public function save($product, $options = false, $categories = false) { - if ($product['id']) - { + if ($product['id']) { CI::db()->where('id', $product['id']); CI::db()->update('products', $product); $id = $product['id']; - } - else - { + } else { CI::db()->insert('products', $product); $id = CI::db()->insert_id(); } //loop through the product options and add them to the db - if($options !== false) - { - - // wipe the slate + if ($options !== false) { + // wipe the slate CI::ProductOptions()->clearOptions($id); // save edited values $count = 1; - foreach ($options as $option) - { + foreach ($options as $option) { $values = $option['values']; unset($option['values']); $option['product_id'] = $id; @@ -255,43 +221,33 @@ public function save($product, $options=false, $categories=false) } } - if($categories !== false) - { - if($product['id']) - { + if ($categories !== false) { + if ($product['id']) { //get all the categories that the product is in $cats = $this->getProductCategories($id); //generate cat_id array $ids = []; - foreach($cats as $c) - { + foreach ($cats as $c) { $ids[] = $c->id; } //eliminate categories that products are no longer in - foreach($ids as $c) - { - if(!in_array($c, $categories)) - { + foreach ($ids as $c) { + if (!in_array($c, $categories)) { CI::db()->delete('category_products', array('product_id'=>$id,'category_id'=>$c)); } } //add products to new categories - foreach($categories as $c) - { - if(!in_array($c, $ids)) - { + foreach ($categories as $c) { + if (!in_array($c, $ids)) { CI::db()->insert('category_products', array('product_id'=>$id,'category_id'=>$c)); } } - } - else - { + } else { //new product add them all - foreach($categories as $c) - { + foreach ($categories as $c) { CI::db()->insert('category_products', array('product_id'=>$id,'category_id'=>$c)); } } @@ -316,30 +272,28 @@ public function delete_product($id) CI::db()->delete('coupons_products'); } - public function search_products($term, $limit=false, $offset=false, $by=false, $sort=false) + public function search_products($term, $limit = false, $offset = false, $by = false, $sort = false) { $results = []; CI::db()->select('*, LEAST(IFNULL(NULLIF(saleprice_'.$this->customer->group_id.', 0), price_'.$this->customer->group_id.'), price_'.$this->customer->group_id.') as sort_price', false); //this one counts the total number for our pagination - CI::db()->where('enabled_'.$this->customer->group_id, 1); + CI::db()->where('enabled'.$this->customer->group_id, 1); CI::db()->where('(name LIKE "%'.CI::db()->escape_like_str($term).'%" OR description LIKE "%'.CI::db()->escape_like_str($term).'%" OR excerpt LIKE "%'.CI::db()->escape_like_str($term).'%" OR sku LIKE "%'.CI::db()->escape_like_str($term).'%")'); $results['count'] = CI::db()->count_all_results('products'); CI::db()->select('*, saleprice_'.$this->customer->group_id.' as saleprice, price_'.$this->customer->group_id.' as price, LEAST(IFNULL(NULLIF(saleprice_'.$this->customer->group_id.', 0), price_'.$this->customer->group_id.'), price_'.$this->customer->group_id.') as sort_price', false); //this one gets just the ones we need. - CI::db()->where('enabled_'.$this->customer->group_id, 1); + CI::db()->where('enabled'.$this->customer->group_id, 1); CI::db()->where('(name LIKE "%'.CI::db()->escape_like_str($term).'%" OR description LIKE "%'.CI::db()->escape_like_str($term).'%" OR excerpt LIKE "%'.CI::db()->escape_like_str($term).'%" OR sku LIKE "%'.CI::db()->escape_like_str($term).'%")'); - if($by && $sort) - { + if ($by && $sort) { CI::db()->order_by($by, $sort); } $products = CI::db()->get('products', $limit, $offset)->result(); $results['products'] = []; - foreach($products as $product) - { + foreach ($products as $product) { $results['products'][] = $this->processImageDecoding($product); } @@ -348,53 +302,39 @@ public function search_products($term, $limit=false, $offset=false, $by=false, $ public function processImageDecoding($product) { - if($product) - { + if ($product) { $product->images = json_decode($product->images, true); - if($product->images) - { + if ($product->images) { $product->images = array_values($product->images); - } - else - { + } else { $product->images = []; } return $product; - } - else - { + } else { return $product; } } - public function validate_slug($slug, $id=false, $counter=false) + public function validate_slug($slug, $id = false, $counter = false) { CI::db()->select('slug'); CI::db()->from('products'); CI::db()->where('slug', $slug.$counter); - if ($id) - { + if ($id) { CI::db()->where('id !=', $id); } $count = CI::db()->count_all_results(); - if ($count > 0) - { - if(!$counter) - { + if ($count > 0) { + if (!$counter) { $counter = 1; - } - else - { + } else { $counter++; } return $this->validate_slug($slug, $id, $counter); - } - else - { + } else { return $slug.$counter; } } - } diff --git a/application/modules/products/views/admin/giftcard_product_form.php b/application/modules/products/views/admin/giftcard_product_form.php index 0f1bcb4..20a67a5 100644 --- a/application/modules/products/views/admin/giftcard_product_form.php +++ b/application/modules/products/views/admin/giftcard_product_form.php @@ -15,7 +15,7 @@ $(".sortable > col-md-").disableSelection(); //if the image already exists (phpcheck) enable the selector - + //options related var ct = $('#option_list').children().size(); // set initial count @@ -66,7 +66,7 @@ function remove_option(id) - +
@@ -118,7 +118,7 @@ function remove_option(id)
- + @@ -129,9 +129,10 @@ function remove_option(id) + foreach ($cats[$parent_id] as $cat) :?> id]) && sizeof($cats[$cat->id]) > 0) - { + if (isset($cats[$cat->id]) && sizeof($cats[$cat->id]) > 0) { $sub2 = str_replace('→ ', ' ', $sub); $sub2 .= '   → '; list_categories($cat->id, $cats, $sub2, $product_categories, $primary_category); @@ -157,7 +157,7 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima ?>
name; ?> @@ -142,8 +143,7 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima
- +
@@ -178,27 +178,23 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima required)){$po->required = false; - } - - if($po->type == 'droplist') - { - if($po->values): - foreach($po->values as $value) - { - $value = (object)$value; - add_option_value($po, $counter++, $value->price); - $GLOBALS['option_value_count']++; - } - endif; - } + if (empty($po->required)) { + $po->required = false; + } + + if ($po->type == 'droplist') { + if ($po->values) : + foreach ($po->values as $value) { + $value = (object)$value; + add_option_value($po, $counter++, $value->price); + $GLOBALS['option_value_count']++; + } + endif; + } $counter++; } } @@ -215,10 +211,8 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima
$photo_obj) - { - if(!empty($photo_obj)) - { + foreach ($images as $photo_id => $photo_obj) { + if (!empty($photo_obj)) { $photo = (array)$photo_obj; add_image($photo_id, $photo['filename'], $photo['alt'], $photo['caption'], isset($photo['primary'])); } @@ -234,7 +228,7 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima
- lang('not_taxable'), 1 => lang('taxable')], assign_value('taxable',$taxable), 'class="form-control"'); ?> + lang('not_taxable'), 1 => lang('taxable')], assign_value('taxable', $taxable), 'class="form-control"'); ?>
@@ -242,13 +236,13 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima 'sku', 'value'=>assign_value('sku', $sku), 'class'=>'form-control']);?>
- +
name;?>
@@ -260,7 +254,7 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima
@@ -306,8 +302,9 @@ function add_image($photo_id, $filename, $alt, $caption, $primary=false) } //this makes it easy to use the same code for initial generation of the form as well as javascript additions -function replace_newline($string) { - return trim((string)str_replace(array("\r", "\r\n", "\n", "\t"), ' ', $string)); +function replace_newline($string) +{ + return trim((string)str_replace(array("\r", "\r\n", "\n", "\t"), ' ', $string)); } ?> diff --git a/application/modules/products/views/admin/product_form.php b/application/modules/products/views/admin/product_form.php index 0e28c46..7f124bb 100644 --- a/application/modules/products/views/admin/product_form.php +++ b/application/modules/products/views/admin/product_form.php @@ -141,7 +141,7 @@ function list_categories($parent_id, $cats, $sub='', $product_categories, $prima ':'';?> name; ?> - {'enabled_'.$group->id})?'':'';?> + {'enabled'.$group->id})?'':'';?> id, $product_categories))?'checked="checked"':'';?>/> @@ -306,7 +306,7 @@ function(data) { name;?>
diff --git a/application/modules/products/views/admin/products.php b/application/modules/products/views/admin/products.php index 3aacfda..071fc69 100644 --- a/application/modules/products/views/admin/products.php +++ b/application/modules/products/views/admin/products.php @@ -116,7 +116,7 @@ function areyousure() - {'enabled_'.$group->id} == '1') ? lang('enabled') : lang('disabled'); ?> + {'enabled'.$group->id} == '1') ? lang('enabled') : lang('disabled'); ?>
diff --git a/application/modules/users/controllers/AdminUsers.php b/application/modules/users/controllers/AdminUsers.php index 7f0ed0f..8754de7 100644 --- a/application/modules/users/controllers/AdminUsers.php +++ b/application/modules/users/controllers/AdminUsers.php @@ -1,4 +1,5 @@ current_admin['id'] == $id) - { + if ($this->current_admin['id'] == $id) { \CI::session()->set_flashdata('message', lang('error_self_delete')); - redirect('admin/users'); + redirect('admin/users'); } //delete the user @@ -50,7 +51,7 @@ public function delete($id) } public function form($id = false) - { + { \CI::load()->helper('form'); \CI::load()->library('form_validation'); \CI::form_validation()->set_error_delimiters('
', '
'); @@ -65,13 +66,11 @@ public function form($id = false) $data['username'] = ''; $data['access'] = ''; - if ($id) - { + if ($id) { $this->admin_id = $id; $admin = \CI::auth()->getAdmin($id); //if the administrator does not exist, redirect them to the admin list with an error - if (!$admin) - { + if (!$admin) { \CI::session()->set_flashdata('message', lang('admin_not_found')); redirect('admin/users'); } @@ -87,33 +86,26 @@ public function form($id = false) \CI::form_validation()->set_rules('firstname', 'lang:firstname', 'trim|max_length[32]'); \CI::form_validation()->set_rules('lastname', 'lang:lastname', 'trim|max_length[32]'); \CI::form_validation()->set_rules('email', 'lang:email', 'trim|required|valid_email|max_length[128]'); - \CI::form_validation()->set_rules('username', 'lang:username', ['trim', 'required', 'max_length[128]', ['username_callable', function($str){ + \CI::form_validation()->set_rules('username', 'lang:username', ['trim', 'required', 'max_length[128]', ['username_callable', function ($str) { $email = \CI::auth()->check_username($str, $this->admin_id); - if ($email) - { + if ($email) { \CI::form_validation()->set_message('username_callable', lang('error_username_taken')); - return FALSE; - } - else - { - return TRUE; + return false; + } else { + return true; } }]]); \CI::form_validation()->set_rules('access', 'lang:access', 'trim|required'); //if this is a new account require a password, or if they have entered either a password or a password confirmation - if (\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '' || !$id) - { - \CI::form_validation()->set_rules('password', 'lang:password', 'required|min_length[6]|sha1'); - \CI::form_validation()->set_rules('confirm', 'lang:confirm_password', 'required|sha1|matches[password]'); + if (\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '' || !$id) { + \CI::form_validation()->set_rules('password', 'lang:password', 'required|min_length[6]'); + \CI::form_validation()->set_rules('confirm', 'lang:confirm_password', 'required|matches[password]'); } - if (\CI::form_validation()->run() == FALSE) - { + if (\CI::form_validation()->run() == false) { $this->view('user_form', $data); - } - else - { + } else { $save['id'] = $id; $save['firstname'] = \CI::input()->post('firstname'); $save['lastname'] = \CI::input()->post('lastname'); @@ -121,8 +113,7 @@ public function form($id = false) $save['username'] = \CI::input()->post('username'); $save['access'] = \CI::input()->post('access'); - if (\CI::input()->post('password') != '' || !$id) - { + if (\CI::input()->post('password') != '' || !$id) { $save['password'] = \CI::input()->post('password'); } @@ -133,4 +124,4 @@ public function form($id = false) redirect('admin/users'); } } -} \ No newline at end of file +} diff --git a/install/database.sql b/install/database.sql index 826197d..af6ba5d 100644 --- a/install/database.sql +++ b/install/database.sql @@ -6,11 +6,11 @@ CREATE TABLE `gc_admin` ( `username` varchar(255) NOT NULL, `email` varchar(128) DEFAULT NULL, `access` varchar(11) NOT NULL, - `password` varchar(40) NOT NULL, + `password` varchar(128) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; -INSERT INTO `gc_admin` (`id`, `firstname`, `lastname`, `username`, `email`, `access`, `password`) VALUES ('1', '', '', 'admin', '', 'Admin', 'd033e22ae348aeb5660fc2140aec35850c4da997'); +INSERT INTO `gc_admin` (`id`, `firstname`, `lastname`, `username`, `email`, `access`, `password`) VALUES ('1', '', '', 'admin', '', 'Admin', '$2a$08$KWNdzFXN53nniFOM6SMzC.oMJEhsaVGagoHHXLD6GYlYAKF9OAoaG'); CREATE TABLE `gc_banner_collections` ( `banner_collection_id` int(4) unsigned NOT NULL AUTO_INCREMENT, @@ -59,7 +59,7 @@ CREATE TABLE `gc_categories` ( `image` varchar(255) DEFAULT NULL, `seo_title` text NOT NULL, `meta` text NOT NULL, - `enabled_1` tinyint(1) DEFAULT '0', + `enabled` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; @@ -4314,7 +4314,7 @@ CREATE TABLE `gc_customers` ( `email_subscribe` tinyint(1) NOT NULL DEFAULT '0', `phone` varchar(32) NOT NULL, `company` varchar(128) NOT NULL, - `password` varchar(40) DEFAULT NULL, + `password` varchar(128) DEFAULT NULL, `active` tinyint(1) NOT NULL, `group_id` int(11) NOT NULL DEFAULT '1', `confirmed` tinyint(1) NOT NULL DEFAULT '0', From 1b33b3796c5a2cc41466157c28a96fc89832f75a Mon Sep 17 00:00:00 2001 From: Lawrence Date: Tue, 17 May 2016 10:06:52 +1000 Subject: [PATCH 02/16] Patch to CI 3.0.6 --- application/config/autoload.php | 12 +- application/config/config.php | 98 ++++---- application/config/constants.php | 53 ++-- application/config/foreign_chars.php | 1 + application/config/mimes.php | 20 +- application/config/user_agents.php | 4 +- .../views/errors/cli/error_exception.php | 28 +-- application/views/errors/cli/error_php.php | 30 +-- system/core/CodeIgniter.php | 14 +- system/core/Common.php | 43 ++-- system/core/Config.php | 45 +++- system/core/Exceptions.php | 12 +- system/core/Input.php | 50 ++-- system/core/Loader.php | 117 ++++++--- system/core/Log.php | 37 ++- system/core/Output.php | 49 ++-- system/core/Router.php | 120 ++++----- system/core/Security.php | 231 ++++++++++++------ system/core/URI.php | 16 +- system/core/compat/hash.php | 51 +++- system/database/DB_driver.php | 209 +++++++++++----- system/database/DB_forge.php | 29 +-- system/database/DB_query_builder.php | 200 +++++++++------ system/database/DB_utility.php | 17 +- .../database/drivers/cubrid/cubrid_driver.php | 48 ++-- .../database/drivers/ibase/ibase_driver.php | 44 ++-- .../database/drivers/mssql/mssql_driver.php | 58 ++--- .../database/drivers/mysql/mysql_driver.php | 70 +++--- .../database/drivers/mysqli/mysqli_driver.php | 146 +++++++---- system/database/drivers/oci8/oci8_driver.php | 124 ++++------ system/database/drivers/odbc/odbc_driver.php | 62 ++--- system/database/drivers/pdo/pdo_driver.php | 40 +-- .../pdo/subdrivers/pdo_mysql_driver.php | 94 ++++++- .../drivers/pdo/subdrivers/pdo_oci_driver.php | 41 +++- .../pdo/subdrivers/pdo_odbc_driver.php | 28 ++- .../pdo/subdrivers/pdo_pgsql_driver.php | 17 +- .../pdo/subdrivers/pdo_sqlite_driver.php | 40 ++- .../pdo/subdrivers/pdo_sqlite_forge.php | 11 +- .../drivers/postgre/postgre_driver.php | 47 ++-- .../database/drivers/sqlite/sqlite_driver.php | 49 +--- .../drivers/sqlite3/sqlite3_driver.php | 70 +++--- .../drivers/sqlite3/sqlite3_forge.php | 13 +- .../database/drivers/sqlsrv/sqlsrv_driver.php | 59 ++--- system/helpers/array_helper.php | 14 +- system/helpers/captcha_helper.php | 101 +++++++- system/helpers/download_helper.php | 31 +-- system/helpers/file_helper.php | 14 +- system/helpers/form_helper.php | 96 +++++--- system/helpers/inflector_helper.php | 13 +- system/helpers/path_helper.php | 12 +- system/helpers/string_helper.php | 15 +- system/helpers/text_helper.php | 33 ++- system/helpers/url_helper.php | 18 +- system/libraries/Cache/Cache.php | 39 +-- system/libraries/Cache/drivers/Cache_apc.php | 35 ++- system/libraries/Cache/drivers/Cache_file.php | 10 +- .../Cache/drivers/Cache_memcached.php | 168 +++++++------ .../libraries/Cache/drivers/Cache_redis.php | 163 ++++++------ .../Cache/drivers/Cache_wincache.php | 35 ++- system/libraries/Email.php | 123 +++++++--- system/libraries/Encryption.php | 17 +- system/libraries/Form_validation.php | 171 +++++++------ system/libraries/Ftp.php | 14 +- system/libraries/Image_lib.php | 54 ++-- system/libraries/Migration.php | 112 ++++++--- system/libraries/Pagination.php | 33 +-- system/libraries/Profiler.php | 60 ++--- system/libraries/Session/Session.php | 32 ++- system/libraries/Session/Session_driver.php | 53 +++- .../drivers/Session_database_driver.php | 78 ++++-- .../Session/drivers/Session_files_driver.php | 77 +++--- .../drivers/Session_memcached_driver.php | 75 +++--- .../Session/drivers/Session_redis_driver.php | 75 +++--- system/libraries/Unit_test.php | 66 ++--- system/libraries/Upload.php | 91 ++++--- system/libraries/Xmlrpc.php | 40 ++- system/libraries/Zip.php | 12 +- 77 files changed, 2673 insertions(+), 1854 deletions(-) diff --git a/application/config/autoload.php b/application/config/autoload.php index 72f855c..b862822 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -42,8 +42,8 @@ $autoload['packages'] = array(); - /* + | ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- @@ -59,11 +59,16 @@ | | $autoload['libraries'] = array('user_agent' => 'ua'); */ - $autoload['libraries'] = array(); - /* +| ------------------------------------------------------------------- +| Auto-load Drivers +| ------------------------------------------------------------------- +| These classes are located in system/libraries/ or in your + + + | ------------------------------------------------------------------- | Auto-load Drivers | ------------------------------------------------------------------- @@ -136,5 +141,4 @@ | | $autoload['model'] = array('first_model' => 'first'); */ - $autoload['model'] = array(); diff --git a/application/config/config.php b/application/config/config.php index f5ee5e2..4bec273 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -1,5 +1,5 @@ 's', '/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T', '/ț|ţ|ť|ŧ|т/' => 't', + '/Þ|þ/' => 'th', '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', diff --git a/application/config/mimes.php b/application/config/mimes.php index 8eff4d2..a093907 100755 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -78,6 +78,14 @@ 'jpeg' => array('image/jpeg', 'image/pjpeg'), 'jpg' => array('image/jpeg', 'image/pjpeg'), 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'png' => array('image/png', 'image/x-png'), 'tiff' => 'image/tiff', 'tif' => 'image/tiff', @@ -127,10 +135,11 @@ 'rsa' => 'application/x-pkcs7', 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), '3g2' => 'video/3gpp2', - '3gp' => 'video/3gp', + '3gp' => array('video/3gp', 'video/3gpp'), 'mp4' => 'video/mp4', 'm4a' => 'audio/x-m4a', - 'f4v' => 'video/mp4', + 'f4v' => array('video/mp4', 'video/x-f4v'), + 'flv' => 'video/x-flv', 'webm' => 'video/webm', 'aac' => 'audio/x-acc', 'm4u' => 'application/vnd.mpegurl', @@ -141,7 +150,7 @@ 'au' => 'audio/x-au', 'ac3' => 'audio/ac3', 'flac' => 'audio/x-flac', - 'ogg' => 'audio/ogg', + 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), 'ics' => 'text/calendar', @@ -152,5 +161,8 @@ 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), - 'vcf' => 'text/x-vcard' + 'vcf' => 'text/x-vcard', + 'srt' => array('text/srt', 'text/plain'), + 'vtt' => array('text/vtt', 'text/plain'), + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') ); diff --git a/application/config/user_agents.php b/application/config/user_agents.php index 68d7853..fd8ed48 100755 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -12,6 +12,7 @@ */ $platforms = array( + 'windows nt 10.0' => 'Windows 10', 'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', @@ -61,6 +62,7 @@ $browsers = array( 'OPR' => 'Opera', 'Flock' => 'Flock', + 'Edge' => 'Spartan', 'Chrome' => 'Chrome', // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string 'Opera.*?Version' => 'Opera', @@ -197,7 +199,7 @@ 'bingbot' => 'Bing', 'slurp' => 'Inktomi Slurp', 'yahoo' => 'Yahoo', - 'askjeeves' => 'AskJeeves', + 'ask jeeves' => 'Ask Jeeves', 'fastcrawler' => 'FastCrawler', 'infoseek' => 'InfoSeek Robot 1.0', 'lycos' => 'Lycos', diff --git a/application/views/errors/cli/error_exception.php b/application/views/errors/cli/error_exception.php index 75d7f0f..efa6a66 100755 --- a/application/views/errors/cli/error_exception.php +++ b/application/views/errors/cli/error_exception.php @@ -1,25 +1,21 @@ - + An uncaught Exception was encountered -Type: -Message: -Filename: getFile(); ?> +Type: +Message: +Filename: getFile(), "\n"; ?> Line Number: getLine(); ?> Backtrace: - getTrace() as $error): ?> - +getTrace() as $error): ?> + + File: + Line: + Function: + + - File: - Line: - Function: - - - - - \ No newline at end of file + diff --git a/application/views/errors/cli/error_php.php b/application/views/errors/cli/error_php.php index fec91e5..8a24b64 100755 --- a/application/views/errors/cli/error_php.php +++ b/application/views/errors/cli/error_php.php @@ -1,25 +1,21 @@ - + A PHP Error was encountered -Severity: -Message: -Filename: -Line Number: +Severity: +Message: +Filename: +Line Number: Backtrace: - - + + + File: + Line: + Function: + + - File: - Line: - Function: - - - - - \ No newline at end of file + diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index b38166b..3eb3e05 100755 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage CodeIgniter * @category Front-controller * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ */ /** @@ -55,7 +55,7 @@ * @var string * */ - define('CI_VERSION', '3.0.0'); + define('CI_VERSION', '3.0.6'); /* * ------------------------------------------------------ @@ -359,7 +359,7 @@ * * Returns current CI instance object * - * @return object + * @return CI_Controller */ function &get_instance() { diff --git a/system/core/Common.php b/system/core/Common.php index f28272b..b87ce4d 100755 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage CodeIgniter * @category Common Functions * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ */ // ------------------------------------------------------------------------ @@ -181,7 +181,7 @@ function &load_class($class, $directory = 'libraries', $param = NULL) // Did we find the class? if ($name === FALSE) { - // Note: We use exit() rather then show_error() in order to avoid a + // Note: We use exit() rather than show_error() in order to avoid a // self-referencing loop with the Exceptions class set_status_header(503); echo 'Unable to locate the specified class: '.$class.'.php'; @@ -506,6 +506,9 @@ function set_status_header($code = 200, $text = '') { is_int($code) OR $code = (int) $code; $stati = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', 201 => 'Created', 202 => 'Accepted', @@ -524,6 +527,7 @@ function set_status_header($code = 200, $text = '') 400 => 'Bad Request', 401 => 'Unauthorized', + 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', @@ -673,7 +677,7 @@ function _exception_handler($exception) * of CodeIgniter.php. The main reason we use this is to simulate * a complete custom exception handler. * - * E_STRICT is purposivly neglected because such events may have + * E_STRICT is purposively neglected because such events may have * been caught. Duplication or none? None is preferred for now. * * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a @@ -745,10 +749,15 @@ function html_escape($var, $double_encode = TRUE) { return $var; } - + if (is_array($var)) { - return array_map('html_escape', $var, array_fill(0, count($var), $double_encode)); + foreach (array_keys($var) as $key) + { + $var[$key] = html_escape($var[$key], $double_encode); + } + + return $var; } return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode); @@ -829,19 +838,9 @@ function function_usable($function_name) { if ( ! isset($_suhosin_func_blacklist)) { - if (extension_loaded('suhosin')) - { - $_suhosin_func_blacklist = explode(',', trim(ini_get('suhosin.executor.func.blacklist'))); - - if ( ! in_array('eval', $_suhosin_func_blacklist, TRUE) && ini_get('suhosin.executor.disable_eval')) - { - $_suhosin_func_blacklist[] = 'eval'; - } - } - else - { - $_suhosin_func_blacklist = array(); - } + $_suhosin_func_blacklist = extension_loaded('suhosin') + ? explode(',', trim(ini_get('suhosin.executor.func.blacklist'))) + : array(); } return ! in_array($function_name, $_suhosin_func_blacklist, TRUE); diff --git a/system/core/Config.php b/system/core/Config.php index d07000a..ca6fb37 100755 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/config.html + * @link https://codeigniter.com/user_guide/libraries/config.html */ class CI_Config { @@ -88,11 +88,18 @@ public function __construct() // Set the base_url automatically if none was provided if (empty($this->config['base_url'])) { - // The regular expression is only a basic validation for a valid "Host" header. - // It's not exhaustive, only checks for valid characters. - if (isset($_SERVER['HTTP_HOST']) && preg_match('/^((\[[0-9a-f:]+\])|(\d{1,3}(\.\d{1,3}){3})|[a-z0-9\-\.]+)(:\d+)?$/i', $_SERVER['HTTP_HOST'])) + if (isset($_SERVER['SERVER_ADDR'])) { - $base_url = (is_https() ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'] + if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE) + { + $server_addr = '['.$_SERVER['SERVER_ADDR'].']'; + } + else + { + $server_addr = $_SERVER['SERVER_ADDR']; + } + + $base_url = (is_https() ? 'https' : 'http').'://'.$server_addr .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME']))); } else @@ -238,7 +245,15 @@ public function site_url($uri = '', $protocol = NULL) if (isset($protocol)) { - $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + // For protocol-relative links + if ($protocol === '') + { + $base_url = substr($base_url, strpos($base_url, '//')); + } + else + { + $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + } } if (empty($uri)) @@ -293,7 +308,15 @@ public function base_url($uri = '', $protocol = NULL) if (isset($protocol)) { - $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + // For protocol-relative links + if ($protocol === '') + { + $base_url = substr($base_url, strpos($base_url, '//')); + } + else + { + $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + } } return $base_url.ltrim($this->_uri_string($uri), '/'); diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index fc25f57..a1c6a19 100755 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Exceptions * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/exceptions.html + * @link https://codeigniter.com/user_guide/libraries/exceptions.html */ class CI_Exceptions { @@ -187,7 +187,7 @@ public function show_error($heading, $message, $template = 'error_general', $sta // -------------------------------------------------------------------- - public function show_exception(Exception $exception) + public function show_exception($exception) { $templates_path = config_item('error_views_path'); if (empty($templates_path)) diff --git a/system/core/Input.php b/system/core/Input.php index 12332cf..a7c9ecd 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Input * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/input.html + * @link https://codeigniter.com/user_guide/libraries/input.html */ class CI_Input { @@ -153,6 +153,12 @@ public function __construct() // Sanitize global arrays $this->_sanitize_globals(); + // CSRF Protection check + if ($this->_enable_csrf === TRUE && ! is_cli()) + { + $this->security->csrf_verify(); + } + log_message('info', 'Input Class Initialized'); } @@ -600,7 +606,7 @@ protected function _sanitize_globals() { $_GET = array(); } - elseif (is_array($_GET) && count($_GET) > 0) + elseif (is_array($_GET)) { foreach ($_GET as $key => $val) { @@ -609,7 +615,7 @@ protected function _sanitize_globals() } // Clean $_POST Data - if (is_array($_POST) && count($_POST) > 0) + if (is_array($_POST)) { foreach ($_POST as $key => $val) { @@ -618,7 +624,7 @@ protected function _sanitize_globals() } // Clean $_COOKIE Data - if (is_array($_COOKIE) && count($_COOKIE) > 0) + if (is_array($_COOKIE)) { // Also get rid of specially treated cookies that might be set by a server // or silly application, that are of no use to a CI application anyway @@ -647,12 +653,6 @@ protected function _sanitize_globals() // Sanitize PHP_SELF $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); - // CSRF Protection check - if ($this->_enable_csrf === TRUE && ! is_cli()) - { - $this->security->csrf_verify(); - } - log_message('debug', 'Global POST, GET and COOKIE data sanitized'); } @@ -682,7 +682,7 @@ protected function _clean_input_data($str) /* We strip slashes if magic quotes is on to keep things consistent NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and - it will probably not exist in future versions at all. + it will probably not exist in future versions at all. */ if ( ! is_php('5.4') && get_magic_quotes_gpc()) { @@ -799,19 +799,27 @@ public function request_headers($xss_clean = FALSE) */ public function get_request_header($index, $xss_clean = FALSE) { - if (empty($this->headers)) + static $headers; + + if ( ! isset($headers)) { - $this->request_headers(); + empty($this->headers) && $this->request_headers(); + foreach ($this->headers as $key => $value) + { + $headers[strtolower($key)] = $value; + } } - if ( ! isset($this->headers[$index])) + $index = strtolower($index); + + if ( ! isset($headers[$index])) { return NULL; } return ($xss_clean === TRUE) - ? $this->security->xss_clean($this->headers[$index]) - : $this->headers[$index]; + ? $this->security->xss_clean($headers[$index]) + : $headers[$index]; } // -------------------------------------------------------------------- @@ -836,7 +844,7 @@ public function is_ajax_request() * Test to see if a request was made from the command line. * * @deprecated 3.0.0 Use is_cli() instead - * @return bool + * @return bool */ public function is_cli_request() { diff --git a/system/core/Loader.php b/system/core/Loader.php index 254ad0d..c742ae7 100755 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Loader * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/loader.html + * @link https://codeigniter.com/user_guide/libraries/loader.html */ class CI_Loader { @@ -272,7 +272,7 @@ public function model($model, $name = '', $db_conn = FALSE) $CI =& get_instance(); if (isset($CI->$name)) { - show_error('The model name you are loading is the name of a resource that is already being used: '.$name); + throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); } if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) @@ -285,29 +285,73 @@ public function model($model, $name = '', $db_conn = FALSE) $this->database($db_conn, FALSE, TRUE); } + // Note: All of the code under this condition used to be just: + // + // load_class('Model', 'core'); + // + // However, load_class() instantiates classes + // to cache them for later use and that prevents + // MY_Model from being an abstract class and is + // sub-optimal otherwise anyway. if ( ! class_exists('CI_Model', FALSE)) { - load_class('Model', 'core'); - } + $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; + if (file_exists($app_path.'Model.php')) + { + require_once($app_path.'Model.php'); + if ( ! class_exists('CI_Model', FALSE)) + { + throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); + } + } + elseif ( ! class_exists('CI_Model', FALSE)) + { + require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php'); + } - $model = ucfirst(strtolower($model)); + $class = config_item('subclass_prefix').'Model'; + if (file_exists($app_path.$class.'.php')) + { + require_once($app_path.$class.'.php'); + if ( ! class_exists($class, FALSE)) + { + throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); + } + } + } - foreach ($this->_ci_model_paths as $mod_path) + $model = ucfirst($model); + if ( ! class_exists($model, FALSE)) { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + foreach ($this->_ci_model_paths as $mod_path) { - continue; - } + if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + { + continue; + } - require_once($mod_path.'models/'.$path.$model.'.php'); + require_once($mod_path.'models/'.$path.$model.'.php'); + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); + } - $this->_ci_models[] = $name; - $CI->$name = new $model(); - return $this; + break; + } + + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException('Unable to locate the model you have specified: '.$model); + } + } + elseif ( ! is_subclass_of($model, 'CI_Model')) + { + throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); } - // couldn't find the model - show_error('Unable to locate the model you have specified: '.$model); + $this->_ci_models[] = $name; + $CI->$name = new $model(); + return $this; } // -------------------------------------------------------------------- @@ -500,7 +544,7 @@ public function vars($vars, $val = '') * * Clears the cached variables. * - * @return object + * @return CI_Loader */ public function clear_vars() { @@ -674,9 +718,16 @@ public function driver($library, $params = NULL, $object_name = NULL) { if (is_array($library)) { - foreach ($library as $driver) + foreach ($library as $key => $value) { - $this->driver($driver); + if (is_int($key)) + { + $this->driver($value, $params); + } + else + { + $this->driver($key, $params, $value); + } } return $this; @@ -885,6 +936,14 @@ protected function _ci_load($_ci_data) */ if (is_array($_ci_vars)) { + foreach (array_keys($_ci_vars) as $key) + { + if (strncmp($key, '_ci_', 4) === 0) + { + unset($_ci_vars[$key]); + } + } + $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); } extract($this->_ci_cached_vars); @@ -905,7 +964,7 @@ protected function _ci_load($_ci_data) // If the PHP installation does not support short tags we'll // do a little string replacement, changing the short tags // to standard PHP echo statements. - if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE && function_usable('eval')) + if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) { echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('driver($item); - } + $this->driver($autoload['drivers']); } // Load libraries @@ -1307,10 +1363,7 @@ protected function _ci_autoloader() } // Load all other libraries - foreach ($autoload['libraries'] as $item) - { - $this->library($item); - } + $this->library($autoload['libraries']); } // Autoload models diff --git a/system/core/Log.php b/system/core/Log.php index e8cb401..1abdaa0 100755 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Logging * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/general/errors.html + * @link https://codeigniter.com/user_guide/general/errors.html */ class CI_Log { @@ -154,8 +154,8 @@ public function __construct() * * Generally this function will be called using the global log_message() function * - * @param string the error level: 'error', 'debug' or 'info' - * @param string the error message + * @param string $level The error level: 'error', 'debug' or 'info' + * @param string $msg The error message * @return bool */ public function write_log($level, $msg) @@ -191,6 +191,8 @@ public function write_log($level, $msg) return FALSE; } + flock($fp, LOCK_EX); + // Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format if (strpos($this->_date_fmt, 'u') !== FALSE) { @@ -204,9 +206,7 @@ public function write_log($level, $msg) $date = date($this->_date_fmt); } - $message .= $level.' - '.$date.' --> '.$msg."\n"; - - flock($fp, LOCK_EX); + $message .= $this->_format_line($level, $date, $msg); for ($written = 0, $length = strlen($message); $written < $length; $written += $result) { @@ -227,4 +227,21 @@ public function write_log($level, $msg) return is_int($result); } + // -------------------------------------------------------------------- + + /** + * Format the log line. + * + * This is for extensibility of log formatting + * If you want to change the log format, extend the CI_Log class and override this method + * + * @param string $level The error level + * @param string $date Formatted date string + * @param string $msg The log message + * @return string Formatted log line with a new line character '\n' at the end + */ + protected function _format_line($level, $date, $message) + { + return $level.' - '.$date.' --> '.$message."\n"; + } } diff --git a/system/core/Output.php b/system/core/Output.php index 02f6693..ec9c21b 100755 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Output * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/output.html + * @link https://codeigniter.com/user_guide/libraries/output.html */ class CI_Output { @@ -377,7 +377,7 @@ public function set_profiler_sections($sections) /** * Set Cache * - * @param int $time Cache expiration time in seconds + * @param int $time Cache expiration time in minutes * @return CI_Output */ public function cache($time) @@ -556,9 +556,16 @@ public function _write_cache($output) .$CI->config->item('index_page') .$CI->uri->uri_string(); - if ($CI->config->item('cache_query_string') && ! empty($_SERVER['QUERY_STRING'])) + if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING'])) { - $uri .= '?'.$_SERVER['QUERY_STRING']; + if (is_array($cache_query_string)) + { + $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); + } + else + { + $uri .= '?'.$_SERVER['QUERY_STRING']; + } } $cache_path .= md5($uri); @@ -646,9 +653,16 @@ public function _display_cache(&$CFG, &$URI) // Build the file path. The file name is an MD5 hash of the full URI $uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string; - if ($CFG->item('cache_query_string') && ! empty($_SERVER['QUERY_STRING'])) + if (($cache_query_string = $CFG->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING'])) { - $uri .= '?'.$_SERVER['QUERY_STRING']; + if (is_array($cache_query_string)) + { + $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); + } + else + { + $uri .= '?'.$_SERVER['QUERY_STRING']; + } } $filepath = $cache_path.md5($uri); @@ -674,7 +688,7 @@ public function _display_cache(&$CFG, &$URI) $cache_info = unserialize($match[1]); $expire = $cache_info['expire']; - $last_modified = filemtime($cache_path); + $last_modified = filemtime($filepath); // Has the file expired? if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path)) @@ -729,13 +743,20 @@ public function delete_cache($uri = '') { $uri = $CI->uri->uri_string(); - if ($CI->config->item('cache_query_string') && ! empty($_SERVER['QUERY_STRING'])) + if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING'])) { - $uri .= '?'.$_SERVER['QUERY_STRING']; + if (is_array($cache_query_string)) + { + $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string))); + } + else + { + $uri .= '?'.$_SERVER['QUERY_STRING']; + } } } - $cache_path .= md5($CI->config->item('base_url').$CI->config->item('index_page').$uri); + $cache_path .= md5($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/')); if ( ! @unlink($cache_path)) { diff --git a/system/core/Router.php b/system/core/Router.php index eb3da22..045d366 100755 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/general/routing.html + * @link https://codeigniter.com/user_guide/general/routing.html */ class CI_Router { @@ -83,7 +83,7 @@ class CI_Router { * * @var string */ - public $directory = ''; + public $directory; /** * Default controller (and method if specific) @@ -105,7 +105,7 @@ class CI_Router { /** * Enable query strings flag * - * Determines wether to use GET parameters or segment URIs + * Determines whether to use GET parameters or segment URIs * * @var bool */ @@ -118,6 +118,7 @@ class CI_Router { * * Runs the route mapping function. * + * @param array $routing * @return void */ public function __construct($routing = NULL) @@ -126,25 +127,16 @@ public function __construct($routing = NULL) $this->uri =& load_class('URI', 'core'); $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE); + + // If a directory override is configured, it has to be set before any dynamic routing logic + is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']); $this->_set_routing(); // Set any routing overrides that may exist in the main index file if (is_array($routing)) { - if (isset($routing['directory'])) - { - $this->set_directory($routing['directory']); - } - - if ( ! empty($routing['controller'])) - { - $this->set_class($routing['controller']); - } - - if ( ! empty($routing['function'])) - { - $this->set_method($routing['function']); - } + empty($routing['controller']) OR $this->set_class($routing['controller']); + empty($routing['function']) OR $this->set_method($routing['function']); } log_message('info', 'Router Class Initialized'); @@ -162,17 +154,44 @@ public function __construct($routing = NULL) */ protected function _set_routing() { + // Load the routes.php file. It would be great if we could + // skip this for enable_query_strings = TRUE, but then + // default_controller would be empty ... + if (file_exists(APPPATH.'config/routes.php')) + { + include(APPPATH.'config/routes.php'); + } + + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php')) + { + include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); + } + + // Validate & get reserved routes + if (isset($route) && is_array($route)) + { + isset($route['default_controller']) && $this->default_controller = $route['default_controller']; + isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes']; + unset($route['default_controller'], $route['translate_uri_dashes']); + $this->routes = $route; + } + // Are query strings enabled in the config file? Normally CI doesn't utilize query strings // since URI segments are more search-engine friendly, but they can optionally be used. // If this feature is enabled, we will gather the directory/class/method a little differently if ($this->enable_query_strings) { - $_d = $this->config->item('directory_trigger'); - $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : ''; - if ($_d !== '') + // If the directory is set at this time, it means an override exists, so skip the checks + if ( ! isset($this->directory)) { - $this->uri->filter_uri($_d); - $this->set_directory($_d); + $_d = $this->config->item('directory_trigger'); + $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : ''; + + if ($_d !== '') + { + $this->uri->filter_uri($_d); + $this->set_directory($_d); + } } $_c = trim($this->config->item('controller_trigger')); @@ -203,26 +222,6 @@ protected function _set_routing() return; } - // Load the routes.php file. - if (file_exists(APPPATH.'config/routes.php')) - { - include(APPPATH.'config/routes.php'); - } - - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php')) - { - include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); - } - - // Validate & get reserved routes - if (isset($route) && is_array($route)) - { - isset($route['default_controller']) && $this->default_controller = $route['default_controller']; - isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes']; - unset($route['default_controller'], $route['translate_uri_dashes']); - $this->routes = $route; - } - // Is there anything to parse? if ($this->uri->uri_string !== '') { @@ -333,6 +332,8 @@ protected function _set_default_controller() protected function _validate_request($segments) { $c = count($segments); + $directory_override = isset($this->directory); + // Loop through our segments and return as soon as a controller // is found or when such a directory doesn't exist while ($c-- > 0) @@ -340,7 +341,10 @@ protected function _validate_request($segments) $test = $this->directory .ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); - if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])) + if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') + && $directory_override === FALSE + && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]) + ) { $this->set_directory(array_shift($segments), TRUE); continue; @@ -371,29 +375,13 @@ protected function _parse_routes() // Get HTTP verb $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli'; - // Is there a literal match? If so we're done - if (isset($this->routes[$uri])) - { - // Check default routes format - if (is_string($this->routes[$uri])) - { - $this->_set_request(explode('/', $this->routes[$uri])); - return; - } - // Is there a matching http verb? - elseif (is_array($this->routes[$uri]) && isset($this->routes[$uri][$http_verb])) - { - $this->_set_request(explode('/', $this->routes[$uri][$http_verb])); - return; - } - } - // Loop through the route array looking for wildcards foreach ($this->routes as $key => $val) { - // Check if route format is using http verb + // Check if route format is using HTTP verbs if (is_array($val)) { + $val = array_change_key_case($val, CASE_LOWER); if (isset($val[$http_verb])) { $val = $val[$http_verb]; @@ -493,7 +481,7 @@ public function fetch_method() * Set directory name * * @param string $dir Directory name - * @param bool $appent Whether we're appending rather then setting the full value + * @param bool $append Whether we're appending rather than setting the full value * @return void */ public function set_directory($dir, $append = FALSE) diff --git a/system/core/Security.php b/system/core/Security.php index 9cef424..d5305d1 100755 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Security * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/security.html + * @link https://codeigniter.com/user_guide/libraries/security.html */ class CI_Security { @@ -275,7 +275,7 @@ public function csrf_set_cookie() $secure_cookie, config_item('cookie_httponly') ); - log_message('info', 'CRSF cookie sent'); + log_message('info', 'CSRF cookie sent'); return $this; } @@ -436,7 +436,7 @@ public function xss_clean($str, $is_image = FALSE) $words = array( 'javascript', 'expression', 'vbscript', 'jscript', 'wscript', 'vbs', 'script', 'base64', 'applet', 'alert', 'document', - 'write', 'cookie', 'window', 'confirm', 'prompt' + 'write', 'cookie', 'window', 'confirm', 'prompt', 'eval' ); foreach ($words as $word) @@ -480,12 +480,8 @@ public function xss_clean($str, $is_image = FALSE) } } while ($original !== $str); - unset($original); - // Remove evil attributes such as style, onclick and xmlns - $str = $this->_remove_evil_attributes($str, $is_image); - /* * Sanitize naughty HTML elements * @@ -495,8 +491,29 @@ public function xss_clean($str, $is_image = FALSE) * So this: * Becomes: <blink> */ - $naughty = 'alert|prompt|confirm|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|math|video|svg|xml|xss'; - $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); + $pattern = '#' + .'<((?/*\s*)(?[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character + .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator + // optional attributes + .'(?(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons + .'[^\s\042\047>/=]+' // attribute characters + // optional attribute-value + .'(?:\s*=' // attribute-value separator + .'(?:[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*))' // single, double or non-quoted value + .')?' // end optional attribute-value group + .')*)' // end optional attributes group + .'[^>]*)(?\>)?#isS'; + + // Note: It would be nice to optimize this for speed, BUT + // only matching the naughty elements here results in + // false positives and in turn - vulnerabilities! + do + { + $old_str = $str; + $str = preg_replace_callback($pattern, array($this, '_sanitize_naughty_html'), $str); + } + while ($old_str !== $str); + unset($old_str); /* * Sanitize naughty scripting elements @@ -510,9 +527,11 @@ public function xss_clean($str, $is_image = FALSE) * For example: eval('some code') * Becomes: eval('some code') */ - $str = preg_replace('#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', - '\\1\\2(\\3)', - $str); + $str = preg_replace( + '#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', + '\\1\\2(\\3)', + $str + ); // Final clean up // This adds a bit of extra precaution in case @@ -574,6 +593,22 @@ public function get_random_bytes($length) return FALSE; } + if (function_exists('random_bytes')) + { + try + { + // The cast is required to avoid TypeError + return random_bytes((int) $length); + } + catch (Exception $e) + { + // If random_bytes() can't do the job, we can't either ... + // There's no point in using fallbacks. + log_message('error', $e->getMessage()); + return FALSE; + } + } + // Unfortunately, none of the following PRNGs is guaranteed to exist ... if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) { @@ -727,7 +762,14 @@ public function sanitize_filename($str, $relative_path = FALSE) */ public function strip_image_tags($str) { - return preg_replace(array('##', '##'), '\\1', $str); + return preg_replace( + array( + '##i', + '#`]+)).*?\>#i' + ), + '\\2', + $str + ); } // ---------------------------------------------------------------- @@ -750,71 +792,92 @@ protected function _compact_exploded_words($matches) // -------------------------------------------------------------------- /** - * Remove Evil HTML Attributes (like event handlers and style) - * - * It removes the evil attribute and either: - * - * - Everything up until a space. For example, everything between the pipes: - * - * - * - * - * - * - Everything inside the quotes. For example, everything between the pipes: + * Sanitize Naughty HTML * - * - * - * + * Callback method for xss_clean() to remove naughty HTML elements. * - * @param string $str The string to check - * @param bool $is_image Whether the input is an image - * @return string The string with the evil attributes removed + * @used-by CI_Security::xss_clean() + * @param array $matches + * @return string */ - protected function _remove_evil_attributes($str, $is_image) + protected function _sanitize_naughty_html($matches) { - $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime'); + static $naughty_tags = array( + 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', + 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer', + 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object', + 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss' + ); - if ($is_image === TRUE) + static $evil_attributes = array( + 'on\w+', 'style', 'xmlns', 'formaction', 'form', 'xlink:href', 'FSCommand', 'seekSegmentTime' + ); + + // First, escape unclosed tags + if (empty($matches['closeTag'])) { - /* - * Adobe Photoshop puts XML metadata into JFIF images, - * including namespacing, so we have to allow this for images. - */ - unset($evil_attributes[array_search('xmlns', $evil_attributes)]); + return '<'.$matches[1]; } + // Is the element that we caught naughty? If so, escape it + elseif (in_array(strtolower($matches['tagName']), $naughty_tags, TRUE)) + { + return '<'.$matches[1].'>'; + } + // For other tags, see if their attributes are "evil" and strip those + elseif (isset($matches['attributes'])) + { + // We'll store the already fitlered attributes here + $attributes = array(); - do { - $count = $temp_count = 0; + // Attribute-catching pattern + $attributes_pattern = '#' + .'(?[^\s\042\047>/=]+)' // attribute characters + // optional attribute-value + .'(?:\s*=(?[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*)))' // attribute-value separator + .'#i'; - // replace occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes) - $str = preg_replace('/(<[^>]+)(?]+)(?]*)/is', '$1[removed]', $str, -1, $temp_count); - $count += $temp_count; - } - while ($count); + // Each iteration filters a single attribute + do + { + // Strip any non-alpha characters that may preceed an attribute. + // Browsers often parse these incorrectly and that has been a + // of numerous XSS issues we've had. + $matches['attributes'] = preg_replace('#^[^a-z]+#i', '', $matches['attributes']); - return $str; - } + if ( ! preg_match($attributes_pattern, $matches['attributes'], $attribute, PREG_OFFSET_CAPTURE)) + { + // No (valid) attribute found? Discard everything else inside the tag + break; + } - // -------------------------------------------------------------------- + if ( + // Is it indeed an "evil" attribute? + preg_match($is_evil_pattern, $attribute['name'][0]) + // Or does it have an equals sign, but no value and not quoted? Strip that too! + OR (trim($attribute['value'][0]) === '') + ) + { + $attributes[] = 'xss=removed'; + } + else + { + $attributes[] = $attribute[0][0]; + } - /** - * Sanitize Naughty HTML - * - * Callback method for xss_clean() to remove naughty HTML elements. - * - * @used-by CI_Security::xss_clean() - * @param array $matches - * @return string - */ - protected function _sanitize_naughty_html($matches) - { - return '<'.$matches[1].$matches[2].$matches[3] // encode opening brace - // encode captured opening or closing brace to prevent recursive vectors: - .str_replace(array('>', '<'), array('>', '<'), $matches[4]); + $matches['attributes'] = substr($matches['attributes'], $attribute[0][1] + strlen($attribute[0][0])); + } + while ($matches['attributes'] !== ''); + + $attributes = empty($attributes) + ? '' + : ' '.implode(' ', $attributes); + return '<'.$matches['slash'].$matches['tagName'].$attributes.'>'; + } + + return $matches[0]; } // -------------------------------------------------------------------- @@ -834,12 +897,15 @@ protected function _sanitize_naughty_html($matches) */ protected function _js_link_removal($match) { - return str_replace($match[1], - preg_replace('#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes(str_replace(array('<', '>'), '', $match[1])) - ), - $match[0]); + return str_replace( + $match[1], + preg_replace( + '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) + ), + $match[0] + ); } // -------------------------------------------------------------------- @@ -859,12 +925,15 @@ protected function _js_link_removal($match) */ protected function _js_img_removal($match) { - return str_replace($match[1], - preg_replace('#src=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes(str_replace(array('<', '>'), '', $match[1])) - ), - $match[0]); + return str_replace( + $match[1], + preg_replace( + '#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) + ), + $match[0] + ); } // -------------------------------------------------------------------- diff --git a/system/core/URI.php b/system/core/URI.php index 2211e36..544f6c8 100755 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category URI * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/uri.html + * @link https://codeigniter.com/user_guide/libraries/uri.html */ class CI_URI { @@ -201,7 +201,9 @@ protected function _parse_request_uri() return ''; } - $uri = parse_url($_SERVER['REQUEST_URI']); + // parse_url() returns false if no host is present, but the path or query string + // contains a colon followed by a number + $uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']); $query = isset($uri['query']) ? $uri['query'] : ''; $uri = isset($uri['path']) ? $uri['path'] : ''; @@ -292,7 +294,7 @@ protected function _parse_argv() * * Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri() * - * @param string $url + * @param string $uri * @return string */ protected function _remove_relative_directory($uri) diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php index 477535d..1595455 100755 --- a/system/core/compat/hash.php +++ b/system/core/compat/hash.php @@ -174,9 +174,56 @@ function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_out } $hash_length = strlen(hash($algo, NULL, TRUE)); - if (empty($length)) + empty($length) && $length = $hash_length; + + // Pre-hash password inputs longer than the algorithm's block size + // (i.e. prepare HMAC key) to mitigate potential DoS attacks. + static $block_sizes; + empty($block_sizes) && $block_sizes = array( + 'gost' => 32, + 'haval128,3' => 128, + 'haval160,3' => 128, + 'haval192,3' => 128, + 'haval224,3' => 128, + 'haval256,3' => 128, + 'haval128,4' => 128, + 'haval160,4' => 128, + 'haval192,4' => 128, + 'haval224,4' => 128, + 'haval256,4' => 128, + 'haval128,5' => 128, + 'haval160,5' => 128, + 'haval192,5' => 128, + 'haval224,5' => 128, + 'haval256,5' => 128, + 'md2' => 16, + 'md4' => 64, + 'md5' => 64, + 'ripemd128' => 64, + 'ripemd160' => 64, + 'ripemd256' => 64, + 'ripemd320' => 64, + 'salsa10' => 64, + 'salsa20' => 64, + 'sha1' => 64, + 'sha224' => 64, + 'sha256' => 64, + 'sha384' => 128, + 'sha512' => 128, + 'snefru' => 32, + 'snefru256' => 32, + 'tiger128,3' => 64, + 'tiger160,3' => 64, + 'tiger192,3' => 64, + 'tiger128,4' => 64, + 'tiger160,4' => 64, + 'tiger192,4' => 64, + 'whirlpool' => 64 + ); + + if (isset($block_sizes[$algo]) && strlen($password) > $block_sizes[$algo]) { - $length = $hash_length; + $password = hash($algo, $password, TRUE); } $hash = ''; diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 3d35c2d..848516a 100755 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ abstract class CI_DB_driver { @@ -451,7 +451,7 @@ public function initialize() * * This is just a dummy method that all drivers will override. * - * @return mixed + * @return mixed */ public function db_connect() { @@ -481,7 +481,7 @@ public function db_pconnect() * This is just a dummy method to allow drivers without such * functionality to not declare it, while others will override it. * - * @return void + * @return void */ public function reconnect() { @@ -495,7 +495,7 @@ public function reconnect() * This is just a dummy method to allow drivers without such * functionality to not declare it, while others will override it. * - * @return bool + * @return bool */ public function db_select() { @@ -504,6 +504,18 @@ public function db_select() // -------------------------------------------------------------------- + /** + * Last error + * + * @return array + */ + public function error() + { + return array('code' => NULL, 'message' => NULL); + } + + // -------------------------------------------------------------------- + /** * Set client character set * @@ -647,7 +659,10 @@ public function query($sql, $binds = FALSE, $return_object = NULL) } // This will trigger a rollback if transactions are being used - $this->_trans_status = FALSE; + if ($this->_trans_depth !== 0) + { + $this->_trans_status = FALSE; + } // Grab the error now, as we might run some additional queries before displaying the error $error = $this->error(); @@ -661,13 +676,15 @@ public function query($sql, $binds = FALSE, $return_object = NULL) // if transactions are enabled. If we don't call this here // the error message will trigger an exit, causing the // transactions to remain in limbo. - if ($this->_trans_depth !== 0) + while ($this->_trans_depth !== 0) { - do + $trans_depth = $this->_trans_depth; + $this->trans_complete(); + if ($trans_depth === $this->_trans_depth) { - $this->trans_complete(); + log_message('error', 'Database: Failure during an automated transaction commit/rollback!'); + break; } - while ($this->_trans_depth !== 0); } // Display errors @@ -765,7 +782,10 @@ public function simple_query($sql) { if ( ! $this->conn_id) { - $this->initialize(); + if ( ! $this->initialize()) + { + return FALSE; + } } return $this->_execute($sql); @@ -788,10 +808,13 @@ public function trans_off() /** * Enable/disable Transaction Strict Mode + * * When strict mode is enabled, if you are running multiple groups of - * transactions, if one group fails all groups will be rolled back. - * If strict mode is disabled, each group is treated autonomously, meaning - * a failure of one group will not affect any others + * transactions, if one group fails all subsequent groups will be + * rolled back. + * + * If strict mode is disabled, each group is treated autonomously, + * meaning a failure of one group will not affect any others * * @param bool $mode = TRUE * @return void @@ -807,24 +830,16 @@ public function trans_strict($mode = TRUE) * Start Transaction * * @param bool $test_mode = FALSE - * @return void + * @return bool */ public function trans_start($test_mode = FALSE) { if ( ! $this->trans_enabled) { - return; - } - - // When transactions are nested we only begin/commit/rollback the outermost ones - if ($this->_trans_depth > 0) - { - $this->_trans_depth += 1; - return; + return FALSE; } - $this->trans_begin($test_mode); - $this->_trans_depth += 1; + return $this->trans_begin($test_mode); } // -------------------------------------------------------------------- @@ -841,25 +856,14 @@ public function trans_complete() return FALSE; } - // When transactions are nested we only begin/commit/rollback the outermost ones - if ($this->_trans_depth > 1) - { - $this->_trans_depth -= 1; - return TRUE; - } - else - { - $this->_trans_depth = 0; - } - // The query() function will set this flag to FALSE in the event that a query failed if ($this->_trans_status === FALSE OR $this->_trans_failure === TRUE) { $this->trans_rollback(); // If we are NOT running in strict mode, we will reset - // the _trans_status flag so that subsequent groups of transactions - // will be permitted. + // the _trans_status flag so that subsequent groups of + // transactions will be permitted. if ($this->trans_strict === FALSE) { $this->_trans_status = TRUE; @@ -869,8 +873,7 @@ public function trans_complete() return FALSE; } - $this->trans_commit(); - return TRUE; + return $this->trans_commit(); } // -------------------------------------------------------------------- @@ -887,6 +890,87 @@ public function trans_status() // -------------------------------------------------------------------- + /** + * Begin Transaction + * + * @param bool $test_mode + * @return bool + */ + public function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return FALSE; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->_trans_depth > 0) + { + $this->_trans_depth++; + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE); + + if ($this->_trans_begin()) + { + $this->_trans_depth++; + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return bool + */ + public function trans_commit() + { + if ( ! $this->trans_enabled OR $this->_trans_depth === 0) + { + return FALSE; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->_trans_depth > 1 OR $this->_trans_commit()) + { + $this->_trans_depth--; + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return bool + */ + public function trans_rollback() + { + if ( ! $this->trans_enabled OR $this->_trans_depth === 0) + { + return FALSE; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->_trans_depth > 1 OR $this->_trans_rollback()) + { + $this->_trans_depth--; + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + /** * Compile Bindings * @@ -1218,7 +1302,7 @@ public function table_exists($table_name) /** * Fetch Field Names * - * @param string the table name + * @param string $table Table name * @return array */ public function list_fields($table) @@ -1477,18 +1561,18 @@ protected function _get_operator($str) ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/') : ''; $_operators = array( - '\s*(?:<|>|!)?=\s*', // =, <=, >=, != - '\s*<>?\s*', // <, <> - '\s*>\s*', // > - '\s+IS NULL', // IS NULL - '\s+IS NOT NULL', // IS NOT NULL - '\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql) - '\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql) - '\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value - '\s+IN\s*\([^\)]+\)', // IN(list) - '\s+NOT IN\s*\([^\)]+\)', // NOT IN (list) - '\s+LIKE\s+\S+'.$_les, // LIKE 'expr'[ ESCAPE '%s'] - '\s+NOT LIKE\s+\S+'.$_les // NOT LIKE 'expr'[ ESCAPE '%s'] + '\s*(?:<|>|!)?=\s*', // =, <=, >=, != + '\s*<>?\s*', // <, <> + '\s*>\s*', // > + '\s+IS NULL', // IS NULL + '\s+IS NOT NULL', // IS NOT NULL + '\s+EXISTS\s*\(.*\)', // EXISTS(sql) + '\s+NOT EXISTS\s*\(.*\)', // NOT EXISTS(sql) + '\s+BETWEEN\s+', // BETWEEN value AND value + '\s+IN\s*\(.*\)', // IN(list) + '\s+NOT IN\s*\(.*\)', // NOT IN (list) + '\s+LIKE\s+\S.*('.$_les.')?', // LIKE 'expr'[ ESCAPE '%s'] + '\s+NOT LIKE\s+\S.*('.$_les.')?' // NOT LIKE 'expr'[ ESCAPE '%s'] ); } @@ -1709,7 +1793,7 @@ public function display_error($error = '', $swap = '', $native = FALSE) * the table prefix onto it. Some logic is necessary in order to deal with * column names that include the path. Consider a query like this: * - * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table + * SELECT hostname.database.table.column AS c FROM hostname.database.table * * Or a query with aliasing: * @@ -1751,13 +1835,13 @@ public function protect_identifiers($item, $prefix_single = FALSE, $protect_iden // // Added exception for single quotes as well, we don't want to alter // literal strings. -- Narf - if (strpos($item, '(') !== FALSE OR strpos($item, "'") !== FALSE) + if (strcspn($item, "()'") !== strlen($item)) { return $item; } // Convert tabs or multiple spaces into single spaces - $item = preg_replace('/\s+/', ' ', $item); + $item = preg_replace('/\s+/', ' ', trim($item)); // If the item has an alias declaration we remove it and set it aside. // Note: strripos() is used in order to support spaces in table names @@ -1785,12 +1869,15 @@ public function protect_identifiers($item, $prefix_single = FALSE, $protect_iden // with an alias. While we're at it, we will escape the components if (strpos($item, '.') !== FALSE) { - $parts = explode('.', $item); + $parts = explode('.', $item); // Does the first segment of the exploded item match // one of the aliases previously identified? If so, // we have nothing more to do other than escape the item - if (in_array($parts[0], $this->qb_aliased_tables)) + // + // NOTE: The ! empty() condition prevents this method + // from breaking when QB isn't enabled. + if ( ! empty($this->qb_aliased_tables) && in_array($parts[0], $this->qb_aliased_tables)) { if ($protect_identifiers === TRUE) { diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index f6ee2a6..826aa1e 100755 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ abstract class CI_DB_forge { @@ -143,7 +143,7 @@ abstract class CI_DB_forge { protected $_unsigned = TRUE; /** - * NULL value representatin in CREATE/ALTER TABLE statements + * NULL value representation in CREATE/ALTER TABLE statements * * @var string */ @@ -239,6 +239,12 @@ public function drop_database($db_name) */ public function add_key($key, $primary = FALSE) { + // DO NOT change this! This condition is only applicable + // for PRIMARY keys because you can only have one such, + // and therefore all fields you add to it will be included + // in the same, composite PRIMARY KEY. + // + // It's not the same for regular indexes. if ($primary === TRUE && is_array($key)) { foreach ($key as $one) @@ -453,12 +459,7 @@ public function drop_table($table_name, $if_exists = FALSE) return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE; } - $query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists); - if ($query === FALSE) - { - return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; - } - elseif ($query === TRUE) + if (($query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists)) === TRUE) { return TRUE; } @@ -779,10 +780,6 @@ protected function _process_fields($create_table = FALSE) case 'ENUM': case 'SET': $attributes['CONSTRAINT'] = $this->db->escape($attributes['CONSTRAINT']); - $field['length'] = is_array($attributes['CONSTRAINT']) - ? "('".implode("','", $attributes['CONSTRAINT'])."')" - : '('.$attributes['CONSTRAINT'].')'; - break; default: $field['length'] = is_array($attributes['CONSTRAINT']) ? '('.implode(',', $attributes['CONSTRAINT']).')' diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index e5ffef2..c862d93 100755 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ abstract class CI_DB_query_builder extends CI_DB_driver { @@ -531,39 +531,46 @@ public function join($table, $cond, $type = '', $escape = NULL) is_bool($escape) OR $escape = $this->_protect_identifiers; - // Split multiple conditions - if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_OFFSET_CAPTURE)) + if ( ! $this->_has_operator($cond)) { - $newcond = ''; - $m[0][] = array('', strlen($cond)); - - for ($i = 0, $c = count($m[0]), $s = 0; - $i < $c; - $s = $m[0][$i][1] + strlen($m[0][$i][0]), $i++) - { - $temp = substr($cond, $s, ($m[0][$i][1] - $s)); - - $newcond .= preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $temp, $match) - ? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]) - : $temp; - - $newcond .= $m[0][$i][0]; - } - - $cond = ' ON '.$newcond; - } - // Split apart the condition and protect the identifiers - elseif ($escape === TRUE && preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $cond, $match)) - { - $cond = ' ON '.$this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]); + $cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')'; } - elseif ( ! $this->_has_operator($cond)) + elseif ($escape === FALSE) { - $cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')'; + $cond = ' ON '.$cond; } else { - $cond = ' ON '.$cond; + // Split multiple conditions + if (preg_match_all('/\sAND\s|\sOR\s/i', $cond, $joints, PREG_OFFSET_CAPTURE)) + { + $conditions = array(); + $joints = $joints[0]; + array_unshift($joints, array('', 0)); + + for ($i = count($joints) - 1, $pos = strlen($cond); $i >= 0; $i--) + { + $joints[$i][1] += strlen($joints[$i][0]); // offset + $conditions[$i] = substr($cond, $joints[$i][1], $pos - $joints[$i][1]); + $pos = $joints[$i][1] - strlen($joints[$i][0]); + $joints[$i] = $joints[$i][0]; + } + } + else + { + $conditions = array($cond); + $joints = array(''); + } + + $cond = ' ON '; + for ($i = 0, $c = count($conditions); $i < $c; $i++) + { + $operator = $this->_get_operator($conditions[$i]); + $cond .= $joints[$i]; + $cond .= preg_match("/(\(*)?([\[\]\w\.'-]+)".preg_quote($operator)."(.*)/i", $conditions[$i], $match) + ? $match[1].$this->protect_identifiers($match[2]).$operator.$this->protect_identifiers($match[3]) + : $conditions[$i]; + } } // Do we want to escape the table name? @@ -794,13 +801,23 @@ protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = $not = ($not) ? ' NOT' : ''; - $where_in = array(); - foreach ($values as $value) + if ($escape === TRUE) { - $where_in[] = $this->escape($value); + $where_in = array(); + foreach ($values as $value) + { + $where_in[] = $this->escape($value); + } + } + else + { + $where_in = array_values($values); } - $prefix = (count($this->qb_where) === 0) ? $this->_group_get_type('') : $this->_group_get_type($type); + $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) + ? $this->_group_get_type('') + : $this->_group_get_type($type); + $where_in = array( 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')', 'escape' => $escape @@ -918,13 +935,18 @@ protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $n } is_bool($escape) OR $escape = $this->_protect_identifiers; + // lowercase $side in case somebody writes e.g. 'BEFORE' instead of 'before' (doh) + $side = strtolower($side); foreach ($field as $k => $v) { $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? $this->_group_get_type('') : $this->_group_get_type($type); - $v = $this->escape_like_str($v); + if ($escape === TRUE) + { + $v = $this->escape_like_str($v); + } if ($side === 'none') { @@ -944,7 +966,7 @@ protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $n } // some platforms require an escape sequence definition for LIKE wildcards - if ($this->_like_escape_str !== '') + if ($escape === TRUE && $this->_like_escape_str !== '') { $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr); } @@ -1123,7 +1145,7 @@ public function group_by($by, $escape = NULL) * @param string $key * @param string $value * @param bool $escape - * @return object + * @return CI_DB_query_builder */ public function having($key, $value = NULL, $escape = NULL) { @@ -1140,7 +1162,7 @@ public function having($key, $value = NULL, $escape = NULL) * @param string $key * @param string $value * @param bool $escape - * @return object + * @return CI_DB_query_builder */ public function or_having($key, $value = NULL, $escape = NULL) { @@ -1292,7 +1314,7 @@ public function set($key, $value = '', $escape = NULL) * Compiles a SELECT query string and returns the sql. * * @param string the table name to select from (optional) - * @param bool TRUE: resets QB values; FALSE: leave QB vaules alone + * @param bool TRUE: resets QB values; FALSE: leave QB values alone * @return string */ public function get_compiled_select($table = '', $reset = TRUE) @@ -1324,7 +1346,7 @@ public function get_compiled_select($table = '', $reset = TRUE) * @param string the table * @param string the limit clause * @param string the offset clause - * @return object + * @return CI_DB_result */ public function get($table = '', $limit = NULL, $offset = NULL) { @@ -1364,6 +1386,15 @@ public function count_all_results($table = '', $reset = TRUE) $this->from($table); } + // ORDER BY usage is often problematic here (most notably + // on Microsoft SQL Server) and ultimately unnecessary + // for selecting COUNT(*) ... + if ( ! empty($this->qb_orderby)) + { + $orderby = $this->qb_orderby; + $this->qb_orderby = NULL; + } + $result = ($this->qb_distinct === TRUE) ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results") : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); @@ -1372,6 +1403,11 @@ public function count_all_results($table = '', $reset = TRUE) { $this->_reset_select(); } + // If we've previously reset the qb_orderby values, get them back + elseif ( ! isset($this->qb_orderby)) + { + $this->qb_orderby = $orderby; + } if ($result->num_rows() === 0) { @@ -1393,7 +1429,7 @@ public function count_all_results($table = '', $reset = TRUE) * @param string $where * @param int $limit * @param int $offset - * @return object + * @return CI_DB_result */ public function get_where($table = '', $where = NULL, $limit = NULL, $offset = NULL) { @@ -1429,20 +1465,26 @@ public function get_where($table = '', $where = NULL, $limit = NULL, $offset = N * @param bool $escape Whether to escape values and identifiers * @return int Number of rows inserted or FALSE on failure */ - public function insert_batch($table = '', $set = NULL, $escape = NULL) + public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 100) { - if ($set !== NULL) + if ($set === NULL) { - $this->set_insert_batch($set, '', $escape); + if (empty($this->qb_set)) + { + return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; + } } - - if (count($this->qb_set) === 0) + else { - // No valid data array. Folds in cases where keys and values did not match up - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; + if (empty($set)) + { + return ($this->db_debug) ? $this->display_error('insert_batch() called with no data') : FALSE; + } + + $this->set_insert_batch($set, '', $escape); } - if ($table === '') + if (strlen($table) === 0) { if ( ! isset($this->qb_from[0])) { @@ -1454,9 +1496,9 @@ public function insert_batch($table = '', $set = NULL, $escape = NULL) // Batch this baby $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100) + for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) { - $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, 100))); + $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size))); $affected_rows += $this->affected_rows(); } @@ -1583,7 +1625,7 @@ public function get_compiled_insert($table = '', $reset = TRUE) * @param string the table to insert data into * @param array an associative array of insert values * @param bool $escape Whether to escape values and identifiers - * @return object + * @return bool TRUE on success, FALSE on failure */ public function insert($table = '', $set = NULL, $escape = NULL) { @@ -1649,7 +1691,7 @@ protected function _validate_insert($table = '') * * @param string the table to replace data into * @param array an associative array of insert values - * @return object + * @return bool TRUE on success, FALSE on failure */ public function replace($table = '', $set = NULL) { @@ -1734,7 +1776,7 @@ public function get_compiled_update($table = '', $reset = TRUE) return FALSE; } - $sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set); + $sql = $this->_update($this->qb_from[0], $this->qb_set); if ($reset === TRUE) { @@ -1755,7 +1797,7 @@ public function get_compiled_update($table = '', $reset = TRUE) * @param array $set An associative array of update values * @param mixed $where * @param int $limit - * @return object + * @return bool TRUE on success, FALSE on failure */ public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) { @@ -1782,7 +1824,7 @@ public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) $this->limit($limit); } - $sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set); + $sql = $this->_update($this->qb_from[0], $this->qb_set); $this->_reset_write(); return $this->query($sql); } @@ -1799,7 +1841,7 @@ public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) * @param string the table to update data on * @return bool */ - protected function _validate_update($table = '') + protected function _validate_update($table) { if (count($this->qb_set) === 0) { @@ -1808,7 +1850,7 @@ protected function _validate_update($table = '') if ($table !== '') { - $this->qb_from[0] = $table; + $this->qb_from = array($this->protect_identifiers($table, TRUE, NULL, FALSE)); } elseif ( ! isset($this->qb_from[0])) { @@ -1830,7 +1872,7 @@ protected function _validate_update($table = '') * @param string the where key * @return int number of rows affected or FALSE on failure */ - public function update_batch($table = '', $set = NULL, $index = NULL) + public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 100) { // Combine any cached components with the current statements $this->_merge_cache(); @@ -1840,17 +1882,24 @@ public function update_batch($table = '', $set = NULL, $index = NULL) return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE; } - if ($set !== NULL) + if ($set === NULL) { - $this->set_update_batch($set, $index); + if (empty($this->qb_set)) + { + return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; + } } - - if (count($this->qb_set) === 0) + else { - return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; + if (empty($set)) + { + return ($this->db_debug) ? $this->display_error('update_batch() called with no data') : FALSE; + } + + $this->set_update_batch($set, $index); } - if ($table === '') + if (strlen($table) === 0) { if ( ! isset($this->qb_from[0])) { @@ -1862,9 +1911,9 @@ public function update_batch($table = '', $set = NULL, $index = NULL) // Batch this baby $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100) + for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) { - $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index))); + $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index))); $affected_rows += $this->affected_rows(); $this->qb_where = array(); } @@ -1968,7 +2017,7 @@ public function set_update_batch($key, $index = '', $escape = NULL) * Compiles a delete string and runs "DELETE FROM table" * * @param string the table to empty - * @return object + * @return bool TRUE on success, FALSE on failure */ public function empty_table($table = '') { @@ -2001,7 +2050,7 @@ public function empty_table($table = '') * This function maps to "DELETE FROM table" * * @param string the table to truncate - * @return object + * @return bool TRUE on success, FALSE on failure */ public function truncate($table = '') { @@ -2090,10 +2139,13 @@ public function delete($table = '', $where = '', $limit = NULL, $reset_data = TR } elseif (is_array($table)) { + empty($where) && $reset_data = FALSE; + foreach ($table as $single_table) { $this->delete($single_table, $where, $limit, $reset_data); } + return; } else @@ -2253,7 +2305,7 @@ protected function _compile_select($select_override = FALSE) else { // Cycle through the "select" portion of the query and prep each column name. - // The reason we protect identifiers here rather then in the select() function + // The reason we protect identifiers here rather than in the select() function // is because until the user calls the from() function we don't know if there are aliases foreach ($this->qb_select as $key => $val) { @@ -2298,7 +2350,7 @@ protected function _compile_select($select_override = FALSE) * * Escapes identifiers in WHERE and HAVING statements at execution time. * - * Required so that aliases are tracked properly, regardless of wether + * Required so that aliases are tracked properly, regardless of whether * where(), or_where(), having(), or_having are called prior to from(), * join() and dbprefix is added only if needed. * @@ -2324,7 +2376,7 @@ protected function _compile_wh($qb_key) // Split multiple conditions $conditions = preg_split( - '/(\s*AND\s+|\s*OR\s+)/i', + '/((?:^|\s+)AND\s+|(?:^|\s+)OR\s+)/i', $this->{$qb_key}[$i]['condition'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php index 57356ac..7052828 100755 --- a/system/database/DB_utility.php +++ b/system/database/DB_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ abstract class CI_DB_utility { @@ -249,16 +249,17 @@ public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosur $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim; } - $out = substr(rtrim($out), 0, -strlen($delim)).$newline; + $out = substr($out, 0, -strlen($delim)).$newline; // Next blast through the result array and build out the rows while ($row = $query->unbuffered_row('array')) { + $line = array(); foreach ($row as $item) { - $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim; + $line[] = $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure; } - $out = substr(rtrim($out), 0, -strlen($delim)).$newline; + $out .= implode($delim, $line).$newline; } return $out; diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php index f80b4db..77f591c 100755 --- a/system/database/drivers/cubrid/cubrid_driver.php +++ b/system/database/drivers/cubrid/cubrid_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author Esen Sagynov - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_cubrid_driver extends CI_DB { @@ -187,25 +187,17 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if (($autocommit = cubrid_get_autocommit($this->conn_id)) === NULL) { - return TRUE; + return FALSE; } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - - if (cubrid_get_autocommit($this->conn_id)) + elseif ($autocommit === TRUE) { - cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE); + return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE); } return TRUE; @@ -218,19 +210,16 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if ( ! cubrid_commit($this->conn_id)) { - return TRUE; + return FALSE; } - cubrid_commit($this->conn_id); - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) { - cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); + return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); } return TRUE; @@ -243,16 +232,13 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if ( ! cubrid_rollback($this->conn_id)) { - return TRUE; + return FALSE; } - cubrid_rollback($this->conn_id); - if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id)) { cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE); diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php index 529c320..c1055c1 100755 --- a/system/database/drivers/ibase/ibase_driver.php +++ b/system/database/drivers/ibase/ibase_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_ibase_driver extends CI_DB { @@ -126,7 +126,7 @@ public function version() */ protected function _execute($sql) { - return ibase_query($this->conn_id, $sql); + return ibase_query(isset($this->_ibase_trans) ? $this->_ibase_trans : $this->conn_id, $sql); } // -------------------------------------------------------------------- @@ -134,24 +134,16 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if (($trans_handle = ibase_trans($this->conn_id)) === FALSE) { - return TRUE; + return FALSE; } - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - - $this->_ibase_trans = ibase_trans($this->conn_id); - + $this->_ibase_trans = $trans_handle; return TRUE; } @@ -162,15 +154,15 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans->depth > 0) + if (ibase_commit($this->_ibase_trans)) { + $this->_ibase_trans = NULL; return TRUE; } - return ibase_commit($this->_ibase_trans); + return FALSE; } // -------------------------------------------------------------------- @@ -180,15 +172,15 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if (ibase_rollback($this->_ibase_trans)) { + $this->_ibase_trans = NULL; return TRUE; } - return ibase_rollback($this->_ibase_trans); + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php index 8f15d8d..d40d67a 100755 --- a/system/database/drivers/mssql/mssql_driver.php +++ b/system/database/drivers/mssql/mssql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mssql_driver extends CI_DB { @@ -182,22 +182,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return $this->simple_query('BEGIN TRAN'); } @@ -208,14 +196,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->simple_query('COMMIT TRAN'); } @@ -226,14 +208,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->simple_query('ROLLBACK TRAN'); } @@ -291,7 +267,7 @@ protected function _db_set_charset($charset) */ protected function _version() { - return 'SELECT @@VERSION AS ver'; + return "SELECT SERVERPROPERTY('ProductVersion') AS ver"; } // -------------------------------------------------------------------- @@ -381,9 +357,19 @@ public function field_data($table) */ public function error() { - $query = $this->query('SELECT @@ERROR AS code'); - $query = $query->row(); - return array('code' => $query->code, 'message' => mssql_get_last_message()); + // We need this because the error info is discarded by the + // server the first time you request it, and query() already + // calls error() once for logging purposes when a query fails. + static $error = array('code' => 0, 'message' => NULL); + + $message = mssql_get_last_message(); + if ( ! empty($message)) + { + $error['code'] = $this->query('SELECT @@ERROR AS code')->row()->code; + $error['message'] = $message; + } + + return $error; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index df0f249..78b1d70 100755 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysql_driver extends CI_DB { @@ -84,7 +84,7 @@ class CI_DB_mysql_driver extends CI_DB { * * @var bool */ - public $stricton = FALSE; + public $stricton; // -------------------------------------------------------------------- @@ -147,9 +147,26 @@ public function db_connect($persistent = FALSE) : FALSE; } - if ($this->stricton && is_resource($this->conn_id)) + if (isset($this->stricton) && is_resource($this->conn_id)) { - $this->simple_query('SET SESSION sql_mode="STRICT_ALL_TABLES"'); + if ($this->stricton) + { + $this->simple_query('SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'); + } + else + { + $this->simple_query( + 'SET SESSION sql_mode = + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( + @@sql_mode, + "STRICT_ALL_TABLES,", ""), + ",STRICT_ALL_TABLES", ""), + "STRICT_ALL_TABLES", ""), + "STRICT_TRANS_TABLES,", ""), + ",STRICT_TRANS_TABLES", ""), + "STRICT_TRANS_TABLES", "")' + ); + } } return $this->conn_id; @@ -272,25 +289,12 @@ protected function _prep_query($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - $this->simple_query('SET AUTOCOMMIT=0'); - $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - return TRUE; + return $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK } // -------------------------------------------------------------------- @@ -300,17 +304,15 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if ($this->simple_query('COMMIT')) { + $this->simple_query('SET AUTOCOMMIT=1'); return TRUE; } - $this->simple_query('COMMIT'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + return FALSE; } // -------------------------------------------------------------------- @@ -320,17 +322,15 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if ($this->simple_query('ROLLBACK')) { + $this->simple_query('SET AUTOCOMMIT=1'); return TRUE; } - $this->simple_query('ROLLBACK'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index e953db0..06c3418 100755 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysqli_driver extends CI_DB { @@ -84,7 +84,7 @@ class CI_DB_mysqli_driver extends CI_DB { * * @var bool */ - public $stricton = FALSE; + public $stricton; // -------------------------------------------------------------------- @@ -97,12 +97,22 @@ class CI_DB_mysqli_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * MySQLi object + * + * Has to be preserved without being assigned to $conn_id. + * + * @var MySQLi + */ + protected $_mysqli; + + // -------------------------------------------------------------------- + /** * Database connection * * @param bool $persistent * @return object - * @todo SSL support */ public function db_connect($persistent = FALSE) { @@ -123,17 +133,91 @@ public function db_connect($persistent = FALSE) } $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0; - $mysqli = mysqli_init(); + $this->_mysqli = mysqli_init(); - $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); + $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); - if ($this->stricton) + if (isset($this->stricton)) { - $mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"'); + if ($this->stricton) + { + $this->_mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'); + } + else + { + $this->_mysqli->options(MYSQLI_INIT_COMMAND, + 'SET SESSION sql_mode = + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( + @@sql_mode, + "STRICT_ALL_TABLES,", ""), + ",STRICT_ALL_TABLES", ""), + "STRICT_ALL_TABLES", ""), + "STRICT_TRANS_TABLES,", ""), + ",STRICT_TRANS_TABLES", ""), + "STRICT_TRANS_TABLES", "")' + ); + } } - return $mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags) - ? $mysqli : FALSE; + if (is_array($this->encrypt)) + { + $ssl = array(); + empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key']; + empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert']; + empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca']; + empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath']; + empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher']; + + if ( ! empty($ssl)) + { + if (isset($this->encrypt['ssl_verify'])) + { + if ($this->encrypt['ssl_verify']) + { + defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT') && $this->_mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, TRUE); + } + // Apparently (when it exists), setting MYSQLI_OPT_SSL_VERIFY_SERVER_CERT + // to FALSE didn't do anything, so PHP 5.6.16 introduced yet another + // constant ... + // + // https://secure.php.net/ChangeLog-5.php#5.6.16 + // https://bugs.php.net/bug.php?id=68344 + elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) + { + $this->_mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, TRUE); + } + } + + $client_flags |= MYSQLI_CLIENT_SSL; + $this->_mysqli->ssl_set( + isset($ssl['key']) ? $ssl['key'] : NULL, + isset($ssl['cert']) ? $ssl['cert'] : NULL, + isset($ssl['ca']) ? $ssl['ca'] : NULL, + isset($ssl['capath']) ? $ssl['capath'] : NULL, + isset($ssl['cipher']) ? $ssl['cipher'] : NULL + ); + } + } + + if ($this->_mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags)) + { + // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails + if ( + ($client_flags & MYSQLI_CLIENT_SSL) + && version_compare($this->_mysqli->client_info, '5.7.3', '<=') + && empty($this->_mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value) + ) + { + $this->_mysqli->close(); + $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!'; + log_message('error', $message); + return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; + } + + return $this->_mysqli; + } + + return FALSE; } // -------------------------------------------------------------------- @@ -248,22 +332,10 @@ protected function _prep_query($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - $this->conn_id->autocommit(FALSE); return is_php('5.5') ? $this->conn_id->begin_transaction() @@ -277,14 +349,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - if ($this->conn_id->commit()) { $this->conn_id->autocommit(TRUE); @@ -301,14 +367,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - if ($this->conn_id->rollback()) { $this->conn_id->autocommit(TRUE); @@ -438,11 +498,11 @@ public function field_data($table) */ public function error() { - if ( ! empty($this->conn_id->connect_errno)) + if ( ! empty($this->_mysqli->connect_errno)) { return array( - 'code' => $this->conn_id->connect_errno, - 'message' => is_php('5.2.9') ? $this->conn_id->connect_error : mysqli_connect_error() + 'code' => $this->_mysqli->connect_errno, + 'message' => is_php('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error() ); } diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index 4010995..59f0e84 100755 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.4.1 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ /** @@ -101,6 +101,14 @@ class CI_DB_oci8_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * Reset $stmt_id flag + * + * Used by stored_procedure() to prevent _execute() from + * re-setting the statement ID. + */ + protected $_reset_stmt_id = TRUE; + /** * List of reserved identifiers * @@ -244,12 +252,16 @@ public function version() return $this->data_cache['version']; } - if ( ! $this->conn_id OR ($version = oci_server_version($this->conn_id)) === FALSE) + if ( ! $this->conn_id OR ($version_string = oci_server_version($this->conn_id)) === FALSE) { return FALSE; } + elseif (preg_match('#Release\s(\d+(?:\.\d+)+)#', $version_string, $match)) + { + return $this->data_cache['version'] = $match[1]; + } - return $this->data_cache['version'] = $version; + return FALSE; } // -------------------------------------------------------------------- @@ -265,26 +277,13 @@ protected function _execute($sql) /* Oracle must parse the query before it is run. All of the actions with * the query are based on the statement id returned by oci_parse(). */ - $this->stmt_id = FALSE; - $this->_set_stmt_id($sql); - oci_set_prefetch($this->stmt_id, 1000); - return oci_execute($this->stmt_id, $this->commit_mode); - } - - // -------------------------------------------------------------------- - - /** - * Generate a statement ID - * - * @param string $sql an SQL query - * @return void - */ - protected function _set_stmt_id($sql) - { - if ( ! is_resource($this->stmt_id)) + if ($this->_reset_stmt_id === TRUE) { $this->stmt_id = oci_parse($this->conn_id, $sql); } + + oci_set_prefetch($this->stmt_id, 1000); + return oci_execute($this->stmt_id, $this->commit_mode); } // -------------------------------------------------------------------- @@ -311,22 +310,22 @@ public function get_cursor() * * params array keys * - * KEY OPTIONAL NOTES - * name no the name of the parameter should be in : format - * value no the value of the parameter. If this is an OUT or IN OUT parameter, - * this should be a reference to a variable - * type yes the type of the parameter - * length yes the max size of the parameter + * KEY OPTIONAL NOTES + * name no the name of the parameter should be in : format + * value no the value of the parameter. If this is an OUT or IN OUT parameter, + * this should be a reference to a variable + * type yes the type of the parameter + * length yes the max size of the parameter */ - public function stored_procedure($package, $procedure, $params) + public function stored_procedure($package, $procedure, array $params) { - if ($package === '' OR $procedure === '' OR ! is_array($params)) + if ($package === '' OR $procedure === '') { log_message('error', 'Invalid query: '.$package.'.'.$procedure); return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE; } - // build the query string + // Build the query string $sql = 'BEGIN '.$package.'.'.$procedure.'('; $have_cursor = FALSE; @@ -341,10 +340,12 @@ public function stored_procedure($package, $procedure, $params) } $sql = trim($sql, ',').'); END;'; - $this->stmt_id = FALSE; - $this->_set_stmt_id($sql); + $this->_reset_stmt_id = FALSE; + $this->stmt_id = oci_parse($this->conn_id, $sql); $this->_bind_params($params); - return $this->query($sql, FALSE, $have_cursor); + $result = $this->query($sql, FALSE, $have_cursor); + $this->_reset_stmt_id = TRUE; + return $result; } // -------------------------------------------------------------------- @@ -381,27 +382,10 @@ protected function _bind_params($params) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - if ( ! $this->trans_enabled) - { - return TRUE; - } - - // When transactions are nested we only begin/commit/rollback the outermost ones - if ($this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - $this->commit_mode = is_php('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; return TRUE; } @@ -413,20 +397,10 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - if ( ! $this->trans_enabled) - { - return TRUE; - } - - // When transactions are nested we only begin/commit/rollback the outermost ones - if ($this->_trans_depth > 0) - { - return TRUE; - } - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; + return oci_commit($this->conn_id); } @@ -437,14 +411,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - $this->commit_mode = OCI_COMMIT_ON_SUCCESS; return oci_rollback($this->conn_id); } @@ -573,7 +541,7 @@ public function field_data($table) { $default = ''; } - $retval[$i]->default = $query[$i]->COLUMN_DEFAULT; + $retval[$i]->default = $default; } return $retval; @@ -686,6 +654,14 @@ protected function _delete($table) */ protected function _limit($sql) { + if (version_compare($this->version(), '12.1', '>=')) + { + // OFFSET-FETCH can be used only with the ORDER BY clause + empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; + + return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; + } + $this->limit_used = TRUE; return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1) : ''); diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php index f5d77a1..19b7b74 100755 --- a/system/database/drivers/odbc/odbc_driver.php +++ b/system/database/drivers/odbc/odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_odbc_driver extends CI_DB { @@ -143,22 +143,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return odbc_autocommit($this->conn_id, FALSE); } @@ -169,17 +157,15 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if (odbc_commit($this->conn_id)) { + odbc_autocommit($this->conn_id, TRUE); return TRUE; } - $ret = odbc_commit($this->conn_id); - odbc_autocommit($this->conn_id, TRUE); - return $ret; + return FALSE; } // -------------------------------------------------------------------- @@ -189,17 +175,33 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + if (odbc_rollback($this->conn_id)) { + odbc_autocommit($this->conn_id, TRUE); return TRUE; } - $ret = odbc_rollback($this->conn_id); - odbc_autocommit($this->conn_id, TRUE); - return $ret; + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Determines if a query is a "write" type. + * + * @param string An SQL query string + * @return bool + */ + public function is_write_type($sql) + { + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + { + return FALSE; + } + + return parent::is_write_type($sql); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index cc77e95..c6f84e0 100755 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_driver extends CI_DB { @@ -186,22 +186,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return $this->conn_id->beginTransaction(); } @@ -212,14 +200,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->conn_id->commit(); } @@ -230,14 +212,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->conn_id->rollBack(); } diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php index 67dc5f5..70f2bfd 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { @@ -73,7 +73,7 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { * * @var bool */ - public $stricton = FALSE; + public $stricton; // -------------------------------------------------------------------- @@ -119,7 +119,6 @@ public function __construct($params) * * @param bool $persistent * @return object - * @todo SSL support */ public function db_connect($persistent = FALSE) { @@ -134,15 +133,34 @@ public function db_connect($persistent = FALSE) .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); } - if ($this->stricton) + if (isset($this->stricton)) { - if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) + if ($this->stricton) { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode="STRICT_ALL_TABLES"'; + $sql = 'CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'; } else { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = "STRICT_ALL_TABLES"'; + $sql = 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( + @@sql_mode, + "STRICT_ALL_TABLES,", ""), + ",STRICT_ALL_TABLES", ""), + "STRICT_ALL_TABLES", ""), + "STRICT_TRANS_TABLES,", ""), + ",STRICT_TRANS_TABLES", ""), + "STRICT_TRANS_TABLES", "")'; + } + + if ( ! empty($sql)) + { + if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) + { + $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = '.$sql; + } + else + { + $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = '.$sql; + } } } @@ -151,7 +169,59 @@ public function db_connect($persistent = FALSE) $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; } - return parent::db_connect($persistent); + // SSL support was added to PDO_MYSQL in PHP 5.3.7 + if (is_array($this->encrypt) && is_php('5.3.7')) + { + $ssl = array(); + empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; + empty($this->encrypt['ssl_cert']) OR $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert']; + empty($this->encrypt['ssl_ca']) OR $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca']; + empty($this->encrypt['ssl_capath']) OR $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath']; + empty($this->encrypt['ssl_cipher']) OR $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher']; + + // DO NOT use array_merge() here! + // It re-indexes numeric keys and the PDO_MYSQL_ATTR_SSL_* constants are integers. + empty($ssl) OR $this->options += $ssl; + } + + // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails + if ( + ($pdo = parent::db_connect($persistent)) !== FALSE + && ! empty($ssl) + && version_compare($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), '5.7.3', '<=') + && empty($pdo->query("SHOW STATUS LIKE 'ssl_cipher'")->fetchObject()->Value) + ) + { + $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!'; + log_message('error', $message); + return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE; + } + + return $pdo; + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @param string $database + * @return bool + */ + public function db_select($database = '') + { + if ($database === '') + { + $database = $this->database; + } + + if (FALSE !== $this->simple_query('USE '.$this->escape_identifiers($database))) + { + $this->database = $database; + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php index d17e311..dd1d31c 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver { @@ -129,6 +129,29 @@ public function __construct($params) // -------------------------------------------------------------------- + /** + * Database version number + * + * @return string + */ + public function version() + { + if (isset($this->data_cache['version'])) + { + return $this->data_cache['version']; + } + + $version_string = parent::version(); + if (preg_match('#Release\s(?\d+(?:\.\d+)+)#', $version_string, $match)) + { + return $this->data_cache['version'] = $match[1]; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + /** * Show table query * @@ -288,6 +311,14 @@ protected function _delete($table) */ protected function _limit($sql) { + if (version_compare($this->version(), '12.1', '>=')) + { + // OFFSET-FETCH can be used only with the ORDER BY clause + empty($this->qb_orderby) && $sql .= ' ORDER BY 1'; + + return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY'; + } + return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($this->qb_offset + $this->qb_limit + 1).')' .($this->qb_offset ? ' WHERE rnum >= '.($this->qb_offset + 1): ''); } diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php index 51c70b6..3334488 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver { @@ -160,6 +160,24 @@ public function __construct($params) // -------------------------------------------------------------------- + /** + * Determines if a query is a "write" type. + * + * @param string An SQL query string + * @return bool + */ + public function is_write_type($sql) + { + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + { + return FALSE; + } + + return parent::is_write_type($sql); + } + + // -------------------------------------------------------------------- + /** * Show table query * diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index 2dd41ca..ee8f763 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { @@ -154,7 +154,12 @@ public function insert_id($name = NULL) */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + { + return FALSE; + } + + return parent::is_write_type($sql); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php index f07f49f..6269013 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver { @@ -121,17 +121,31 @@ protected function _list_tables($prefix_limit = FALSE) // -------------------------------------------------------------------- /** - * Show column query + * Fetch Field Names * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string + * @param string $table Table name + * @return array */ - protected function _list_columns($table = '') + public function list_fields($table) { - // Not supported - return FALSE; + // Is there a cached result? + if (isset($this->data_cache['field_names'][$table])) + { + return $this->data_cache['field_names'][$table]; + } + + if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) + { + return FALSE; + } + + $this->data_cache['field_names'][$table] = array(); + foreach ($result->result_array() as $row) + { + $this->data_cache['field_names'][$table][] = $row['name']; + } + + return $this->data_cache['field_names'][$table]; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php index 28faadd..f6f9bb4 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_sqlite_forge extends CI_DB_pdo_forge { @@ -89,6 +89,7 @@ public function __construct(&$db) if (version_compare($this->db->version(), '3.3', '<')) { $this->_create_table_if = FALSE; + $this->_drop_table_if = FALSE; } } diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index 7be07c3..58d4451 100755 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_postgre_driver extends CI_DB { @@ -247,22 +247,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return (bool) pg_query($this->conn_id, 'BEGIN'); } @@ -273,14 +261,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return (bool) pg_query($this->conn_id, 'COMMIT'); } @@ -291,14 +273,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return (bool) pg_query($this->conn_id, 'ROLLBACK'); } @@ -312,7 +288,12 @@ public function trans_rollback() */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + { + return FALSE; + } + + return parent::is_write_type($sql); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php index 9d9caa0..16b8c29 100755 --- a/system/database/drivers/sqlite/sqlite_driver.php +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite_driver extends CI_DB { @@ -122,24 +122,11 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - - $this->simple_query('BEGIN TRANSACTION'); - return TRUE; + return $this->simple_query('BEGIN TRANSACTION'); } // -------------------------------------------------------------------- @@ -149,16 +136,9 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - $this->simple_query('COMMIT'); - return TRUE; + return $this->simple_query('COMMIT'); } // -------------------------------------------------------------------- @@ -168,16 +148,9 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - $this->simple_query('ROLLBACK'); - return TRUE; + return $this->simple_query('ROLLBACK'); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php index fdbe949..9743499 100755 --- a/system/database/drivers/sqlite3/sqlite3_driver.php +++ b/system/database/drivers/sqlite3/sqlite3_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite3_driver extends CI_DB { @@ -134,22 +134,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return $this->conn_id->exec('BEGIN TRANSACTION'); } @@ -160,14 +148,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->conn_id->exec('END TRANSACTION'); } @@ -178,14 +160,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return $this->conn_id->exec('ROLLBACK'); } @@ -247,17 +223,31 @@ protected function _list_tables($prefix_limit = FALSE) // -------------------------------------------------------------------- /** - * Show column query + * Fetch Field Names * - * Generates a platform-specific query string so that the column names can be fetched - * - * @param string $table - * @return string + * @param string $table Table name + * @return array */ - protected function _list_columns($table = '') + public function list_fields($table) { - // Not supported - return FALSE; + // Is there a cached result? + if (isset($this->data_cache['field_names'][$table])) + { + return $this->data_cache['field_names'][$table]; + } + + if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) + { + return FALSE; + } + + $this->data_cache['field_names'][$table] = array(); + foreach ($result->result_array() as $row) + { + $this->data_cache['field_names'][$table][] = $row['name']; + } + + return $this->data_cache['field_names'][$table]; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php index 69f65b6..43cbe33 100755 --- a/system/database/drivers/sqlite3/sqlite3_forge.php +++ b/system/database/drivers/sqlite3/sqlite3_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite3_forge extends CI_DB_forge { @@ -74,7 +74,8 @@ public function __construct(&$db) if (version_compare($this->db->version(), '3.3', '<')) { - $this->create_table_if = FALSE; + $this->_create_table_if = FALSE; + $this->_drop_table_if = FALSE; } } diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php index 16f77fa..0cd9ce1 100755 --- a/system/database/drivers/sqlsrv/sqlsrv_driver.php +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.3 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlsrv_driver extends CI_DB { @@ -141,13 +141,14 @@ public function db_connect($pooling = FALSE) unset($connection['UID'], $connection['PWD']); } - $this->conn_id = sqlsrv_connect($this->hostname, $connection); - - // Determine how identifiers are escaped - $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); - $query = $query->row_array(); - $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; - $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); + if (FALSE !== ($this->conn_id = sqlsrv_connect($this->hostname, $connection))) + { + // Determine how identifiers are escaped + $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi'); + $query = $query->row_array(); + $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi']; + $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']'); + } return $this->conn_id; } @@ -196,22 +197,10 @@ protected function _execute($sql) /** * Begin Transaction * - * @param bool $test_mode * @return bool */ - public function trans_begin($test_mode = FALSE) + protected function _trans_begin() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - - // Reset the transaction failure flag. - // If the $test_mode flag is set to TRUE transactions will be rolled back - // even if the queries produce a successful result. - $this->_trans_failure = ($test_mode === TRUE); - return sqlsrv_begin_transaction($this->conn_id); } @@ -222,14 +211,8 @@ public function trans_begin($test_mode = FALSE) * * @return bool */ - public function trans_commit() + protected function _trans_commit() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return sqlsrv_commit($this->conn_id); } @@ -240,14 +223,8 @@ public function trans_commit() * * @return bool */ - public function trans_rollback() + protected function _trans_rollback() { - // When transactions are nested we only begin/commit/rollback the outermost ones - if ( ! $this->trans_enabled OR $this->_trans_depth > 0) - { - return TRUE; - } - return sqlsrv_rollback($this->conn_id); } @@ -274,9 +251,7 @@ public function affected_rows() */ public function insert_id() { - $query = $this->query('SELECT @@IDENTITY AS insert_id'); - $query = $query->row(); - return $query->insert_id; + return $this->query('SELECT SCOPE_IDENTITY() AS insert_id')->row()->insert_id; } // -------------------------------------------------------------------- diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php index e07b52b..3fdccf9 100755 --- a/system/helpers/array_helper.php +++ b/system/helpers/array_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/array_helper.html + * @link https://codeigniter.com/user_guide/helpers/array_helper.html */ // ------------------------------------------------------------------------ @@ -62,7 +62,7 @@ * @param mixed * @return mixed depends on what the array contains */ - function element($item, $array, $default = NULL) + function element($item, array $array, $default = NULL) { return array_key_exists($item, $array) ? $array[$item] : $default; } @@ -99,7 +99,7 @@ function random_element($array) * @param mixed * @return mixed depends on what the array contains */ - function elements($items, $array, $default = NULL) + function elements($items, array $array, $default = NULL) { $return = array(); diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 201987a..3c1e006 100755 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/captcha_helper.html + * @link https://codeigniter.com/user_guide/helpers/captcha_helper.html */ // ------------------------------------------------------------------------ @@ -125,9 +125,96 @@ function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = if (empty($word)) { $word = ''; - for ($i = 0, $mt_rand_max = strlen($pool) - 1; $i < $word_length; $i++) + $pool_length = strlen($pool); + $rand_max = $pool_length - 1; + + // PHP7 or a suitable polyfill + if (function_exists('random_int')) + { + try + { + for ($i = 0; $i < $word_length; $i++) + { + $word .= $pool[random_int(0, $rand_max)]; + } + } + catch (Exception $e) + { + // This means fallback to the next possible + // alternative to random_int() + $word = ''; + } + } + } + + if (empty($word)) + { + // Nobody will have a larger character pool than + // 256 characters, but let's handle it just in case ... + // + // No, I do not care that the fallback to mt_rand() can + // handle it; if you trigger this, you're very obviously + // trying to break it. -- Narf + if ($pool_length > 256) + { + return FALSE; + } + + // We'll try using the operating system's PRNG first, + // which we can access through CI_Security::get_random_bytes() + $security = get_instance()->security; + + // To avoid numerous get_random_bytes() calls, we'll + // just try fetching as much bytes as we need at once. + if (($bytes = $security->get_random_bytes($pool_length)) !== FALSE) + { + $byte_index = $word_index = 0; + while ($word_index < $word_length) + { + // Do we have more random data to use? + // It could be exhausted by previous iterations + // ignoring bytes higher than $rand_max. + if ($byte_index === $pool_length) + { + // No failures should be possible if the + // first get_random_bytes() call didn't + // return FALSE, but still ... + for ($i = 0; $i < 5; $i++) + { + if (($bytes = $security->get_random_bytes($pool_length)) === FALSE) + { + continue; + } + + $byte_index = 0; + break; + } + + if ($bytes === FALSE) + { + // Sadly, this means fallback to mt_rand() + $word = ''; + break; + } + } + + list(, $rand_index) = unpack('C', $bytes[$byte_index++]); + if ($rand_index > $rand_max) + { + continue; + } + + $word .= $pool[$rand_index]; + $word_index++; + } + } + } + + if (empty($word)) + { + for ($i = 0; $i < $word_length; $i++) { - $word .= $pool[mt_rand(0, $mt_rand_max)]; + $word .= $pool[mt_rand(0, $rand_max)]; } } elseif ( ! is_string($word)) diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index 95c94a1..a6463df 100755 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/download_helper.html + * @link https://codeigniter.com/user_guide/helpers/download_helper.html */ // ------------------------------------------------------------------------ @@ -69,16 +69,14 @@ function force_download($filename = '', $data = '', $set_mime = FALSE) } elseif ($data === NULL) { - if (@is_file($filename) && ($filesize = @filesize($filename)) !== FALSE) - { - $filepath = $filename; - $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename)); - $filename = end($filename); - } - else + if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE) { return; } + + $filepath = $filename; + $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename)); + $filename = end($filename); } else { @@ -140,14 +138,7 @@ function force_download($filename = '', $data = '', $set_mime = FALSE) header('Expires: 0'); header('Content-Transfer-Encoding: binary'); header('Content-Length: '.$filesize); - - // Internet Explorer-specific headers - if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) - { - header('Cache-Control: no-cache, no-store, must-revalidate'); - } - - header('Pragma: no-cache'); + header('Cache-Control: private, no-transform, no-store, must-revalidate'); // If we have raw data - just dump it if ($data !== NULL) diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 8b15e60..0d8d1d0 100755 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/file_helper.html + * @link https://codeigniter.com/user_guide/helpers/file_helper.html */ // ------------------------------------------------------------------------ @@ -54,7 +54,7 @@ /** * Read File * - * Opens the file specfied in the path and returns it as a string. + * Opens the file specified in the path and returns it as a string. * * @todo Remove in version 3.1+. * @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents(). @@ -343,7 +343,7 @@ function get_mime_by_extension($filename) if ( ! is_array($mimes)) { - $mimes =& get_mimes(); + $mimes = get_mimes(); if (empty($mimes)) { diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 53ee8eb..3e10395 100755 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/form_helper.html + * @link https://codeigniter.com/user_guide/helpers/form_helper.html */ // ------------------------------------------------------------------------ @@ -197,7 +197,7 @@ function form_hidden($name, $value = '', $recursing = FALSE) * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_input($data = '', $value = '', $extra = '') @@ -208,7 +208,7 @@ function form_input($data = '', $value = '', $extra = '') 'value' => $value ); - return '\n"; + return '\n"; } } @@ -223,7 +223,7 @@ function form_input($data = '', $value = '', $extra = '') * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_password($data = '', $value = '', $extra = '') @@ -245,7 +245,7 @@ function form_password($data = '', $value = '', $extra = '') * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_upload($data = '', $value = '', $extra = '') @@ -253,7 +253,8 @@ function form_upload($data = '', $value = '', $extra = '') $defaults = array('type' => 'file', 'name' => ''); is_array($data) OR $data = array('name' => $data); $data['type'] = 'file'; - return '\n"; + + return '\n"; } } @@ -266,7 +267,7 @@ function form_upload($data = '', $value = '', $extra = '') * * @param mixed $data * @param string $value - * @param string $extra + * @param mixed $extra * @return string */ function form_textarea($data = '', $value = '', $extra = '') @@ -287,7 +288,9 @@ function form_textarea($data = '', $value = '', $extra = '') unset($data['value']); // textareas don't use the value attribute } - return '\n"; + return '\n"; } } @@ -301,12 +304,13 @@ function form_textarea($data = '', $value = '', $extra = '') * @param string * @param array * @param mixed - * @param string + * @param mixed * @return string */ function form_multiselect($name = '', $options = array(), $selected = array(), $extra = '') { - if ( ! strpos($extra, 'multiple')) + $extra = _attributes_to_string($extra); + if (stripos($extra, 'multiple') === FALSE) { $extra .= ' multiple="multiple"'; } @@ -372,7 +376,7 @@ function form_dropdown($data = '', $options = array(), $selected = array(), $ext $extra = _attributes_to_string($extra); - $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; + $multiple = (count($selected) > 1 && stripos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; $form = '\n"; + return '\n"; } } @@ -464,13 +468,14 @@ function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '') * @param mixed * @param string * @param bool - * @param string + * @param mixed * @return string */ function form_radio($data = '', $value = '', $checked = FALSE, $extra = '') { is_array($data) OR $data = array('name' => $data); $data['type'] = 'radio'; + return form_checkbox($data, $value, $checked, $extra); } } @@ -484,7 +489,7 @@ function form_radio($data = '', $value = '', $checked = FALSE, $extra = '') * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_submit($data = '', $value = '', $extra = '') @@ -495,7 +500,7 @@ function form_submit($data = '', $value = '', $extra = '') 'value' => $value ); - return '\n"; + return '\n"; } } @@ -508,7 +513,7 @@ function form_submit($data = '', $value = '', $extra = '') * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_reset($data = '', $value = '', $extra = '') @@ -519,7 +524,7 @@ function form_reset($data = '', $value = '', $extra = '') 'value' => $value ); - return '\n"; + return '\n"; } } @@ -532,7 +537,7 @@ function form_reset($data = '', $value = '', $extra = '') * * @param mixed * @param string - * @param string + * @param mixed * @return string */ function form_button($data = '', $content = '', $extra = '') @@ -548,7 +553,9 @@ function form_button($data = '', $content = '', $extra = '') unset($data['content']); // content is not an attribute } - return '\n"; + return '\n"; } } @@ -762,12 +769,11 @@ function set_checkbox($field, $value = '', $default = FALSE) { return $CI->form_validation->set_checkbox($field, $value, $default); } - elseif (($input = $CI->input->post($field, FALSE)) === NULL) - { - return ($default === TRUE) ? ' checked="checked"' : ''; - } + // Form inputs are always strings ... $value = (string) $value; + $input = $CI->input->post($field, FALSE); + if (is_array($input)) { // Note: in_array('', array(0)) returns TRUE, do not use it @@ -782,7 +788,13 @@ function set_checkbox($field, $value = '', $default = FALSE) return ''; } - return ($input === $value) ? ' checked="checked"' : ''; + // Unchecked checkbox and radio inputs are not even submitted by browsers ... + if ($CI->input->method() === 'post') + { + return ($input === $value) ? ' checked="checked"' : ''; + } + + return ($default === TRUE) ? ' checked="checked"' : ''; } } @@ -809,12 +821,32 @@ function set_radio($field, $value = '', $default = FALSE) { return $CI->form_validation->set_radio($field, $value, $default); } - elseif (($input = $CI->input->post($field, FALSE)) === NULL) + + // Form inputs are always strings ... + $value = (string) $value; + $input = $CI->input->post($field, FALSE); + + if (is_array($input)) + { + // Note: in_array('', array(0)) returns TRUE, do not use it + foreach ($input as &$v) + { + if ($value === $v) + { + return ' checked="checked"'; + } + } + + return ''; + } + + // Unchecked checkbox and radio inputs are not even submitted by browsers ... + if ($CI->input->method() === 'post') { - return ($default === TRUE) ? ' checked="checked"' : ''; + return ($input === $value) ? ' checked="checked"' : ''; } - return ($input === (string) $value) ? ' checked="checked"' : ''; + return ($default === TRUE) ? ' checked="checked"' : ''; } } diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index d8ed45d..c064d8d 100755 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/inflector_helper.html + * @link https://codeigniter.com/user_guide/helpers/inflector_helper.html */ // -------------------------------------------------------------------- @@ -133,6 +133,7 @@ function plural($str) } $plural_rules = array( + '/(quiz)$/' => '\1zes', // quizzes '/^(ox)$/' => '\1\2en', // ox '/([m|l])ouse$/' => '\1ice', // mouse, louse '/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index @@ -218,7 +219,7 @@ function underscore($str) */ function humanize($str, $separator = '_') { - return ucwords(preg_replace('/['.$separator.']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str)))); + return ucwords(preg_replace('/['.preg_quote($separator).']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str)))); } } diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index c23ec64..838ece9 100755 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/path_helper.html + * @link https://codeigniter.com/user_guide/helpers/path_helper.html */ // ------------------------------------------------------------------------ @@ -61,7 +61,7 @@ function set_realpath($path, $check_existance = FALSE) { // Security check to make sure the path is NOT a URL. No remote file inclusion! - if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i', $path)) + if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path ) { show_error('The path you submitted must be a local server path, not a URL'); } diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php index 5860e15..db531fa 100755 --- a/system/helpers/string_helper.php +++ b/system/helpers/string_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/string_helper.html + * @link https://codeigniter.com/user_guide/helpers/string_helper.html */ // ------------------------------------------------------------------------ @@ -253,7 +253,7 @@ function random_string($type = 'alnum', $len = 8) */ function increment_string($str, $separator = '_', $first = 1) { - preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match); + preg_match('/(.+)'.preg_quote($separator, '/').'([0-9]+)$/', $str, $match); return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first; } } @@ -270,7 +270,7 @@ function increment_string($str, $separator = '_', $first = 1) * @param string (as many parameters as needed) * @return string */ - function alternator($args) + function alternator() { static $i; @@ -279,6 +279,7 @@ function alternator($args) $i = 0; return ''; } + $args = func_get_args(); return $args[($i++ % count($args))]; } diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index f2290c8..4f9210f 100755 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/text_helper.html + * @link https://codeigniter.com/user_guide/helpers/text_helper.html */ // ------------------------------------------------------------------------ @@ -254,7 +254,7 @@ function entities_to_ascii($str, $all = TRUE) * word you've submitted. * * @param string the text string - * @param string the array of censoered words + * @param string the array of censored words * @param string the optional replacement value * @return string */ @@ -275,13 +275,28 @@ function word_censor($str, $censored, $replacement = '') foreach ($censored as $badword) { + $badword = str_replace('\*', '\w*?', preg_quote($badword, '/')); if ($replacement !== '') { - $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/i", "\\1{$replacement}\\3", $str); + $str = preg_replace( + "/({$delim})(".$badword.")({$delim})/i", + "\\1{$replacement}\\3", + $str + ); } - else + elseif (preg_match_all("/{$delim}(".$badword."){$delim}/i", $str, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE)) { - $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $str); + $matches = $matches[1]; + for ($i = count($matches) - 1; $i >= 0; $i--) + { + $length = strlen($matches[$i][0]); + $str = substr_replace( + $str, + str_repeat('#', $length), + $matches[$i][1], + $length + ); + } } } diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index bf623b0..fd7b5e1 100755 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/url_helper.html + * @link https://codeigniter.com/user_guide/helpers/url_helper.html */ // ------------------------------------------------------------------------ @@ -161,7 +161,7 @@ function anchor($uri = '', $title = '', $attributes = '') $site_url = is_array($uri) ? site_url($uri) - : preg_match('#^(\w+:)?//#i', $uri) ? $uri : site_url($uri); + : (preg_match('#^(\w+:)?//#i', $uri) ? $uri : site_url($uri)); if ($title === '') { @@ -474,7 +474,7 @@ function prep_url($str = '') * @param string $str Input string * @param string $separator Word separator * (usually '-' or '_') - * @param bool $lowercase Wether to transform the output string to lowercase + * @param bool $lowercase Whether to transform the output string to lowercase * @return string */ function url_title($str, $separator = '-', $lowercase = FALSE) @@ -492,7 +492,7 @@ function url_title($str, $separator = '-', $lowercase = FALSE) $trans = array( '&.+?;' => '', - '[^a-z0-9 _-]' => '', + '[^\w\d _-]' => '', '\s+' => $separator, '('.$q_separator.')+' => $separator ); @@ -500,7 +500,7 @@ function url_title($str, $separator = '-', $lowercase = FALSE) $str = strip_tags($str); foreach ($trans as $key => $val) { - $str = preg_replace('#'.$key.'#i', $val, $str); + $str = preg_replace('#'.$key.'#i'.(UTF8_ENABLED ? 'u' : ''), $val, $str); } if ($lowercase === TRUE) diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index 40ac701..349af15 100755 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.0 * @filesource */ @@ -100,28 +100,10 @@ class CI_Cache extends CI_Driver_Library { */ public function __construct($config = array()) { - $default_config = array( - 'adapter', - 'memcached' - ); - - foreach ($default_config as $key) - { - if (isset($config[$key])) - { - $param = '_'.$key; - - $this->{$param} = $config[$key]; - } - } - + isset($config['adapter']) && $this->_adapter = $config['adapter']; + isset($config['backup']) && $this->_backup_driver = $config['backup']; isset($config['key_prefix']) && $this->key_prefix = $config['key_prefix']; - if (isset($config['backup']) && in_array($config['backup'], $this->valid_drivers)) - { - $this->_backup_driver = $config['backup']; - } - // If the specified adapter isn't available, check the backup. if ( ! $this->is_supported($this->_adapter)) { @@ -196,7 +178,7 @@ public function delete($id) */ public function increment($id, $offset = 1) { - return $this->{$this->_adapter}->increment($id, $offset); + return $this->{$this->_adapter}->increment($this->key_prefix.$id, $offset); } // ------------------------------------------------------------------------ @@ -210,7 +192,7 @@ public function increment($id, $offset = 1) */ public function decrement($id, $offset = 1) { - return $this->{$this->_adapter}->decrement($id, $offset); + return $this->{$this->_adapter}->decrement($this->key_prefix.$id, $offset); } // ------------------------------------------------------------------------ @@ -261,14 +243,13 @@ public function get_metadata($id) */ public function is_supported($driver) { - static $support = array(); + static $support; - if ( ! isset($support[$driver])) + if ( ! isset($support, $support[$driver])) { $support[$driver] = $this->{$driver}->is_supported(); } return $support[$driver]; } - } diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index e0d2ffb..07ea8f4 100755 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.0 * @filesource */ @@ -48,6 +48,24 @@ */ class CI_Cache_apc extends CI_Driver { + /** + * Class constructor + * + * Only present so that an error message is logged + * if APC is not available. + * + * @return void + */ + public function __construct() + { + if ( ! $this->is_supported()) + { + log_message('error', 'Cache: Failed to initialize APC; extension not loaded/enabled?'); + } + } + + // ------------------------------------------------------------------------ + /** * Get * @@ -198,13 +216,6 @@ public function get_metadata($id) */ public function is_supported() { - if ( ! extension_loaded('apc') OR ! ini_get('apc.enabled')) - { - log_message('debug', 'The APC PHP extension must be loaded to use APC Cache.'); - return FALSE; - } - - return TRUE; + return (extension_loaded('apc') && ini_get('apc.enabled')); } - } diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php index 68bc1ec..e1ce16a 100755 --- a/system/libraries/Cache/drivers/Cache_file.php +++ b/system/libraries/Cache/drivers/Cache_file.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0 * @filesource */ @@ -267,7 +267,7 @@ public function is_supported() */ protected function _get($id) { - if ( ! file_exists($this->_cache_path.$id)) + if ( ! is_file($this->_cache_path.$id)) { return FALSE; } diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index b90b561..6dee1e8 100755 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0 * @filesource */ @@ -60,7 +60,7 @@ class CI_Cache_memcached extends CI_Driver { * * @var array */ - protected $_memcache_conf = array( + protected $_config = array( 'default' => array( 'host' => '127.0.0.1', 'port' => 11211, @@ -68,6 +68,69 @@ class CI_Cache_memcached extends CI_Driver { ) ); + // ------------------------------------------------------------------------ + + /** + * Class constructor + * + * Setup Memcache(d) + * + * @return void + */ + public function __construct() + { + // Try to load memcached server info from the config file. + $CI =& get_instance(); + $defaults = $this->_config['default']; + + if ($CI->config->load('memcached', TRUE, TRUE)) + { + $this->_config = $CI->config->config['memcached']; + } + + if (class_exists('Memcached', FALSE)) + { + $this->_memcached = new Memcached(); + } + elseif (class_exists('Memcache', FALSE)) + { + $this->_memcached = new Memcache(); + } + else + { + log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?'); + return; + } + + foreach ($this->_config as $cache_server) + { + isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; + isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; + isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; + + if ($this->_memcached instanceof Memcache) + { + // Third parameter is persistance and defaults to TRUE. + $this->_memcached->addServer( + $cache_server['hostname'], + $cache_server['port'], + TRUE, + $cache_server['weight'] + ); + } + elseif ($this->_memcached instanceof Memcached) + { + $this->_memcached->addServer( + $cache_server['hostname'], + $cache_server['port'], + $cache_server['weight'] + ); + } + } + } + + // ------------------------------------------------------------------------ + /** * Fetch from cache * @@ -99,11 +162,11 @@ public function save($id, $data, $ttl = 60, $raw = FALSE) $data = array($data, time(), $ttl); } - if (get_class($this->_memcached) === 'Memcached') + if ($this->_memcached instanceof Memcached) { return $this->_memcached->set($id, $data, $ttl); } - elseif (get_class($this->_memcached) === 'Memcache') + elseif ($this->_memcached instanceof Memcache) { return $this->_memcached->set($id, $data, 0, $ttl); } @@ -116,7 +179,7 @@ public function save($id, $data, $ttl = 60, $raw = FALSE) /** * Delete from Cache * - * @param mixed key to be deleted. + * @param mixed $id key to be deleted. * @return bool true on success, false on failure */ public function delete($id) @@ -181,7 +244,7 @@ public function cache_info() /** * Get Cache Metadata * - * @param mixed key to get cache metadata on + * @param mixed $id key to get cache metadata on * @return mixed FALSE on failure, array on success. */ public function get_metadata($id) @@ -205,91 +268,36 @@ public function get_metadata($id) // ------------------------------------------------------------------------ /** - * Setup memcached. + * Is supported + * + * Returns FALSE if memcached is not supported on the system. + * If it is, we setup the memcached object & return TRUE * * @return bool */ - protected function _setup_memcached() + public function is_supported() { - // Try to load memcached server info from the config file. - $CI =& get_instance(); - $defaults = $this->_memcache_conf['default']; - - if ($CI->config->load('memcached', TRUE, TRUE)) - { - if (is_array($CI->config->config['memcached'])) - { - $this->_memcache_conf = array(); - - foreach ($CI->config->config['memcached'] as $name => $conf) - { - $this->_memcache_conf[$name] = $conf; - } - } - } - - if (class_exists('Memcached', FALSE)) - { - $this->_memcached = new Memcached(); - } - elseif (class_exists('Memcache', FALSE)) - { - $this->_memcached = new Memcache(); - } - else - { - log_message('error', 'Failed to create object for Memcached Cache; extension not loaded?'); - return FALSE; - } - - foreach ($this->_memcache_conf as $cache_server) - { - isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; - isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; - isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; - - if (get_class($this->_memcached) === 'Memcache') - { - // Third parameter is persistance and defaults to TRUE. - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - TRUE, - $cache_server['weight'] - ); - } - else - { - $this->_memcached->addServer( - $cache_server['hostname'], - $cache_server['port'], - $cache_server['weight'] - ); - } - } - - return TRUE; + return (extension_loaded('memcached') OR extension_loaded('memcache')); } // ------------------------------------------------------------------------ /** - * Is supported + * Class destructor * - * Returns FALSE if memcached is not supported on the system. - * If it is, we setup the memcached object & return TRUE + * Closes the connection to Memcache(d) if present. * - * @return bool + * @return void */ - public function is_supported() + public function __destruct() { - if ( ! extension_loaded('memcached') && ! extension_loaded('memcache')) + if ($this->_memcached instanceof Memcache) { - log_message('debug', 'The Memcached Extension must be loaded to use Memcached Cache.'); - return FALSE; + $this->_memcached->close(); + } + elseif ($this->_memcached instanceof Memcached) + { + $this->_memcached->quit(); } - - return $this->_setup_memcached(); } - } diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index a35fbf6..d4d95eb 100755 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -78,10 +78,75 @@ class CI_Cache_redis extends CI_Driver // ------------------------------------------------------------------------ + /** + * Class constructor + * + * Setup Redis + * + * Loads Redis config file if present. Will halt execution + * if a Redis connection can't be established. + * + * @return void + * @see Redis::connect() + */ + public function __construct() + { + if ( ! $this->is_supported()) + { + log_message('error', 'Cache: Failed to create Redis object; extension not loaded?'); + return; + } + + $CI =& get_instance(); + + if ($CI->config->load('redis', TRUE, TRUE)) + { + $config = array_merge(self::$_default_config, $CI->config->item('redis')); + } + else + { + $config = self::$_default_config; + } + + $this->_redis = new Redis(); + + try + { + if ($config['socket_type'] === 'unix') + { + $success = $this->_redis->connect($config['socket']); + } + else // tcp socket + { + $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); + } + + if ( ! $success) + { + log_message('error', 'Cache: Redis connection failed. Check your configuration.'); + } + + if (isset($config['password']) && ! $this->_redis->auth($config['password'])) + { + log_message('error', 'Cache: Redis authentication failed.'); + } + } + catch (RedisException $e) + { + log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')'); + } + + // Initialize the index of serialized values. + $serialized = $this->_redis->sMembers('_ci_redis_serialized'); + empty($serialized) OR $this->_serialized = array_flip($serialized); + } + + // ------------------------------------------------------------------------ + /** * Get cache * - * @param string Cache ID + * @param string $key Cache ID * @return mixed */ public function get($key) @@ -125,9 +190,7 @@ public function save($id, $data, $ttl = 60, $raw = FALSE) $this->_redis->sRemove('_ci_redis_serialized', $id); } - return ($ttl) - ? $this->_redis->setex($id, $ttl, $data) - : $this->_redis->set($id, $data); + return $this->_redis->set($id, $data, $ttl); } // ------------------------------------------------------------------------ @@ -135,7 +198,7 @@ public function save($id, $data, $ttl = 60, $raw = FALSE) /** * Delete from cache * - * @param string Cache key + * @param string $key Cache key * @return bool */ public function delete($key) @@ -200,9 +263,9 @@ public function clean() /** * Get cache driver info * - * @param string Not supported in Redis. - * Only included in order to offer a - * consistent cache API. + * @param string $type Not supported in Redis. + * Only included in order to offer a + * consistent cache API. * @return array * @see Redis::info() */ @@ -216,14 +279,14 @@ public function cache_info($type = NULL) /** * Get cache metadata * - * @param string Cache key + * @param string $key Cache key * @return array */ public function get_metadata($key) { $value = $this->get($key); - if ($value) + if ($value !== FALSE) { return array( 'expire' => time() + $this->_redis->ttl($key), @@ -243,76 +306,7 @@ public function get_metadata($key) */ public function is_supported() { - if ( ! extension_loaded('redis')) - { - log_message('debug', 'The Redis extension must be loaded to use Redis cache.'); - return FALSE; - } - - return $this->_setup_redis(); - } - - // ------------------------------------------------------------------------ - - /** - * Setup Redis config and connection - * - * Loads Redis config file if present. Will halt execution - * if a Redis connection can't be established. - * - * @return bool - * @see Redis::connect() - */ - protected function _setup_redis() - { - $config = array(); - $CI =& get_instance(); - - if ($CI->config->load('redis', TRUE, TRUE)) - { - $config += $CI->config->item('redis'); - } - - $config = array_merge(self::$_default_config, $config); - - $this->_redis = new Redis(); - - try - { - if ($config['socket_type'] === 'unix') - { - $success = $this->_redis->connect($config['socket']); - } - else // tcp socket - { - $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); - } - - if ( ! $success) - { - log_message('debug', 'Cache: Redis connection refused. Check the config.'); - return FALSE; - } - } - catch (RedisException $e) - { - log_message('debug', 'Cache: Redis connection refused ('.$e->getMessage().')'); - return FALSE; - } - - if (isset($config['password'])) - { - $this->_redis->auth($config['password']); - } - - // Initialize the index of serialized values. - $serialized = $this->_redis->sMembers('_ci_redis_serialized'); - if ( ! empty($serialized)) - { - $this->_serialized = array_flip($serialized); - } - - return TRUE; + return extension_loaded('redis'); } // ------------------------------------------------------------------------ @@ -331,5 +325,4 @@ public function __destruct() $this->_redis->close(); } } - } diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index 9cc6ff0..d6a0d4f 100755 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -51,6 +51,24 @@ */ class CI_Cache_wincache extends CI_Driver { + /** + * Class constructor + * + * Only present so that an error message is logged + * if APC is not available. + * + * @return void + */ + public function __construct() + { + if ( ! $this->is_supported()) + { + log_message('error', 'Cache: Failed to initialize Wincache; extension not loaded/enabled?'); + } + } + + // ------------------------------------------------------------------------ + /** * Get * @@ -194,13 +212,6 @@ public function get_metadata($id) */ public function is_supported() { - if ( ! extension_loaded('wincache') OR ! ini_get('wincache.ucenabled')) - { - log_message('debug', 'The Wincache PHP extension must be loaded to use Wincache Cache.'); - return FALSE; - } - - return TRUE; + return (extension_loaded('wincache') && ini_get('wincache.ucenabled')); } - } diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 66b5803..ed6f737 100755 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/email.html + * @link https://codeigniter.com/user_guide/libraries/email.html */ class CI_Email { @@ -574,14 +574,18 @@ public function reply_to($replyto, $name = '') $this->validate_email($this->_str_to_array($replyto)); } - if ($name === '') - { - $name = $replyto; - } - - if (strpos($name, '"') !== 0) + if ($name !== '') { - $name = '"'.$name.'"'; + // only use Q encoding if there are characters that would require it + if ( ! preg_match('/[\200-\377]/', $name)) + { + // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes + $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; + } + else + { + $name = $this->_prep_q_encoding($name); + } } $this->set_header('Reply-To', $name.' <'.$replyto.'>'); @@ -804,11 +808,12 @@ public function attachment_cid($filename) * * @param string * @param string - * @return void + * @return CI_Email */ public function set_header($header, $value) { $this->_headers[$header] = str_replace(array("\n", "\r"), '', $value); + return $this; } // -------------------------------------------------------------------- @@ -1468,6 +1473,20 @@ protected function _build_message() */ protected function _prep_quoted_printable($str) { + // ASCII code numbers for "safe" characters that can always be + // used literally, without encoding, as described in RFC 2049. + // http://www.ietf.org/rfc/rfc2049.txt + static $ascii_safe_chars = array( + // ' ( ) + , - . / : = ? + 39, 40, 41, 43, 44, 45, 46, 47, 58, 61, 63, + // numbers + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + // upper-case letters + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + // lower-case letters + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 + ); + // We are intentionally wrapping so mail servers will encode characters // properly and MUAs will behave, so {unwrap} must go! $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str); @@ -1515,14 +1534,25 @@ protected function _prep_quoted_printable($str) $ascii = ord($char); // Convert spaces and tabs but only if it's the end of the line - if ($i === ($length - 1) && ($ascii === 32 OR $ascii === 9)) + if ($ascii === 32 OR $ascii === 9) { - $char = $escape.sprintf('%02s', dechex($ascii)); + if ($i === ($length - 1)) + { + $char = $escape.sprintf('%02s', dechex($ascii)); + } } - elseif ($ascii === 61) // encode = signs + // DO NOT move this below the $ascii_safe_chars line! + // + // = (equals) signs are allowed by RFC2049, but must be encoded + // as they are the encoding delimiter! + elseif ($ascii === 61) { $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D } + elseif ( ! in_array($ascii, $ascii_safe_chars, TRUE)) + { + $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); + } // If we're at the character limit, add the line to the output, // reset our temp variable, and keep on chuggin' @@ -1562,11 +1592,10 @@ protected function _prep_q_encoding($str) if ($this->charset === 'UTF-8') { - if (MB_ENABLED === TRUE) - { - return mb_encode_mimeheader($str, $this->charset, 'Q', $this->crlf); - } - elseif (ICONV_ENABLED === TRUE) + // Note: We used to have mb_encode_mimeheader() as the first choice + // here, but it turned out to be buggy and unreliable. DO NOT + // re-add it! -- Narf + if (ICONV_ENABLED === TRUE) { $output = @iconv_mime_encode('', $str, array( @@ -1589,6 +1618,10 @@ protected function _prep_q_encoding($str) $chars = iconv_strlen($str, 'UTF-8'); } + elseif (MB_ENABLED === TRUE) + { + $chars = mb_strlen($str, 'UTF-8'); + } } // We might already have this set for UTF-8 @@ -1825,8 +1858,7 @@ protected function _send_with_sendmail() // is popen() enabled? if ( ! function_usable('popen') OR FALSE === ($fp = @popen( - $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']) - .' -t -r '.$this->clean_email($this->_headers['Return-Path']) + $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t' , 'w')) ) // server probably has popen disabled, so nothing we can do to get a verbose error. { @@ -1868,20 +1900,26 @@ protected function _send_with_smtp() return FALSE; } - $this->_send_command('from', $this->clean_email($this->_headers['From'])); + if ( ! $this->_send_command('from', $this->clean_email($this->_headers['From']))) + { + return FALSE; + } foreach ($this->_recipients as $val) { - $this->_send_command('to', $val); + if ( ! $this->_send_command('to', $val)) + { + return FALSE; + } } if (count($this->_cc_array) > 0) { foreach ($this->_cc_array as $val) { - if ($val !== '') + if ($val !== '' && ! $this->_send_command('to', $val)) { - $this->_send_command('to', $val); + return FALSE; } } } @@ -1890,14 +1928,17 @@ protected function _send_with_smtp() { foreach ($this->_bcc_array as $val) { - if ($val !== '') + if ($val !== '' && ! $this->_send_command('to', $val)) { - $this->_send_command('to', $val); + return FALSE; } } } - $this->_send_command('data'); + if ( ! $this->_send_command('data')) + { + return FALSE; + } // perform dot transformation on any lines that begin with a dot $this->_send_data($this->_header_str.preg_replace('/^\./m', '..$1', $this->_finalbody)); @@ -2126,12 +2167,32 @@ protected function _smtp_authenticate() protected function _send_data($data) { $data .= $this->newline; - for ($written = 0, $length = strlen($data); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = strlen($data); $written < $length; $written += $result) { if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) { break; } + // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951 + elseif ($result === 0) + { + if ($timestamp === 0) + { + $timestamp = time(); + } + elseif ($timestamp < (time() - $this->smtp_timeout)) + { + $result = FALSE; + break; + } + + usleep(250000); + continue; + } + else + { + $timestamp = 0; + } } if ($result === FALSE) diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php index e3e6813..92c38a0 100755 --- a/system/libraries/Encryption.php +++ b/system/libraries/Encryption.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/encryption.html + * @link https://codeigniter.com/user_guide/libraries/encryption.html */ class CI_Encryption { @@ -121,7 +121,7 @@ class CI_Encryption { ); /** - * List of supported HMAC algorightms + * List of supported HMAC algorithms * * name => digest size pairs * @@ -337,6 +337,11 @@ protected function _openssl_initialize($params) */ public function create_key($length) { + if (function_exists('random_bytes')) + { + return random_bytes((int) $length); + } + return ($this->_driver === 'mcrypt') ? mcrypt_create_iv($length, MCRYPT_DEV_URANDOM) : openssl_random_pseudo_bytes($length); diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 05de596..e4a5189 100755 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Validation * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/form_validation.html + * @link https://codeigniter.com/user_guide/libraries/form_validation.html */ class CI_Form_validation { @@ -198,22 +198,20 @@ public function set_rules($field, $label = '', $rules = array(), $errors = array return $this; } - // No fields? Nothing to do... - if ( ! is_string($field) OR $field === '') + // No fields or no rules? Nothing to do... + if ( ! is_string($field) OR $field === '' OR empty($rules)) { return $this; } elseif ( ! is_array($rules)) { // BC: Convert pipe-separated rules string to an array - if (is_string($rules)) - { - $rules = explode('|', $rules); - } - else + if ( ! is_string($rules)) { return $this; } + + $rules = preg_split('/\|(?![^\[]*\])/', $rules); } // If the field label wasn't passed we use the field name @@ -417,12 +415,9 @@ public function error_string($prefix = '', $suffix = '') */ public function run($group = '') { - // Do we even have any data to process? Mm? - $validation_array = empty($this->validation_data) ? $_POST : $this->validation_data; - if (count($validation_array) === 0) - { - return FALSE; - } + $validation_array = empty($this->validation_data) + ? $_POST + : $this->validation_data; // Does the _field_data array containing the validation rules exist? // If not, we look to see if they were assigned via a config file @@ -455,7 +450,7 @@ public function run($group = '') $this->CI->lang->load('form_validation'); // Cycle through the rules for each field and match the corresponding $validation_data item - foreach ($this->_field_data as $field => $row) + foreach ($this->_field_data as $field => &$row) { // Fetch the data from the validation_data array item and cache it in the _field_data array. // Depending on whether the field name is an array or a string will determine where we get it from. @@ -463,7 +458,7 @@ public function run($group = '') { $this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']); } - elseif (isset($validation_array[$field]) && $validation_array[$field] !== '') + elseif (isset($validation_array[$field])) { $this->_field_data[$field]['postdata'] = $validation_array[$field]; } @@ -472,7 +467,7 @@ public function run($group = '') // Execute validation rules // Note: A second foreach (for now) is required in order to avoid false-positives // for rules like 'matches', which correlate to other validation fields. - foreach ($this->_field_data as $field => $row) + foreach ($this->_field_data as $field => &$row) { // Don't try to validate if we have no rules set if (empty($row['rules'])) @@ -480,7 +475,7 @@ public function run($group = '') continue; } - $this->_execute($row, $row['rules'], $this->_field_data[$field]['postdata']); + $this->_execute($row, $row['rules'], $row['postdata']); } // Did we end up with any errors? @@ -491,7 +486,7 @@ public function run($group = '') } // Now we need to re-set the POST data with the new, processed data - $this->_reset_post_array(); + empty($this->validation_data) && $this->_reset_post_array(); return ($total_errors === 0); } @@ -532,10 +527,7 @@ protected function _reset_post_array() { if ($row['is_array'] === FALSE) { - if (isset($_POST[$row['field']])) - { - $_POST[$row['field']] = $row['postdata']; - } + isset($_POST[$field]) && $_POST[$field] = $row['postdata']; } else { @@ -555,20 +547,7 @@ protected function _reset_post_array() } } - if (is_array($row['postdata'])) - { - $array = array(); - foreach ($row['postdata'] as $k => $v) - { - $array[$k] = $v; - } - - $post_ref = $array; - } - else - { - $post_ref = $row['postdata']; - } + $post_ref = $row['postdata']; } } } @@ -588,7 +567,10 @@ protected function _reset_post_array() protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) { // If the $_POST data is an array we will run a recursive call - if (is_array($postdata)) + // + // Note: We MUST check if the array is empty or not! + // Otherwise empty arrays will always pass validation. + if (is_array($postdata) && ! empty($postdata)) { foreach ($postdata as $key => $val) { @@ -620,6 +602,12 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) $rules = array(1 => $rule); break; } + elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1])) + { + $callback = TRUE; + $rules = array(array($rule[0], $rule[1])); + break; + } } if ( ! $callback) @@ -636,21 +624,7 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) // Set the message type $type = in_array('required', $rules) ? 'required' : 'isset'; - // Check if a custom message is defined - if (isset($this->_field_data[$row['field']]['errors'][$type])) - { - $line = $this->_field_data[$row['field']]['errors'][$type]; - } - elseif (isset($this->_error_messages[$type])) - { - $line = $this->_error_messages[$type]; - } - elseif (FALSE === ($line = $this->CI->lang->line('form_validation_'.$type)) - // DEPRECATED support for non-prefixed keys - && FALSE === ($line = $this->CI->lang->line($type, FALSE))) - { - $line = 'The field was not set'; - } + $line = $this->_get_error_message($type, $row['field']); // Build the error message $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label'])); @@ -817,26 +791,11 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) // Callable rules might not have named error messages if ( ! is_string($rule)) { - return; - } - - // Check if a custom message is defined - if (isset($this->_field_data[$row['field']]['errors'][$rule])) - { - $line = $this->_field_data[$row['field']]['errors'][$rule]; - } - elseif ( ! isset($this->_error_messages[$rule])) - { - if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule)) - // DEPRECATED support for non-prefixed keys - && FALSE === ($line = $this->CI->lang->line($rule, FALSE))) - { - $line = $this->CI->lang->line('form_validation_error_message_not_set').'('.$rule.')'; - } + $line = $this->CI->lang->line('form_validation_error_message_not_set').'(Anonymous function)'; } else { - $line = $this->_error_messages[$rule]; + $line = $this->_get_error_message($rule, $row['field']); } // Is the parameter we are inserting into the error message the name @@ -864,6 +823,40 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) // -------------------------------------------------------------------- + /** + * Get the error message for the rule + * + * @param string $rule The rule name + * @param string $field The field name + * @return string + */ + protected function _get_error_message($rule, $field) + { + // check if a custom message is defined through validation config row. + if (isset($this->_field_data[$field]['errors'][$rule])) + { + return $this->_field_data[$field]['errors'][$rule]; + } + // check if a custom message has been set using the set_message() function + elseif (isset($this->_error_messages[$rule])) + { + return $this->_error_messages[$rule]; + } + elseif (FALSE !== ($line = $this->CI->lang->line('form_validation_'.$rule))) + { + return $line; + } + // DEPRECATED support for non-prefixed keys, lang file again + elseif (FALSE !== ($line = $this->CI->lang->line($rule, FALSE))) + { + return $line; + } + + return $this->CI->lang->line('form_validation_error_message_not_set').'('.$rule.')'; + } + + // -------------------------------------------------------------------- + /** * Translate a field name * @@ -872,17 +865,11 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) */ protected function _translate_fieldname($fieldname) { - // Do we need to translate the field name? - // We look for the prefix lang: to determine this - if (sscanf($fieldname, 'lang:%s', $line) === 1) + // Do we need to translate the field name? We look for the prefix 'lang:' to determine this + // If we find one, but there's no translation for the string - just return it + if (sscanf($fieldname, 'lang:%s', $line) === 1 && FALSE === ($fieldname = $this->CI->lang->line($line, FALSE))) { - // Were we able to translate the field name? If not we use $line - if (FALSE === ($fieldname = $this->CI->lang->line('form_validation_'.$line)) - // DEPRECATED support for non-prefixed keys - && FALSE === ($fieldname = $this->CI->lang->line($line, FALSE))) - { - return $line; - } + return $line; } return $fieldname; @@ -1220,6 +1207,14 @@ public function valid_url($str) $str = $matches[2]; } + // PHP 7 accepts IPv6 addresses within square brackets as hostnames, + // but it appears that the PR that came in with https://bugs.php.net/bug.php?id=68039 + // was never merged into a PHP 5 branch ... https://3v4l.org/8PsSN + if (preg_match('/^\[([^\]]+)\]/', $str, $matches) && ! is_php('7') && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE) + { + $str = 'ipv6.host'.substr($str, strlen($matches[1]) + 2); + } + $str = 'http://'.$str; // There's a bug affecting PHP 5.2.13, 5.3.2 that considers the @@ -1504,10 +1499,11 @@ public function valid_base64($str) * This function allows HTML to be safely shown in a form. * Special characters are converted. * - * @param string - * @return string + * @deprecated 3.0.6 Not used anywhere within the framework and pretty much useless + * @param mixed $data Input data + * @return mixed */ - public function prep_for_form($data = '') + public function prep_for_form($data) { if ($this->_safe_form_data === FALSE OR empty($data)) { @@ -1589,7 +1585,6 @@ public function encode_php_tags($str) public function reset_validation() { $this->_field_data = array(); - $this->_config_rules = array(); $this->_error_array = array(); $this->_error_messages = array(); $this->error_string = ''; diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index af45bb5..88f2658 100755 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/ftp.html + * @link https://codeigniter.com/user_guide/libraries/ftp.html */ class CI_FTP { @@ -466,7 +466,7 @@ public function delete_file($filepath) /** * Delete a folder and recursively delete everything (including sub-folders) - * containted within it. + * contained within it. * * @param string $filepath * @return bool @@ -490,7 +490,7 @@ public function delete_dir($filepath) // so we'll recursively call delete_dir() if ( ! preg_match('#/\.\.?$#', $list[$i]) && ! @ftp_delete($this->conn_id, $list[$i])) { - $this->delete_dir($list[$i]); + $this->delete_dir($filepath.$list[$i]); } } } diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index e056654..f594b71 100755 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Image_lib * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/image_lib.html + * @link https://codeigniter.com/user_guide/libraries/image_lib.html */ class CI_Image_lib { @@ -779,7 +779,7 @@ public function image_process_gd($action = 'resize') $this->y_axis = 0; } - // Create the image handle + // Create the image handle if ( ! ($src_img = $this->image_create_gd())) { return FALSE; @@ -845,7 +845,7 @@ public function image_process_gd($action = 'resize') */ public function image_process_imagemagick($action = 'resize') { - // Do we have a vaild library path? + // Do we have a vaild library path? if ($this->library_path === '') { $this->set_error('imglib_libpath_invalid'); @@ -1010,7 +1010,7 @@ public function image_rotate_gd() // going to have to figure out how to determine the color // of the alpha channel in a future release. - $white = imagecolorallocate($src_img, 255, 255, 255); + $white = imagecolorallocate($src_img, 255, 255, 255); // Rotate it! $dst_img = imagerotate($src_img, $this->rotation_angle, $white); @@ -1055,8 +1055,11 @@ public function image_mirror_gd() if ($this->rotation_angle === 'hor') { - for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1) + for ($i = 0; $i < $height; $i++) { + $left = 0; + $right = $width - 1; + while ($left < $right) { $cl = imagecolorat($src_img, $left, $i); @@ -1072,18 +1075,21 @@ public function image_mirror_gd() } else { - for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1) + for ($i = 0; $i < $width; $i++) { - while ($top < $bot) + $top = 0; + $bottom = $height - 1; + + while ($top < $bottom) { $ct = imagecolorat($src_img, $i, $top); - $cb = imagecolorat($src_img, $i, $bot); + $cb = imagecolorat($src_img, $i, $bottom); imagesetpixel($src_img, $i, $top, $cb); - imagesetpixel($src_img, $i, $bot, $ct); + imagesetpixel($src_img, $i, $bottom, $ct); $top++; - $bot--; + $bottom--; } } } @@ -1189,7 +1195,7 @@ public function overlay_watermark() $x_axis += $this->orig_width - $wm_width; } - // Build the finalized image + // Build the finalized image if ($wm_img_type === 3 && function_exists('imagealphablending')) { @imagealphablending($src_img, TRUE); @@ -1327,7 +1333,7 @@ public function text_watermark() { $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2); } - + // Set horizontal alignment if ($this->wm_hor_alignment === 'R') { @@ -1337,13 +1343,13 @@ public function text_watermark() { $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2); } - + if ($this->wm_use_drop_shadow) { // Offset from text $x_shad = $x_axis + $this->wm_shadow_distance; $y_shad = $y_axis + $this->wm_shadow_distance; - + /* Set RGB values for shadow * * First character is #, so we don't really need it. @@ -1352,7 +1358,7 @@ public function text_watermark() */ $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2); $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2])); - + // Add the shadow to the source image if ($this->wm_use_truetype) { @@ -1363,7 +1369,7 @@ public function text_watermark() imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color); } } - + /* Set RGB values for text * * First character is #, so we don't really need it. @@ -1382,7 +1388,7 @@ public function text_watermark() { imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color); } - + // We can preserve transparency for PNG images if ($this->image_type === 3) { @@ -1431,7 +1437,7 @@ public function image_create_gd($path = '', $image_type = '') switch ($image_type) { - case 1 : + case 1: if ( ! function_exists('imagecreatefromgif')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); @@ -1439,7 +1445,7 @@ public function image_create_gd($path = '', $image_type = '') } return imagecreatefromgif($path); - case 2 : + case 2: if ( ! function_exists('imagecreatefromjpeg')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); @@ -1447,7 +1453,7 @@ public function image_create_gd($path = '', $image_type = '') } return imagecreatefromjpeg($path); - case 3 : + case 3: if ( ! function_exists('imagecreatefrompng')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php index ae36a3b..316c94a 100755 --- a/system/libraries/Migration.php +++ b/system/libraries/Migration.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -96,9 +96,9 @@ class CI_Migration { /** * Migration basename regex * - * @var bool + * @var string */ - protected $_migration_regex = NULL; + protected $_migration_regex; /** * Error message @@ -191,7 +191,7 @@ public function __construct($config = array()) * choice * * @param string $target_version Target schema version - * @return mixed TRUE if already latest, FALSE if failed, string if upgraded + * @return mixed TRUE if no migrations are found, current version string on success, FALSE on failure */ public function version($target_version) { @@ -217,31 +217,66 @@ public function version($target_version) if ($target_version > $current_version) { - // Moving Up $method = 'up'; } - else + elseif ($target_version < $current_version) { - // Moving Down, apply in reverse order $method = 'down'; + // We need this so that migrations are applied in reverse order krsort($migrations); } - - if (empty($migrations)) + else { + // Well, there's nothing to migrate then ... return TRUE; } - $previous = FALSE; - - // Validate all available migrations, and run the ones within our target range + // Validate all available migrations within our target range. + // + // Unfortunately, we'll have to use another loop to run them + // in order to avoid leaving the procedure in a broken state. + // + // See https://github.com/bcit-ci/CodeIgniter/issues/4539 + $pending = array(); foreach ($migrations as $number => $file) { + // Ignore versions out of our range. + // + // Because we've previously sorted the $migrations array depending on the direction, + // we can safely break the loop once we reach $target_version ... + if ($method === 'up') + { + if ($number <= $current_version) + { + continue; + } + elseif ($number > $target_version) + { + break; + } + } + else + { + if ($number > $current_version) + { + continue; + } + elseif ($number <= $target_version) + { + break; + } + } + // Check for sequence gaps - if ($this->_migration_type === 'sequential' && $previous !== FALSE && abs($number - $previous) > 1) + if ($this->_migration_type === 'sequential') { - $this->_error_string = sprintf($this->lang->line('migration_sequence_gap'), $number); - return FALSE; + if (isset($previous) && abs($number - $previous) > 1) + { + $this->_error_string = sprintf($this->lang->line('migration_sequence_gap'), $number); + return FALSE; + } + + $previous = $number; } include_once($file); @@ -253,27 +288,27 @@ public function version($target_version) $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class); return FALSE; } + // method_exists() returns true for non-public methods, + // while is_callable() can't be used without instantiating. + // Only get_class_methods() satisfies both conditions. + elseif ( ! in_array($method, array_map('strtolower', get_class_methods($class)))) + { + $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); + return FALSE; + } - $previous = $number; + $pending[$number] = array($class, $method); + } - // Run migrations that are inside the target range - if ( - ($method === 'up' && $number > $current_version && $number <= $target_version) OR - ($method === 'down' && $number <= $current_version && $number > $target_version) - ) - { - $instance = new $class(); - if ( ! is_callable(array($instance, $method))) - { - $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); - return FALSE; - } + // Now just run the necessary migrations + foreach ($pending as $number => $migration) + { + log_message('debug', 'Migrating '.$method.' from version '.$current_version.' to version '.$number); - log_message('debug', 'Migrating '.$method.' from version '.$current_version.' to version '.$number); - call_user_func(array($instance, $method)); - $current_version = $number; - $this->_update_version($current_version); - } + $migration[0] = new $migration[0]; + call_user_func($migration); + $current_version = $number; + $this->_update_version($current_version); } // This is necessary when moving down, since the the last migration applied @@ -285,7 +320,6 @@ public function version($target_version) } log_message('debug', 'Finished migrating to '.$current_version); - return $current_version; } @@ -294,7 +328,7 @@ public function version($target_version) /** * Sets the schema to the latest migration * - * @return mixed TRUE if already latest, FALSE if failed, string if upgraded + * @return mixed Current version string on success, FALSE on failure */ public function latest() { @@ -318,7 +352,7 @@ public function latest() /** * Sets the schema to the migration version set in config * - * @return mixed TRUE if already current, FALSE if failed, string if upgraded + * @return mixed TRUE if no migrations are found, current version string on success, FALSE on failure */ public function current() { diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index d63f61d..44f848f 100755 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Pagination * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/pagination.html + * @link https://codeigniter.com/user_guide/libraries/pagination.html */ class CI_Pagination { @@ -353,7 +353,8 @@ public function __construct($params = array()) */ public function initialize(array $params = array()) { - if (isset($params['attributes']) && is_array($params['attributes'])) + isset($params['attributes']) OR $params['attributes'] = array(); + if (is_array($params['attributes'])) { $this->_parse_attributes($params['attributes']); unset($params['attributes']); @@ -496,7 +497,7 @@ public function create_links() { $this->cur_page = $this->CI->input->get($this->query_string_segment); } - else + elseif (empty($this->cur_page)) { // Default to the last segment number if one hasn't been defined. if ($this->uri_segment === 0) @@ -512,6 +513,10 @@ public function create_links() $this->cur_page = str_replace(array($this->prefix, $this->suffix), '', $this->cur_page); } } + else + { + $this->cur_page = (string) $this->cur_page; + } // If something isn't quite right, back to the default base page. if ( ! ctype_digit($this->cur_page) OR ($this->use_page_numbers && (int) $this->cur_page === 0)) @@ -570,7 +575,7 @@ public function create_links() { $i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page; - $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i); + $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, ($this->cur_page - 1)); if ($i === $base_page) { @@ -591,11 +596,11 @@ public function create_links() if ($this->display_pages !== FALSE) { // Write the digit links - for ($loop = $start -1; $loop <= $end; $loop++) + for ($loop = $start - 1; $loop <= $end; $loop++) { $i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page; - $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i); + $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $loop); if ($i >= $base_page) { @@ -613,7 +618,7 @@ public function create_links() else { $append = $this->prefix.$i.$this->suffix; - $output .= $this->num_tag_open.'_attr_rel('start').'>' + $output .= $this->num_tag_open.'' .$loop.''.$this->num_tag_close; } } @@ -625,7 +630,7 @@ public function create_links() { $i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page; - $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i); + $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $this->cur_page + 1); $output .= $this->next_tag_open.'_attr_rel('next').'>'.$this->next_link.''.$this->next_tag_close; @@ -636,7 +641,7 @@ public function create_links() { $i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page; - $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i); + $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $num_pages); $output .= $this->last_tag_open.'' .$this->last_link.''.$this->last_tag_close; @@ -644,7 +649,7 @@ public function create_links() // Kill double slashes. Note: Sometimes we can end up with a double slash // in the penultimate link so we'll kill all double slashes. - $output = preg_replace('#([^:])//+#', '\\1/', $output); + $output = preg_replace('#([^:"])//+#', '\\1/', $output); // Add the wrapper HTML if exists return $this->full_tag_open.$output.$this->full_tag_close; diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index f35d23f..cf455d3 100755 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -50,7 +50,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/general/profiling.html + * @link https://codeigniter.com/user_guide/general/profiling.html */ class CI_Profiler { @@ -100,12 +100,6 @@ public function __construct($config = array()) $this->CI =& get_instance(); $this->CI->load->language('profiler'); - if (isset($config['query_toggle_count'])) - { - $this->_query_toggle_count = (int) $config['query_toggle_count']; - unset($config['query_toggle_count']); - } - // default all sections to display foreach ($this->_available_sections as $section) { @@ -320,12 +314,14 @@ protected function _compile_get() foreach ($_GET as $key => $val) { - is_int($key) OR $key = "'".$key."'"; + is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; + $val = (is_array($val) OR is_object($val)) + ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
 
 				$output .= '$_GET['
 					.$key.']   '
-					.((is_array($val) OR is_object($val)) ? '
'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'
' : htmlspecialchars(stripslashes($val))) - ."\n"; + .$val."\n"; } $output .= "\n"; @@ -358,36 +354,26 @@ protected function _compile_post() foreach ($_POST as $key => $val) { - is_int($key) OR $key = "'".$key."'"; + is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; + $val = (is_array($val) OR is_object($val)) + ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
 
 				$output .= '$_POST['
-					.$key.']   ';
-
-				if (is_array($val) OR is_object($val))
-				{
-					$output .= '
'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'
'; - } - else - { - $output .= htmlspecialchars(stripslashes($val)); - } - - $output .= "\n"; + .$key.']   ' + .$val."\n"; } foreach ($_FILES as $key => $val) { - is_int($key) OR $key = "'".$key."'"; + is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'"; + $val = (is_array($val) OR is_object($val)) + ? '
'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
+					: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
 
 				$output .= '$_FILES['
-					.$key.']   ';
-
-				if (is_array($val) OR is_object($val))
-				{
-					$output .= '
'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'
'; - } - - $output .= "\n"; + .$key.']   ' + .$val."\n"; } $output .= "\n"; @@ -471,7 +457,7 @@ protected function _compile_http_headers() foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR', 'HTTP_DNT') as $header) { - $val = isset($_SERVER[$header]) ? $_SERVER[$header] : ''; + $val = isset($_SERVER[$header]) ? htmlspecialchars($_SERVER[$header], ENT_QUOTES, config_item('charset')) : ''; $output .= '' .$header.'  '.$val."\n"; } diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 0549fef..c9d2e8a 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session { @@ -231,7 +231,7 @@ interface_exists('SessionHandlerInterface', FALSE) OR require_once(BASEPATH.'lib } } - if ( ! class_exists($prefix.$class) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php')) + if ( ! class_exists($prefix.$class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php')) { require_once($file_path); if (class_exists($prefix.$class, FALSE)) @@ -583,6 +583,24 @@ public function __get($key) // ------------------------------------------------------------------------ + /** + * __isset() + * + * @param string $key 'session_id' or a session data key + * @return bool + */ + public function __isset($key) + { + if ($key === 'session_id') + { + return (session_status() === PHP_SESSION_ACTIVE); + } + + return isset($_SESSION[$key]); + } + + // ------------------------------------------------------------------------ + /** * __set() * @@ -795,7 +813,7 @@ public function flashdata($key = NULL) /** * Set flashdata * - * Legacy CI_Session compatibiliy method + * Legacy CI_Session compatibility method * * @param mixed $data Session data key or an associative array * @param mixed $value Value to store diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 47376da..55ddb25 100755 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ abstract class CI_Session_driver implements SessionHandlerInterface { @@ -74,6 +74,18 @@ abstract class CI_Session_driver implements SessionHandlerInterface { */ protected $_session_id; + /** + * Success and failure return values + * + * Necessary due to a bug in all PHP 5 versions where return values + * from userspace handlers are not handled properly. PHP 7 fixes the + * bug, so we need to return different values depending on the version. + * + * @see https://wiki.php.net/rfc/session.user.return-value + * @var mixed + */ + protected $_success, $_failure; + // ------------------------------------------------------------------------ /** @@ -85,6 +97,17 @@ abstract class CI_Session_driver implements SessionHandlerInterface { public function __construct(&$params) { $this->_config =& $params; + + if (is_php('7')) + { + $this->_success = TRUE; + $this->_failure = FALSE; + } + else + { + $this->_success = 0; + $this->_failure = -1; + } } // ------------------------------------------------------------------------ @@ -145,4 +168,24 @@ protected function _release_lock() return TRUE; } + // ------------------------------------------------------------------------ + + /** + * Fail + * + * Drivers other than the 'files' one don't (need to) use the + * session.save_path INI setting, but that leads to confusing + * error messages emitted by PHP when open() or write() fail, + * as the message contains session.save_path ... + * To work around the problem, the drivers will call this method + * so that the INI is set just in time for the error message to + * be properly generated. + * + * @return mixed + */ + protected function _fail() + { + ini_set('session.save_path', config_item('sess_save_path')); + return $this->_failure; + } } diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 1d01c29..317bd7d 100755 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface { @@ -125,9 +125,12 @@ public function __construct(&$params) */ public function open($save_path, $name) { - return empty($this->_db->conn_id) - ? (bool) $this->_db->db_connect() - : TRUE; + if (empty($this->_db->conn_id) && ! $this->_db->db_connect()) + { + return $this->_fail(); + } + + return $this->_success; } // ------------------------------------------------------------------------ @@ -144,6 +147,9 @@ public function read($session_id) { if ($this->_get_lock($session_id) !== FALSE) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; @@ -157,8 +163,12 @@ public function read($session_id) $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - if (($result = $this->_db->get()->row()) === NULL) + if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL) { + // PHP7 will reuse the same SessionHandler object after + // ID regeneration, so we need to explicitly set this to + // FALSE instead of relying on the default ... + $this->_row_exists = FALSE; $this->_fingerprint = md5(''); return ''; } @@ -192,12 +202,15 @@ public function read($session_id) */ public function write($session_id, $session_data) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + // Was the ID regenerated? if ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_fail(); } $this->_row_exists = FALSE; @@ -205,7 +218,7 @@ public function write($session_id, $session_data) } elseif ($this->_lock === FALSE) { - return FALSE; + return $this->_fail(); } if ($this->_row_exists === FALSE) @@ -220,10 +233,11 @@ public function write($session_id, $session_data) if ($this->_db->insert($this->_config['save_path'], $insert_data)) { $this->_fingerprint = md5($session_data); - return $this->_row_exists = TRUE; + $this->_row_exists = TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } $this->_db->where('id', $session_id); @@ -243,10 +257,10 @@ public function write($session_id, $session_data) if ($this->_db->update($this->_config['save_path'], $update_data)) { $this->_fingerprint = md5($session_data); - return TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -260,9 +274,9 @@ public function write($session_id, $session_data) */ public function close() { - return ($this->_lock) - ? $this->_release_lock() - : TRUE; + return ($this->_lock && ! $this->_release_lock()) + ? $this->_fail() + : $this->_success; } // ------------------------------------------------------------------------ @@ -279,18 +293,28 @@ public function destroy($session_id) { if ($this->_lock) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + $this->_db->where('id', $session_id); if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - return $this->_db->delete($this->_config['save_path']) - ? ($this->close() && $this->_cookie_destroy()) - : FALSE; + if ( ! $this->_db->delete($this->_config['save_path'])) + { + return $this->_fail(); + } + } + + if ($this->close() === $this->_success) + { + $this->_cookie_destroy(); + return $this->_success; } - return ($this->close() && $this->_cookie_destroy()); + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -305,7 +329,12 @@ public function destroy($session_id) */ public function gc($maxlifetime) { - return $this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)); + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + + return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) + ? $this->_success + : $this->_fail(); } // ------------------------------------------------------------------------ @@ -385,5 +414,4 @@ protected function _release_lock() return parent::_release_lock(); } - -} +} \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 45da91c..119bf65 100755 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface { @@ -129,7 +129,7 @@ public function open($save_path, $name) .$name // we'll use the session cookie name as a prefix to avoid collisions .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -156,13 +156,13 @@ public function read($session_id) if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) { log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return FALSE; + return $this->_failure; } } elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); - return FALSE; + return $this->_failure; } if (flock($this->_file_handle, LOCK_EX) === FALSE) @@ -170,7 +170,7 @@ public function read($session_id) log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; - return FALSE; + return $this->_failure; } // Needed by write() to detect session_regenerate_id() calls @@ -183,6 +183,12 @@ public function read($session_id) return ''; } } + // We shouldn't need this, but apparently we do ... + // See https://github.com/bcit-ci/CodeIgniter/issues/4039 + elseif ($this->_file_handle === FALSE) + { + return $this->_failure; + } else { rewind($this->_file_handle); @@ -218,20 +224,20 @@ public function write($session_id, $session_data) { // If the two IDs don't match, we have a session_regenerate_id() call // and we need to close the old handle and open a new one - if ($session_id !== $this->_session_id && ( ! $this->close() OR $this->read($session_id) === FALSE)) + if ($session_id !== $this->_session_id && ($this->close() === $this->_failure OR $this->read($session_id) === $this->_failure)) { - return FALSE; + return $this->_failure; } if ( ! is_resource($this->_file_handle)) { - return FALSE; + return $this->_failure; } elseif ($this->_fingerprint === md5($session_data)) { - return ($this->_file_new) - ? TRUE - : touch($this->_file_path.$session_id); + return ( ! $this->_file_new && ! touch($this->_file_path.$session_id)) + ? $this->_failure + : $this->_success; } if ( ! $this->_file_new) @@ -254,12 +260,12 @@ public function write($session_id, $session_data) { $this->_fingerprint = md5(substr($session_data, 0, $written)); log_message('error', 'Session: Unable to write data.'); - return FALSE; + return $this->_failure; } } $this->_fingerprint = md5($session_data); - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -279,10 +285,9 @@ public function close() fclose($this->_file_handle); $this->_file_handle = $this->_file_new = $this->_session_id = NULL; - return TRUE; } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -297,21 +302,33 @@ public function close() */ public function destroy($session_id) { - if ($this->close()) + if ($this->close() === $this->_success) { - return file_exists($this->_file_path.$session_id) - ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) - : TRUE; + if (file_exists($this->_file_path.$session_id)) + { + $this->_cookie_destroy(); + return unlink($this->_file_path.$session_id) + ? $this->_success + : $this->_failure; + } + + return $this->_success; } elseif ($this->_file_path !== NULL) { clearstatcache(); - return file_exists($this->_file_path.$session_id) - ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) - : TRUE; + if (file_exists($this->_file_path.$session_id)) + { + $this->_cookie_destroy(); + return unlink($this->_file_path.$session_id) + ? $this->_success + : $this->_failure; + } + + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -329,7 +346,7 @@ public function gc($maxlifetime) if ( ! is_dir($this->_config['save_path']) OR ($directory = opendir($this->_config['save_path'])) === FALSE) { log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_config['save_path']."'."); - return FALSE; + return $this->_failure; } $ts = time() - $maxlifetime; @@ -356,7 +373,7 @@ public function gc($maxlifetime) closedir($directory); - return TRUE; + return $this->_success; } -} +} \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index c7185ee..88eb4b3 100755 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface { @@ -117,7 +117,7 @@ public function open($save_path, $name) { $this->_memcached = NULL; log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); - return FALSE; + return $this->_fail(); } foreach ($matches as $match) @@ -142,10 +142,10 @@ public function open($save_path, $name) if (empty($server_list)) { log_message('error', 'Session: Memcached server pool is empty.'); - return FALSE; + return $this->_fail(); } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -170,7 +170,7 @@ public function read($session_id) return $session_data; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -188,14 +188,14 @@ public function write($session_id, $session_data) { if ( ! isset($this->_memcached)) { - return FALSE; + return $this->_fail(); } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_fail(); } $this->_fingerprint = md5(''); @@ -204,22 +204,33 @@ public function write($session_id, $session_data) if (isset($this->_lock_key)) { + $key = $this->_key_prefix.$session_id; + $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) + if ( + $this->_memcached->replace($key, $session_data, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) { $this->_fingerprint = $fingerprint; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } - return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration']); + if ( + $this->_memcached->touch($key, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) + { + return $this->_success; + } } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -235,17 +246,17 @@ public function close() { if (isset($this->_memcached)) { - isset($this->_lock_key) && $this->_memcached->delete($this->_lock_key); + $this->_release_lock(); if ( ! $this->_memcached->quit()) { - return FALSE; + return $this->_fail(); } $this->_memcached = NULL; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -263,10 +274,11 @@ public function destroy($session_id) if (isset($this->_memcached, $this->_lock_key)) { $this->_memcached->delete($this->_key_prefix.$session_id); - return $this->_cookie_destroy(); + $this->_cookie_destroy(); + return $this->_success; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -282,7 +294,7 @@ public function destroy($session_id) public function gc($maxlifetime) { // Not necessary, Memcached takes care of that. - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -297,9 +309,17 @@ public function gc($maxlifetime) */ protected function _get_lock($session_id) { - if (isset($this->_lock_key)) + // PHP 7 reuses the SessionHandler object on regeneration, + // so we need to check here if the lock key is for the + // correct session ID. + if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { - return $this->_memcached->replace($this->_lock_key, time(), 300); + if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) + { + return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) + ? $this->_memcached->set($this->_lock_key, time(), 300) + : FALSE; + } } // 30 attempts to obtain a lock, in case another request already has it @@ -322,7 +342,7 @@ protected function _get_lock($session_id) $this->_lock_key = $lock_key; break; } - while ($attempt++ < 30); + while (++$attempt < 30); if ($attempt === 30) { @@ -359,5 +379,4 @@ protected function _release_lock() return TRUE; } - -} +} \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 1ce101d..e4e09fe 100755 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface { @@ -69,6 +69,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ protected $_lock_key; + /** + * Key exists flag + * + * @var bool + */ + protected $_key_exists = FALSE; + // ------------------------------------------------------------------------ /** @@ -124,7 +131,7 @@ public function open($save_path, $name) { if (empty($this->_config['save_path'])) { - return FALSE; + return $this->_fail(); } $redis = new Redis(); @@ -143,10 +150,10 @@ public function open($save_path, $name) else { $this->_redis = $redis; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -166,12 +173,17 @@ public function read($session_id) // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; - $session_data = (string) $this->_redis->get($this->_key_prefix.$session_id); + $session_data = $this->_redis->get($this->_key_prefix.$session_id); + + is_string($session_data) + ? $this->_key_exists = TRUE + : $session_data = ''; + $this->_fingerprint = md5($session_data); return $session_data; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -189,38 +201,41 @@ public function write($session_id, $session_data) { if ( ! isset($this->_redis)) { - return FALSE; + return $this->_fail(); } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_fail(); } - $this->_fingerprint = md5(''); + $this->_key_exists = FALSE; $this->_session_id = $session_id; } if (isset($this->_lock_key)) { $this->_redis->setTimeout($this->_lock_key, 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; - return TRUE; + $this->_key_exists = TRUE; + return $this->_success; } - return FALSE; + return $this->_fail(); } - return $this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']); + return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + ? $this->_success + : $this->_fail(); } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -239,10 +254,10 @@ public function close() try { if ($this->_redis->ping() === '+PONG') { - isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); - if ( ! $this->_redis->close()) + $this->_release_lock(); + if ($this->_redis->close() === $this->_failure) { - return FALSE; + return $this->_fail(); } } } @@ -252,10 +267,10 @@ public function close() } $this->_redis = NULL; - return TRUE; + return $this->_success; } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -277,10 +292,11 @@ public function destroy($session_id) log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); } - return $this->_cookie_destroy(); + $this->_cookie_destroy(); + return $this->_success; } - return FALSE; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -296,7 +312,7 @@ public function destroy($session_id) public function gc($maxlifetime) { // Not necessary, Redis takes care of that. - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -311,7 +327,10 @@ public function gc($maxlifetime) */ protected function _get_lock($session_id) { - if (isset($this->_lock_key)) + // PHP 7 reuses the SessionHandler object on regeneration, + // so we need to check here if the lock key is for the + // correct session ID. + if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { return $this->_redis->setTimeout($this->_lock_key, 300); } @@ -336,7 +355,7 @@ protected function _get_lock($session_id) $this->_lock_key = $lock_key; break; } - while ($attempt++ < 30); + while (++$attempt < 30); if ($attempt === 30) { diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 7b744ad..3ac6af7 100755 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.1 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category UnitTesting * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/unit_testing.html + * @link https://codeigniter.com/user_guide/libraries/unit_testing.html */ class CI_Unit_test { @@ -55,14 +55,14 @@ class CI_Unit_test { * * @var bool */ - public $active = TRUE; + public $active = TRUE; /** * Test results * * @var array */ - public $results = array(); + public $results = array(); /** * Strict comparison flag @@ -71,21 +71,21 @@ class CI_Unit_test { * * @var bool */ - public $strict = FALSE; + public $strict = FALSE; /** * Template * * @var string */ - protected $_template = NULL; + protected $_template = NULL; /** * Template rows * * @var string */ - protected $_template_rows = NULL; + protected $_template_rows = NULL; /** * List of visible test items @@ -93,13 +93,13 @@ class CI_Unit_test { * @var array */ protected $_test_items_visible = array( - 'test_name', - 'test_datatype', - 'res_datatype', - 'result', - 'file', - 'line', - 'notes' + 'test_name', + 'test_datatype', + 'res_datatype', + 'result', + 'file', + 'line', + 'notes' ); // -------------------------------------------------------------------- @@ -152,7 +152,7 @@ public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = return FALSE; } - if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE)) + if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null', 'is_resource'), TRUE)) { $expected = str_replace('is_double', 'is_float', $expected); $result = $expected($test); @@ -167,14 +167,14 @@ public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = $back = $this->_backtrace(); $report = array ( - 'test_name' => $test_name, - 'test_datatype' => gettype($test), - 'res_datatype' => $extype, - 'result' => ($result === TRUE) ? 'passed' : 'failed', - 'file' => $back['file'], - 'line' => $back['line'], - 'notes' => $notes - ); + 'test_name' => $test_name, + 'test_datatype' => gettype($test), + 'res_datatype' => $extype, + 'result' => ($result === TRUE) ? 'passed' : 'failed', + 'file' => $back['file'], + 'line' => $back['line'], + 'notes' => $notes + ); $this->results[] = $report; @@ -291,10 +291,12 @@ public function result($results = array()) { continue; } - - if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE))) + elseif (in_array($key, array('test_name', 'test_datatype', 'test_res_datatype', 'result'), TRUE)) { - $val = $line; + if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE))) + { + $val = $line; + } } $temp[$CI->lang->line('ut_'.$key, FALSE)] = $val; @@ -334,9 +336,9 @@ protected function _backtrace() { $back = debug_backtrace(); return array( - 'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''), - 'line' => (isset($back[1]['line']) ? $back[1]['line'] : '') - ); + 'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''), + 'line' => (isset($back[1]['line']) ? $back[1]['line'] : '') + ); } // -------------------------------------------------------------------- diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index f5534a7..f241837 100755 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Uploads * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/file_uploading.html + * @link https://codeigniter.com/user_guide/libraries/file_uploading.html */ class CI_Upload { @@ -397,7 +397,7 @@ public function do_upload($field = 'userfile') if ( ! isset($_file)) { - $this->set_error('upload_no_file_selected'); + $this->set_error('upload_no_file_selected', 'debug'); return FALSE; } @@ -416,28 +416,28 @@ public function do_upload($field = 'userfile') switch ($error) { case UPLOAD_ERR_INI_SIZE: - $this->set_error('upload_file_exceeds_limit'); + $this->set_error('upload_file_exceeds_limit', 'info'); break; case UPLOAD_ERR_FORM_SIZE: - $this->set_error('upload_file_exceeds_form_limit'); + $this->set_error('upload_file_exceeds_form_limit', 'info'); break; case UPLOAD_ERR_PARTIAL: - $this->set_error('upload_file_partial'); + $this->set_error('upload_file_partial', 'debug'); break; case UPLOAD_ERR_NO_FILE: - $this->set_error('upload_no_file_selected'); + $this->set_error('upload_no_file_selected', 'debug'); break; case UPLOAD_ERR_NO_TMP_DIR: - $this->set_error('upload_no_temp_directory'); + $this->set_error('upload_no_temp_directory', 'error'); break; case UPLOAD_ERR_CANT_WRITE: - $this->set_error('upload_unable_to_write_file'); + $this->set_error('upload_unable_to_write_file', 'error'); break; case UPLOAD_ERR_EXTENSION: - $this->set_error('upload_stopped_by_extension'); + $this->set_error('upload_stopped_by_extension', 'debug'); break; default: - $this->set_error('upload_no_file_selected'); + $this->set_error('upload_no_file_selected', 'debug'); break; } @@ -463,7 +463,7 @@ public function do_upload($field = 'userfile') // Is the file type allowed to be uploaded? if ( ! $this->is_allowed_filetype()) { - $this->set_error('upload_invalid_filetype'); + $this->set_error('upload_invalid_filetype', 'debug'); return FALSE; } @@ -485,7 +485,7 @@ public function do_upload($field = 'userfile') if ( ! $this->is_allowed_filetype(TRUE)) { - $this->set_error('upload_invalid_filetype'); + $this->set_error('upload_invalid_filetype', 'debug'); return FALSE; } } @@ -499,7 +499,7 @@ public function do_upload($field = 'userfile') // Is the file size within the allowed maximum? if ( ! $this->is_allowed_filesize()) { - $this->set_error('upload_invalid_filesize'); + $this->set_error('upload_invalid_filesize', 'info'); return FALSE; } @@ -507,7 +507,7 @@ public function do_upload($field = 'userfile') // Note: This can fail if the server has an open_basedir restriction. if ( ! $this->is_allowed_dimensions()) { - $this->set_error('upload_invalid_dimensions'); + $this->set_error('upload_invalid_dimensions', 'info'); return FALSE; } @@ -526,6 +526,12 @@ public function do_upload($field = 'userfile') $this->file_name = preg_replace('/\s+/', '_', $this->file_name); } + if ($this->file_ext_tolower && ($ext_length = strlen($this->file_ext))) + { + // file_ext was previously lower-cased by a get_extension() call + $this->file_name = substr($this->file_name, 0, -$ext_length).$this->file_ext; + } + /* * Validate the file name * This function appends an number onto the end of @@ -533,15 +539,9 @@ public function do_upload($field = 'userfile') * If it returns false there was a problem. */ $this->orig_name = $this->file_name; - - if ($this->overwrite === FALSE) + if (FALSE === ($this->file_name = $this->set_filename($this->upload_path, $this->file_name))) { - $this->file_name = $this->set_filename($this->upload_path, $this->file_name); - - if ($this->file_name === FALSE) - { - return FALSE; - } + return FALSE; } /* @@ -552,7 +552,7 @@ public function do_upload($field = 'userfile') */ if ($this->xss_clean && $this->do_xss_clean() === FALSE) { - $this->set_error('upload_unable_to_write_file'); + $this->set_error('upload_unable_to_write_file', 'error'); return FALSE; } @@ -567,7 +567,7 @@ public function do_upload($field = 'userfile') { if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) { - $this->set_error('upload_destination_error'); + $this->set_error('upload_destination_error', 'error'); return FALSE; } } @@ -656,7 +656,7 @@ public function set_filename($path, $filename) $filename = md5(uniqid(mt_rand())).$this->file_ext; } - if ( ! file_exists($path.$filename)) + if ($this->overwrite === TRUE OR ! file_exists($path.$filename)) { return $filename; } @@ -675,7 +675,7 @@ public function set_filename($path, $filename) if ($new_filename === '') { - $this->set_error('upload_bad_filename'); + $this->set_error('upload_bad_filename', 'debug'); return FALSE; } else @@ -700,6 +700,22 @@ public function set_max_filesize($n) // -------------------------------------------------------------------- + /** + * Set Maximum File Size + * + * An internal alias to set_max_filesize() to help with configuration + * as initialize() will look for a set_() method ... + * + * @param int $n + * @return CI_Upload + */ + protected function set_max_size($n) + { + return $this->set_max_filesize($n); + } + + // -------------------------------------------------------------------- + /** * Set Maximum File Name Length * @@ -875,7 +891,7 @@ public function is_allowed_filetype($ignore_mime = FALSE) if (empty($this->allowed_types) OR ! is_array($this->allowed_types)) { - $this->set_error('upload_no_file_types'); + $this->set_error('upload_no_file_types', 'debug'); return FALSE; } @@ -974,7 +990,7 @@ public function validate_upload_path() { if ($this->upload_path === '') { - $this->set_error('upload_no_filepath'); + $this->set_error('upload_no_filepath', 'error'); return FALSE; } @@ -985,13 +1001,13 @@ public function validate_upload_path() if ( ! is_dir($this->upload_path)) { - $this->set_error('upload_no_filepath'); + $this->set_error('upload_no_filepath', 'error'); return FALSE; } if ( ! is_really_writable($this->upload_path)) { - $this->set_error('upload_not_writable'); + $this->set_error('upload_not_writable', 'error'); return FALSE; } @@ -1013,7 +1029,7 @@ public function get_extension($filename) if (count($x) === 1) { - return ''; + return ''; } $ext = ($this->file_ext_tolower) ? strtolower(end($x)) : end($x); @@ -1121,17 +1137,16 @@ public function do_xss_clean() * @param string $msg * @return CI_Upload */ - public function set_error($msg) + public function set_error($msg, $log_level = 'error') { $this->_CI->lang->load('upload'); is_array($msg) OR $msg = array($msg); - foreach ($msg as $val) { $msg = ($this->_CI->lang->line($val) === FALSE) ? $val : $this->_CI->lang->line($val); $this->error_msg[] = $msg; - log_message('error', $msg); + log_message($log_level, $msg); } return $this; diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index 8fbc18f..f965858 100755 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -51,7 +51,7 @@ * @subpackage Libraries * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class CI_Xmlrpc { @@ -559,7 +559,7 @@ public function send_response($response) * * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class XML_RPC_Client extends CI_Xmlrpc { @@ -735,12 +735,32 @@ public function sendPayload($msg) .'Content-Length: '.strlen($msg->payload).$r.$r .$msg->payload; - for ($written = 0, $length = strlen($op); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result) { if (($result = fwrite($fp, substr($op, $written))) === FALSE) { break; } + // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951 + elseif ($result === 0) + { + if ($timestamp === 0) + { + $timestamp = time(); + } + elseif ($timestamp < (time() - $this->timeout)) + { + $result = FALSE; + break; + } + + usleep(250000); + continue; + } + else + { + $timestamp = 0; + } } if ($result === FALSE) @@ -761,7 +781,7 @@ public function sendPayload($msg) * * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class XML_RPC_Response { @@ -1010,7 +1030,7 @@ public function iso8601_decode($time, $utc = FALSE) * * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class XML_RPC_Message extends CI_Xmlrpc { @@ -1629,7 +1649,7 @@ public function decode_message($param) * * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class XML_RPC_Values extends CI_Xmlrpc { diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index f2f1714..140ad72 100755 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -50,7 +50,7 @@ * @subpackage Libraries * @category Encryption * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/zip.html + * @link https://codeigniter.com/user_guide/libraries/zip.html */ class CI_Zip { @@ -352,7 +352,7 @@ public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL) // Set the original directory root for child dir's to use as relative if ($root_path === NULL) { - $root_path = dirname($path).DIRECTORY_SEPARATOR; + $root_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, dirname($path)).DIRECTORY_SEPARATOR; } while (FALSE !== ($file = readdir($fp))) From bf13bb1d9679b177d1c65b4978c4caf93c5c4460 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Tue, 17 May 2016 11:46:33 +1000 Subject: [PATCH 03/16] Installer to CI 3.0.6 --- install/installer/config/config.php | 36 +++++++-------- install/installer/config/constants.php | 53 +++++++++++----------- install/installer/config/database.php | 16 +++---- install/installer/config/foreign_chars.php | 1 + install/installer/config/mimes.php | 20 ++++++-- install/installer/config/user_agents.php | 3 +- 6 files changed, 72 insertions(+), 57 deletions(-) diff --git a/install/installer/config/config.php b/install/installer/config/config.php index f78371f..35c93f1 100755 --- a/install/installer/config/config.php +++ b/install/installer/config/config.php @@ -95,7 +95,7 @@ | setting this variable to TRUE (boolean). See the user guide for details. | */ -$config['enable_hooks'] = FALSE; +$config['enable_hooks'] = false; /* |-------------------------------------------------------------------------- @@ -181,8 +181,8 @@ | use segment based URLs. | */ -$config['allow_get_array'] = TRUE; -$config['enable_query_strings'] = FALSE; +$config['allow_get_array'] = true; +$config['enable_query_strings'] = false; $config['controller_trigger'] = 'c'; $config['function_trigger'] = 'm'; $config['directory_trigger'] = 'd'; @@ -292,7 +292,7 @@ | URL query string. Please be aware this might result in numerous cache files. | */ -$config['cache_query_string'] = FALSE; +$config['cache_query_string'] = false; /* |-------------------------------------------------------------------------- @@ -358,10 +358,10 @@ $config['sess_driver'] = 'files'; $config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 7200; -$config['sess_save_path'] = NULL; -$config['sess_match_ip'] = FALSE; +$config['sess_save_path'] = null; +$config['sess_match_ip'] = false; $config['sess_time_to_update'] = 300; -$config['sess_regenerate_destroy'] = FALSE; +$config['sess_regenerate_destroy'] = false; /* |-------------------------------------------------------------------------- @@ -378,11 +378,11 @@ | 'cookie_httponly') will also affect sessions. | */ -$config['cookie_prefix'] = ''; -$config['cookie_domain'] = ''; -$config['cookie_path'] = '/'; -$config['cookie_secure'] = FALSE; -$config['cookie_httponly'] = FALSE; +$config['cookie_prefix'] = ''; +$config['cookie_domain'] = ''; +$config['cookie_path'] = '/'; +$config['cookie_secure'] = false; +$config['cookie_httponly'] = false; /* |-------------------------------------------------------------------------- @@ -396,7 +396,7 @@ | (usually \n) and Windows (\r\n). | */ -$config['standardize_newlines'] = FALSE; +$config['standardize_newlines'] = false; /* |-------------------------------------------------------------------------- @@ -410,7 +410,7 @@ | for backwards compatibility purposes! | */ -$config['global_xss_filtering'] = FALSE; +$config['global_xss_filtering'] = false; /* |-------------------------------------------------------------------------- @@ -426,11 +426,11 @@ | 'csrf_regenerate' = Regenerate token on every submission | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks */ -$config['csrf_protection'] = FALSE; +$config['csrf_protection'] = false; $config['csrf_token_name'] = 'csrf_test_name'; $config['csrf_cookie_name'] = 'csrf_cookie_name'; $config['csrf_expire'] = 7200; -$config['csrf_regenerate'] = TRUE; +$config['csrf_regenerate'] = true; $config['csrf_exclude_uris'] = array(); /* @@ -453,7 +453,7 @@ | by the output class. Do not 'echo' any values with compression enabled. | */ -$config['compress_output'] = FALSE; +$config['compress_output'] = false; /* |-------------------------------------------------------------------------- @@ -478,7 +478,7 @@ | in your view files. Options are TRUE or FALSE (boolean) | */ -$config['rewrite_short_tags'] = FALSE; +$config['rewrite_short_tags'] = false; /* diff --git a/install/installer/config/constants.php b/install/installer/config/constants.php index 01096c7..9c407ee 100755 --- a/install/installer/config/constants.php +++ b/install/installer/config/constants.php @@ -10,16 +10,15 @@ | with the file system. The defaults are fine on servers with proper | security, but you may wish (or even need) to change the values in | certain environments (Apache running a separate process for each +*/ +defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE); + +/* +|-------------------------------------------------------------------------- | user, PHP under CGI with Apache suEXEC, etc.). Octal values should | always be used to set the mode correctly. | -*/ -define('FILE_READ_MODE', 0644); -define('FILE_WRITE_MODE', 0666); -define('DIR_READ_MODE', 0755); -define('DIR_WRITE_MODE', 0755); -/* |-------------------------------------------------------------------------- | File Stream Modes |-------------------------------------------------------------------------- @@ -27,15 +26,10 @@ | These modes are used when working with fopen()/popen() | */ - -define('FOPEN_READ', 'rb'); -define('FOPEN_READ_WRITE', 'r+b'); -define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care -define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care -define('FOPEN_WRITE_CREATE', 'ab'); -define('FOPEN_READ_WRITE_CREATE', 'a+b'); -define('FOPEN_WRITE_CREATE_STRICT', 'xb'); -define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b'); +defined('FILE_READ_MODE') OR define('FILE_READ_MODE', 0644); +defined('FILE_WRITE_MODE') OR define('FILE_WRITE_MODE', 0666); +defined('DIR_READ_MODE') OR define('DIR_READ_MODE', 0755); +defined('DIR_WRITE_MODE') OR define('DIR_WRITE_MODE', 0755); /* |-------------------------------------------------------------------------- @@ -47,7 +41,14 @@ | of this setting | */ -define('SHOW_DEBUG_BACKTRACE', TRUE); +defined('FOPEN_READ') OR define('FOPEN_READ', 'rb'); +defined('FOPEN_READ_WRITE') OR define('FOPEN_READ_WRITE', 'r+b'); +defined('FOPEN_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care +defined('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care +defined('FOPEN_WRITE_CREATE') OR define('FOPEN_WRITE_CREATE', 'ab'); +defined('FOPEN_READ_WRITE_CREATE') OR define('FOPEN_READ_WRITE_CREATE', 'a+b'); +defined('FOPEN_WRITE_CREATE_STRICT') OR define('FOPEN_WRITE_CREATE_STRICT', 'xb'); +defined('FOPEN_READ_WRITE_CREATE_STRICT') OR define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b'); /* |-------------------------------------------------------------------------- @@ -74,13 +75,13 @@ | http://tldp.org/LDP/abs/html/exitcodes.html | */ -define('EXIT_SUCCESS', 0); // no errors -define('EXIT_ERROR', 1); // generic error -define('EXIT_CONFIG', 3); // configuration error -define('EXIT_UNKNOWN_FILE', 4); // file not found -define('EXIT_UNKNOWN_CLASS', 5); // unknown class -define('EXIT_UNKNOWN_METHOD', 6); // unknown class member -define('EXIT_USER_INPUT', 7); // invalid user input -define('EXIT_DATABASE', 8); // database error -define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code -define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code +defined('EXIT_SUCCESS') OR define('EXIT_SUCCESS', 0); // no errors +defined('EXIT_ERROR') OR define('EXIT_ERROR', 1); // generic error +defined('EXIT_CONFIG') OR define('EXIT_CONFIG', 3); // configuration error +defined('EXIT_UNKNOWN_FILE') OR define('EXIT_UNKNOWN_FILE', 4); // file not found +defined('EXIT_UNKNOWN_CLASS') OR define('EXIT_UNKNOWN_CLASS', 5); // unknown class +defined('EXIT_UNKNOWN_METHOD') OR define('EXIT_UNKNOWN_METHOD', 6); // unknown class member +defined('EXIT_USER_INPUT') OR define('EXIT_USER_INPUT', 7); // invalid user input +defined('EXIT_DATABASE') OR define('EXIT_DATABASE', 8); // database error +defined('EXIT__AUTO_MIN') OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code +defined('EXIT__AUTO_MAX') OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code diff --git a/install/installer/config/database.php b/install/installer/config/database.php index 925b3e5..0eef3c5 100755 --- a/install/installer/config/database.php +++ b/install/installer/config/database.php @@ -60,7 +60,7 @@ */ $active_group = 'default'; -$query_builder = TRUE; +$query_builder = true; $db['default'] = array( 'dsn' => '', @@ -70,16 +70,16 @@ 'database' => '', 'dbdriver' => 'mysqli', 'dbprefix' => '', - 'pconnect' => FALSE, - 'db_debug' => TRUE, - 'cache_on' => FALSE, + 'pconnect' => false, + 'db_debug' => (ENVIRONMENT !== 'production'), + 'cache_on' => false, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, + 'encrypt' => false, + 'compress' => false, + 'stricton' => false, 'failover' => array(), - 'save_queries' => TRUE + 'save_queries' => true ); diff --git a/install/installer/config/foreign_chars.php b/install/installer/config/foreign_chars.php index d02dea9..ac406e3 100755 --- a/install/installer/config/foreign_chars.php +++ b/install/installer/config/foreign_chars.php @@ -56,6 +56,7 @@ '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', '/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T', '/ț|ţ|ť|ŧ|т/' => 't', + '/Þ|þ/' => 'th', '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', diff --git a/install/installer/config/mimes.php b/install/installer/config/mimes.php index 8eff4d2..a093907 100755 --- a/install/installer/config/mimes.php +++ b/install/installer/config/mimes.php @@ -78,6 +78,14 @@ 'jpeg' => array('image/jpeg', 'image/pjpeg'), 'jpg' => array('image/jpeg', 'image/pjpeg'), 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'png' => array('image/png', 'image/x-png'), 'tiff' => 'image/tiff', 'tif' => 'image/tiff', @@ -127,10 +135,11 @@ 'rsa' => 'application/x-pkcs7', 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), '3g2' => 'video/3gpp2', - '3gp' => 'video/3gp', + '3gp' => array('video/3gp', 'video/3gpp'), 'mp4' => 'video/mp4', 'm4a' => 'audio/x-m4a', - 'f4v' => 'video/mp4', + 'f4v' => array('video/mp4', 'video/x-f4v'), + 'flv' => 'video/x-flv', 'webm' => 'video/webm', 'aac' => 'audio/x-acc', 'm4u' => 'application/vnd.mpegurl', @@ -141,7 +150,7 @@ 'au' => 'audio/x-au', 'ac3' => 'audio/ac3', 'flac' => 'audio/x-flac', - 'ogg' => 'audio/ogg', + 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), 'ics' => 'text/calendar', @@ -152,5 +161,8 @@ 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), 'svg' => array('image/svg+xml', 'application/xml', 'text/xml'), - 'vcf' => 'text/x-vcard' + 'vcf' => 'text/x-vcard', + 'srt' => array('text/srt', 'text/plain'), + 'vtt' => array('text/vtt', 'text/plain'), + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') ); diff --git a/install/installer/config/user_agents.php b/install/installer/config/user_agents.php index 6f3295a..fd8ed48 100755 --- a/install/installer/config/user_agents.php +++ b/install/installer/config/user_agents.php @@ -62,6 +62,7 @@ $browsers = array( 'OPR' => 'Opera', 'Flock' => 'Flock', + 'Edge' => 'Spartan', 'Chrome' => 'Chrome', // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string 'Opera.*?Version' => 'Opera', @@ -198,7 +199,7 @@ 'bingbot' => 'Bing', 'slurp' => 'Inktomi Slurp', 'yahoo' => 'Yahoo', - 'askjeeves' => 'AskJeeves', + 'ask jeeves' => 'Ask Jeeves', 'fastcrawler' => 'FastCrawler', 'infoseek' => 'InfoSeek Robot 1.0', 'lycos' => 'Lycos', From fcd3f4cb0c75ec2b235dc4167fde7d4a2fc01619 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Tue, 17 May 2016 12:38:50 +1000 Subject: [PATCH 04/16] CI Config 3.0.6 installer patch --- install/installer/config/config.php | 66 +++++++++++++++-------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/install/installer/config/config.php b/install/installer/config/config.php index 35c93f1..495ce23 100755 --- a/install/installer/config/config.php +++ b/install/installer/config/config.php @@ -1,5 +1,5 @@ Date: Tue, 17 May 2016 12:52:10 +1000 Subject: [PATCH 05/16] CI 3.0.6 database installer fix --- install/installer/views/database.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/install/installer/views/database.php b/install/installer/views/database.php index 7c0f914..ebb3829 100644 --- a/install/installer/views/database.php +++ b/install/installer/views/database.php @@ -59,7 +59,7 @@ */ $active_group = 'default'; -$query_builder = TRUE; +$query_builder = true; $db['default'] = array( 'dsn' => '', @@ -69,16 +69,16 @@ 'database' => '', 'dbdriver' => 'mysqli', 'dbprefix' => '', - 'pconnect' => FALSE, - 'db_debug' => TRUE, - 'cache_on' => FALSE, + 'pconnect' => false, + 'db_debug' => (ENVIRONMENT !== 'production'), + 'cache_on' => false, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, + 'encrypt' => false, + 'compress' => false, + 'stricton' => false, 'failover' => array(), - 'save_queries' => TRUE -); \ No newline at end of file + 'save_queries' => true +); From 3ca16849a6a1a496c3c45ae312a2dd51834f80aa Mon Sep 17 00:00:00 2001 From: Lawrence Date: Tue, 17 May 2016 14:58:42 +1000 Subject: [PATCH 06/16] Better CI 3.0.6 base negotiation --- application/config/config.php | 3 ++- install/installer/config/config.php | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/application/config/config.php b/application/config/config.php index 4bec273..8d47a67 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -19,7 +19,8 @@ */ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; -$config['base_url'] = $protocol.$_SERVER['SERVER_NAME']; +$config['base_url'] = $protocol.$_SERVER['HTTP_HOST']; +$config['base_url'] .= preg_replace('@/+$@', '', dirname($_SERVER['SCRIPT_NAME'])).'/'; /* |-------------------------------------------------------------------------- diff --git a/install/installer/config/config.php b/install/installer/config/config.php index 495ce23..c535312 100755 --- a/install/installer/config/config.php +++ b/install/installer/config/config.php @@ -17,9 +17,11 @@ | environments. | */ + $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; -$config['base_url'] = $protocol.$_SERVER['SERVER_NAME']; +$config['base_url'] = $protocol.$_SERVER['HTTP_HOST']; +$config['base_url'] .= preg_replace('@/+$@', '', dirname($_SERVER['SCRIPT_NAME'])).'/'; /* |-------------------------------------------------------------------------- From 423f3c095436712902ba6aadfaa26921c62f0349 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 18 May 2016 08:43:25 +1000 Subject: [PATCH 07/16] CI 3.0.6 fix trailing slash route --- application/config/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/config/config.php b/application/config/config.php index 8d47a67..d6a6d94 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -20,7 +20,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $config['base_url'] = $protocol.$_SERVER['HTTP_HOST']; -$config['base_url'] .= preg_replace('@/+$@', '', dirname($_SERVER['SCRIPT_NAME'])).'/'; +$config['base_url'] .= preg_replace('@/+$@', '', dirname($_SERVER['SCRIPT_NAME'])); /* |-------------------------------------------------------------------------- From 492e84cee43bc9e910dc74c2de12778d71f0649e Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 18 May 2016 09:11:50 +1000 Subject: [PATCH 08/16] Keep frontend routing right --- application/config/config.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/application/config/config.php b/application/config/config.php index d6a6d94..6d26790 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -18,9 +18,7 @@ | */ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; - $config['base_url'] = $protocol.$_SERVER['HTTP_HOST']; -$config['base_url'] .= preg_replace('@/+$@', '', dirname($_SERVER['SCRIPT_NAME'])); /* |-------------------------------------------------------------------------- From 6fcb250d864e5b886ca63fd4ab02e1231fc426b9 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Mon, 23 May 2016 08:27:48 +1000 Subject: [PATCH 09/16] Strongly type base variable. PSR2 format --- application/controllers/Bootstrap.php | 495 ++++++++++++-------------- 1 file changed, 233 insertions(+), 262 deletions(-) diff --git a/application/controllers/Bootstrap.php b/application/controllers/Bootstrap.php index ecee7ee..99dd200 100644 --- a/application/controllers/Bootstrap.php +++ b/application/controllers/Bootstrap.php @@ -1,263 +1,234 @@ load->helper('url'); - if(!file_exists(APPPATH.'/config/database.php')) - { - redirect('install'); - exit; - } - - session_start(); - - //set the session userdata if non-existant - if(!isset($_SESSION['userdata'])) - { - $_SESSION['userdata'] = []; - } - //set newFlashdata if non-existent - if(!isset($_SESSION['newFlashdata'])) - { - $_SESSION['newFlashdata'] = []; - } - - //empty out the "oldFlashdata" field - $_SESSION['oldFlashdata'] = []; - - //shift newFlashdata over to oldFlashdata - $_SESSION['oldFlashdata'] = $_SESSION['newFlashdata']; - $_SESSION['newFlashdata'] = []; - - //module list - $GLOBALS['modules'] = []; - - if(!file_exists(APPPATH.'config/manifest.php')) - { - $this->load->helper('file'); - - $manifest = "classMap = []; - $paths = [FCPATH.'addons', APPPATH.'modules', APPPATH.'libraries', APPPATH.'core']; - - $paymentModules = []; - $shippingModules = []; - $themeShortcodes = []; - $routes = []; - $modules = []; - - //just modules - $moduleDirectories = [ - APPPATH.'modules', - FCPATH.'addons' - ]; - - foreach($moduleDirectories as $moduleDirectory) - { - foreach(array_diff( scandir($moduleDirectory), ['..', '.']) as $availableModule) - { - if(is_dir($moduleDirectory.'/'.$availableModule)) - { - //create a codeigniter package path to the module. - //$this->load->add_package_path($moduleDirectory.'/'.$availableModule); - $modules[] = $moduleDirectory.'/'.$availableModule; - } - } - } - - foreach($paths as $path) - { - $dir_iterator = new RecursiveDirectoryIterator($path); - $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); - - foreach ($iterator as $file) { - - if(!is_dir($file)) - { - $ext = pathinfo($file,PATHINFO_EXTENSION); - $filename = pathinfo($file, PATHINFO_FILENAME); - if($ext == 'php') - { - if($filename == 'manifest') - { - include($file); - } - $this->getPhpClasses((string)$file); - } - } - } - } - - $manifest .= '//ClassMap for autoloader'."\n".'$classes = '.var_export($this->classMap, true).';'; - $manifest .= "\n\n".'//Available Payment Modules'."\n".'$GLOBALS[\'paymentModules\'] ='.var_export($paymentModules, true).';'; - $manifest .= "\n\n".'//Available Shipping Modules'."\n".'$GLOBALS[\'shippingModules\'] = '.var_export($shippingModules, true).';'; - $manifest .= "\n\n".'//Theme Shortcodes'."\n".'$GLOBALS[\'themeShortcodes\'] = '.var_export($themeShortcodes, true).';'; - $manifest .= "\n\n".'//Complete Module List'."\n".'$GLOBALS[\'modules\'] = '.var_export($modules,true).';'; - $manifest .= "\n\n".'//Defined Routes'."\n".'$routes = '.var_export($routes,true).';'; - - //generate the autoload file - write_file(APPPATH.'config/manifest.php', $manifest); - } - - require(APPPATH.'config/manifest.php'); - - //load in the database. - $this->load->database(); - - //set up routing... - $router = new \AltoRouter(); - - $base = trim($_SERVER['BASE'], '/'); - if($base != '') - { - $router->setBasePath('/'.$base); - } - - //set the homepage route - $router->map('GET|POST', '/', 'GoCart\Controller\Page#homepage'); - - //map the routes from the manifest. - foreach($routes as $route) { - $router->map($route[0], $route[1], $route[2]); - } - - foreach($GLOBALS['modules'] as $module) - { - $this->load->add_package_path($module); - } - - //autoloader for Modules - spl_autoload_register(function($class) use ($classes){ - - if(isset($classes[$class])) - { - include($classes[$class]); - } - }); - - //autoload some libraries here. - $this->load->model('Settings'); - $this->load->library(['session', 'auth', 'form_validation']); - $this->load->helper(['file', 'string', 'html', 'language', 'form', 'formatting']); - - //get settings from the DB - $settings = $this->Settings->get_settings('gocart'); - - //loop through the settings and set them in the config library - foreach($settings as $key=>$setting) - { - //special for the order status settings - if($key == 'order_statuses') - { - $setting = json_decode($setting, true); - } - - //other config items get set directly to the config class - $this->config->set_item($key, $setting); - } - - date_default_timezone_set(config_item('timezone')); - - //if SSL is enabled in config force it here. - if (config_item('ssl_support') && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off')) - { - $this->config->set_item('base_url', str_replace('http://', 'https://', config_item('base_url') )); - redirect( \CI::uri()->uri_string() ); - } - - //do we have a dev username & password in place? - //if there is a username and password for dev, require them - if(config_item('stage_username') != '' && config_item('stage_password') != '') - { - if (!isset($_SERVER['PHP_AUTH_USER'])) { - header('WWW-Authenticate: Basic realm="Login to restricted area"'); - header('HTTP/1.0 401 Unauthorized'); - echo config_item('company_name').' Restricted Location'; - exit; - } else { - if(config_item('stage_username') != $_SERVER['PHP_AUTH_USER'] || config_item('stage_password') != $_SERVER['PHP_AUTH_PW']) - { - header('WWW-Authenticate: Basic realm="Login to restricted area"'); - header('HTTP/1.0 401 Unauthorized'); - echo 'Restricted Location'; - exit; - } - } - } - - // lets run the routes - $match = $router->match(); - - // call a closure - if( $match && is_callable( $match['target'] ) ) { - call_user_func_array( $match['target'], $match['params'] ); - } - - // parse a string and call it - elseif($match && is_string($match['target'])) - { - $target = explode('#', $match['target']); - - try { - $class = new $target[0]; - call_user_func_array([$class, $target[1]], $match['params']); - - } catch(Exception $e) { - var_dump($e); - throw_404(); - } - } - - // throw a 404 error - else - { - throw_404(); - } - } - - private function getPhpClasses($file) { - - $phpcode = file_get_contents($file); - - $namespace = 0; - $tokens = token_get_all($phpcode); - $count = count($tokens); - $dlm = false; - for ($i = 2; $i < $count; $i++) - { - if ((isset($tokens[$i - 2][1]) && ($tokens[$i - 2][1] == "phpnamespace" || $tokens[$i - 2][1] == "namespace")) || ($dlm && $tokens[$i - 1][0] == T_NS_SEPARATOR && $tokens[$i][0] == T_STRING)) - { - if (!$dlm) - { - $namespace = 0; - } - if (isset($tokens[$i][1])) - { - $namespace = $namespace ? $namespace . "\\" . $tokens[$i][1] : $tokens[$i][1]; - $dlm = true; - } - } - elseif ($dlm && ($tokens[$i][0] != T_NS_SEPARATOR) && ($tokens[$i][0] != T_STRING)) - { - $dlm = false; - } - if (($tokens[$i - 2][0] == T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] == "phpclass")) && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) - { - $class_name = $tokens[$i][1]; - - if($namespace != '') - { - $this->classMap[$namespace.'\\'.$class_name] = $file; - } - else - { - $this->classMap[$class_name] = $file; - } - } - } - } -} \ No newline at end of file +defined('BASEPATH') or exit('No direct script access allowed'); + +class Bootstrap extends CI_Controller +{ + + public function init() + { + $this->load->helper('url'); + if (!file_exists(APPPATH.'/config/database.php')) { + redirect('install'); + exit; + } + + session_start(); + + //set the session userdata if non-existant + if (!isset($_SESSION['userdata'])) { + $_SESSION['userdata'] = []; + } + //set newFlashdata if non-existent + if (!isset($_SESSION['newFlashdata'])) { + $_SESSION['newFlashdata'] = []; + } + + //empty out the "oldFlashdata" field + $_SESSION['oldFlashdata'] = []; + + //shift newFlashdata over to oldFlashdata + $_SESSION['oldFlashdata'] = $_SESSION['newFlashdata']; + $_SESSION['newFlashdata'] = []; + + //module list + $GLOBALS['modules'] = []; + + if (!file_exists(APPPATH.'config/manifest.php')) { + $this->load->helper('file'); + + $manifest = "classMap = []; + $paths = [FCPATH.'addons', APPPATH.'modules', APPPATH.'libraries', APPPATH.'core']; + + $paymentModules = []; + $shippingModules = []; + $themeShortcodes = []; + $routes = []; + $modules = []; + + //just modules + $moduleDirectories = [ + APPPATH.'modules', + FCPATH.'addons' + ]; + + foreach ($moduleDirectories as $moduleDirectory) { + foreach (array_diff(scandir($moduleDirectory), ['..', '.']) as $availableModule) { + if (is_dir($moduleDirectory.'/'.$availableModule)) { + //create a codeigniter package path to the module. + //$this->load->add_package_path($moduleDirectory.'/'.$availableModule); + $modules[] = $moduleDirectory.'/'.$availableModule; + } + } + } + + foreach ($paths as $path) { + $dir_iterator = new RecursiveDirectoryIterator($path); + $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); + + foreach ($iterator as $file) { + + if (!is_dir($file)) { + $ext = pathinfo($file, PATHINFO_EXTENSION); + $filename = pathinfo($file, PATHINFO_FILENAME); + if ($ext == 'php') { + if ($filename == 'manifest') { + include($file); + } + $this->getPhpClasses((string)$file); + } + } + } + } + + $manifest .= '//ClassMap for autoloader'."\n".'$classes = '.var_export($this->classMap, true).';'; + $manifest .= "\n\n".'//Available Payment Modules'."\n".'$GLOBALS[\'paymentModules\'] ='.var_export($paymentModules, true).';'; + $manifest .= "\n\n".'//Available Shipping Modules'."\n".'$GLOBALS[\'shippingModules\'] = '.var_export($shippingModules, true).';'; + $manifest .= "\n\n".'//Theme Shortcodes'."\n".'$GLOBALS[\'themeShortcodes\'] = '.var_export($themeShortcodes, true).';'; + $manifest .= "\n\n".'//Complete Module List'."\n".'$GLOBALS[\'modules\'] = '.var_export($modules, true).';'; + $manifest .= "\n\n".'//Defined Routes'."\n".'$routes = '.var_export($routes, true).';'; + + //generate the autoload file + write_file(APPPATH.'config/manifest.php', $manifest); + } + + require(APPPATH.'config/manifest.php'); + + //load in the database. + $this->load->database(); + + //set up routing... + $router = new \AltoRouter(); + + $base = ''; + if (isset($_SERVER['BASE'])) { + $base = trim($_SERVER['BASE'], '/'); + } + + if ($base != '') { + $router->setBasePath('/'.$base); + } + + //set the homepage route + $router->map('GET|POST', '/', 'GoCart\Controller\Page#homepage'); + + //map the routes from the manifest. + foreach ($routes as $route) { + $router->map($route[0], $route[1], $route[2]); + } + + foreach ($GLOBALS['modules'] as $module) { + $this->load->add_package_path($module); + } + + //autoloader for Modules + spl_autoload_register(function ($class) use ($classes) { + + if (isset($classes[$class])) { + include($classes[$class]); + } + }); + + //autoload some libraries here. + $this->load->model('Settings'); + $this->load->library(['session', 'auth', 'form_validation']); + $this->load->helper(['file', 'string', 'html', 'language', 'form', 'formatting']); + + //get settings from the DB + $settings = $this->Settings->get_settings('gocart'); + + //loop through the settings and set them in the config library + foreach ($settings as $key => $setting) { + //special for the order status settings + if ($key == 'order_statuses') { + $setting = json_decode($setting, true); + } + + //other config items get set directly to the config class + $this->config->set_item($key, $setting); + } + + date_default_timezone_set(config_item('timezone')); + + //if SSL is enabled in config force it here. + if (config_item('ssl_support') && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off')) { + $this->config->set_item('base_url', str_replace('http://', 'https://', config_item('base_url'))); + redirect(\CI::uri()->uri_string()); + } + + //do we have a dev username & password in place? + //if there is a username and password for dev, require them + if (config_item('stage_username') != '' && config_item('stage_password') != '') { + if (!isset($_SERVER['PHP_AUTH_USER'])) { + header('WWW-Authenticate: Basic realm="Login to restricted area"'); + header('HTTP/1.0 401 Unauthorized'); + echo config_item('company_name').' Restricted Location'; + exit; + } else { + if (config_item('stage_username') != $_SERVER['PHP_AUTH_USER'] || config_item('stage_password') != $_SERVER['PHP_AUTH_PW']) { + header('WWW-Authenticate: Basic realm="Login to restricted area"'); + header('HTTP/1.0 401 Unauthorized'); + echo 'Restricted Location'; + exit; + } + } + } + + // lets run the routes + $match = $router->match(); + + // call a closure + if ($match && is_callable($match['target'])) { + call_user_func_array($match['target'], $match['params']); + } // parse a string and call it + elseif ($match && is_string($match['target'])) { + $target = explode('#', $match['target']); + + try { + $class = new $target[0]; + call_user_func_array([$class, $target[1]], $match['params']); + + } catch (Exception $e) { + var_dump($e); + throw_404(); + } + } // throw a 404 error + else { + throw_404(); + } + } + + private function getPhpClasses($file) + { + + $phpcode = file_get_contents($file); + + $namespace = 0; + $tokens = token_get_all($phpcode); + $count = count($tokens); + $dlm = false; + for ($i = 2; $i < $count; $i++) { + if ((isset($tokens[$i - 2][1]) && ($tokens[$i - 2][1] == "phpnamespace" || $tokens[$i - 2][1] == "namespace")) || ($dlm && $tokens[$i - 1][0] == T_NS_SEPARATOR && $tokens[$i][0] == T_STRING)) { + if (!$dlm) { + $namespace = 0; + } + if (isset($tokens[$i][1])) { + $namespace = $namespace ? $namespace . "\\" . $tokens[$i][1] : $tokens[$i][1]; + $dlm = true; + } + } elseif ($dlm && ($tokens[$i][0] != T_NS_SEPARATOR) && ($tokens[$i][0] != T_STRING)) { + $dlm = false; + } + if (($tokens[$i - 2][0] == T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] == "phpclass")) && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) { + $class_name = $tokens[$i][1]; + + if ($namespace != '') { + $this->classMap[$namespace.'\\'.$class_name] = $file; + } else { + $this->classMap[$class_name] = $file; + } + } + } + } +} From a0b3987a9d87e5bf0d387a295462fa109109a005 Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Fri, 20 Jan 2017 10:56:10 +1000 Subject: [PATCH 10/16] Update gitignore --- .gitignore | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f3588e6..fc0f314 100755 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,40 @@ -*.bak +# Ignore vendor -> must generate with composer +vendor +# Ignore uploaded folder -> this folder contains file uploaded by an user +assets/uploaded/* +!assets/uploaded/index.html +!assets/uploaded/.htaccess + +# Ignore cache folders +assets/cache/* +!assets/cache/index.html +!assets/cache/.htaccess application/cache/* !application/cache/index.html !application/cache/.htaccess -application/logs/* -!application/logs/index.html -!application/logs/.htaccess +# Thumbnails +._* -application/config/database.php +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.git +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### END SPECIAL MAC ### application/config/manifest.php +application/config/database.php # OS generated files # ###################### From b725f5e16f3a11f6461a2889dd72e8d0e5959103 Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Fri, 20 Jan 2017 10:57:01 +1000 Subject: [PATCH 11/16] Editor config --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 0000000..39f48d9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*] +charset = utf-8 + +# Tab indentation (no size specified) +indent_style = tab From 22fa8a1e37fb19a49317114c7658fe674783aff9 Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Fri, 20 Jan 2017 10:58:33 +1000 Subject: [PATCH 12/16] CI 3.1.3 System directory --- system/core/Benchmark.php | 10 +- system/core/CodeIgniter.php | 36 +- system/core/Common.php | 20 +- system/core/Config.php | 13 +- system/core/Controller.php | 10 +- system/core/Exceptions.php | 5 +- system/core/Hooks.php | 10 +- system/core/Input.php | 34 +- system/core/Lang.php | 10 +- system/core/Loader.php | 104 ++--- system/core/Log.php | 59 ++- system/core/Model.php | 10 +- system/core/Output.php | 71 ++- system/core/Router.php | 4 +- system/core/Security.php | 121 +++-- system/core/URI.php | 4 +- system/core/Utf8.php | 10 +- system/core/compat/hash.php | 12 +- system/core/compat/mbstring.php | 10 +- system/core/compat/password.php | 38 +- system/core/compat/standard.php | 221 +-------- system/database/DB.php | 10 +- system/database/DB_cache.php | 10 +- system/database/DB_driver.php | 8 +- system/database/DB_forge.php | 10 +- system/database/DB_query_builder.php | 52 ++- system/database/DB_result.php | 12 +- system/database/DB_utility.php | 4 +- .../database/drivers/cubrid/cubrid_driver.php | 4 +- .../database/drivers/cubrid/cubrid_forge.php | 13 +- .../database/drivers/cubrid/cubrid_result.php | 10 +- .../drivers/cubrid/cubrid_utility.php | 10 +- .../database/drivers/ibase/ibase_driver.php | 21 +- system/database/drivers/ibase/ibase_forge.php | 12 +- .../database/drivers/ibase/ibase_result.php | 10 +- .../database/drivers/ibase/ibase_utility.php | 10 +- .../database/drivers/mssql/mssql_driver.php | 5 +- system/database/drivers/mssql/mssql_forge.php | 15 +- .../database/drivers/mssql/mssql_result.php | 10 +- .../database/drivers/mssql/mssql_utility.php | 10 +- .../database/drivers/mysql/mysql_driver.php | 5 +- system/database/drivers/mysql/mysql_forge.php | 10 +- .../database/drivers/mysql/mysql_result.php | 10 +- .../database/drivers/mysql/mysql_utility.php | 10 +- .../database/drivers/mysqli/mysqli_driver.php | 14 +- .../database/drivers/mysqli/mysqli_forge.php | 10 +- .../database/drivers/mysqli/mysqli_result.php | 10 +- .../drivers/mysqli/mysqli_utility.php | 10 +- system/database/drivers/oci8/oci8_driver.php | 26 +- system/database/drivers/oci8/oci8_forge.php | 50 +- system/database/drivers/oci8/oci8_result.php | 10 +- system/database/drivers/oci8/oci8_utility.php | 10 +- system/database/drivers/odbc/odbc_driver.php | 167 ++++--- system/database/drivers/odbc/odbc_forge.php | 10 +- system/database/drivers/odbc/odbc_result.php | 10 +- system/database/drivers/odbc/odbc_utility.php | 10 +- system/database/drivers/pdo/pdo_driver.php | 55 +-- system/database/drivers/pdo/pdo_forge.php | 10 +- system/database/drivers/pdo/pdo_result.php | 10 +- system/database/drivers/pdo/pdo_utility.php | 10 +- .../drivers/pdo/subdrivers/pdo_4d_driver.php | 12 +- .../drivers/pdo/subdrivers/pdo_4d_forge.php | 10 +- .../pdo/subdrivers/pdo_cubrid_driver.php | 51 +- .../pdo/subdrivers/pdo_cubrid_forge.php | 13 +- .../pdo/subdrivers/pdo_dblib_driver.php | 19 +- .../pdo/subdrivers/pdo_dblib_forge.php | 15 +- .../pdo/subdrivers/pdo_firebird_driver.php | 28 +- .../pdo/subdrivers/pdo_firebird_forge.php | 12 +- .../drivers/pdo/subdrivers/pdo_ibm_driver.php | 10 +- .../drivers/pdo/subdrivers/pdo_ibm_forge.php | 10 +- .../pdo/subdrivers/pdo_informix_driver.php | 10 +- .../pdo/subdrivers/pdo_informix_forge.php | 10 +- .../pdo/subdrivers/pdo_mysql_driver.php | 70 ++- .../pdo/subdrivers/pdo_mysql_forge.php | 10 +- .../drivers/pdo/subdrivers/pdo_oci_driver.php | 4 +- .../drivers/pdo/subdrivers/pdo_oci_forge.php | 45 +- .../pdo/subdrivers/pdo_odbc_driver.php | 87 +--- .../drivers/pdo/subdrivers/pdo_odbc_forge.php | 10 +- .../pdo/subdrivers/pdo_pgsql_driver.php | 14 +- .../pdo/subdrivers/pdo_pgsql_forge.php | 10 +- .../pdo/subdrivers/pdo_sqlite_driver.php | 6 +- .../pdo/subdrivers/pdo_sqlite_forge.php | 8 +- .../pdo/subdrivers/pdo_sqlsrv_driver.php | 10 +- .../pdo/subdrivers/pdo_sqlsrv_forge.php | 15 +- .../drivers/postgre/postgre_driver.php | 14 +- .../drivers/postgre/postgre_forge.php | 10 +- .../drivers/postgre/postgre_result.php | 10 +- .../drivers/postgre/postgre_utility.php | 10 +- .../database/drivers/sqlite/sqlite_driver.php | 4 +- .../database/drivers/sqlite/sqlite_forge.php | 14 +- .../database/drivers/sqlite/sqlite_result.php | 10 +- .../drivers/sqlite/sqlite_utility.php | 10 +- .../drivers/sqlite3/sqlite3_driver.php | 4 +- .../drivers/sqlite3/sqlite3_forge.php | 8 +- .../drivers/sqlite3/sqlite3_result.php | 10 +- .../drivers/sqlite3/sqlite3_utility.php | 10 +- .../database/drivers/sqlsrv/sqlsrv_driver.php | 5 +- .../database/drivers/sqlsrv/sqlsrv_forge.php | 15 +- .../database/drivers/sqlsrv/sqlsrv_result.php | 10 +- .../drivers/sqlsrv/sqlsrv_utility.php | 10 +- system/helpers/array_helper.php | 4 +- system/helpers/captcha_helper.php | 7 +- system/helpers/cookie_helper.php | 10 +- system/helpers/date_helper.php | 94 +--- system/helpers/directory_helper.php | 10 +- system/helpers/download_helper.php | 4 +- system/helpers/email_helper.php | 10 +- system/helpers/file_helper.php | 12 +- system/helpers/form_helper.php | 47 +- system/helpers/html_helper.php | 10 +- system/helpers/inflector_helper.php | 37 +- system/helpers/language_helper.php | 10 +- system/helpers/number_helper.php | 10 +- system/helpers/path_helper.php | 6 +- system/helpers/security_helper.php | 10 +- system/helpers/smiley_helper.php | 10 +- system/helpers/string_helper.php | 4 +- system/helpers/text_helper.php | 6 +- system/helpers/typography_helper.php | 10 +- system/helpers/url_helper.php | 4 +- system/helpers/xml_helper.php | 10 +- system/language/english/calendar_lang.php | 8 +- system/language/english/date_lang.php | 8 +- system/language/english/db_lang.php | 8 +- system/language/english/email_lang.php | 8 +- .../language/english/form_validation_lang.php | 8 +- system/language/english/ftp_lang.php | 8 +- system/language/english/imglib_lang.php | 9 +- system/language/english/migration_lang.php | 8 +- system/language/english/number_lang.php | 8 +- system/language/english/pagination_lang.php | 8 +- system/language/english/profiler_lang.php | 8 +- system/language/english/unit_test_lang.php | 8 +- system/language/english/upload_lang.php | 8 +- system/libraries/Cache/Cache.php | 4 +- system/libraries/Cache/drivers/Cache_apc.php | 6 +- .../libraries/Cache/drivers/Cache_dummy.php | 8 +- system/libraries/Cache/drivers/Cache_file.php | 12 +- .../Cache/drivers/Cache_memcached.php | 6 +- .../libraries/Cache/drivers/Cache_redis.php | 4 +- .../Cache/drivers/Cache_wincache.php | 4 +- system/libraries/Calendar.php | 10 +- system/libraries/Cart.php | 10 +- system/libraries/Driver.php | 8 +- system/libraries/Email.php | 441 +++++++++++------- system/libraries/Encrypt.php | 14 +- system/libraries/Encryption.php | 38 +- system/libraries/Form_validation.php | 166 ++++--- system/libraries/Ftp.php | 4 +- system/libraries/Image_lib.php | 88 ++-- system/libraries/Javascript.php | 10 +- system/libraries/Javascript/Jquery.php | 12 +- system/libraries/Migration.php | 9 +- system/libraries/Pagination.php | 4 +- system/libraries/Parser.php | 10 +- system/libraries/Profiler.php | 4 +- system/libraries/Session/Session.php | 89 +++- .../Session/SessionHandlerInterface.php | 10 +- system/libraries/Session/Session_driver.php | 4 +- .../drivers/Session_database_driver.php | 23 +- .../Session/drivers/Session_files_driver.php | 65 ++- .../drivers/Session_memcached_driver.php | 45 +- .../Session/drivers/Session_redis_driver.php | 33 +- system/libraries/Table.php | 11 +- system/libraries/Trackback.php | 12 +- system/libraries/Typography.php | 10 +- system/libraries/Unit_test.php | 7 +- system/libraries/Upload.php | 44 +- system/libraries/User_agent.php | 16 +- system/libraries/Xmlrpc.php | 11 +- system/libraries/Xmlrpcs.php | 18 +- system/libraries/Zip.php | 78 +++- 172 files changed, 2127 insertions(+), 1799 deletions(-) diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index e420f62..b3ac79c 100755 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -47,7 +47,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/benchmark.html + * @link https://codeigniter.com/user_guide/libraries/benchmark.html */ class CI_Benchmark { diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 3eb3e05..0edcf97 100755 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -55,7 +55,7 @@ * @var string * */ - define('CI_VERSION', '3.0.6'); + const CI_VERSION = '3.1.3'; /* * ------------------------------------------------------ @@ -67,7 +67,10 @@ require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); } - require_once(APPPATH.'config/constants.php'); + if (file_exists(APPPATH.'config/constants.php')) + { + require_once(APPPATH.'config/constants.php'); + } /* * ------------------------------------------------------ @@ -416,14 +419,29 @@ function &get_instance() $params = array($method, array_slice($URI->rsegments, 2)); $method = '_remap'; } - // WARNING: It appears that there are issues with is_callable() even in PHP 5.2! - // Furthermore, there are bug reports and feature/change requests related to it - // that make it unreliable to use in this context. Please, DO NOT change this - // work-around until a better alternative is available. - elseif ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE)) + elseif ( ! method_exists($class, $method)) { $e404 = TRUE; } + /** + * DO NOT CHANGE THIS, NOTHING ELSE WORKS! + * + * - method_exists() returns true for non-public methods, which passes the previous elseif + * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct() + * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited + * - People will only complain if this doesn't work, even though it is documented that it shouldn't. + * + * ReflectionMethod::isConstructor() is the ONLY reliable check, + * knowing which method will be executed as a constructor. + */ + elseif ( ! is_callable(array($class, $method)) && strcasecmp($class, $method) === 0) + { + $reflection = new ReflectionMethod($class, $method); + if ( ! $reflection->isPublic() OR $reflection->isConstructor()) + { + $e404 = TRUE; + } + } } if ($e404) diff --git a/system/core/Common.php b/system/core/Common.php index b87ce4d..7b3eb6a 100755 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -355,7 +355,7 @@ function is_https() { return TRUE; } - elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') + elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') { return TRUE; } @@ -544,13 +544,18 @@ function set_status_header($code = 200, $text = '') 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 422 => 'Unprocessable Entity', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported' + 505 => 'HTTP Version Not Supported', + 511 => 'Network Authentication Required', ); if (isset($stati[$code])) @@ -598,7 +603,7 @@ function set_status_header($code = 200, $text = '') */ function _error_handler($severity, $message, $filepath, $line) { - $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); + $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); // When an error occurred, set the status header to '500 Internal Server Error' // to indicate to the client something went wrong. @@ -656,6 +661,7 @@ function _exception_handler($exception) $_error =& load_class('Exceptions', 'core'); $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); + is_cli() OR set_status_header(500); // Should we display the error? if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) { @@ -716,8 +722,8 @@ function remove_invisible_characters($str, $url_encoded = TRUE) // carriage return (dec 13) and horizontal tab (dec 09) if ($url_encoded) { - $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[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15 + $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31 } $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 diff --git a/system/core/Config.php b/system/core/Config.php index ca6fb37..cda6224 100755 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -319,7 +319,7 @@ public function base_url($uri = '', $protocol = NULL) } } - return $base_url.ltrim($this->_uri_string($uri), '/'); + return $base_url.$this->_uri_string($uri); } // ------------------------------------------------------------- @@ -337,11 +337,8 @@ protected function _uri_string($uri) { if ($this->item('enable_query_strings') === FALSE) { - if (is_array($uri)) - { - $uri = implode('/', $uri); - } - return trim($uri, '/'); + is_array($uri) && $uri = implode('/', $uri); + return ltrim($uri, '/'); } elseif (is_array($uri)) { diff --git a/system/core/Controller.php b/system/core/Controller.php index a0d97ba..59a9167 100755 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -47,7 +47,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/general/controllers.html + * @link https://codeigniter.com/user_guide/general/controllers.html */ class CI_Controller { diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index a1c6a19..47d153f 100755 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -207,7 +207,6 @@ public function show_exception($exception) } else { - set_status_header(500); $templates_path .= 'html'.DIRECTORY_SEPARATOR; } diff --git a/system/core/Hooks.php b/system/core/Hooks.php index 08479b1..f2d6f21 100755 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/encryption.html + * @link https://codeigniter.com/user_guide/general/hooks.html */ class CI_Hooks { diff --git a/system/core/Input.php b/system/core/Input.php index a7c9ecd..d7cd292 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -519,9 +519,9 @@ public function ip_address() if ($separator === ':') { $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); - for ($i = 0; $i < 8; $i++) + for ($j = 0; $j < 8; $j++) { - $netaddr[$i] = intval($netaddr[$i], 16); + $netaddr[$j] = intval($netaddr[$j], 16); } } else @@ -760,30 +760,32 @@ public function request_headers($xss_clean = FALSE) // If header is already defined, return it immediately if ( ! empty($this->headers)) { - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // In Apache, you can simply call apache_request_headers() if (function_exists('apache_request_headers')) { - return $this->headers = apache_request_headers(); + $this->headers = apache_request_headers(); } - - $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE'); - - foreach ($_SERVER as $key => $val) + else { - if (sscanf($key, 'HTTP_%s', $header) === 1) + isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; + + foreach ($_SERVER as $key => $val) { - // take SOME_HEADER and turn it into Some-Header - $header = str_replace('_', ' ', strtolower($header)); - $header = str_replace(' ', '-', ucwords($header)); + if (sscanf($key, 'HTTP_%s', $header) === 1) + { + // take SOME_HEADER and turn it into Some-Header + $header = str_replace('_', ' ', strtolower($header)); + $header = str_replace(' ', '-', ucwords($header)); - $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean); + $this->headers[$header] = $_SERVER[$key]; + } } } - return $this->headers; + return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // -------------------------------------------------------------------- diff --git a/system/core/Lang.php b/system/core/Lang.php index deb9554..569b023 100755 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Language * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/language.html + * @link https://codeigniter.com/user_guide/libraries/language.html */ class CI_Lang { diff --git a/system/core/Loader.php b/system/core/Loader.php index c742ae7..17ff236 100755 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -486,7 +486,7 @@ class_exists('CI_DB', FALSE) OR $this->database(); */ public function view($view, $vars = array(), $return = FALSE) { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); } // -------------------------------------------------------------------- @@ -519,19 +519,13 @@ public function file($path, $return = FALSE) */ public function vars($vars, $val = '') { - if (is_string($vars)) - { - $vars = array($vars => $val); - } - - $vars = $this->_ci_object_to_array($vars); + $vars = is_string($vars) + ? array($vars => $val) + : $this->_ci_prepare_view_vars($vars); - if (is_array($vars) && count($vars) > 0) + foreach ($vars as $key => $val) { - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } + $this->_ci_cached_vars[$key] = $val; } return $this; @@ -591,15 +585,21 @@ public function get_vars() */ public function helper($helpers = array()) { - foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper) + is_array($helpers) OR $helpers = array($helpers); + foreach ($helpers as &$helper) { + $filename = basename($helper); + $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); + $filename = strtolower(preg_replace('#(_helper)?(.php)?$#i', '', $filename)).'_helper'; + $helper = $filepath.$filename; + if (isset($this->_ci_helpers[$helper])) { continue; } // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$helper; + $ext_helper = config_item('subclass_prefix').$filename; $ext_loaded = FALSE; foreach ($this->_ci_helper_paths as $path) { @@ -934,18 +934,7 @@ protected function _ci_load($_ci_data) * the two types and cache them so that views that are embedded within * other views can have access to these variables. */ - if (is_array($_ci_vars)) - { - foreach (array_keys($_ci_vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($_ci_vars[$key]); - } - } - - $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - } + empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); extract($this->_ci_cached_vars); /* @@ -1106,7 +1095,7 @@ protected function _ci_load_library($class, $params = NULL, $object_name = NULL) * @used-by CI_Loader::_ci_load_library() * @uses CI_Loader::_ci_init_library() * - * @param string $library Library name to load + * @param string $library_name Library name to load * @param string $file_path Path to the library filename, relative to libraries/ * @param mixed $params Optional parameters to pass to the class constructor * @param string $object_name Optional object name to assign to @@ -1376,17 +1365,32 @@ protected function _ci_autoloader() // -------------------------------------------------------------------- /** - * CI Object to Array translator + * Prepare variables for _ci_vars, to be later extract()-ed inside views * - * Takes an object as input and converts the class variables to - * an associative array with key/value pairs. + * Converts objects to associative arrays and filters-out internal + * variable names (i.e. keys prexied with '_ci_'). * - * @param object $object Object data to translate + * @param mixed $vars * @return array */ - protected function _ci_object_to_array($object) + protected function _ci_prepare_view_vars($vars) { - return is_object($object) ? get_object_vars($object) : $object; + if ( ! is_array($vars)) + { + $vars = is_object($vars) + ? get_object_vars($object) + : array(); + } + + foreach (array_keys($vars) as $key) + { + if (strncmp($key, '_ci_', 4) === 0) + { + unset($vars[$key]); + } + } + + return $vars; } // -------------------------------------------------------------------- @@ -1404,34 +1408,4 @@ protected function &_ci_get_component($component) $CI =& get_instance(); return $CI->$component; } - - // -------------------------------------------------------------------- - - /** - * Prep filename - * - * This function prepares filenames of various items to - * make their loading more reliable. - * - * @param string|string[] $filename Filename(s) - * @param string $extension Filename extension - * @return array - */ - protected function _ci_prep_filename($filename, $extension) - { - if ( ! is_array($filename)) - { - return array(strtolower(str_replace(array($extension, '.php'), '', $filename).$extension)); - } - else - { - foreach ($filename as $key => $val) - { - $filename[$key] = strtolower(str_replace(array($extension, '.php'), '', $val).$extension); - } - - return $filename; - } - } - } diff --git a/system/core/Log.php b/system/core/Log.php index 1abdaa0..3e11b35 100755 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -104,6 +104,13 @@ class CI_Log { */ protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4); + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + // -------------------------------------------------------------------- /** @@ -115,6 +122,8 @@ public function __construct() { $config =& get_config(); + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + $this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/'; $this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '') ? ltrim($config['log_file_extension'], '.') : 'php'; @@ -208,9 +217,9 @@ public function write_log($level, $msg) $message .= $this->_format_line($level, $date, $msg); - for ($written = 0, $length = strlen($message); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($message, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($message, $written))) === FALSE) { break; } @@ -237,11 +246,51 @@ public function write_log($level, $msg) * * @param string $level The error level * @param string $date Formatted date string - * @param string $msg The log message + * @param string $message The log message * @return string Formatted log line with a new line character '\n' at the end */ protected function _format_line($level, $date, $message) { return $level.' - '.$date.' --> '.$message."\n"; } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_override) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/core/Model.php b/system/core/Model.php index a0469de..c809e7b 100755 --- a/system/core/Model.php +++ b/system/core/Model.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/config.html + * @link https://codeigniter.com/user_guide/libraries/config.html */ class CI_Model { diff --git a/system/core/Output.php b/system/core/Output.php index ec9c21b..349955c 100755 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -122,6 +122,13 @@ class CI_Output { */ public $parse_exec_vars = TRUE; + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + /** * Class constructor * @@ -138,6 +145,8 @@ public function __construct() && extension_loaded('zlib') ); + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + // Get mime types for later $this->mimes =& get_mimes(); @@ -285,7 +294,7 @@ public function get_content_type() /** * Get Header * - * @param string $header_name + * @param string $header * @return string */ public function get_header($header) @@ -302,11 +311,12 @@ public function get_header($header) return NULL; } - for ($i = 0, $c = count($headers); $i < $c; $i++) + // Count backwards, in order to get the last matching header + for ($c = count($headers) - 1; $c > -1; $c--) { - if (strncasecmp($header, $headers[$i], $l = strlen($header)) === 0) + if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0) { - return trim(substr($headers[$i], $l+1)); + return trim(self::substr($headers[$c], $l+1)); } } @@ -480,13 +490,13 @@ public function _display($output = '') if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { header('Content-Encoding: gzip'); - header('Content-Length: '.strlen($output)); + header('Content-Length: '.self::strlen($output)); } else { // User agent doesn't support gzip compression, // so we'll have to decompress our cache - $output = gzinflate(substr($output, 10, -8)); + $output = gzinflate(self::substr($output, 10, -8)); } } @@ -601,9 +611,9 @@ public function _write_cache($output) $output = $cache_info.'ENDCI--->'.$output; - for ($written = 0, $length = strlen($output); $written < $length; $written += $result) + for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($output, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($output, $written))) === FALSE) { break; } @@ -711,7 +721,7 @@ public function _display_cache(&$CFG, &$URI) } // Display the cache - $this->_display(substr($cache, strlen($match[0]))); + $this->_display(self::substr($cache, self::strlen($match[0]))); log_message('debug', 'Cache file is current. Sending it to browser.'); return TRUE; } @@ -797,4 +807,43 @@ public function set_cache_header($last_modified, $expiration) } } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_override) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/core/Router.php b/system/core/Router.php index 045d366..1abe4c4 100755 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Security.php b/system/core/Security.php index d5305d1..585ed90 100755 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -133,15 +133,16 @@ class CI_Security { * @var array */ protected $_never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - '-moz-binding' => '[removed]', - '' => '-->', - ' '<![CDATA[', - '' => '<comment>' + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[', + '' => '<comment>', + '<%' => '<%' ); /** @@ -223,14 +224,11 @@ public function csrf_verify() } } - // Do the tokens exist in both the _POST and _COOKIE arrays? - if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) - OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match? - { - $this->csrf_show_error(); - } + // Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate + $valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) + && hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]); - // We kill this since we're done and we don't want to polute the _POST array + // We kill this since we're done and we don't want to pollute the _POST array unset($_POST[$this->_csrf_token_name]); // Regenerate on every submission? @@ -244,6 +242,11 @@ public function csrf_verify() $this->_csrf_set_hash(); $this->csrf_set_cookie(); + if ($valid !== TRUE) + { + $this->csrf_show_error(); + } + log_message('info', 'CSRF token verified'); return $this; } @@ -371,11 +374,17 @@ public function xss_clean($str, $is_image = FALSE) * * Note: Use rawurldecode() so it does not remove plus signs */ - do + if (stripos($str, '%') !== false) { - $str = rawurldecode($str); + do + { + $oldstr = $str; + $str = rawurldecode($str); + $str = preg_replace_callback('#%(?:\s*[0-9a-f]){2,}#i', array($this, '_urldecodespaces'), $str); + } + while ($oldstr !== $str); + unset($oldstr); } - while (preg_match('/%[0-9a-f]{2,}/i', $str)); /* * Convert character entities to ASCII @@ -466,7 +475,7 @@ public function xss_clean($str, $is_image = FALSE) if (preg_match('/]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); + $str = preg_replace_callback('#]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); } if (preg_match('//*\s*)(?[a-z0-9]+)(?=[^a-z0-9]|$)' // tag start and name, followed by a non-tag character + .'<((?/*\s*)((?[a-z0-9]+)(?=[^a-z0-9]|$)|.+)' // tag start and name, followed by a non-tag character .'[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator // optional attributes .'(?(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons @@ -669,6 +678,22 @@ public function entity_decode($str, $charset = NULL) ? ENT_COMPAT | ENT_HTML5 : ENT_COMPAT; + if ( ! isset($_entities)) + { + $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset)); + + // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 + // entities to the array manually + if ($flag === ENT_COMPAT) + { + $_entities[':'] = ':'; + $_entities['('] = '('; + $_entities[')'] = ')'; + $_entities["\n"] = ' '; + $_entities["\t"] = ' '; + } + } + do { $str_compare = $str; @@ -676,27 +701,6 @@ public function entity_decode($str, $charset = NULL) // Decode standard entities, avoiding false positives if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) { - if ( ! isset($_entities)) - { - $_entities = array_map( - 'strtolower', - is_php('5.3.4') - ? get_html_translation_table(HTML_ENTITIES, $flag, $charset) - : get_html_translation_table(HTML_ENTITIES, $flag) - ); - - // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 - // entities to the array manually - if ($flag === ENT_COMPAT) - { - $_entities[':'] = ':'; - $_entities['('] = '('; - $_entities[')'] = ')'; - $_entities["\n"] = '&newline;'; - $_entities["\t"] = '&tab;'; - } - } - $replace = array(); $matches = array_unique(array_map('strtolower', $matches[0])); foreach ($matches as &$match) @@ -707,7 +711,7 @@ public function entity_decode($str, $charset = NULL) } } - $str = str_ireplace(array_keys($replace), array_values($replace), $str); + $str = str_replace(array_keys($replace), array_values($replace), $str); } // Decode numeric & UTF16 two byte entities @@ -716,6 +720,11 @@ public function entity_decode($str, $charset = NULL) $flag, $charset ); + + if ($flag === ENT_COMPAT) + { + $str = str_replace(array_values($_entities), array_keys($_entities), $str); + } } while ($str_compare !== $str); return $str; @@ -774,6 +783,24 @@ public function strip_image_tags($str) // ---------------------------------------------------------------- + /** + * URL-decode taking spaces into account + * + * @see https://github.com/bcit-ci/CodeIgniter/issues/4877 + * @param array $matches + * @return string + */ + protected function _urldecodespaces($matches) + { + $input = $matches[0]; + $nospaces = preg_replace('#\s+#', '', $input); + return ($nospaces === $input) + ? $input + : rawurldecode($nospaces); + } + + // ---------------------------------------------------------------- + /** * Compact Exploded Words * @@ -803,7 +830,7 @@ protected function _compact_exploded_words($matches) protected function _sanitize_naughty_html($matches) { static $naughty_tags = array( - 'alert', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', + 'alert', 'area', 'prompt', 'confirm', 'applet', 'audio', 'basefont', 'base', 'behavior', 'bgsound', 'blink', 'body', 'embed', 'expression', 'form', 'frameset', 'frame', 'head', 'html', 'ilayer', 'iframe', 'input', 'button', 'select', 'isindex', 'layer', 'link', 'meta', 'keygen', 'object', 'plaintext', 'style', 'script', 'textarea', 'title', 'math', 'video', 'svg', 'xml', 'xss' @@ -900,7 +927,7 @@ protected function _js_link_removal($match) return str_replace( $match[1], preg_replace( - '#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|_filter_attributes($match[1]) ), diff --git a/system/core/URI.php b/system/core/URI.php index 544f6c8..3ccdfa7 100755 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/core/Utf8.php b/system/core/Utf8.php index 9d8ac41..dfbbfff 100755 --- a/system/core/Utf8.php +++ b/system/core/Utf8.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category UTF-8 * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/utf8.html + * @link https://codeigniter.com/user_guide/libraries/utf8.html */ class CI_Utf8 { diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php index 1595455..ba0198e 100755 --- a/system/core/compat/hash.php +++ b/system/core/compat/hash.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ * @link http://php.net/hash */ @@ -119,7 +119,7 @@ function hash_equals($known_string, $user_string) */ function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE) { - if ( ! in_array($algo, hash_algos(), TRUE)) + if ( ! in_array(strtolower($algo), hash_algos(), TRUE)) { trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING); return FALSE; diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php index e335c85..f466e1c 100755 --- a/system/core/compat/mbstring.php +++ b/system/core/compat/mbstring.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ * @link http://php.net/mbstring */ diff --git a/system/core/compat/password.php b/system/core/compat/password.php index 7b933aa..b209cbe 100755 --- a/system/core/compat/password.php +++ b/system/core/compat/password.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,13 +44,13 @@ * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ * @link http://php.net/password */ // ------------------------------------------------------------------------ -if (is_php('5.5') OR ! is_php('5.3.7') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION')) +if (is_php('5.5') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION')) { return; } @@ -116,13 +116,21 @@ function password_hash($password, $algo, array $options = array()) } elseif ( ! isset($options['salt'])) { - if (defined('MCRYPT_DEV_URANDOM')) + if (function_exists('random_bytes')) { - $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); + try + { + $options['salt'] = random_bytes(16); + } + catch (Exception $e) + { + log_message('error', 'compat/password: Error while trying to use random_bytes(): '.$e->getMessage()); + return FALSE; + } } - elseif (function_exists('openssl_random_pseudo_bytes')) + elseif (defined('MCRYPT_DEV_URANDOM')) { - $options['salt'] = openssl_random_pseudo_bytes(16); + $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); } elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom'))) { @@ -148,6 +156,16 @@ function password_hash($password, $algo, array $options = array()) fclose($fp); } + elseif (function_exists('openssl_random_pseudo_bytes')) + { + $is_secure = NULL; + $options['salt'] = openssl_random_pseudo_bytes(16, $is_secure); + if ($is_secure !== TRUE) + { + log_message('error', 'compat/password: openssl_random_pseudo_bytes() set the $cryto_strong flag to FALSE'); + return FALSE; + } + } else { log_message('error', 'compat/password: No CSPRNG available.'); diff --git a/system/core/compat/standard.php b/system/core/compat/standard.php index 5a428c1..7db2efb 100755 --- a/system/core/compat/standard.php +++ b/system/core/compat/standard.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage CodeIgniter * @category Compatibility * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/ + * @link https://codeigniter.com/user_guide/ */ // ------------------------------------------------------------------------ @@ -62,7 +62,7 @@ * array_column() * * @link http://php.net/array_column - * @param string $array + * @param array $array * @param mixed $column_key * @param mixed $index_key * @return array @@ -153,7 +153,7 @@ function array_column(array $array, $column_key, $index_key = NULL) */ function hex2bin($data) { - if (in_array($type = gettype($data), array('array', 'double', 'object'), TRUE)) + if (in_array($type = gettype($data), array('array', 'double', 'object', 'resource'), TRUE)) { if ($type === 'object' && method_exists($data, '__toString')) { @@ -180,210 +180,3 @@ function hex2bin($data) return pack('H*', $data); } } - -// ------------------------------------------------------------------------ - -if (is_php('5.3')) -{ - return; -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('array_replace')) -{ - /** - * array_replace() - * - * @link http://php.net/array_replace - * @return array - */ - function array_replace() - { - $arrays = func_get_args(); - - if (($c = count($arrays)) === 0) - { - trigger_error('array_replace() expects at least 1 parameter, 0 given', E_USER_WARNING); - return NULL; - } - elseif ($c === 1) - { - if ( ! is_array($arrays[0])) - { - trigger_error('array_replace(): Argument #1 is not an array', E_USER_WARNING); - return NULL; - } - - return $arrays[0]; - } - - $array = array_shift($arrays); - $c--; - - for ($i = 0; $i < $c; $i++) - { - if ( ! is_array($arrays[$i])) - { - trigger_error('array_replace(): Argument #'.($i + 2).' is not an array', E_USER_WARNING); - return NULL; - } - elseif (empty($arrays[$i])) - { - continue; - } - - foreach (array_keys($arrays[$i]) as $key) - { - $array[$key] = $arrays[$i][$key]; - } - } - - return $array; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('array_replace_recursive')) -{ - /** - * array_replace_recursive() - * - * @link http://php.net/array_replace_recursive - * @return array - */ - function array_replace_recursive() - { - $arrays = func_get_args(); - - if (($c = count($arrays)) === 0) - { - trigger_error('array_replace_recursive() expects at least 1 parameter, 0 given', E_USER_WARNING); - return NULL; - } - elseif ($c === 1) - { - if ( ! is_array($arrays[0])) - { - trigger_error('array_replace_recursive(): Argument #1 is not an array', E_USER_WARNING); - return NULL; - } - - return $arrays[0]; - } - - $array = array_shift($arrays); - $c--; - - for ($i = 0; $i < $c; $i++) - { - if ( ! is_array($arrays[$i])) - { - trigger_error('array_replace_recursive(): Argument #'.($i + 2).' is not an array', E_USER_WARNING); - return NULL; - } - elseif (empty($arrays[$i])) - { - continue; - } - - foreach (array_keys($arrays[$i]) as $key) - { - $array[$key] = (is_array($arrays[$i][$key]) && isset($array[$key]) && is_array($array[$key])) - ? array_replace_recursive($array[$key], $arrays[$i][$key]) - : $arrays[$i][$key]; - } - } - - return $array; - } -} - -// ------------------------------------------------------------------------ - -if ( ! function_exists('quoted_printable_encode')) -{ - /** - * quoted_printable_encode() - * - * @link http://php.net/quoted_printable_encode - * @param string $str - * @return string - */ - function quoted_printable_encode($str) - { - if (strlen($str) === 0) - { - return ''; - } - elseif (in_array($type = gettype($str), array('array', 'object'), TRUE)) - { - if ($type === 'object' && method_exists($str, '__toString')) - { - $str = (string) $str; - } - else - { - trigger_error('quoted_printable_encode() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING); - return NULL; - } - } - - if (function_exists('imap_8bit')) - { - return imap_8bit($str); - } - - $i = $lp = 0; - $output = ''; - $hex = '0123456789ABCDEF'; - $length = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')) - ? mb_strlen($str, '8bit') - : strlen($str); - - while ($length--) - { - if ((($c = $str[$i++]) === "\015") && isset($str[$i]) && ($str[$i] === "\012") && $length > 0) - { - $output .= "\015".$str[$i++]; - $length--; - $lp = 0; - continue; - } - - if ( - ctype_cntrl($c) - OR (ord($c) === 0x7f) - OR (ord($c) & 0x80) - OR ($c === '=') - OR ($c === ' ' && isset($str[$i]) && $str[$i] === "\015") - ) - { - if ( - (($lp += 3) > 75 && ord($c) <= 0x7f) - OR (ord($c) > 0x7f && ord($c) <= 0xdf && ($lp + 3) > 75) - OR (ord($c) > 0xdf && ord($c) <= 0xef && ($lp + 6) > 75) - OR (ord($c) > 0xef && ord($c) <= 0xf4 && ($lp + 9) > 75) - ) - { - $output .= "=\015\012"; - $lp = 3; - } - - $output .= '='.$hex[ord($c) >> 4].$hex[ord($c) & 0xf]; - continue; - } - - if ((++$lp) > 75) - { - $output .= "=\015\012"; - $lp = 1; - } - - $output .= $c; - } - - return $output; - } -} diff --git a/system/database/DB.php b/system/database/DB.php index 0c7cf54..c19eef7 100755 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ * * @param string|string[] $params * @param bool $query_builder_override diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php index 223055f..b74c319 100755 --- a/system/database/DB_cache.php +++ b/system/database/DB_cache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_Cache { diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 848516a..19afdd4 100755 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -980,7 +980,7 @@ public function trans_rollback() */ public function compile_binds($sql, $binds) { - if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) + if (empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) { return $sql; } @@ -1000,7 +1000,7 @@ public function compile_binds($sql, $binds) $ml = strlen($this->bind_marker); // Make sure not to replace a chunk inside a string that happens to match the bind marker - if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) + if ($c = preg_match_all("/'[^']*'|\"[^\"]*\"/i", $sql, $matches)) { $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', str_replace($matches[0], diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index 826aa1e..7289235 100755 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -184,7 +184,7 @@ public function create_database($db_name) { return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; } - elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat))) + elseif ( ! $this->db->query(sprintf($this->_create_database, $this->db->escape_identifiers($db_name), $this->db->char_set, $this->db->dbcollat))) { return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; } @@ -211,7 +211,7 @@ public function drop_database($db_name) { return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; } - elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name))) + elseif ( ! $this->db->query(sprintf($this->_drop_database, $this->db->escape_identifiers($db_name)))) { return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; } @@ -348,7 +348,7 @@ public function create_table($table, $if_not_exists = FALSE, array $attributes = if (($result = $this->db->query($sql)) !== FALSE) { - empty($this->db->data_cache['table_names']) OR $this->db->data_cache['table_names'][] = $table; + isset($this->db->data_cache['table_names']) && $this->db->data_cache['table_names'][] = $table; // Most databases don't support creating indexes from within the CREATE TABLE statement if ( ! empty($this->keys)) diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index c862d93..ab19d97 100755 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -149,6 +149,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver { */ protected $qb_set = array(); + /** + * QB data set for update_batch() + * + * @var array + */ + protected $qb_set_ub = array(); + /** * QB aliased tables list * @@ -679,7 +686,7 @@ protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = N // value appears not to have been set, assign the test to IS NULL $k .= ' IS NULL'; } - elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) + elseif (preg_match('/\s*(!?=|<>|\sIS(?:\s+NOT)?\s)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) { $k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL'); } @@ -1271,7 +1278,7 @@ public function offset($offset) */ protected function _limit($sql) { - return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').$this->qb_limit; + return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').(int) $this->qb_limit; } // -------------------------------------------------------------------- @@ -1395,7 +1402,7 @@ public function count_all_results($table = '', $reset = TRUE) $this->qb_orderby = NULL; } - $result = ($this->qb_distinct === TRUE) + $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby)) ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results") : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows'))); @@ -1498,8 +1505,10 @@ public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = $affected_rows = 0; for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) { - $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size))); - $affected_rows += $this->affected_rows(); + if ($this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size)))) + { + $affected_rows += $this->affected_rows(); + } } $this->_reset_write(); @@ -1544,7 +1553,7 @@ public function set_insert_batch($key, $value = '', $escape = NULL) is_bool($escape) OR $escape = $this->_protect_identifiers; - $keys = array_keys($this->_object_to_array(current($key))); + $keys = array_keys($this->_object_to_array(reset($key))); sort($keys); foreach ($key as $row) @@ -1884,7 +1893,7 @@ public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 1 if ($set === NULL) { - if (empty($this->qb_set)) + if (empty($this->qb_set_ub)) { return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE; } @@ -1911,10 +1920,13 @@ public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 1 // Batch this baby $affected_rows = 0; - for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size) + for ($i = 0, $total = count($this->qb_set_ub); $i < $total; $i += $batch_size) { - $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index))); - $affected_rows += $this->affected_rows(); + if ($this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set_ub, $i, $batch_size), $index))) + { + $affected_rows += $this->affected_rows(); + } + $this->qb_where = array(); } @@ -1939,13 +1951,13 @@ protected function _update_batch($table, $values, $index) $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['field'].' = '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -1958,7 +1970,7 @@ protected function _update_batch($table, $values, $index) .'ELSE '.$k.' END, '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } @@ -1995,7 +2007,10 @@ public function set_update_batch($key, $index = '', $escape = NULL) $index_set = TRUE; } - $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2); + $clean[$k2] = array( + 'field' => $this->protect_identifiers($k2, FALSE, $escape), + 'value' => ($escape === FALSE ? $v2 : $this->escape($v2)) + ); } if ($index_set === FALSE) @@ -2003,7 +2018,7 @@ public function set_update_batch($key, $index = '', $escape = NULL) return $this->display_error('db_batch_missing_index'); } - $this->qb_set[] = $clean; + $this->qb_set_ub[] = $clean; } return $this; @@ -2335,7 +2350,7 @@ protected function _compile_select($select_override = FALSE) .$this->_compile_order_by(); // ORDER BY // LIMIT - if ($this->qb_limit) + if ($this->qb_limit OR $this->qb_offset) { return $this->_limit($sql."\n"); } @@ -2770,6 +2785,7 @@ protected function _reset_write() { $this->_reset_run(array( 'qb_set' => array(), + 'qb_set_ub' => array(), 'qb_from' => array(), 'qb_join' => array(), 'qb_where' => array(), diff --git a/system/database/DB_result.php b/system/database/DB_result.php index 746f2a1..98d8876 100755 --- a/system/database/DB_result.php +++ b/system/database/DB_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_result { @@ -660,7 +660,7 @@ protected function _fetch_assoc() */ protected function _fetch_object($class_name = 'stdClass') { - return array(); + return new $class_name(); } } diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php index 7052828..25d842c 100755 --- a/system/database/DB_utility.php +++ b/system/database/DB_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php index 77f591c..257925d 100755 --- a/system/database/drivers/cubrid/cubrid_driver.php +++ b/system/database/drivers/cubrid/cubrid_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php index 9484e94..27bfc14 100755 --- a/system/database/drivers/cubrid/cubrid_forge.php +++ b/system/database/drivers/cubrid/cubrid_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author Esen Sagynov - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_cubrid_forge extends CI_DB_forge { @@ -178,6 +178,9 @@ protected function _attr_type(&$attributes) $attributes['TYPE'] = 'INTEGER'; $attributes['UNSIGNED'] = FALSE; return; + case 'LONGTEXT': + $attributes['TYPE'] = 'STRING'; + return; default: return; } } diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php index e666bab..251b70a 100755 --- a/system/database/drivers/cubrid/cubrid_result.php +++ b/system/database/drivers/cubrid/cubrid_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author Esen Sagynov - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_cubrid_result extends CI_DB_result { diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php index de7d715..555ae7a 100755 --- a/system/database/drivers/cubrid/cubrid_utility.php +++ b/system/database/drivers/cubrid/cubrid_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author Esen Sagynov - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_cubrid_utility extends CI_DB_utility { diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php index c1055c1..106d5ef 100755 --- a/system/database/drivers/ibase/ibase_driver.php +++ b/system/database/drivers/ibase/ibase_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -383,6 +383,23 @@ protected function _limit($sql) // -------------------------------------------------------------------- + /** + * Insert batch statement + * + * Generates a platform-specific insert string from the supplied data. + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * @return string|bool + */ + protected function _insert_batch($table, $keys, $values) + { + return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + } + + // -------------------------------------------------------------------- + /** * Close DB Connection * diff --git a/system/database/drivers/ibase/ibase_forge.php b/system/database/drivers/ibase/ibase_forge.php index 0e748c7..44bb24e 100755 --- a/system/database/drivers/ibase/ibase_forge.php +++ b/system/database/drivers/ibase/ibase_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_ibase_forge extends CI_DB_forge { @@ -111,7 +111,7 @@ public function create_database($db_name) * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! ibase_drop_db($this->conn_id)) { diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php index 991146f..7d7dd79 100755 --- a/system/database/drivers/ibase/ibase_result.php +++ b/system/database/drivers/ibase/ibase_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_ibase_result extends CI_DB_result { diff --git a/system/database/drivers/ibase/ibase_utility.php b/system/database/drivers/ibase/ibase_utility.php index 79d2788..3c15210 100755 --- a/system/database/drivers/ibase/ibase_utility.php +++ b/system/database/drivers/ibase/ibase_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_ibase_utility extends CI_DB_utility { diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php index d40d67a..f0cfb2f 100755 --- a/system/database/drivers/mssql/mssql_driver.php +++ b/system/database/drivers/mssql/mssql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -158,6 +158,7 @@ public function db_select($database = '') if (mssql_select_db('['.$database.']', $this->conn_id)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php index 84406a0..6b61098 100755 --- a/system/database/drivers/mssql/mssql_forge.php +++ b/system/database/drivers/mssql/mssql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mssql_forge extends CI_DB_forge { @@ -113,6 +113,11 @@ protected function _alter_table($alter_type, $table, $field) */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php index c1c42a4..38a0a05 100755 --- a/system/database/drivers/mssql/mssql_result.php +++ b/system/database/drivers/mssql/mssql_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mssql_result extends CI_DB_result { diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php index 1040b5e..95ce88f 100755 --- a/system/database/drivers/mssql/mssql_utility.php +++ b/system/database/drivers/mssql/mssql_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mssql_utility extends CI_DB_utility { diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index 78b1d70..8f2dd74 100755 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -208,6 +208,7 @@ public function db_select($database = '') if (mysql_select_db($database, $this->conn_id)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php index cb90065..7ed8f8d 100755 --- a/system/database/drivers/mysql/mysql_forge.php +++ b/system/database/drivers/mysql/mysql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysql_forge extends CI_DB_forge { diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php index 26aaddd..7aa265e 100755 --- a/system/database/drivers/mysql/mysql_result.php +++ b/system/database/drivers/mysql/mysql_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysql_result extends CI_DB_result { diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php index 55857ab..bc01fc5 100755 --- a/system/database/drivers/mysql/mysql_utility.php +++ b/system/database/drivers/mysql/mysql_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysql_utility extends CI_DB_utility { diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index 06c3418..7e42904 100755 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -125,8 +125,7 @@ public function db_connect($persistent = FALSE) } else { - // Persistent connection support was added in PHP 5.3.0 - $hostname = ($persistent === TRUE && is_php('5.3')) + $hostname = ($persistent === TRUE) ? 'p:'.$this->hostname : $this->hostname; $port = empty($this->port) ? NULL : $this->port; $socket = NULL; @@ -184,7 +183,7 @@ public function db_connect($persistent = FALSE) // https://bugs.php.net/bug.php?id=68344 elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) { - $this->_mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, TRUE); + $client_flags |= MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; } } @@ -256,6 +255,7 @@ public function db_select($database = '') if ($this->conn_id->select_db($database)) { $this->database = $database; + $this->data_cache = array(); return TRUE; } @@ -501,8 +501,8 @@ public function error() if ( ! empty($this->_mysqli->connect_errno)) { return array( - 'code' => $this->_mysqli->connect_errno, - 'message' => is_php('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error() + 'code' => $this->_mysqli->connect_errno, + 'message' => $this->_mysqli->connect_error ); } diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php index 196afa8..c5b23b6 100755 --- a/system/database/drivers/mysqli/mysqli_forge.php +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysqli_forge extends CI_DB_forge { diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php index d648828..929c2b4 100755 --- a/system/database/drivers/mysqli/mysqli_result.php +++ b/system/database/drivers/mysqli/mysqli_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysqli_result extends CI_DB_result { diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php index 04fcd1d..4a3dad4 100755 --- a/system/database/drivers/mysqli/mysqli_utility.php +++ b/system/database/drivers/mysqli/mysqli_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_mysqli_utility extends CI_DB_utility { diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index 59f0e84..c7f0330 100755 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.4.1 @@ -386,7 +386,7 @@ protected function _bind_params($params) */ protected function _trans_begin() { - $this->commit_mode = is_php('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; + $this->commit_mode = OCI_NO_AUTO_COMMIT; return TRUE; } @@ -559,23 +559,29 @@ public function field_data($table) */ public function error() { - /* oci_error() returns an array that already contains the - * 'code' and 'message' keys, so we can just return it. - */ + // oci_error() returns an array that already contains + // 'code' and 'message' keys, but it can return false + // if there was no error .... if (is_resource($this->curs_id)) { - return oci_error($this->curs_id); + $error = oci_error($this->curs_id); } elseif (is_resource($this->stmt_id)) { - return oci_error($this->stmt_id); + $error = oci_error($this->stmt_id); } elseif (is_resource($this->conn_id)) { - return oci_error($this->conn_id); + $error = oci_error($this->conn_id); + } + else + { + $error = oci_error(); } - return oci_error(); + return is_array($error) + ? $error + : array('code' => '', 'message' => ''); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php index 8010097..867a943 100755 --- a/system/database/drivers/oci8/oci8_forge.php +++ b/system/database/drivers/oci8/oci8_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.4.1 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_oci8_forge extends CI_DB_forge { @@ -53,6 +53,13 @@ class CI_DB_oci8_forge extends CI_DB_forge { */ protected $_create_database = FALSE; + /** + * CREATE TABLE IF statement + * + * @var string + */ + protected $_create_table_if = FALSE; + /** * DROP DATABASE statement * @@ -119,6 +126,8 @@ protected function _alter_table($alter_type, $table, $field) $sqls[] = $sql.' RENAME COLUMN '.$this->db->escape_identifiers($field[$i]['name']) .' '.$this->db->escape_identifiers($field[$i]['new_name']); } + + $field[$i] = "\n\t".$field[$i]['_literal']; } } @@ -129,7 +138,7 @@ protected function _alter_table($alter_type, $table, $field) // RENAME COLUMN must be executed after MODIFY array_unshift($sqls, $sql); - return $sql; + return $sqls; } // -------------------------------------------------------------------- @@ -146,4 +155,33 @@ protected function _attr_auto_increment(&$attributes, &$field) // Not supported - sequences and triggers must be used instead } + // -------------------------------------------------------------------- + + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * @return void + */ + protected function _attr_type(&$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'TINYINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'MEDIUMINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'INT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'BIGINT': + $attributes['TYPE'] = 'NUMBER'; + return; + default: return; + } + } } diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php index 9ec54cc..0c35433 100755 --- a/system/database/drivers/oci8/oci8_result.php +++ b/system/database/drivers/oci8/oci8_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.4.1 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_oci8_result extends CI_DB_result { diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php index 90022a8..ce0dfc5 100755 --- a/system/database/drivers/oci8/oci8_utility.php +++ b/system/database/drivers/oci8/oci8_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.4.1 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_oci8_utility extends CI_DB_utility { diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php index 19b7b74..9f5a86f 100755 --- a/system/database/drivers/odbc/odbc_driver.php +++ b/system/database/drivers/odbc/odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -50,7 +50,7 @@ * @author EllisLab Dev Team * @link https://codeigniter.com/user_guide/database/ */ -class CI_DB_odbc_driver extends CI_DB { +class CI_DB_odbc_driver extends CI_DB_driver { /** * Database driver @@ -93,6 +93,22 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * ODBC result ID resource returned from odbc_prepare() + * + * @var resource + */ + private $odbc_result; + + /** + * Values to use with odbc_execute() for prepared statements + * + * @var array + */ + private $binds = array(); + + // -------------------------------------------------------------------- + /** * Class constructor * @@ -127,6 +143,74 @@ public function db_connect($persistent = FALSE) // -------------------------------------------------------------------- + /** + * Compile Bindings + * + * @param string $sql SQL statement + * @param array $binds An array of values to bind + * @return string + */ + public function compile_binds($sql, $binds) + { + if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE) + { + return $sql; + } + elseif ( ! is_array($binds)) + { + $binds = array($binds); + $bind_count = 1; + } + else + { + // Make sure we're using numeric keys + $binds = array_values($binds); + $bind_count = count($binds); + } + + // We'll need the marker length later + $ml = strlen($this->bind_marker); + + // Make sure not to replace a chunk inside a string that happens to match the bind marker + if ($c = preg_match_all("/'[^']*'|\"[^\"]*\"/i", $sql, $matches)) + { + $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', + str_replace($matches[0], + str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), + $sql, $c), + $matches, PREG_OFFSET_CAPTURE); + + // Bind values' count must match the count of markers in the query + if ($bind_count !== $c) + { + return $sql; + } + } + elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) + { + return $sql; + } + + if ($this->bind_marker !== '?') + { + do + { + $c--; + $sql = substr_replace($sql, '?', $matches[0][$c][1], $ml); + } + while ($c !== 0); + } + + if (FALSE !== ($this->odbc_result = odbc_prepare($this->conn_id, $sql))) + { + $this->binds = array_values($binds); + } + + return $sql; + } + + // -------------------------------------------------------------------- + /** * Execute the query * @@ -135,7 +219,25 @@ public function db_connect($persistent = FALSE) */ protected function _execute($sql) { - return odbc_exec($this->conn_id, $sql); + if ( ! isset($this->odbc_result)) + { + return odbc_exec($this->conn_id, $sql); + } + elseif ($this->odbc_result === FALSE) + { + return FALSE; + } + + if (TRUE === ($success = odbc_execute($this->odbc_result, $this->binds))) + { + // For queries that return result sets, return the result_id resource on success + $this->is_write_type($sql) OR $success = $this->odbc_result; + } + + $this->odbc_result = NULL; + $this->binds = array(); + + return $success; } // -------------------------------------------------------------------- @@ -196,7 +298,7 @@ protected function _trans_rollback() */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -214,7 +316,7 @@ public function is_write_type($sql) */ protected function _escape_str($str) { - return remove_invisible_characters($str); + $this->db->display_error('db_unsupported_feature'); } // -------------------------------------------------------------------- @@ -311,58 +413,6 @@ public function error() // -------------------------------------------------------------------- - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string $table - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - /** * Close DB Connection * @@ -372,5 +422,4 @@ protected function _close() { odbc_close($this->conn_id); } - } diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php index 45c5dc1..77b2fdf 100755 --- a/system/database/drivers/odbc/odbc_forge.php +++ b/system/database/drivers/odbc/odbc_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/database/ + * @link https://codeigniter.com/database/ */ class CI_DB_odbc_forge extends CI_DB_forge { diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php index 10b93d4..845aa9c 100755 --- a/system/database/drivers/odbc/odbc_result.php +++ b/system/database/drivers/odbc/odbc_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_odbc_result extends CI_DB_result { diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php index 0e6c233..643f6ec 100755 --- a/system/database/drivers/odbc/odbc_utility.php +++ b/system/database/drivers/odbc/odbc_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/database/ + * @link https://codeigniter.com/database/ */ class CI_DB_odbc_utility extends CI_DB_utility { diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index c6f84e0..d816dcb 100755 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.1.0 @@ -126,7 +126,10 @@ public function __construct($params) */ public function db_connect($persistent = FALSE) { - $this->options[PDO::ATTR_PERSISTENT] = $persistent; + if ($persistent === TRUE) + { + $this->options[PDO::ATTR_PERSISTENT] = TRUE; + } try { @@ -307,52 +310,6 @@ public function error() // -------------------------------------------------------------------- - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k.' = CASE '."\n"; - - foreach ($v as $row) - { - $cases .= $row."\n"; - } - - $cases .= 'ELSE '.$k.' END, '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - /** * Truncate statement * diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php index eedd972..685b677 100755 --- a/system/database/drivers/pdo/pdo_forge.php +++ b/system/database/drivers/pdo/pdo_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/database/ + * @link https://codeigniter.com/database/ */ class CI_DB_pdo_forge extends CI_DB_forge { diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php index fe26fea..bbc2cdc 100755 --- a/system/database/drivers/pdo/pdo_result.php +++ b/system/database/drivers/pdo/pdo_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_result extends CI_DB_result { diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php index 72169c3..5029cac 100755 --- a/system/database/drivers/pdo/pdo_utility.php +++ b/system/database/drivers/pdo/pdo_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.1.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/database/ + * @link https://codeigniter.com/database/ */ class CI_DB_pdo_utility extends CI_DB_utility { diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php index cf5a0c7..7eaeaa1 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_4d_driver extends CI_DB_pdo_driver { @@ -158,7 +158,7 @@ protected function _field_data($table) * @param string $table * @param array $values * @return string - */ + */ protected function _update($table, $values) { $this->qb_limit = FALSE; diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php index 6b42054..3f636d3 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_4d_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php index 98ac89f..fc49e0d 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver { @@ -170,47 +170,6 @@ public function field_data($table) // -------------------------------------------------------------------- - /** - * Update_Batch statement - * - * Generates a platform-specific batch update string from the supplied data - * - * @param string $table Table name - * @param array $values Update data - * @param string $index WHERE key - * @return string - */ - protected function _update_batch($table, $values, $index) - { - $ids = array(); - foreach ($values as $key => $val) - { - $ids[] = $val[$index]; - - foreach (array_keys($val) as $field) - { - if ($field !== $index) - { - $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; - } - } - } - - $cases = ''; - foreach ($final as $k => $v) - { - $cases .= $k." = CASE \n" - .implode("\n", $v)."\n" - .'ELSE '.$k.' END), '; - } - - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); - - return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); - } - - // -------------------------------------------------------------------- - /** * Truncate statement * diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php index 15b100d..276cbb6 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_cubrid_forge extends CI_DB_pdo_forge { @@ -178,6 +178,9 @@ protected function _attr_type(&$attributes) $attributes['TYPE'] = 'INTEGER'; $attributes['UNSIGNED'] = FALSE; return; + case 'LONGTEXT': + $attributes['TYPE'] = 'STRING'; + return; default: return; } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php index 844ffab..3249a1d 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver { @@ -126,7 +126,12 @@ public function __construct($params) */ public function db_connect($persistent = FALSE) { - $this->conn_id = parent::db_connect($persistent); + if ($persistent === TRUE) + { + log_message('debug', "dblib driver doesn't support persistent connections"); + } + + $this->conn_id = parent::db_connect(FALSE); if ( ! is_object($this->conn_id)) { @@ -227,7 +232,7 @@ public function field_data($table) * @param string $table * @param array $values * @return string - */ + */ protected function _update($table, $values) { $this->qb_limit = FALSE; diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php index d3dd903..d0cca38 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_dblib_forge extends CI_DB_pdo_forge { @@ -111,6 +111,11 @@ protected function _alter_table($alter_type, $table, $field) */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php index 3bd5c93..aa5e7d6 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_firebird_driver extends CI_DB_pdo_driver { @@ -211,7 +211,7 @@ protected function _update($table, $values) * * @param string $table * @return string - */ + */ protected function _truncate($table) { return 'DELETE FROM '.$table; @@ -260,4 +260,20 @@ protected function _limit($sql) return preg_replace('`SELECT`i', 'SELECT '.$select, $sql); } + // -------------------------------------------------------------------- + + /** + * Insert batch statement + * + * Generates a platform-specific insert string from the supplied data. + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * @return string|bool + */ + protected function _insert_batch($table, $keys, $values) + { + return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE; + } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php index ad28a65..20c5a68 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_firebird_forge extends CI_DB_pdo_forge { @@ -97,7 +97,7 @@ public function create_database($db_name) * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! ibase_drop_db($this->conn_id)) { diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php index 5dba26e..26b556a 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_ibm_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php index d1b5f92..4238ca0 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_ibm_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php index 9f8c017..050171f 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_informix_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php index 22bdf61..2ddc2a9 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_informix_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php index 70f2bfd..66c15da 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -106,7 +106,7 @@ public function __construct($params) empty($this->database) OR $this->dsn .= ';dbname='.$this->database; empty($this->char_set) OR $this->dsn .= ';charset='.$this->char_set; } - elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE && is_php('5.3.6')) + elseif ( ! empty($this->char_set) && strpos($this->dsn, 'charset=', 6) === FALSE) { $this->dsn .= ';charset='.$this->char_set; } @@ -122,17 +122,6 @@ public function __construct($params) */ public function db_connect($persistent = FALSE) { - /* Prior to PHP 5.3.6, even if the charset was supplied in the DSN - * on connect - it was ignored. This is a work-around for the issue. - * - * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php - */ - if ( ! is_php('5.3.6') && ! empty($this->char_set)) - { - $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set - .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); - } - if (isset($this->stricton)) { if ($this->stricton) @@ -169,8 +158,7 @@ public function db_connect($persistent = FALSE) $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; } - // SSL support was added to PDO_MYSQL in PHP 5.3.7 - if (is_array($this->encrypt) && is_php('5.3.7')) + if (is_array($this->encrypt)) { $ssl = array(); empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; @@ -218,6 +206,56 @@ public function db_select($database = '') if (FALSE !== $this->simple_query('USE '.$this->escape_identifiers($database))) { $this->database = $database; + $this->data_cache = array(); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return bool + */ + protected function _trans_begin() + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE); + return $this->conn_id->beginTransaction(); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return bool + */ + protected function _trans_commit() + { + if ($this->conn_id->commit()) + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return bool + */ + protected function _trans_rollback() + { + if ($this->conn_id->rollBack()) + { + $this->conn_id->setAttribute(PDO::ATTR_AUTOCOMMIT, TRUE); return TRUE; } diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php index e8e24c6..c7a92b8 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_mysql_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php index dd1d31c..abf9167 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php index e2078cf..c8983ee 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { @@ -54,18 +54,18 @@ class CI_DB_pdo_oci_forge extends CI_DB_pdo_forge { protected $_create_database = FALSE; /** - * DROP DATABASE statement + * CREATE TABLE IF statement * * @var string */ - protected $_drop_database = FALSE; + protected $_create_table_if = FALSE; /** - * CREATE TABLE IF statement + * DROP DATABASE statement * * @var string */ - protected $_create_table_if = 'CREATE TABLE IF NOT EXISTS'; + protected $_drop_database = FALSE; /** * UNSIGNED support @@ -146,4 +146,31 @@ protected function _attr_auto_increment(&$attributes, &$field) // Not supported - sequences and triggers must be used instead } + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * @return void + */ + protected function _attr_type(&$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'TINYINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'MEDIUMINT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'INT': + $attributes['TYPE'] = 'NUMBER'; + return; + case 'BIGINT': + $attributes['TYPE'] = 'NUMBER'; + return; + default: return; + } + } } diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php index 3334488..f4a2f08 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -160,6 +160,19 @@ public function __construct($params) // -------------------------------------------------------------------- + /** + * Platform-dependant string escape + * + * @param string + * @return string + */ + protected function _escape_str($str) + { + $this->db->display_error('db_unsupported_feature'); + } + + // -------------------------------------------------------------------- + /** * Determines if a query is a "write" type. * @@ -168,7 +181,7 @@ public function __construct($params) */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -213,72 +226,4 @@ protected function _list_columns($table = '') { return 'SELECT column_name FROM information_schema.columns WHERE table_name = '.$this->escape($table); } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @param string $table - * @param array $values - * @return string - */ - protected function _update($table, $values) - { - $this->qb_limit = FALSE; - $this->qb_orderby = array(); - return parent::_update($table, $values); - } - - // -------------------------------------------------------------------- - - /** - * Truncate statement - * - * Generates a platform-specific truncate string from the supplied data - * - * If the database does not support the TRUNCATE statement, - * then this method maps to 'DELETE FROM table' - * - * @param string $table - * @return string - */ - protected function _truncate($table) - { - return 'DELETE FROM '.$table; - } - - // -------------------------------------------------------------------- - - /** - * Delete statement - * - * Generates a platform-specific delete string from the supplied data - * - * @param string the table name - * @return string - */ - protected function _delete($table) - { - $this->qb_limit = FALSE; - return parent::_delete($table); - } - - // -------------------------------------------------------------------- - - /** - * LIMIT - * - * Generates a platform-specific LIMIT clause - * - * @param string $sql SQL Query - * @return string - */ - protected function _limit($sql) - { - return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$this->qb_limit.' ', $sql); - } - } diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php index 2913529..a2a3bad 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/database/ + * @link https://codeigniter.com/database/ */ class CI_DB_pdo_odbc_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index ee8f763..9aed3a2 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -154,7 +154,7 @@ public function insert_id($name = NULL) */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -326,13 +326,13 @@ protected function _update_batch($table, $values, $index) $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -340,12 +340,12 @@ protected function _update_batch($table, $values, $index) $cases = ''; foreach ($final as $k => $v) { - $cases .= $k.' = (CASE '.$index."\n" + $cases .= $k.' = (CASE '.$val[$index]['field']."\n" .implode("\n", $v)."\n" .'ELSE '.$k.' END), '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php index b4a6160..18e399d 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_pgsql_forge extends CI_DB_pdo_forge { diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php index 6269013..9b70f3e 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -66,7 +66,7 @@ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver { * * @var array */ - protected $_random_keyword = ' RANDOM()'; + protected $_random_keyword = array('RANDOM()', 'RANDOM()'); // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php index f6f9bb4..18c475b 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -101,7 +101,7 @@ public function __construct(&$db) * @param string $db_name (ignored) * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -116,7 +116,7 @@ public function create_database($db_name = '') * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { // In SQLite, a database is dropped when we delete a file if (file_exists($this->db->database)) diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php index f8ae5f6..1cf6c61 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -48,7 +48,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver { diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php index 602a1d4..82a0d51 100755 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_pdo_sqlsrv_forge extends CI_DB_pdo_forge { @@ -111,6 +111,11 @@ protected function _alter_table($alter_type, $table, $field) */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index 58d4451..cef464a 100755 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 @@ -288,7 +288,7 @@ protected function _trans_rollback() */ public function is_write_type($sql) { - if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#i', $sql)) + if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql)) { return FALSE; } @@ -550,13 +550,13 @@ protected function _update_batch($table, $values, $index) $ids = array(); foreach ($values as $key => $val) { - $ids[] = $val[$index]; + $ids[] = $val[$index]['value']; foreach (array_keys($val) as $field) { if ($field !== $index) { - $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field]; + $final[$val[$field]['field']][] = 'WHEN '.$val[$index]['value'].' THEN '.$val[$field]['value']; } } } @@ -564,12 +564,12 @@ protected function _update_batch($table, $values, $index) $cases = ''; foreach ($final as $k => $v) { - $cases .= $k.' = (CASE '.$index."\n" + $cases .= $k.' = (CASE '.$val[$index]['field']."\n" .implode("\n", $v)."\n" .'ELSE '.$k.' END), '; } - $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE); + $this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE); return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where'); } diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php index d26e84c..f7bbf74 100755 --- a/system/database/drivers/postgre/postgre_forge.php +++ b/system/database/drivers/postgre/postgre_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_postgre_forge extends CI_DB_forge { diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php index a8ad24e..57864a7 100755 --- a/system/database/drivers/postgre/postgre_result.php +++ b/system/database/drivers/postgre/postgre_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_postgre_result extends CI_DB_result { diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php index 7c6c025..5ca358d 100755 --- a/system/database/drivers/postgre/postgre_utility.php +++ b/system/database/drivers/postgre/postgre_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Drivers * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_postgre_utility extends CI_DB_utility { diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php index 16b8c29..03c96e4 100755 --- a/system/database/drivers/sqlite/sqlite_driver.php +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.0 diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php index 2bba330..a0fc0cd 100755 --- a/system/database/drivers/sqlite/sqlite_forge.php +++ b/system/database/drivers/sqlite/sqlite_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite_forge extends CI_DB_forge { @@ -75,7 +75,7 @@ class CI_DB_sqlite_forge extends CI_DB_forge { * @param string $db_name (ignored) * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -90,7 +90,7 @@ public function create_database($db_name = '') * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { if ( ! file_exists($this->db->database) OR ! @unlink($this->db->database)) { diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php index 487d003..34d3ac3 100755 --- a/system/database/drivers/sqlite/sqlite_result.php +++ b/system/database/drivers/sqlite/sqlite_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite_result extends CI_DB_result { diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php index 9cb4542..90ca4b1 100755 --- a/system/database/drivers/sqlite/sqlite_utility.php +++ b/system/database/drivers/sqlite/sqlite_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite_utility extends CI_DB_utility { diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php index 9743499..2d78a0f 100755 --- a/system/database/drivers/sqlite3/sqlite3_driver.php +++ b/system/database/drivers/sqlite3/sqlite3_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php index 43cbe33..5ee6daa 100755 --- a/system/database/drivers/sqlite3/sqlite3_forge.php +++ b/system/database/drivers/sqlite3/sqlite3_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -87,7 +87,7 @@ public function __construct(&$db) * @param string $db_name * @return bool */ - public function create_database($db_name = '') + public function create_database($db_name) { // In SQLite, a database is created when you connect to the database. // We'll return TRUE so that an error isn't generated @@ -102,7 +102,7 @@ public function create_database($db_name = '') * @param string $db_name (ignored) * @return bool */ - public function drop_database($db_name = '') + public function drop_database($db_name) { // In SQLite, a database is dropped when we delete a file if (file_exists($this->db->database)) diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php index 387481b..03751f0 100755 --- a/system/database/drivers/sqlite3/sqlite3_result.php +++ b/system/database/drivers/sqlite3/sqlite3_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite3_result extends CI_DB_result { diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php index 336f687..20d562f 100755 --- a/system/database/drivers/sqlite3/sqlite3_utility.php +++ b/system/database/drivers/sqlite3/sqlite3_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlite3_utility extends CI_DB_utility { diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php index 0cd9ce1..10aad11 100755 --- a/system/database/drivers/sqlsrv/sqlsrv_driver.php +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.3 @@ -171,6 +171,7 @@ public function db_select($database = '') if ($this->_execute('USE '.$this->escape_identifiers($database))) { $this->database = $database; + $this->data_cache = array(); return TRUE; } diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php index b22b60a..aa8490e 100755 --- a/system/database/drivers/sqlsrv/sqlsrv_forge.php +++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.3 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlsrv_forge extends CI_DB_forge { @@ -111,6 +111,11 @@ protected function _alter_table($alter_type, $table, $field) */ protected function _attr_type(&$attributes) { + if (isset($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') !== FALSE) + { + unset($attributes['CONSTRAINT']); + } + switch (strtoupper($attributes['TYPE'])) { case 'MEDIUMINT': diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php index d2be926..f784ebe 100755 --- a/system/database/drivers/sqlsrv/sqlsrv_result.php +++ b/system/database/drivers/sqlsrv/sqlsrv_result.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.3 * @filesource */ @@ -44,7 +44,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlsrv_result extends CI_DB_result { diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php index 77cf0aa..19c93d0 100755 --- a/system/database/drivers/sqlsrv/sqlsrv_utility.php +++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.3 * @filesource */ @@ -42,7 +42,7 @@ * * @category Database * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/database/ + * @link https://codeigniter.com/user_guide/database/ */ class CI_DB_sqlsrv_utility extends CI_DB_utility { diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php index 3fdccf9..74c7c15 100755 --- a/system/helpers/array_helper.php +++ b/system/helpers/array_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 3c1e006..8f44806 100755 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -110,7 +110,8 @@ function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = $current_dir = @opendir($img_path); while ($filename = @readdir($current_dir)) { - if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) + if (in_array(substr($filename, -4), array('.jpg', '.png')) + && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now) { @unlink($img_path.$filename); } diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php index c2dc73a..bb90cba 100755 --- a/system/helpers/cookie_helper.php +++ b/system/helpers/cookie_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/cookie_helper.html + * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index c9b71c3..bb15042 100755 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/date_helper.html + * @link https://codeigniter.com/user_guide/helpers/date_helper.html */ // ------------------------------------------------------------------------ @@ -496,6 +496,7 @@ function human_to_unix($datestr = '') * Turns many "reasonably-date-like" strings into something * that is actually useful. This only works for dates after unix epoch. * + * @deprecated 3.1.3 Use DateTime::createFromFormat($input_format, $input)->format($output_format); * @param string The terribly formatted date-like string * @param string Date format to return (same as php date function) * @return string @@ -529,9 +530,9 @@ function nice_date($bad_date = '', $format = FALSE) } // Date Like: YYYYMMDD - if (preg_match('/^(\d{2})\d{2}(\d{4})$/i', $bad_date, $matches)) + if (preg_match('/^\d{8}$/i', $bad_date, $matches)) { - return date($format, strtotime($matches[1].'/01/'.$matches[2])); + return DateTime::createFromFormat('Ymd', $bad_date)->format($format); } // Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between) @@ -707,87 +708,32 @@ function date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y $range = array(); - /* NOTE: Even though the DateTime object has many useful features, it appears that - * it doesn't always handle properly timezones, when timestamps are passed - * directly to its constructor. Neither of the following gave proper results: - * - * new DateTime('') - * new DateTime('', '') - * - * --- available in PHP 5.3: - * - * DateTime::createFromFormat('', '') - * DateTime::createFromFormat('', '', 'setTimestamp($unix_start); - if (is_php('5.3')) - { - $from->setTimestamp($unix_start); - if ($is_unix) - { - $arg = new DateTime(); - $arg->setTimestamp($mixed); - } - else - { - $arg = (int) $mixed; - } - - $period = new DatePeriod($from, new DateInterval('P1D'), $arg); - foreach ($period as $date) - { - $range[] = $date->format($format); - } - - /* If a period end date was passed to the DatePeriod constructor, it might not - * be in our results. Not sure if this is a bug or it's just possible because - * the end date might actually be less than 24 hours away from the previously - * generated DateTime object, but either way - we have to append it manually. - */ - if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format)) - { - $range[] = $arg->format($format); - } - - return $range; - } - - $from->setDate(date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start)); - $from->setTime(date('G', $unix_start), date('i', $unix_start), date('s', $unix_start)); if ($is_unix) { $arg = new DateTime(); - $arg->setDate(date('Y', $mixed), date('n', $mixed), date('j', $mixed)); - $arg->setTime(date('G', $mixed), date('i', $mixed), date('s', $mixed)); + $arg->setTimestamp($mixed); } else { $arg = (int) $mixed; } - $range[] = $from->format($format); - if (is_int($arg)) // Day intervals + $period = new DatePeriod($from, new DateInterval('P1D'), $arg); + foreach ($period as $date) { - do - { - $from->modify('+1 day'); - $range[] = $from->format($format); - } - while (--$arg > 0); + $range[] = $date->format($format); } - else // end date UNIX timestamp - { - for ($from->modify('+1 day'), $end_check = $arg->format('Ymd'); $from->format('Ymd') < $end_check; $from->modify('+1 day')) - { - $range[] = $from->format($format); - } - // Our loop only appended dates prior to our end date + /* If a period end date was passed to the DatePeriod constructor, it might not + * be in our results. Not sure if this is a bug or it's just possible because + * the end date might actually be less than 24 hours away from the previously + * generated DateTime object, but either way - we have to append it manually. + */ + if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format)) + { $range[] = $arg->format($format); } diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php index 8f05c5b..2785241 100755 --- a/system/helpers/directory_helper.php +++ b/system/helpers/directory_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/directory_helper.html + * @link https://codeigniter.com/user_guide/helpers/directory_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index a6463df..b2a1458 100755 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php index c4d7058..b3755d4 100755 --- a/system/helpers/email_helper.php +++ b/system/helpers/email_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/email_helper.html + * @link https://codeigniter.com/user_guide/helpers/email_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 0d8d1d0..d227f46 100755 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -138,13 +138,15 @@ function delete_files($path, $del_dir = FALSE, $htdocs = FALSE, $_level = 0) { if ($filename !== '.' && $filename !== '..') { - if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.') + $filepath = $path.DIRECTORY_SEPARATOR.$filename; + + if (is_dir($filepath) && $filename[0] !== '.' && ! is_link($filepath)) { - delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $htdocs, $_level + 1); + delete_files($filepath, $del_dir, $htdocs, $_level + 1); } elseif ($htdocs !== TRUE OR ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) { - @unlink($path.DIRECTORY_SEPARATOR.$filename); + @unlink($filepath); } } } diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 3e10395..a49eea8 100755 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -90,18 +90,47 @@ function form_open($action = '', $attributes = array(), $hidden = array()) $form = '
\n"; - // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites - if ($CI->config->item('csrf_protection') === TRUE && strpos($action, $CI->config->base_url()) !== FALSE && ! stripos($form, 'method="get"')) + if (is_array($hidden)) { - $hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash(); + foreach ($hidden as $name => $value) + { + $form .= ''."\n"; + } } - if (is_array($hidden)) + // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites + if ($CI->config->item('csrf_protection') === TRUE && strpos($action, $CI->config->base_url()) !== FALSE && ! stripos($form, 'method="get"')) { - foreach ($hidden as $name => $value) + // Prepend/append random-length "white noise" around the CSRF + // token input, as a form of protection against BREACH attacks + if (FALSE !== ($noise = $CI->security->get_random_bytes(1))) { - $form .= ''."\n"; + list(, $noise) = unpack('c', $noise); } + else + { + $noise = mt_rand(-128, 127); + } + + // Prepend if $noise has a negative value, append if positive, do nothing for zero + $prepend = $append = ''; + if ($noise < 0) + { + $prepend = str_repeat(" ", abs($noise)); + } + elseif ($noise > 0) + { + $append = str_repeat(" ", $noise); + } + + $form .= sprintf( + '%s%s%s', + $prepend, + $CI->security->get_csrf_token_name(), + $CI->security->get_csrf_hash(), + $append, + "\n" + ); } return $form; @@ -568,7 +597,7 @@ function form_button($data = '', $content = '', $extra = '') * * @param string The text to appear onscreen * @param string The id the label applies to - * @param string Additional attributes + * @param array Additional attributes * @return string */ function form_label($label_text = '', $id = '', $attributes = array()) diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index 28fbe00..de1b92c 100755 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/html_helper.html + * @link https://codeigniter.com/user_guide/helpers/html_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index c064d8d..26a5a5c 100755 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -238,8 +238,37 @@ function is_countable($word) return ! in_array( strtolower($word), array( - 'equipment', 'information', 'rice', 'money', - 'species', 'series', 'fish', 'meta' + 'audio', + 'bison', + 'chassis', + 'compensation', + 'coreopsis', + 'data', + 'deer', + 'education', + 'emoji', + 'equipment', + 'fish', + 'furniture', + 'gold', + 'information', + 'knowledge', + 'love', + 'rain', + 'money', + 'moose', + 'nutrition', + 'offspring', + 'plankton', + 'pokemon', + 'police', + 'rice', + 'series', + 'sheep', + 'species', + 'swine', + 'traffic', + 'wheat' ) ); } diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php index 25ce8ab..d26cf5b 100755 --- a/system/helpers/language_helper.php +++ b/system/helpers/language_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/language_helper.html + * @link https://codeigniter.com/user_guide/helpers/language_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php index 3a24259..cc8a776 100755 --- a/system/helpers/number_helper.php +++ b/system/helpers/number_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/number_helper.html + * @link https://codeigniter.com/user_guide/helpers/number_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index 838ece9..6896cb9 100755 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -61,7 +61,7 @@ function set_realpath($path, $check_existance = FALSE) { // Security check to make sure the path is NOT a URL. No remote file inclusion! - if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path ) + if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|php:\/\/)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path) { show_error('The path you submitted must be a local server path, not a URL'); } diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php index adbf136..5e2970a 100755 --- a/system/helpers/security_helper.php +++ b/system/helpers/security_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/security_helper.html + * @link https://codeigniter.com/user_guide/helpers/security_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php index d053dd2..2c9a3b4 100755 --- a/system/helpers/smiley_helper.php +++ b/system/helpers/smiley_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/smiley_helper.html + * @link https://codeigniter.com/user_guide/helpers/smiley_helper.html * @deprecated 3.0.0 This helper is too specific for CI. */ diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php index db531fa..23608e5 100755 --- a/system/helpers/string_helper.php +++ b/system/helpers/string_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index 4f9210f..07c01c3 100755 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -102,7 +102,7 @@ function character_limiter($str, $n = 500, $end_char = '…') } // a bit complicated, but faster than preg_replace with \s+ - $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str)); + $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\v", "\f"), ' ', $str)); if (mb_strlen($str) <= $n) { diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php index 45bb9b1..183e117 100755 --- a/system/helpers/typography_helper.php +++ b/system/helpers/typography_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/typography_helper.html + * @link https://codeigniter.com/user_guide/helpers/typography_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index fd7b5e1..84023af 100755 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php index 55f9c2f..a12ee25 100755 --- a/system/helpers/xml_helper.php +++ b/system/helpers/xml_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/xml_helper.html + * @link https://codeigniter.com/user_guide/helpers/xml_helper.html */ // ------------------------------------------------------------------------ diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php index 9d33528..77911e9 100755 --- a/system/language/english/calendar_lang.php +++ b/system/language/english/calendar_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php index c61c9c2..bb454ed 100755 --- a/system/language/english/date_lang.php +++ b/system/language/english/date_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php index 5b67da6..b44bda9 100755 --- a/system/language/english/db_lang.php +++ b/system/language/english/db_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php index cc6b2fd..22dc0fa 100755 --- a/system/language/english/email_lang.php +++ b/system/language/english/email_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php index 75d6e4b..aa9ff33 100755 --- a/system/language/english/form_validation_lang.php +++ b/system/language/english/form_validation_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php index bccc273..eada3e5 100755 --- a/system/language/english/ftp_lang.php +++ b/system/language/english/ftp_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php index 41129cd..218874c 100755 --- a/system/language/english/imglib_lang.php +++ b/system/language/english/imglib_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -51,6 +51,7 @@ $lang['imglib_image_process_failed'] = 'Image processing failed. Please verify that your server supports the chosen protocol and that the path to your image library is correct.'; $lang['imglib_rotation_angle_required'] = 'An angle of rotation is required to rotate the image.'; $lang['imglib_invalid_path'] = 'The path to the image is not correct.'; +$lang['imglib_invalid_image'] = 'The provided image is not valid.'; $lang['imglib_copy_failed'] = 'The image copy routine failed.'; $lang['imglib_missing_font'] = 'Unable to find a font to use.'; $lang['imglib_save_failed'] = 'Unable to save the image. Please make sure the image and file directory are writable.'; diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php index 9e4a7c5..1684960 100755 --- a/system/language/english/migration_lang.php +++ b/system/language/english/migration_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php index db229c5..9723ce5 100755 --- a/system/language/english/number_lang.php +++ b/system/language/english/number_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/pagination_lang.php b/system/language/english/pagination_lang.php index be13378..d24dd04 100755 --- a/system/language/english/pagination_lang.php +++ b/system/language/english/pagination_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php index ba3edba..20949a2 100755 --- a/system/language/english/profiler_lang.php +++ b/system/language/english/profiler_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php index 639829e..a89cb2d 100755 --- a/system/language/english/unit_test_lang.php +++ b/system/language/english/unit_test_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php index a536dda..ec611f9 100755 --- a/system/language/english/upload_lang.php +++ b/system/language/english/upload_lang.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index 349af15..267dffb 100755 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index 07ea8f4..f2b61ad 100755 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 @@ -97,7 +97,7 @@ public function get($id) * * @param string $id Cache ID * @param mixed $data Data to store - * @param int $ttol Length of time (in seconds) to cache the data + * @param int $ttl Length of time (in seconds) to cache the data * @param bool $raw Whether to store the raw value * @return bool TRUE on success, FALSE on failure */ diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php index bf80945..c6d9a61 100755 --- a/system/libraries/Cache/drivers/Cache_dummy.php +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0 * @filesource */ diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php index e1ce16a..8a36e9d 100755 --- a/system/libraries/Cache/drivers/Cache_file.php +++ b/system/libraries/Cache/drivers/Cache_file.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0 @@ -120,7 +120,7 @@ public function save($id, $data, $ttl = 60, $raw = FALSE) */ public function delete($id) { - return file_exists($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; + return is_file($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; } // ------------------------------------------------------------------------ @@ -216,7 +216,7 @@ public function cache_info($type = NULL) */ public function get_metadata($id) { - if ( ! file_exists($this->_cache_path.$id)) + if ( ! is_file($this->_cache_path.$id)) { return FALSE; } @@ -227,13 +227,13 @@ public function get_metadata($id) { $mtime = filemtime($this->_cache_path.$id); - if ( ! isset($data['ttl'])) + if ( ! isset($data['ttl'], $data['time'])) { return FALSE; } return array( - 'expire' => $mtime + $data['ttl'], + 'expire' => $data['time'] + $data['ttl'], 'mtime' => $mtime ); } diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index 6dee1e8..17e3611 100755 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0 @@ -295,7 +295,7 @@ public function __destruct() { $this->_memcached->close(); } - elseif ($this->_memcached instanceof Memcached) + elseif ($this->_memcached instanceof Memcached && method_exists($this->_memcached, 'quit')) { $this->_memcached->quit(); } diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index d4d95eb..ac67be0 100755 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index d6a0d4f..f296a5e 100755 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php index f6a0c39..edb0fb4 100755 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/calendar.html + * @link https://codeigniter.com/user_guide/libraries/calendar.html */ class CI_Calendar { diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php index bf27c63..734c434 100755 --- a/system/libraries/Cart.php +++ b/system/libraries/Cart.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Shopping Cart * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/cart.html + * @link https://codeigniter.com/user_guide/libraries/cart.html * @deprecated 3.0.0 This class is too specific for CI. */ class CI_Cart { diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index da4c548..00e8416 100755 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ diff --git a/system/libraries/Email.php b/system/libraries/Email.php index ed6f737..117c484 100755 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -147,14 +147,7 @@ class CI_Email { * * @var string */ - public $charset = 'utf-8'; - - /** - * Multipart message - * - * @var string 'mixed' (in the body) or 'related' (separate) - */ - public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate) + public $charset = 'UTF-8'; /** * Alternative message (for HTML messages only) @@ -260,20 +253,6 @@ class CI_Email { */ protected $_finalbody = ''; - /** - * multipart/alternative boundary - * - * @var string - */ - protected $_alt_boundary = ''; - - /** - * Attachment boundary - * - * @var string - */ - protected $_atc_boundary = ''; - /** * Final headers to send * @@ -395,6 +374,13 @@ class CI_Email { 5 => '5 (Lowest)' ); + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + // -------------------------------------------------------------------- /** @@ -408,35 +394,12 @@ class CI_Email { public function __construct(array $config = array()) { $this->charset = config_item('charset'); - - if (count($config) > 0) - { - $this->initialize($config); - } - else - { - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - } - + $this->initialize($config); $this->_safe_mode = ( ! is_php('5.4') && ini_get('safe_mode')); - $this->charset = strtoupper($this->charset); - log_message('info', 'Email Class Initialized'); - } + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); - // -------------------------------------------------------------------- - - /** - * Destructor - Releases Resources - * - * @return void - */ - public function __destruct() - { - if (is_resource($this->_smtp_connect)) - { - $this->_send_command('quit'); - } + log_message('info', 'Email Class Initialized'); } // -------------------------------------------------------------------- @@ -444,11 +407,13 @@ public function __destruct() /** * Initialize preferences * - * @param array + * @param array $config * @return CI_Email */ - public function initialize($config = array()) + public function initialize(array $config = array()) { + $this->clear(); + foreach ($config as $key => $val) { if (isset($this->$key)) @@ -465,9 +430,9 @@ public function initialize($config = array()) } } } - $this->clear(); - $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); + $this->charset = strtoupper($this->charset); + $this->_smtp_auth = isset($this->smtp_user[0], $this->smtp_pass[0]); return $this; } @@ -493,7 +458,6 @@ public function clear($clear_attachments = FALSE) $this->_headers = array(); $this->_debug_msg = array(); - $this->set_header('User-Agent', $this->useragent); $this->set_header('Date', $this->_set_date()); if ($clear_attachments !== FALSE) @@ -766,7 +730,8 @@ public function attach($file, $disposition = '', $newname = NULL, $mime = '') 'name' => array($file, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters 'type' => $mime, - 'content' => chunk_split(base64_encode($file_content)) + 'content' => chunk_split(base64_encode($file_content)), + 'multipart' => 'mixed' ); return $this; @@ -784,15 +749,11 @@ public function attach($file, $disposition = '', $newname = NULL, $mime = '') */ public function attachment_cid($filename) { - if ($this->multipart !== 'related') - { - $this->multipart = 'related'; // Thunderbird need this for inline images - } - for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { if ($this->_attachments[$i]['name'][0] === $filename) { + $this->_attachments[$i]['multipart'] = 'related'; $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); return $this->_attachments[$i]['cid']; } @@ -936,19 +897,6 @@ public function set_crlf($crlf = "\n") // -------------------------------------------------------------------- - /** - * Set Message Boundary - * - * @return void - */ - protected function _set_boundaries() - { - $this->_alt_boundary = 'B_ALT_'.uniqid(''); // multipart/alternative - $this->_atc_boundary = 'B_ATC_'.uniqid(''); // attachment boundary - } - - // -------------------------------------------------------------------- - /** * Get the Message ID * @@ -1016,9 +964,9 @@ protected function _get_content_type() { if ($this->mailtype === 'html') { - return (count($this->_attachments) === 0) ? 'html' : 'html-attach'; + return empty($this->_attachments) ? 'html' : 'html-attach'; } - elseif ($this->mailtype === 'text' && count($this->_attachments) > 0) + elseif ($this->mailtype === 'text' && ! empty($this->_attachments)) { return 'plain-attach'; } @@ -1097,7 +1045,7 @@ public function valid_email($email) { if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@')) { - $email = substr($email, 0, ++$atpos).idn_to_ascii(substr($email, $atpos)); + $email = self::substr($email, 0, ++$atpos).idn_to_ascii(self::substr($email, $atpos)); } return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); @@ -1214,7 +1162,7 @@ public function word_wrap($str, $charlim = NULL) { // Is the line within the allowed character count? // If so we'll join it to the output and continue - if (mb_strlen($line) <= $charlim) + if (self::strlen($line) <= $charlim) { $output .= $line.$this->newline; continue; @@ -1230,10 +1178,10 @@ public function word_wrap($str, $charlim = NULL) } // Trim the word down - $temp .= mb_substr($line, 0, $charlim - 1); - $line = mb_substr($line, $charlim - 1); + $temp .= self::substr($line, 0, $charlim - 1); + $line = self::substr($line, $charlim - 1); } - while (mb_strlen($line) > $charlim); + while (self::strlen($line) > $charlim); // If $temp contains data it means we had to split up an over-length // word into smaller chunks so we'll add it back to our current line @@ -1262,10 +1210,11 @@ public function word_wrap($str, $charlim = NULL) /** * Build final headers * - * @return string + * @return void */ protected function _build_headers() { + $this->set_header('User-Agent', $this->useragent); $this->set_header('X-Sender', $this->clean_email($this->_headers['From'])); $this->set_header('X-Mailer', $this->useragent); $this->set_header('X-Priority', $this->_priorities[$this->priority]); @@ -1324,7 +1273,6 @@ protected function _build_message() $this->_body = $this->word_wrap($this->_body); } - $this->_set_boundaries(); $this->_write_headers(); $hdr = ($this->_get_protocol() === 'mail') ? $this->newline : ''; @@ -1332,7 +1280,7 @@ protected function _build_message() switch ($this->_get_content_type()) { - case 'plain' : + case 'plain': $hdr .= 'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding(); @@ -1349,7 +1297,7 @@ protected function _build_message() return; - case 'html' : + case 'html': if ($this->send_multipart === FALSE) { @@ -1358,14 +1306,16 @@ protected function _build_message() } else { - $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'; + $boundary = uniqid('B_ALT_'); + $hdr .= 'Content-Type: multipart/alternative; boundary="'.$boundary.'"'; $body .= $this->_get_mime_message().$this->newline.$this->newline - .'--'.$this->_alt_boundary.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline - .$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline + .$this->_get_alt_message().$this->newline.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/html; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline; @@ -1384,14 +1334,15 @@ protected function _build_message() if ($this->send_multipart !== FALSE) { - $this->_finalbody .= '--'.$this->_alt_boundary.'--'; + $this->_finalbody .= '--'.$boundary.'--'; } return; - case 'plain-attach' : + case 'plain-attach': - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; + $boundary = uniqid('B_ATC_'); + $hdr .= 'Content-Type: multipart/mixed; boundary="'.$boundary.'"'; if ($this->_get_protocol() === 'mail') { @@ -1400,59 +1351,83 @@ protected function _build_message() $body .= $this->_get_mime_message().$this->newline .$this->newline - .'--'.$this->_atc_boundary.$this->newline + .'--'.$boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline .$this->newline .$this->_body.$this->newline.$this->newline; - break; - case 'html-attach' : + $this->_append_attachments($body, $boundary); + + break; + case 'html-attach': + + $alt_boundary = uniqid('B_ALT_'); + $last_boundary = NULL; + + if ($this->_attachments_have_multipart('mixed')) + { + $atc_boundary = uniqid('B_ATC_'); + $hdr .= 'Content-Type: multipart/mixed; boundary="'.$atc_boundary.'"'; + $last_boundary = $atc_boundary; + } + + if ($this->_attachments_have_multipart('related')) + { + $rel_boundary = uniqid('B_REL_'); + $rel_boundary_header = 'Content-Type: multipart/related; boundary="'.$rel_boundary.'"'; + + if (isset($last_boundary)) + { + $body .= '--'.$last_boundary.$this->newline.$rel_boundary_header; + } + else + { + $hdr .= $rel_boundary_header; + } - $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'; + $last_boundary = $rel_boundary; + } if ($this->_get_protocol() === 'mail') { $this->_header_str .= $hdr; } + self::strlen($body) && $body .= $this->newline.$this->newline; $body .= $this->_get_mime_message().$this->newline.$this->newline - .'--'.$this->_atc_boundary.$this->newline + .'--'.$last_boundary.$this->newline - .'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline - .'--'.$this->_alt_boundary.$this->newline + .'Content-Type: multipart/alternative; boundary="'.$alt_boundary.'"'.$this->newline.$this->newline + .'--'.$alt_boundary.$this->newline .'Content-Type: text/plain; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline - .$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline + .$this->_get_alt_message().$this->newline.$this->newline + .'--'.$alt_boundary.$this->newline .'Content-Type: text/html; charset='.$this->charset.$this->newline .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline .$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline - .'--'.$this->_alt_boundary.'--'.$this->newline.$this->newline; - - break; - } + .'--'.$alt_boundary.'--'.$this->newline.$this->newline; - $attachment = array(); - for ($i = 0, $c = count($this->_attachments), $z = 0; $i < $c; $i++) - { - $filename = $this->_attachments[$i]['name'][0]; - $basename = ($this->_attachments[$i]['name'][1] === NULL) - ? basename($filename) : $this->_attachments[$i]['name'][1]; + if ( ! empty($rel_boundary)) + { + $body .= $this->newline.$this->newline; + $this->_append_attachments($body, $rel_boundary, 'related'); + } - $attachment[$z++] = '--'.$this->_atc_boundary.$this->newline - .'Content-type: '.$this->_attachments[$i]['type'].'; ' - .'name="'.$basename.'"'.$this->newline - .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline - .'Content-Transfer-Encoding: base64'.$this->newline - .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline); + // multipart/mixed attachments + if ( ! empty($atc_boundary)) + { + $body .= $this->newline.$this->newline; + $this->_append_attachments($body, $atc_boundary, 'mixed'); + } - $attachment[$z++] = $this->_attachments[$i]['content']; + break; } - $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--'; $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$this->newline.$this->newline.$body; @@ -1462,6 +1437,58 @@ protected function _build_message() // -------------------------------------------------------------------- + protected function _attachments_have_multipart($type) + { + foreach ($this->_attachments as &$attachment) + { + if ($attachment['multipart'] === $type) + { + return TRUE; + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Prepares attachment string + * + * @param string $body Message body to append to + * @param string $boundary Multipart boundary + * @param string $multipart When provided, only attachments of this type will be processed + * @return string + */ + protected function _append_attachments(&$body, $boundary, $multipart = null) + { + for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) + { + if (isset($multipart) && $this->_attachments[$i]['multipart'] !== $multipart) + { + continue; + } + + $name = isset($this->_attachments[$i]['name'][1]) + ? $this->_attachments[$i]['name'][1] + : basename($this->_attachments[$i]['name'][0]); + + $body .= '--'.$boundary.$this->newline + .'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline + .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline + .'Content-Transfer-Encoding: base64'.$this->newline + .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline) + .$this->newline + .$this->_attachments[$i]['content'].$this->newline; + } + + // $name won't be set if no attachments were appended, + // and therefore a boundary wouldn't be necessary + empty($name) OR $body .= '--'.$boundary.'--'; + } + + // -------------------------------------------------------------------- + /** * Prep Quoted Printable * @@ -1497,14 +1524,7 @@ protected function _prep_quoted_printable($str) // which only works with "\n". if ($this->crlf === "\r\n") { - if (is_php('5.3')) - { - return quoted_printable_encode($str); - } - elseif (function_exists('imap_8bit')) - { - return imap_8bit($str); - } + return quoted_printable_encode($str); } // Reduce multiple spaces & remove nulls @@ -1521,7 +1541,7 @@ protected function _prep_quoted_printable($str) foreach (explode("\n", $str) as $line) { - $length = strlen($line); + $length = self::strlen($line); $temp = ''; // Loop through each character in the line to add soft-wrap @@ -1556,7 +1576,7 @@ protected function _prep_quoted_printable($str) // If we're at the character limit, add the line to the output, // reset our temp variable, and keep on chuggin' - if ((strlen($temp) + strlen($char)) >= 76) + if ((self::strlen($temp) + self::strlen($char)) >= 76) { $output .= $temp.$escape.$this->crlf; $temp = ''; @@ -1571,7 +1591,7 @@ protected function _prep_quoted_printable($str) } // get rid of extra CRLF tacked onto the end - return substr($output, 0, strlen($this->crlf) * -1); + return self::substr($output, 0, self::strlen($this->crlf) * -1); } // -------------------------------------------------------------------- @@ -1613,7 +1633,7 @@ protected function _prep_q_encoding($str) // iconv_mime_encode() will always put a header field name. // We've passed it an empty one, but it still prepends our // encoded string with ': ', so we need to strip it. - return substr($output, 2); + return self::substr($output, 2); } $chars = iconv_strlen($str, 'UTF-8'); @@ -1625,10 +1645,10 @@ protected function _prep_q_encoding($str) } // We might already have this set for UTF-8 - isset($chars) OR $chars = strlen($str); + isset($chars) OR $chars = self::strlen($str); $output = '=?'.$this->charset.'?Q?'; - for ($i = 0, $length = strlen($output); $i < $chars; $i++) + for ($i = 0, $length = self::strlen($output); $i < $chars; $i++) { $chr = ($this->charset === 'UTF-8' && ICONV_ENABLED === TRUE) ? '='.implode('=', str_split(strtoupper(bin2hex(iconv_substr($str, $i, 1, $this->charset))), 2)) @@ -1636,11 +1656,11 @@ protected function _prep_q_encoding($str) // RFC 2045 sets a limit of 76 characters per line. // We'll append ?= to the end of each line though. - if ($length + ($l = strlen($chr)) > 74) + if ($length + ($l = self::strlen($chr)) > 74) { $output .= '?='.$this->crlf // EOL .' =?'.$this->charset.'?Q?'.$chr; // New line - $length = 6 + strlen($this->charset) + $l; // Reset the length for the new line + $length = 6 + self::strlen($this->charset) + $l; // Reset the length for the new line } else { @@ -1733,14 +1753,14 @@ public function batch_bcc_send() if ($i === $float) { - $chunk[] = substr($set, 1); + $chunk[] = self::substr($set, 1); $float += $this->bcc_batch_size; $set = ''; } if ($i === $c-1) { - $chunk[] = substr($set, 1); + $chunk[] = self::substr($set, 1); } } @@ -1822,6 +1842,33 @@ protected function _spool_email() // -------------------------------------------------------------------- + /** + * Validate email for shell + * + * Applies stricter, shell-safe validation to email addresses. + * Introduced to prevent RCE via sendmail's -f option. + * + * @see https://github.com/bcit-ci/CodeIgniter/issues/4963 + * @see https://gist.github.com/Zenexer/40d02da5e07f151adeaeeaa11af9ab36 + * @license https://creativecommons.org/publicdomain/zero/1.0/ CC0 1.0, Public Domain + * + * Credits for the base concept go to Paul Buonopane + * + * @param string $email + * @return bool + */ + protected function _validate_email_for_shell(&$email) + { + if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@')) + { + $email = self::substr($email, 0, ++$atpos).idn_to_ascii(self::substr($email, $atpos)); + } + + return (filter_var($email, FILTER_VALIDATE_EMAIL) === $email && preg_match('#\A[a-z0-9._+-]+@[a-z0-9.-]{1,253}\z#i', $email)); + } + + // -------------------------------------------------------------------- + /** * Send using mail() * @@ -1834,7 +1881,11 @@ protected function _send_with_mail() $this->_recipients = implode(', ', $this->_recipients); } - if ($this->_safe_mode === TRUE) + // _validate_email_for_shell() below accepts by reference, + // so this needs to be assigned to a variable + $from = $this->clean_email($this->_headers['Return-Path']); + + if ($this->_safe_mode === TRUE || ! $this->_validate_email_for_shell($from)) { return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str); } @@ -1842,7 +1893,7 @@ protected function _send_with_mail() { // most documentation of sendmail using the "-f" flag lacks a space after it, however // we've encountered servers that seem to require it to be in place. - return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['Return-Path'])); + return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$from); } } @@ -1855,13 +1906,22 @@ protected function _send_with_mail() */ protected function _send_with_sendmail() { + // _validate_email_for_shell() below accepts by reference, + // so this needs to be assigned to a variable + $from = $this->clean_email($this->_headers['From']); + if ($this->_validate_email_for_shell($from)) + { + $from = '-f '.$from; + } + else + { + $from = ''; + } + // is popen() enabled? - if ( ! function_usable('popen') - OR FALSE === ($fp = @popen( - $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t' - , 'w')) - ) // server probably has popen disabled, so nothing we can do to get a verbose error. + if ( ! function_usable('popen') OR FALSE === ($fp = @popen($this->mailpath.' -oi '.$from.' -t', 'w'))) { + // server probably has popen disabled, so nothing we can do to get a verbose error. return FALSE; } @@ -1902,6 +1962,7 @@ protected function _send_with_smtp() if ( ! $this->_send_command('from', $this->clean_email($this->_headers['From']))) { + $this->_smtp_end(); return FALSE; } @@ -1909,6 +1970,7 @@ protected function _send_with_smtp() { if ( ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1919,6 +1981,7 @@ protected function _send_with_smtp() { if ($val !== '' && ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1930,6 +1993,7 @@ protected function _send_with_smtp() { if ($val !== '' && ! $this->_send_command('to', $val)) { + $this->_smtp_end(); return FALSE; } } @@ -1937,6 +2001,7 @@ protected function _send_with_smtp() if ( ! $this->_send_command('data')) { + $this->_smtp_end(); return FALSE; } @@ -1946,29 +2011,37 @@ protected function _send_with_smtp() $this->_send_data('.'); $reply = $this->_get_smtp_data(); - $this->_set_error_message($reply); + $this->_smtp_end(); + if (strpos($reply, '250') !== 0) { $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; } - if ($this->smtp_keepalive) - { - $this->_send_command('reset'); - } - else - { - $this->_send_command('quit'); - } - return TRUE; } // -------------------------------------------------------------------- + /** + * SMTP End + * + * Shortcut to send RSET or QUIT depending on keep-alive + * + * @return void + */ + protected function _smtp_end() + { + ($this->smtp_keepalive) + ? $this->_send_command('reset') + : $this->_send_command('quit'); + } + + // -------------------------------------------------------------------- + /** * SMTP Connect * @@ -2022,7 +2095,7 @@ protected function _smtp_connect() * * @param string * @param string - * @return string + * @return bool */ protected function _send_command($cmd, $data = '') { @@ -2085,7 +2158,7 @@ protected function _send_command($cmd, $data = '') $this->_debug_msg[] = '
'.$cmd.': '.$reply.'
'; - if ((int) substr($reply, 0, 3) !== $resp) + if ((int) self::substr($reply, 0, 3) !== $resp) { $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; @@ -2153,6 +2226,11 @@ protected function _smtp_authenticate() return FALSE; } + if ($this->smtp_keepalive) + { + $this->_smtp_auth = FALSE; + } + return TRUE; } @@ -2167,9 +2245,9 @@ protected function _smtp_authenticate() protected function _send_data($data) { $data .= $this->newline; - for ($written = $timestamp = 0, $length = strlen($data); $written < $length; $written += $result) + for ($written = $timestamp = 0, $length = self::strlen($data); $written < $length; $written += $result) { - if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) + if (($result = fwrite($this->_smtp_connect, self::substr($data, $written))) === FALSE) { break; } @@ -2342,4 +2420,55 @@ protected function _mime_types($ext = '') return 'application/x-unknown-content-type'; } + // -------------------------------------------------------------------- + + /** + * Destructor + * + * @return void + */ + public function __destruct() + { + is_resource($this->_smtp_connect) && $this->_send_command('quit'); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_override) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index 5faf1f2..46f3747 100755 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Libraries * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/encryption.html + * @link https://codeigniter.com/user_guide/libraries/encryption.html */ class CI_Encrypt { @@ -65,7 +65,7 @@ class CI_Encrypt { protected $_hash_type = 'sha1'; /** - * Flag for the existance of mcrypt + * Flag for the existence of mcrypt * * @var bool */ @@ -198,7 +198,7 @@ public function decode($string, $key = '') * This allows for backwards compatibility and a method to transition to the * new encryption algorithms. * - * For more details, see http://codeigniter.com/user_guide/installation/upgrade_200.html#encryption + * For more details, see https://codeigniter.com/user_guide/installation/upgrade_200.html#encryption * * @param string * @param int (mcrypt mode constant) diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php index 92c38a0..74832ed 100755 --- a/system/libraries/Encryption.php +++ b/system/libraries/Encryption.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -152,10 +152,8 @@ class CI_Encryption { public function __construct(array $params = array()) { $this->_drivers = array( - 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), - // While OpenSSL is available for PHP 5.3.0, an IV parameter - // for the encrypt/decrypt functions is only available since 5.3.3 - 'openssl' => (is_php('5.3.3') && extension_loaded('openssl')) + 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), + 'openssl' => extension_loaded('openssl') ); if ( ! $this->_drivers['mcrypt'] && ! $this->_drivers['openssl']) @@ -339,12 +337,26 @@ public function create_key($length) { if (function_exists('random_bytes')) { - return random_bytes((int) $length); + try + { + return random_bytes((int) $length); + } + catch (Exception $e) + { + log_message('error', $e->getMessage()); + return FALSE; + } + } + elseif (defined('MCRYPT_DEV_URANDOM')) + { + return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); } - return ($this->_driver === 'mcrypt') - ? mcrypt_create_iv($length, MCRYPT_DEV_URANDOM) - : openssl_random_pseudo_bytes($length); + $is_secure = NULL; + $key = openssl_random_pseudo_bytes($length, $is_secure); + return ($is_secure === TRUE) + ? $key + : FALSE; } // -------------------------------------------------------------------- @@ -400,7 +412,7 @@ protected function _mcrypt_encrypt($data, $params) // The greater-than-1 comparison is mostly a work-around for a bug, // where 1 is returned for ARCFour instead of 0. $iv = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) - ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM) + ? $this->create_key($iv_size) : NULL; if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) @@ -463,7 +475,7 @@ protected function _openssl_encrypt($data, $params) } $iv = ($iv_size = openssl_cipher_iv_length($params['handle'])) - ? openssl_random_pseudo_bytes($iv_size) + ? $this->create_key($iv_size) : NULL; $data = openssl_encrypt( @@ -895,7 +907,7 @@ public function __get($key) * Byte-safe strlen() * * @param string $str - * @return integer + * @return int */ protected static function strlen($str) { diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index e4a5189..4f679a1 100755 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -493,6 +493,63 @@ public function run($group = '') // -------------------------------------------------------------------- + /** + * Prepare rules + * + * Re-orders the provided rules in order of importance, so that + * they can easily be executed later without weird checks ... + * + * "Callbacks" are given the highest priority (always called), + * followed by 'required' (called if callbacks didn't fail), + * and then every next rule depends on the previous one passing. + * + * @param array $rules + * @return array + */ + protected function _prepare_rules($rules) + { + $new_rules = array(); + $callbacks = array(); + + foreach ($rules as &$rule) + { + // Let 'required' always be the first (non-callback) rule + if ($rule === 'required') + { + array_unshift($new_rules, 'required'); + } + // 'isset' is a kind of a weird alias for 'required' ... + elseif ($rule === 'isset' && (empty($new_rules) OR $new_rules[0] !== 'required')) + { + array_unshift($new_rules, 'isset'); + } + // The old/classic 'callback_'-prefixed rules + elseif (is_string($rule) && strncmp('callback_', $rule, 9) === 0) + { + $callbacks[] = $rule; + } + // Proper callables + elseif (is_callable($rule)) + { + $callbacks[] = $rule; + } + // "Named" callables; i.e. array('name' => $callable) + elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1])) + { + $callbacks[] = $rule; + } + // Everything else goes at the end of the queue + else + { + $new_rules[] = $rule; + } + } + + return array_merge($callbacks, $new_rules); + } + + // -------------------------------------------------------------------- + /** * Traverse a multidimensional $_POST array index until the data is found * @@ -580,70 +637,7 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) return; } - // If the field is blank, but NOT required, no further tests are necessary - $callback = FALSE; - if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === '')) - { - // Before we bail out, does the rule contain a callback? - foreach ($rules as &$rule) - { - if (is_string($rule)) - { - if (strncmp($rule, 'callback_', 9) === 0) - { - $callback = TRUE; - $rules = array(1 => $rule); - break; - } - } - elseif (is_callable($rule)) - { - $callback = TRUE; - $rules = array(1 => $rule); - break; - } - elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1])) - { - $callback = TRUE; - $rules = array(array($rule[0], $rule[1])); - break; - } - } - - if ( ! $callback) - { - return; - } - } - - // Isset Test. Typically this rule will only apply to checkboxes. - if (($postdata === NULL OR $postdata === '') && ! $callback) - { - if (in_array('isset', $rules, TRUE) OR in_array('required', $rules)) - { - // Set the message type - $type = in_array('required', $rules) ? 'required' : 'isset'; - - $line = $this->_get_error_message($type, $row['field']); - - // Build the error message - $message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label'])); - - // Save the error message - $this->_field_data[$row['field']]['error'] = $message; - - if ( ! isset($this->_error_array[$row['field']])) - { - $this->_error_array[$row['field']] = $message; - } - } - - return; - } - - // -------------------------------------------------------------------- - - // Cycle through each rule and run it + $rules = $this->_prepare_rules($rules); foreach ($rules as $rule) { $_in_array = FALSE; @@ -702,6 +696,17 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) $param = $match[2]; } + // Ignore empty, non-required inputs with a few exceptions ... + if ( + ($postdata === NULL OR $postdata === '') + && $callback === FALSE + && $callable === FALSE + && ! in_array($rule, array('required', 'isset', 'matches'), TRUE) + ) + { + continue; + } + // Call the function that corresponds to the rule if ($callback OR $callable !== FALSE) { @@ -740,12 +745,6 @@ protected function _execute($row, $rules, $postdata = NULL, $cycles = 0) { $this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result; } - - // If the field isn't required and we just processed a callback we'll move on... - if ( ! in_array('required', $rules, TRUE) && $result !== FALSE) - { - continue; - } } elseif ( ! method_exists($this, $rule)) { @@ -1055,7 +1054,9 @@ public function set_checkbox($field = '', $value = '', $default = FALSE) */ public function required($str) { - return is_array($str) ? (bool) count($str) : (trim($str) !== ''); + return is_array($str) + ? (empty($str) === FALSE) + : (trim($str) !== ''); } // -------------------------------------------------------------------- @@ -1199,7 +1200,7 @@ public function valid_url($str) { return FALSE; } - elseif ( ! in_array($matches[1], array('http', 'https'), TRUE)) + elseif ( ! in_array(strtolower($matches[1]), array('http', 'https'), TRUE)) { return FALSE; } @@ -1215,18 +1216,7 @@ public function valid_url($str) $str = 'ipv6.host'.substr($str, strlen($matches[1]) + 2); } - $str = 'http://'.$str; - - // There's a bug affecting PHP 5.2.13, 5.3.2 that considers the - // underscore to be a valid hostname character instead of a dash. - // Reference: https://bugs.php.net/bug.php?id=51192 - if (version_compare(PHP_VERSION, '5.2.13', '==') OR version_compare(PHP_VERSION, '5.3.2', '==')) - { - sscanf($str, 'http://%[^/]', $host); - $str = substr_replace($str, strtr($host, array('_' => '-', '-' => '_')), 7, strlen($host)); - } - - return (filter_var($str, FILTER_VALIDATE_URL) !== FALSE); + return (filter_var('http://'.$str, FILTER_VALIDATE_URL) !== FALSE); } // -------------------------------------------------------------------- @@ -1239,9 +1229,9 @@ public function valid_url($str) */ public function valid_email($str) { - if (function_exists('idn_to_ascii') && $atpos = strpos($str, '@')) + if (function_exists('idn_to_ascii') && sscanf($str, '%[^@]@%s', $name, $domain) === 2) { - $str = substr($str, 0, ++$atpos).idn_to_ascii(substr($str, $atpos)); + $str = $name.'@'.idn_to_ascii($domain); } return (bool) filter_var($str, FILTER_VALIDATE_EMAIL); diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index 88f2658..ac960a4 100755 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index f594b71..9ec44da 100755 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -456,7 +456,7 @@ public function initialize($props = array()) { if (property_exists($this, $key)) { - if (in_array($key, array('wm_font_color', 'wm_shadow_color'))) + if (in_array($key, array('wm_font_color', 'wm_shadow_color'), TRUE)) { if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches)) { @@ -478,6 +478,10 @@ public function initialize($props = array()) continue; } } + elseif (in_array($key, array('width', 'height'), TRUE) && ! ctype_digit((string) $val)) + { + continue; + } $this->$key = $val; } @@ -540,37 +544,30 @@ public function initialize($props = array()) */ if ($this->new_image === '') { - $this->dest_image = $this->source_image; + $this->dest_image = $this->source_image; $this->dest_folder = $this->source_folder; } - elseif (strpos($this->new_image, '/') === FALSE) + elseif (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE) { + $this->dest_image = $this->new_image; $this->dest_folder = $this->source_folder; - $this->dest_image = $this->new_image; } else { - if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE) - { - $full_dest_path = str_replace('\\', '/', realpath($this->new_image)); - } - else - { - $full_dest_path = $this->new_image; - } - // Is there a file name? - if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path)) + if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $this->new_image)) { - $this->dest_folder = $full_dest_path.'/'; - $this->dest_image = $this->source_image; + $this->dest_image = $this->source_image; + $this->dest_folder = $this->new_image; } else { - $x = explode('/', $full_dest_path); - $this->dest_image = end($x); - $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path); + $x = explode('/', str_replace('\\', '/', $this->new_image)); + $this->dest_image = end($x); + $this->dest_folder = str_replace($this->dest_image, '', $this->new_image); } + + $this->dest_folder = realpath($this->dest_folder).'/'; } /* Compile the finalized filenames/paths @@ -862,27 +859,28 @@ public function image_process_imagemagick($action = 'resize') if ($action === 'crop') { - $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis.' "'.$this->full_src_path.'" "'.$this->full_dst_path .'" 2>&1'; + $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis; } elseif ($action === 'rotate') { - $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt') - ? '-flop' : '-rotate '.$this->rotation_angle; - - $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt') + ? ' -flop' + : ' -rotate '.$this->rotation_angle; } else // Resize { if($this->maintain_ratio === TRUE) { - $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ' -resize '.$this->width.'x'.$this->height; } else { - $cmd .= ' -resize '.$this->width.'x'.$this->height.'\! "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1'; + $cmd .= ' -resize '.$this->width.'x'.$this->height.'\!'; } } + $cmd .= ' '.escapeshellarg($this->full_src_path).' '.escapeshellarg($this->full_dst_path).' 2>&1'; + $retval = 1; // exec() might be disabled if (function_usable('exec')) @@ -1641,25 +1639,31 @@ public function get_image_properties($path = '', $return = FALSE) } $vals = getimagesize($path); + if ($vals === FALSE) + { + $this->set_error('imglib_invalid_image'); + return FALSE; + } + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); - $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg'; + $mime = isset($types[$vals[2]]) ? 'image/'.$types[$vals[2]] : 'image/jpg'; if ($return === TRUE) { return array( - 'width' => $vals[0], - 'height' => $vals[1], - 'image_type' => $vals[2], - 'size_str' => $vals[3], - 'mime_type' => $mime - ); - } - - $this->orig_width = $vals[0]; - $this->orig_height = $vals[1]; - $this->image_type = $vals[2]; - $this->size_str = $vals[3]; - $this->mime_type = $mime; + 'width' => $vals[0], + 'height' => $vals[1], + 'image_type' => $vals[2], + 'size_str' => $vals[3], + 'mime_type' => $mime + ); + } + + $this->orig_width = $vals[0]; + $this->orig_height = $vals[1]; + $this->image_type = $vals[2]; + $this->size_str = $vals[3]; + $this->mime_type = $mime; return TRUE; } diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php index 4cc6286..7648526 100755 --- a/system/libraries/Javascript.php +++ b/system/libraries/Javascript.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Javascript * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/javascript.html + * @link https://codeigniter.com/user_guide/libraries/javascript.html * @deprecated 3.0.0 This was never a good idea in the first place. */ class CI_Javascript { diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php index 25accee..ee5f9de 100755 --- a/system/libraries/Javascript/Jquery.php +++ b/system/libraries/Javascript/Jquery.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Loader * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/javascript.html + * @link https://codeigniter.com/user_guide/libraries/javascript.html */ class CI_Jquery extends CI_Javascript { @@ -84,7 +84,7 @@ class CI_Jquery extends CI_Javascript { public $jquery_table_sorter_active = FALSE; /** - * JQuery table sorder pager active + * JQuery table sorter pager active * * @var bool */ diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php index 316c94a..2a87d9d 100755 --- a/system/libraries/Migration.php +++ b/system/libraries/Migration.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -288,10 +288,7 @@ public function version($target_version) $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class); return FALSE; } - // method_exists() returns true for non-public methods, - // while is_callable() can't be used without instantiating. - // Only get_class_methods() satisfies both conditions. - elseif ( ! in_array($method, array_map('strtolower', get_class_methods($class)))) + elseif ( ! is_callable(array($class, $method))) { $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); return FALSE; diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 44f848f..1df5f9c 100755 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index 57981af..fdd958b 100755 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Parser * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/parser.html + * @link https://codeigniter.com/user_guide/libraries/parser.html */ class CI_Parser { diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index cf455d3..e9e03cf 100755 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c9d2e8a..eb433de 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 @@ -57,6 +57,7 @@ class CI_Session { protected $_driver = 'files'; protected $_config; + protected $_sid_regexp; // ------------------------------------------------------------------------ @@ -91,6 +92,7 @@ public function __construct(array $params = array()) // Note: BC workaround elseif (config_item('sess_use_database')) { + log_message('debug', 'Session: "sess_driver" is empty; using BC fallback to "sess_use_database".'); $this->_driver = 'database'; } @@ -98,6 +100,7 @@ public function __construct(array $params = array()) // Configuration ... $this->_configure($params); + $this->_config['_sid_regexp'] = $this->_sid_regexp; $class = new $class($this->_config); if ($class instanceof SessionHandlerInterface) @@ -130,7 +133,7 @@ public function __construct(array $params = array()) if (isset($_COOKIE[$this->_config['cookie_name']]) && ( ! is_string($_COOKIE[$this->_config['cookie_name']]) - OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']]) + OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']]) ) ) { @@ -314,8 +317,82 @@ protected function _configure(&$params) ini_set('session.use_strict_mode', 1); ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); - ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', 4); + + $this->_configure_sid_length(); + } + + // ------------------------------------------------------------------------ + + /** + * Configure session ID length + * + * To make life easier, we used to force SHA-1 and 4 bits per + * character on everyone. And of course, someone was unhappy. + * + * Then PHP 7.1 broke backwards-compatibility because ext/session + * is such a mess that nobody wants to touch it with a pole stick, + * and the one guy who does, nobody has the energy to argue with. + * + * So we were forced to make changes, and OF COURSE something was + * going to break and now we have this pile of shit. -- Narf + * + * @return void + */ + protected function _configure_sid_length() + { + if (PHP_VERSION_ID < 70100) + { + $hash_function = ini_get('session.hash_function'); + if (ctype_digit($hash_function)) + { + if ($hash_function !== '1') + { + ini_set('session.hash_function', 1); + } + + $bits = 160; + } + elseif ( ! in_array($hash_function, hash_algos(), TRUE)) + { + ini_set('session.hash_function', 1); + $bits = 160; + } + elseif (($bits = strlen(hash($hash_function, 'dummy', false)) * 4) < 160) + { + ini_set('session.hash_function', 1); + $bits = 160; + } + + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + $sid_length = (int) ceil($bits / $bits_per_character); + } + else + { + $bits_per_character = (int) ini_get('session.sid_bits_per_character'); + $sid_length = (int) ini_get('session.sid_length'); + if (($bits = $sid_length * $bits_per_character) < 160) + { + // Add as many more characters as necessary to reach at least 160 bits + $sid_length += (int) ceil((160 % $bits) / $bits_per_character); + ini_set('session.sid_length', $sid_length); + } + } + + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 + switch ($bits_per_character) + { + case 4: + $this->_sid_regexp = '[0-9a-f]'; + break; + case 5: + $this->_sid_regexp = '[0-9a-v]'; + break; + case 6: + $this->_sid_regexp = '[0-9a-zA-Z,-]'; + break; + } + + $this->_sid_regexp .= '{'.$sid_length.'}'; } // ------------------------------------------------------------------------ @@ -729,7 +806,7 @@ public function set_userdata($data, $value = NULL) * * Legacy CI_Session compatibility method * - * @param mixed $data Session data key(s) + * @param mixed $key Session data key(s) * @return void */ public function unset_userdata($key) diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 9dab5ac..2eef61d 100755 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ interface SessionHandlerInterface { diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 55ddb25..f32f14a 100755 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 317bd7d..31f5a46 100755 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -109,7 +109,10 @@ public function __construct(&$params) } // Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future. - isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); + if ( ! isset($this->_config['save_path']) && ($this->_config['save_path'] = config_item('sess_table_name'))) + { + log_message('debug', 'Session: "sess_save_path" is empty; using BC fallback to "sess_table_name".'); + } } // ------------------------------------------------------------------------ @@ -205,8 +208,12 @@ public function write($session_id, $session_data) // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); + if ($this->_lock === FALSE) + { + return $this->_fail(); + } // Was the ID regenerated? - if ($session_id !== $this->_session_id) + elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { @@ -216,10 +223,6 @@ public function write($session_id, $session_data) $this->_row_exists = FALSE; $this->_session_id = $session_id; } - elseif ($this->_lock === FALSE) - { - return $this->_fail(); - } if ($this->_row_exists === FALSE) { @@ -351,7 +354,7 @@ protected function _get_lock($session_id) { if ($this->_platform === 'mysql') { - $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + $arg = md5($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : '')); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 300) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; @@ -414,4 +417,4 @@ protected function _release_lock() return parent::_release_lock(); } -} \ No newline at end of file +} diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 119bf65..6016e09 100755 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -76,6 +76,20 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * Validate SID regular expression + * + * @var string + */ + protected $_sid_regexp; + + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + // ------------------------------------------------------------------------ /** @@ -95,8 +109,13 @@ public function __construct(&$params) } else { + log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + + $this->_sid_regexp = $this->_config['_sid_regexp']; + + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); } // ------------------------------------------------------------------------ @@ -148,18 +167,9 @@ public function read($session_id) // which re-reads session data if ($this->_file_handle === NULL) { - // Just using fopen() with 'c+b' mode would be perfect, but it is only - // available since PHP 5.2.6 and we have to set permissions for new files, - // so we'd have to hack around this ... - if (($this->_file_new = ! file_exists($this->_file_path.$session_id)) === TRUE) - { - if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) - { - log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return $this->_failure; - } - } - elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) + $this->_file_new = ! file_exists($this->_file_path.$session_id); + + if (($this->_file_handle = fopen($this->_file_path.$session_id, 'c+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); return $this->_failure; @@ -195,7 +205,7 @@ public function read($session_id) } $session_data = ''; - for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += strlen($buffer)) + for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += self::strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { @@ -351,10 +361,13 @@ public function gc($maxlifetime) $ts = time() - $maxlifetime; + $pattern = ($this->_config['match_ip'] === TRUE) + ? '[0-9a-f]{32}' + : ''; + $pattern = sprintf( - '/^%s[0-9a-f]{%d}$/', - preg_quote($this->_config['cookie_name'], '/'), - ($this->_config['match_ip'] === TRUE ? 72 : 40) + '#\A%s'.$pattern.$this->_sid_regexp.'\z#', + preg_quote($this->_config['cookie_name']) ); while (($file = readdir($directory)) !== FALSE) @@ -376,4 +389,18 @@ public function gc($maxlifetime) return $this->_success; } -} \ No newline at end of file + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } +} diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 88eb4b3..2556bf0 100755 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -186,7 +186,7 @@ public function read($session_id) */ public function write($session_id, $session_data) { - if ( ! isset($this->_memcached)) + if ( ! isset($this->_memcached, $this->_lock_key)) { return $this->_fail(); } @@ -202,32 +202,25 @@ public function write($session_id, $session_data) $this->_session_id = $session_id; } - if (isset($this->_lock_key)) - { - $key = $this->_key_prefix.$session_id; - - $this->_memcached->replace($this->_lock_key, time(), 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data))) - { - if ( - $this->_memcached->replace($key, $session_data, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) - { - $this->_fingerprint = $fingerprint; - return $this->_success; - } - - return $this->_fail(); - } + $key = $this->_key_prefix.$session_id; - if ( - $this->_memcached->touch($key, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) + $this->_memcached->replace($this->_lock_key, time(), 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + { + if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) { + $this->_fingerprint = $fingerprint; return $this->_success; } + + return $this->_fail(); + } + elseif ( + $this->_memcached->touch($key, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) + { + return $this->_success; } return $this->_fail(); @@ -379,4 +372,4 @@ protected function _release_lock() return TRUE; } -} \ No newline at end of file +} diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index e4e09fe..d260f7b 100755 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 @@ -199,7 +199,7 @@ public function read($session_id) */ public function write($session_id, $session_data) { - if ( ! isset($this->_redis)) + if ( ! isset($this->_redis, $this->_lock_key)) { return $this->_fail(); } @@ -215,27 +215,22 @@ public function write($session_id, $session_data) $this->_session_id = $session_id; } - if (isset($this->_lock_key)) + $this->_redis->setTimeout($this->_lock_key, 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { - $this->_redis->setTimeout($this->_lock_key, 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) + if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { - if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) - { - $this->_fingerprint = $fingerprint; - $this->_key_exists = TRUE; - return $this->_success; - } - - return $this->_fail(); + $this->_fingerprint = $fingerprint; + $this->_key_exists = TRUE; + return $this->_success; } - return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) - ? $this->_success - : $this->_fail(); + return $this->_fail(); } - return $this->_fail(); + return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + ? $this->_success + : $this->_fail(); } // ------------------------------------------------------------------------ @@ -255,7 +250,7 @@ public function close() if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); - if ($this->_redis->close() === $this->_failure) + if ($this->_redis->close() === FALSE) { return $this->_fail(); } diff --git a/system/libraries/Table.php b/system/libraries/Table.php index 2d98230..fef9bb0 100755 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.3.1 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category HTML Tables * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/table.html + * @link https://codeigniter.com/user_guide/libraries/table.html */ class CI_Table { @@ -277,6 +277,7 @@ protected function _prep_args($args) public function set_caption($caption) { $this->caption = $caption; + return $this; } // -------------------------------------------------------------------- diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index 23bdbbd..55e9a0e 100755 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category Trackbacks * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/trackback.html + * @link https://codeigniter.com/user_guide/libraries/trackback.html */ class CI_Trackback { @@ -370,7 +370,7 @@ public function validate_url(&$url) { $url = trim($url); - if (strpos($url, 'http') !== 0) + if (stripos($url, 'http') !== 0) { $url = 'http://'.$url; } diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index 3b6cb16..ce31ba3 100755 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ * @subpackage Libraries * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/typography.html + * @link https://codeigniter.com/user_guide/libraries/typography.html */ class CI_Typography { diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 3ac6af7..38e0fbd 100755 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.3.1 @@ -154,7 +154,6 @@ public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null', 'is_resource'), TRUE)) { - $expected = str_replace('is_double', 'is_float', $expected); $result = $expected($test); $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected)); } @@ -291,7 +290,7 @@ public function result($results = array()) { continue; } - elseif (in_array($key, array('test_name', 'test_datatype', 'test_res_datatype', 'result'), TRUE)) + elseif (in_array($key, array('test_name', 'test_datatype', 'res_datatype', 'result'), TRUE)) { if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE))) { diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index f241837..b37cc2f 100755 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -286,7 +286,7 @@ class CI_Upload { /** * Constructor * - * @param array $props + * @param array $config * @return void */ public function __construct($config = array()) @@ -601,7 +601,7 @@ public function data($index = NULL) 'file_type' => $this->file_type, 'file_path' => $this->upload_path, 'full_path' => $this->upload_path.$this->file_name, - 'raw_name' => str_replace($this->file_ext, '', $this->file_name), + 'raw_name' => substr($this->file_name, 0, -strlen($this->file_ext)), 'orig_name' => $this->orig_name, 'client_name' => $this->client_name, 'file_ext' => $this->file_ext, @@ -1083,16 +1083,27 @@ public function do_xss_clean() return FALSE; } - if (memory_get_usage() && ($memory_limit = ini_get('memory_limit'))) + if (memory_get_usage() && ($memory_limit = ini_get('memory_limit')) > 0) { - $memory_limit *= 1024 * 1024; - - // There was a bug/behavioural change in PHP 5.2, where numbers over one million get output - // into scientific notation. number_format() ensures this number is an integer - // http://bugs.php.net/bug.php?id=43053 - - $memory_limit = number_format(ceil(filesize($file) + $memory_limit), 0, '.', ''); + $memory_limit = str_split($memory_limit, strspn($memory_limit, '1234567890')); + if ( ! empty($memory_limit[1])) + { + switch ($memory_limit[1][0]) + { + case 'g': + case 'G': + $memory_limit[0] *= 1024 * 1024 * 1024; + break; + case 'm': + case 'M': + $memory_limit[0] *= 1024 * 1024; + break; + default: + break; + } + } + $memory_limit = (int) ceil(filesize($file) + $memory_limit[0]); ini_set('memory_limit', $memory_limit); // When an integer is used, the value is measured in bytes. - PHP.net } @@ -1207,10 +1218,13 @@ protected function _file_mime_type($file) // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii) $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/'; - /* Fileinfo extension - most reliable method + /** + * Fileinfo extension - most reliable method * - * Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the - * more convenient FILEINFO_MIME_TYPE flag doesn't exist. + * Apparently XAMPP, CentOS, cPanel and who knows what + * other PHP distribution channels EXPLICITLY DISABLE + * ext/fileinfo, which is otherwise enabled by default + * since PHP 5.3 ... */ if (function_exists('finfo_file')) { diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index 53d932a..cda3ef0 100755 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -46,7 +46,7 @@ * @subpackage Libraries * @category User Agent * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/user_agent.html + * @link https://codeigniter.com/user_guide/libraries/user_agent.html */ class CI_User_agent { @@ -173,13 +173,11 @@ class CI_User_agent { */ public function __construct() { + $this->_load_agent_file(); + if (isset($_SERVER['HTTP_USER_AGENT'])) { $this->agent = trim($_SERVER['HTTP_USER_AGENT']); - } - - if ($this->agent !== NULL && $this->_load_agent_file()) - { $this->_compile_data(); } diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index f965858..f043e0f 100755 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -352,7 +352,7 @@ public function initialize($config = array()) */ public function server($url, $port = 80, $proxy = FALSE, $proxy_port = 8080) { - if (strpos($url, 'http') !== 0) + if (stripos($url, 'http') !== 0) { $url = 'http://'.$url; } @@ -735,6 +735,8 @@ public function sendPayload($msg) .'Content-Length: '.strlen($msg->payload).$r.$r .$msg->payload; + stream_set_timeout($fp, $this->timeout); // set timeout for subsequent operations + for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result) { if (($result = fwrite($fp, substr($op, $written))) === FALSE) @@ -753,9 +755,6 @@ public function sendPayload($msg) $result = FALSE; break; } - - usleep(250000); - continue; } else { diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index 00d1fec..21de937 100755 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,10 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -56,7 +56,7 @@ * @subpackage Libraries * @category XML-RPC * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + * @link https://codeigniter.com/user_guide/libraries/xmlrpc.html */ class CI_Xmlrpcs extends CI_Xmlrpc { @@ -339,11 +339,11 @@ protected function _execute($m) //------------------------------------- $method_parts = explode('.', $this->methods[$methName]['function']); - $objectCall = (isset($method_parts[1]) && $method_parts[1] !== ''); + $objectCall = ! empty($method_parts[1]); if ($system_call === TRUE) { - if ( ! is_callable(array($this,$method_parts[1]))) + if ( ! is_callable(array($this, $method_parts[1]))) { return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); } @@ -400,11 +400,11 @@ protected function _execute($m) } elseif ($this->object === FALSE) { - return get_instance()->$method_parts[1]($m); + return get_instance()->{$method_parts[1]}($m); } else { - return $this->object->$method_parts[1]($m); + return $this->object->{$method_parts[1]}($m); } } else diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index 140ad72..46f6c14 100755 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 @@ -105,6 +105,13 @@ class CI_Zip { */ public $compression_level = 2; + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + /** * Initialize zip compression class * @@ -112,6 +119,8 @@ class CI_Zip { */ public function __construct() { + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + $this->now = time(); log_message('info', 'Zip Compression Class Initialized'); } @@ -182,7 +191,7 @@ protected function _add_dir($dir, $file_mtime, $file_mdate) .pack('V', 0) // crc32 .pack('V', 0) // compressed filesize .pack('V', 0) // uncompressed filesize - .pack('v', strlen($dir)) // length of pathname + .pack('v', self::strlen($dir)) // length of pathname .pack('v', 0) // extra field length .$dir // below is "data descriptor" segment @@ -197,7 +206,7 @@ protected function _add_dir($dir, $file_mtime, $file_mdate) .pack('V',0) // crc32 .pack('V',0) // compressed filesize .pack('V',0) // uncompressed filesize - .pack('v', strlen($dir)) // length of pathname + .pack('v', self::strlen($dir)) // length of pathname .pack('v', 0) // extra field length .pack('v', 0) // file comment length .pack('v', 0) // disk number start @@ -206,7 +215,7 @@ protected function _add_dir($dir, $file_mtime, $file_mdate) .pack('V', $this->offset) // relative offset of local header .$dir; - $this->offset = strlen($this->zipdata); + $this->offset = self::strlen($this->zipdata); $this->entries++; } @@ -255,10 +264,10 @@ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) { $filepath = str_replace('\\', '/', $filepath); - $uncompressed_size = strlen($data); + $uncompressed_size = self::strlen($data); $crc32 = crc32($data); - $gzdata = substr(gzcompress($data, $this->compression_level), 2, -4); - $compressed_size = strlen($gzdata); + $gzdata = self::substr(gzcompress($data, $this->compression_level), 2, -4); + $compressed_size = self::strlen($gzdata); $this->zipdata .= "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00" @@ -267,7 +276,7 @@ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) - .pack('v', strlen($filepath)) // length of filename + .pack('v', self::strlen($filepath)) // length of filename .pack('v', 0) // extra field length .$filepath .$gzdata; // "file data" segment @@ -279,7 +288,7 @@ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) - .pack('v', strlen($filepath)) // length of filename + .pack('v', self::strlen($filepath)) // length of filename .pack('v', 0) // extra field length .pack('v', 0) // file comment length .pack('v', 0) // disk number start @@ -288,7 +297,7 @@ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) .pack('V', $this->offset) // relative offset of local header .$filepath; - $this->offset = strlen($this->zipdata); + $this->offset = self::strlen($this->zipdata); $this->entries++; $this->file_num++; } @@ -401,8 +410,8 @@ public function get_zip() .$this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00" .pack('v', $this->entries) // total # of entries "on this disk" .pack('v', $this->entries) // total # of entries overall - .pack('V', strlen($this->directory)) // size of central dir - .pack('V', strlen($this->zipdata)) // offset to start of central dir + .pack('V', self::strlen($this->directory)) // size of central dir + .pack('V', self::strlen($this->zipdata)) // offset to start of central dir ."\x00\x00"; // .zip file comment length } @@ -425,9 +434,9 @@ public function archive($filepath) flock($fp, LOCK_EX); - for ($result = $written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result) + for ($result = $written = 0, $data = $this->get_zip(), $length = self::strlen($data); $written < $length; $written += $result) { - if (($result = fwrite($fp, substr($data, $written))) === FALSE) + if (($result = fwrite($fp, self::substr($data, $written))) === FALSE) { break; } @@ -481,4 +490,43 @@ public function clear_data() return $this; } + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + // -------------------------------------------------------------------- + + /** + * Byte-safe substr() + * + * @param string $str + * @param int $start + * @param int $length + * @return string + */ + protected static function substr($str, $start, $length = NULL) + { + if (self::$func_override) + { + // mb_substr($str, $start, null, '8bit') returns an empty + // string on PHP 5.3 + isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } } From e8671490a3aa1192a402d067db1465181d748f08 Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Fri, 20 Jan 2017 11:12:37 +1000 Subject: [PATCH 13/16] 3.1.3 Application directories --- application/config/autoload.php | 31 ++++----- application/config/constants.php | 30 ++++----- application/config/hooks.php | 2 +- application/config/memcached.php | 2 +- application/config/migration.php | 84 ++++++++++++++++++++++++ application/config/mimes.php | 19 +++++- application/config/profiler.php | 2 +- application/config/routes.php | 2 +- application/config/smileys.php | 3 +- application/config/user_agents.php | 6 +- install/installer/config/autoload.php | 29 ++++---- install/installer/config/constants.php | 30 ++++----- install/installer/config/hooks.php | 2 +- install/installer/config/memcached.php | 2 +- install/installer/config/migration.php | 6 +- install/installer/config/mimes.php | 19 +++++- install/installer/config/profiler.php | 2 +- install/installer/config/routes.php | 2 +- install/installer/config/smileys.php | 3 +- install/installer/config/user_agents.php | 6 +- 20 files changed, 190 insertions(+), 92 deletions(-) mode change 100644 => 100755 application/config/autoload.php create mode 100755 application/config/migration.php diff --git a/application/config/autoload.php b/application/config/autoload.php old mode 100644 new mode 100755 index b862822..7cdc901 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -39,16 +39,15 @@ | $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared'); | */ - $autoload['packages'] = array(); /* - | ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- -| These are the classes located in the system/libraries folder -| or in your application/libraries folder. +| These are the classes located in system/libraries/ or your +| application/libraries/ directory, with the addition of the +| 'database' library, which is somewhat of a special case. | | Prototype: | @@ -66,24 +65,22 @@ | Auto-load Drivers | ------------------------------------------------------------------- | These classes are located in system/libraries/ or in your - - - -| ------------------------------------------------------------------- -| Auto-load Drivers -| ------------------------------------------------------------------- -| These classes are located in the system/libraries folder or in your -| application/libraries folder within their own subdirectory. They +| application/libraries/ directory, but are also placed inside their +| own subdirectory and they extend the CI_Driver_Library class. They | offer multiple interchangeable driver options. | | Prototype: | | $autoload['drivers'] = array('cache'); +| +| You can also supply an alternative property name to be assigned in +| the controller: +| +| $autoload['drivers'] = array('cache' => 'cch'); +| */ - $autoload['drivers'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Helper Files @@ -92,10 +89,8 @@ | | $autoload['helper'] = array('url', 'file'); */ - $autoload['helper'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Config files @@ -108,10 +103,8 @@ | config files. Otherwise, leave it blank. | */ - $autoload['config'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Language files @@ -124,10 +117,8 @@ | "codeigniter_lang.php" would be referenced as array('codeigniter'); | */ - $autoload['language'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Models diff --git a/application/config/constants.php b/application/config/constants.php index 9c407ee..18d3b4b 100755 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -3,27 +3,27 @@ /* |-------------------------------------------------------------------------- -| File and Directory Modes +| Display Debug backtrace |-------------------------------------------------------------------------- | -| These prefs are used when checking and setting modes when working -| with the file system. The defaults are fine on servers with proper -| security, but you may wish (or even need) to change the values in -| certain environments (Apache running a separate process for each +| If set to TRUE, a backtrace will be displayed along with php errors. If +| error_reporting is disabled, the backtrace will not display, regardless +| of this setting +| */ defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE); /* |-------------------------------------------------------------------------- -| user, PHP under CGI with Apache suEXEC, etc.). Octal values should -| always be used to set the mode correctly. -| - -|-------------------------------------------------------------------------- -| File Stream Modes +| File and Directory Modes |-------------------------------------------------------------------------- | -| These modes are used when working with fopen()/popen() +| These prefs are used when checking and setting modes when working +| with the file system. The defaults are fine on servers with proper +| security, but you may wish (or even need) to change the values in +| certain environments (Apache running a separate process for each +| user, PHP under CGI with Apache suEXEC, etc.). Octal values should +| always be used to set the mode correctly. | */ defined('FILE_READ_MODE') OR define('FILE_READ_MODE', 0644); @@ -33,12 +33,10 @@ /* |-------------------------------------------------------------------------- -| Display Debug backtrace +| File Stream Modes |-------------------------------------------------------------------------- | -| If set to TRUE, a backtrace will be displayed along with php errors. If -| error_reporting is disabled, the backtrace will not display, regardless -| of this setting +| These modes are used when working with fopen()/popen() | */ defined('FOPEN_READ') OR define('FOPEN_READ', 'rb'); diff --git a/application/config/hooks.php b/application/config/hooks.php index 2eac5bb..a8f38a5 100755 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -8,6 +8,6 @@ | This file lets you define "hooks" to extend CI without hacking the core | files. Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/hooks.html +| https://codeigniter.com/user_guide/general/hooks.html | */ diff --git a/application/config/memcached.php b/application/config/memcached.php index 55949a6..5c23b39 100755 --- a/application/config/memcached.php +++ b/application/config/memcached.php @@ -7,7 +7,7 @@ | ------------------------------------------------------------------------- | Your Memcached servers can be specified below. | -| See: http://codeigniter.com/user_guide/libraries/caching.html#memcached +| See: https://codeigniter.com/user_guide/libraries/caching.html#memcached | */ $config = array( diff --git a/application/config/migration.php b/application/config/migration.php new file mode 100755 index 0000000..4b585a6 --- /dev/null +++ b/application/config/migration.php @@ -0,0 +1,84 @@ +migration->current() this is the version that schema will +| be upgraded / downgraded to. +| +*/ +$config['migration_version'] = 0; + +/* +|-------------------------------------------------------------------------- +| Migrations Path +|-------------------------------------------------------------------------- +| +| Path to your migrations folder. +| Typically, it will be within your application path. +| Also, writing permission is required within the migrations path. +| +*/ +$config['migration_path'] = APPPATH.'migrations/'; diff --git a/application/config/mimes.php b/application/config/mimes.php index a093907..0176533 100755 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -9,7 +9,6 @@ | Upload class to help identify allowed file types. | */ - return array( 'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), 'cpt' => 'application/mac-compactpro', @@ -164,5 +163,21 @@ 'vcf' => 'text/x-vcard', 'srt' => array('text/srt', 'text/plain'), 'vtt' => array('text/vtt', 'text/plain'), - 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'), + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web' ); diff --git a/application/config/profiler.php b/application/config/profiler.php index b30204e..3db22e3 100755 --- a/application/config/profiler.php +++ b/application/config/profiler.php @@ -9,6 +9,6 @@ | data are displayed when the Profiler is enabled. | Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/profiling.html +| https://codeigniter.com/user_guide/general/profiling.html | */ diff --git a/application/config/routes.php b/application/config/routes.php index a98c6d1..1b45740 100755 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -19,7 +19,7 @@ | | Please see the user guide for complete details: | -| http://codeigniter.com/user_guide/general/routing.html +| https://codeigniter.com/user_guide/general/routing.html | | ------------------------------------------------------------------------- | RESERVED ROUTES diff --git a/application/config/smileys.php b/application/config/smileys.php index 1428d68..abf9a89 100755 --- a/application/config/smileys.php +++ b/application/config/smileys.php @@ -10,10 +10,9 @@ | :-) and :) use the same image replacement. | | Please see user guide for more info: -| http://codeigniter.com/user_guide/helpers/smiley_helper.html +| https://codeigniter.com/user_guide/helpers/smiley_helper.html | */ - $smileys = array( // smiley image name width height alt diff --git a/application/config/user_agents.php b/application/config/user_agents.php index fd8ed48..798086b 100755 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -10,7 +10,6 @@ | mobile device data. The array keys are used to identify the device | and the array values are used to set the actual name of the item. */ - $platforms = array( 'windows nt 10.0' => 'Windows 10', 'windows nt 6.3' => 'Windows 8.1', @@ -208,5 +207,8 @@ 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', 'adsbot-google' => 'AdsBot Google', 'feedfetcher-google' => 'Feedfetcher Google', - 'curious george' => 'Curious George' + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot' ); diff --git a/install/installer/config/autoload.php b/install/installer/config/autoload.php index 72f855c..7cdc901 100755 --- a/install/installer/config/autoload.php +++ b/install/installer/config/autoload.php @@ -39,16 +39,15 @@ | $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared'); | */ - $autoload['packages'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- -| These are the classes located in the system/libraries folder -| or in your application/libraries folder. +| These are the classes located in system/libraries/ or your +| application/libraries/ directory, with the addition of the +| 'database' library, which is somewhat of a special case. | | Prototype: | @@ -59,26 +58,29 @@ | | $autoload['libraries'] = array('user_agent' => 'ua'); */ - $autoload['libraries'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Drivers | ------------------------------------------------------------------- -| These classes are located in the system/libraries folder or in your -| application/libraries folder within their own subdirectory. They +| These classes are located in system/libraries/ or in your +| application/libraries/ directory, but are also placed inside their +| own subdirectory and they extend the CI_Driver_Library class. They | offer multiple interchangeable driver options. | | Prototype: | | $autoload['drivers'] = array('cache'); +| +| You can also supply an alternative property name to be assigned in +| the controller: +| +| $autoload['drivers'] = array('cache' => 'cch'); +| */ - $autoload['drivers'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Helper Files @@ -87,10 +89,8 @@ | | $autoload['helper'] = array('url', 'file'); */ - $autoload['helper'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Config files @@ -103,10 +103,8 @@ | config files. Otherwise, leave it blank. | */ - $autoload['config'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Language files @@ -119,10 +117,8 @@ | "codeigniter_lang.php" would be referenced as array('codeigniter'); | */ - $autoload['language'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Models @@ -136,5 +132,4 @@ | | $autoload['model'] = array('first_model' => 'first'); */ - $autoload['model'] = array(); diff --git a/install/installer/config/constants.php b/install/installer/config/constants.php index 9c407ee..18d3b4b 100755 --- a/install/installer/config/constants.php +++ b/install/installer/config/constants.php @@ -3,27 +3,27 @@ /* |-------------------------------------------------------------------------- -| File and Directory Modes +| Display Debug backtrace |-------------------------------------------------------------------------- | -| These prefs are used when checking and setting modes when working -| with the file system. The defaults are fine on servers with proper -| security, but you may wish (or even need) to change the values in -| certain environments (Apache running a separate process for each +| If set to TRUE, a backtrace will be displayed along with php errors. If +| error_reporting is disabled, the backtrace will not display, regardless +| of this setting +| */ defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE); /* |-------------------------------------------------------------------------- -| user, PHP under CGI with Apache suEXEC, etc.). Octal values should -| always be used to set the mode correctly. -| - -|-------------------------------------------------------------------------- -| File Stream Modes +| File and Directory Modes |-------------------------------------------------------------------------- | -| These modes are used when working with fopen()/popen() +| These prefs are used when checking and setting modes when working +| with the file system. The defaults are fine on servers with proper +| security, but you may wish (or even need) to change the values in +| certain environments (Apache running a separate process for each +| user, PHP under CGI with Apache suEXEC, etc.). Octal values should +| always be used to set the mode correctly. | */ defined('FILE_READ_MODE') OR define('FILE_READ_MODE', 0644); @@ -33,12 +33,10 @@ /* |-------------------------------------------------------------------------- -| Display Debug backtrace +| File Stream Modes |-------------------------------------------------------------------------- | -| If set to TRUE, a backtrace will be displayed along with php errors. If -| error_reporting is disabled, the backtrace will not display, regardless -| of this setting +| These modes are used when working with fopen()/popen() | */ defined('FOPEN_READ') OR define('FOPEN_READ', 'rb'); diff --git a/install/installer/config/hooks.php b/install/installer/config/hooks.php index 2eac5bb..a8f38a5 100755 --- a/install/installer/config/hooks.php +++ b/install/installer/config/hooks.php @@ -8,6 +8,6 @@ | This file lets you define "hooks" to extend CI without hacking the core | files. Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/hooks.html +| https://codeigniter.com/user_guide/general/hooks.html | */ diff --git a/install/installer/config/memcached.php b/install/installer/config/memcached.php index 55949a6..5c23b39 100755 --- a/install/installer/config/memcached.php +++ b/install/installer/config/memcached.php @@ -7,7 +7,7 @@ | ------------------------------------------------------------------------- | Your Memcached servers can be specified below. | -| See: http://codeigniter.com/user_guide/libraries/caching.html#memcached +| See: https://codeigniter.com/user_guide/libraries/caching.html#memcached | */ $config = array( diff --git a/install/installer/config/migration.php b/install/installer/config/migration.php index 083bf28..4b585a6 100755 --- a/install/installer/config/migration.php +++ b/install/installer/config/migration.php @@ -21,12 +21,12 @@ | Migration file names may be based on a sequential identifier or on | a timestamp. Options are: | -| 'sequential' = Default migration naming (001_add_blog.php) +| 'sequential' = Sequential migration naming (001_add_blog.php) | 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php) | Use timestamp format YYYYMMDDHHIISS. | -| If this configuration value is missing the Migration library defaults -| to 'sequential' for backward compatibility. +| Note: If this configuration value is missing the Migration library +| defaults to 'sequential' for backward compatibility with CI2. | */ $config['migration_type'] = 'timestamp'; diff --git a/install/installer/config/mimes.php b/install/installer/config/mimes.php index a093907..0176533 100755 --- a/install/installer/config/mimes.php +++ b/install/installer/config/mimes.php @@ -9,7 +9,6 @@ | Upload class to help identify allowed file types. | */ - return array( 'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), 'cpt' => 'application/mac-compactpro', @@ -164,5 +163,21 @@ 'vcf' => 'text/x-vcard', 'srt' => array('text/srt', 'text/plain'), 'vtt' => array('text/vtt', 'text/plain'), - 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon') + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'), + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web' ); diff --git a/install/installer/config/profiler.php b/install/installer/config/profiler.php index b30204e..3db22e3 100755 --- a/install/installer/config/profiler.php +++ b/install/installer/config/profiler.php @@ -9,6 +9,6 @@ | data are displayed when the Profiler is enabled. | Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/profiling.html +| https://codeigniter.com/user_guide/general/profiling.html | */ diff --git a/install/installer/config/routes.php b/install/installer/config/routes.php index a98c6d1..1b45740 100755 --- a/install/installer/config/routes.php +++ b/install/installer/config/routes.php @@ -19,7 +19,7 @@ | | Please see the user guide for complete details: | -| http://codeigniter.com/user_guide/general/routing.html +| https://codeigniter.com/user_guide/general/routing.html | | ------------------------------------------------------------------------- | RESERVED ROUTES diff --git a/install/installer/config/smileys.php b/install/installer/config/smileys.php index 1428d68..abf9a89 100755 --- a/install/installer/config/smileys.php +++ b/install/installer/config/smileys.php @@ -10,10 +10,9 @@ | :-) and :) use the same image replacement. | | Please see user guide for more info: -| http://codeigniter.com/user_guide/helpers/smiley_helper.html +| https://codeigniter.com/user_guide/helpers/smiley_helper.html | */ - $smileys = array( // smiley image name width height alt diff --git a/install/installer/config/user_agents.php b/install/installer/config/user_agents.php index fd8ed48..798086b 100755 --- a/install/installer/config/user_agents.php +++ b/install/installer/config/user_agents.php @@ -10,7 +10,6 @@ | mobile device data. The array keys are used to identify the device | and the array values are used to set the actual name of the item. */ - $platforms = array( 'windows nt 10.0' => 'Windows 10', 'windows nt 6.3' => 'Windows 8.1', @@ -208,5 +207,8 @@ 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', 'adsbot-google' => 'AdsBot Google', 'feedfetcher-google' => 'Feedfetcher Google', - 'curious george' => 'Curious George' + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot' ); From f900ae12d0bfa0c60bee975fd3033f4f014bdd4d Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Mon, 23 Jan 2017 11:00:16 +1000 Subject: [PATCH 14/16] 3.1.3 Admin Controller patch --- application/core/AdminController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/core/AdminController.php b/application/core/AdminController.php index cd5bf82..15d098a 100644 --- a/application/core/AdminController.php +++ b/application/core/AdminController.php @@ -21,7 +21,7 @@ public function __construct() public function view($view, $vars = [], $string=false) { - $vars['this'] = $this; + ///$vars['this'] = $this; if($string) { @@ -44,7 +44,7 @@ public function view($view, $vars = [], $string=false) */ public function partial($view, $vars = [], $string=false) { - $vars['this'] = $this; + // $vars['this'] = $this; if($string) { From 629b8e643ed4524776a5afbfa5a8a8e90e5ad02a Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Wed, 8 Feb 2017 09:36:21 +1000 Subject: [PATCH 15/16] Better hash for admin password --- install/database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/database.sql b/install/database.sql index af6ba5d..564e86f 100644 --- a/install/database.sql +++ b/install/database.sql @@ -10,7 +10,7 @@ CREATE TABLE `gc_admin` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; -INSERT INTO `gc_admin` (`id`, `firstname`, `lastname`, `username`, `email`, `access`, `password`) VALUES ('1', '', '', 'admin', '', 'Admin', '$2a$08$KWNdzFXN53nniFOM6SMzC.oMJEhsaVGagoHHXLD6GYlYAKF9OAoaG'); +INSERT INTO `gc_admin` (`id`, `firstname`, `lastname`, `username`, `email`, `access`, `password`) VALUES ('1', '', '', 'admin', '', 'Admin', '$2y$10$bZ8cSKBYfQu/XK4PXj8iJOHtvKFoxbiCjYMz3bZzSrcCwEWd/p9D2'); CREATE TABLE `gc_banner_collections` ( `banner_collection_id` int(4) unsigned NOT NULL AUTO_INCREMENT, From 31cbb32527f64756a60d2ef166ecb193d5b1b5f7 Mon Sep 17 00:00:00 2001 From: Lawrence Meckan Date: Tue, 14 Feb 2017 10:56:46 +1000 Subject: [PATCH 16/16] Remove MCrypt & SHA1 dependencies --- application/libraries/Auth.php | 5 +++-- application/modules/login/models/Login.php | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/application/libraries/Auth.php b/application/libraries/Auth.php index bafece5..e78a5db 100644 --- a/application/libraries/Auth.php +++ b/application/libraries/Auth.php @@ -63,7 +63,8 @@ public function isLoggedIn($redirect = false, $defaultRedirect = true) if (isset($_COOKIE['GoCartAdmin'])) { //the cookie is there, lets log the customer back in. if ($_COOKIE['GoCartAdmin']) { - $result = CI::db()->select('*, sha1(username+password) as hash')->get('admin')->row_array(); + $result = CI::db()->select('*')->get('admin')->row_array(); + $result['hash'] = password_hash($result['user'].$result['password']); if ($result) { //unset these 2 fields unset($result['password']); @@ -110,7 +111,7 @@ public function login_admin($username, $password, $remember = false) if (password_verify($password, $result['password']) == true && sizeof($result) > 0) { if ($remember) { //generate a remember cookie - $loginCred = sha1($username.$result['password']); + $loginCred = password_hash($username.$result['password']); $this->generateCookie($loginCred, strtotime('+6 months')); //remember the user for 6 months } diff --git a/application/modules/login/models/Login.php b/application/modules/login/models/Login.php index baafcc5..3c2e486 100644 --- a/application/modules/login/models/Login.php +++ b/application/modules/login/models/Login.php @@ -10,7 +10,7 @@ public function __construct() //If we don't have a customer, check for a cookie. if (isset($_COOKIE['GoCartCustomer'])) { //the cookie is there, lets log the customer back in. - $info = $this->aes256Decrypt(base64_decode($_COOKIE['GoCartCustomer'])); + $info = $this->aes256Decrypt($_COOKIE['GoCartCustomer']); $cred = json_decode($info); if (is_object($cred)) { @@ -66,7 +66,7 @@ public function loginCustomer($email, $password, $remember = false) if ($remember) { $loginCred = json_encode(array('email'=>$customer->email, 'password'=>$customer->password)); - $loginCred = base64_encode($this->aes256Encrypt($loginCred)); + $loginCred = $this->aes256Encrypt($loginCred); //remember the user for 6 months $this->generateCookie($loginCred, strtotime('+6 months')); } @@ -120,8 +120,10 @@ private function aes256Encrypt($data) $key = hash('SHA256', $key, true); } $padding = 16 - (strlen($data) % 16); + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); $data .= str_repeat(chr($padding), $padding); - return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16)); + $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); + return base64_encode($encrypted . '::' . $iv); } private function aes256Decrypt($data) @@ -130,8 +132,7 @@ private function aes256Decrypt($data) if (32 !== strlen($key)) { $key = hash('SHA256', $key, true); } - $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16)); - $padding = ord($data[strlen($data) - 1]); - return substr($data, 0, -$padding); + list($encrypted_data, $iv) = explode('::', base64_decode($data), 2); + return openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv); } }