diff --git a/README.md b/README.md
index f0373593..a98665e5 100755
--- a/README.md
+++ b/README.md
@@ -1,19 +1,21 @@
-## CodeIgniter 3 Bootstrap
+## CodeIgniter 3 Bootstrap
+
+**Latest Build: 2017-03-24**
**Note: This project is still in progress, but welcome for any issues encountered**
A starter template that supports multi-tenant (Frontend / Admin Panel / API) website in a single application.
This repository is developed upon the following tools:
-* [CodeIgniter](http://www.codeigniter.com/) (v3.0.6) - PHP framework
+* [CodeIgniter](http://www.codeigniter.com/) (v3.1.3) - PHP framework
* [CodeIgniter HMVC Extensions](https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc) - modular structure by [wiredesignz](http://wiredesignz.co.nz/)
* [codeigniter-base-model](https://github.com/jamierumbelow/codeigniter-base-model) - more advanced CRUD functions for models by [jamierumbelow](https://github.com/jamierumbelow)
* [codeigniter-restserver](https://github.com/chriskacerguis/codeigniter-restserver) - base setup for API module
* [Ion Auth](http://benedmunds.com/ion_auth/) - authentication library for CodeIgniter by [Ben Edmunds](http://benedmunds.com/)
-* [Bootstrap](http://getbootstrap.com/) (v3.3.6) - popular frontend framework
-* [Grocery CRUD](http://www.grocerycrud.com/) (v1.5.5) - feature-rich library to build CRUD tables
+* [Bootstrap](http://getbootstrap.com/) (v3.3.7) - popular frontend framework
+* [Grocery CRUD](http://www.grocerycrud.com/) (v1.5.8) - feature-rich library to build CRUD tables
* [Image CRUD](http://www.grocerycrud.com/image-crud) (v0.6) - CRUD library for image management
-* [AdminLTE](https://github.com/almasaeed2010/AdminLTE) (v2.3.3) - bootstrap theme for Admin Panel
+* [AdminLTE](https://github.com/almasaeed2010/AdminLTE) (v2.3.11) - bootstrap theme for Admin Panel
### Features
@@ -40,7 +42,7 @@ This repository contains setup for rapid development:
* ... more coming!
-### Demo Project (in progress)
+### Demo Project
A demo repository can be found from: https://github.com/waifung0207/ci_bootstrap_3_demo
@@ -49,7 +51,7 @@ A demo repository can be found from: https://github.com/waifung0207/ci_bootstrap
Below configuration are preferred; other environments are not well-tested, but still feel free to report and issues.
-* **PHP 5.5+**
+* **PHP 5.6+**
* **Apache 2.2+** with rewrite mod enabled
* **MySQL 5.5+** (not tested on MariaDB)
@@ -86,7 +88,7 @@ application/ --- Main CodeIgniter source files
autoload.php --- By default, some files are loaded for this repo
ci_bootstrap.php --- Core configuration file for all sites
database.php --- Need to verify to ensure connection with MySQL database
- email.php --- Created to centralize email configuration (preset: using Mandrill service)
+ email.php --- Created to centralize email configuration (default: using Mailgun)
form_validation.php --- Created to centralize validation forms for all forms, include ReCAPTCHA settings
routes.php --- Changed default controller from Welcome to Home
controllers/ --- Controllers for Frontend Website; extends from MY_Controller (except Cli)
@@ -99,7 +101,8 @@ application/ --- Main CodeIgniter source files
MY_Router.php --- Required for HMVC extension
helpers/ --- Contains custom helper functions being used throughout this repo
language/ --- Preset language files
- libraries/ --- Custom libraries (e.g. Ion Auth, Form Builder, System Message)
+ libraries/ --- Custom libraries (e.g. Form Builder, System Message)
+ MY_Email.php --- Enhanced email library, includes work with Mailgun API
models/ --- Sample model extending from MY_Model
modules/ --- Each module can be accessed by http://{base_url}/{module_name}/{module_controller}/, etc.
admin/ --- Module for Admin Panel
@@ -170,7 +173,5 @@ More screenshots can be viewed from the [screenshots folder](https://github.com/
* Changelog file
* Better documentation (e.g. on [Gitbook](http://gitbook.com/))
* Enhance Form Builder library to support more field types
-* API authentication (by API key or JSON Web Token, i.e. JWT)
-* Database backup and restore versions
* Grocery CRUD / Image CRUD file upload - add Amazon S3 integration
* Grocery CRUD / Image CRUD image upload - add cropping feature
diff --git a/application/config/ci_bootstrap.php b/application/config/ci_bootstrap.php
index ad82717e..4da72846 100755
--- a/application/config/ci_bootstrap.php
+++ b/application/config/ci_bootstrap.php
@@ -91,7 +91,19 @@
// Restricted pages
'page_auth' => array(
- 'test' => array('membders'),
+ ),
+
+ // Email config
+ 'email' => array(
+ 'from_email' => '',
+ 'from_name' => '',
+ 'subject_prefix' => '',
+
+ // Mailgun HTTP API
+ 'mailgun_api' => array(
+ 'domain' => '',
+ 'private_api_key' => ''
+ ),
),
// Debug tools
diff --git a/application/config/ci_bootstrap_example.php b/application/config/ci_bootstrap_example.php
index c73f5656..509c072c 100644
--- a/application/config/ci_bootstrap_example.php
+++ b/application/config/ci_bootstrap_example.php
@@ -137,6 +137,19 @@
'panel/admin_user_group' => array('webmaster'),
),
+ // Email config (to be used in MY_Email library)
+ 'email' => array(
+ 'from_email' => 'noreply@email.com',
+ 'from_name' => 'CI Bootstrap',
+ 'subject_prefix' => '[CI Bootstrap] ',
+
+ // Mailgun HTTP API
+ 'mailgun_api' => array(
+ 'domain' => '',
+ 'private_api_key' => ''
+ ),
+ ),
+
// Debug tools (available only when ENVIRONMENT = 'development')
'debug' => array(
'view_data' => FALSE, // whether to display MY_Controller's mViewData at page end
diff --git a/application/config/constants.php b/application/config/constants.php
index c958b263..4037aca1 100755
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -93,15 +93,19 @@
*/
if (!(PHP_SAPI === 'cli' OR defined('STDIN')))
{
- // Base URL with directory support; also for API prefix in Swagger annotation (/application/modules/api/swagger/info.php)
+ // Base URL with directory support
$protocol = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS'])!== 'off') ? 'https' : 'http';
$base_url = $protocol.'://'.$_SERVER['HTTP_HOST'];
$base_url.= dirname($_SERVER['SCRIPT_NAME']);
define('BASE_URL', $base_url);
+
+ // For API prefix in Swagger annotation (/application/modules/api/swagger/info.php)
+ define('API_PROTOCOL', $protocol);
+ define('API_HOST', $_SERVER['HTTP_HOST'].dirname($_SERVER['SCRIPT_NAME']));
}
define('CI_BOOTSTRAP_REPO', 'https://github.com/waifung0207/ci_bootstrap_3');
-define('CI_BOOTSTRAP_VERSION', 'Build 20160610'); // will follow semantic version (e.g. v1.x.x) after first stable launch
+define('CI_BOOTSTRAP_VERSION', 'Build 20170324'); // will follow semantic version (e.g. v1.x.x) after first stable launch
// Upload paths
-//define('UPLOAD_COVER_PHOTO', 'assets/uploads/cover_photos');
\ No newline at end of file
+//define('UPLOAD_COVER_PHOTO', 'assets/uploads/cover_photos');
diff --git a/application/config/email.php b/application/config/email.php
index 2dc35a66..57df7457 100755
--- a/application/config/email.php
+++ b/application/config/email.php
@@ -8,23 +8,12 @@
| */
$config['protocol'] = 'smtp';
-$config['smtp_host'] = 'smtp.mandrillapp.com';
+$config['smtp_host'] = 'smtp.mailgun.org';
$config['smtp_port'] = '587';
$config['smtp_timeout'] = '30';
-$config['smtp_user'] = 'username';
+$config['smtp_user'] = 'postmaster@yourdomain.com';
$config['smtp_pass'] = 'password';
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
$config['wordwrap'] = TRUE;
$config['newline'] = "\r\n";
-
-// custom values from CI Bootstrap
-$config['from_email'] = "noreply@email.com";
-$config['from_name'] = "CI Bootstrap";
-$config['subject_prefix'] = "[CI Bootstrap] ";
-
-// Mailgun API (to be used in Email Client library)
-$config['mailgun'] = array(
- 'domain' => '',
- 'private_api_key' => '',
-);
\ No newline at end of file
diff --git a/application/config/routes.php b/application/config/routes.php
index 272ea58d..2fc8757e 100755
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -56,11 +56,11 @@
/*
| -------------------------------------------------------------------------
| Added by CI Bootstrap 3
-| Multilingual routing (update "en|zh|cn|es" for available languages)
+| Multilingual routing (use 2 characters (e.g. en, zh, cn, es) for switching languages)
| -------------------------------------------------------------------------
*/
-$route['^en|zh|cn|es/(.+)$'] = "$1";
-$route['^en|zh|cn|es$'] = $route['default_controller'];
+$route['^(\w{2})/(.*)$'] = '$2';
+$route['^(\w{2})$'] = $route['default_controller'];
/*
| -------------------------------------------------------------------------
diff --git a/application/config/testing/database.php b/application/config/testing/database.php
new file mode 100755
index 00000000..bf9857ff
--- /dev/null
+++ b/application/config/testing/database.php
@@ -0,0 +1,96 @@
+db->last_query() and profiling of DB queries.
+| When you run a query, with this setting set to TRUE (default),
+| CodeIgniter will store the SQL statement for debugging purposes.
+| However, this may cause high memory usage, especially if you run
+| a lot of SQL queries ... disable this to avoid that problem.
+|
+| The $active_group variable lets you choose which connection group to
+| make active. By default there is only one group (the 'default' group).
+|
+| The $query_builder variables lets you determine whether or not to load
+| the query builder class.
+*/
+$active_group = 'default';
+$query_builder = TRUE;
+
+$db['default'] = array(
+ 'dsn' => '',
+ 'hostname' => 'localhost',
+ 'username' => '',
+ 'password' => '',
+ 'database' => '',
+ 'dbdriver' => 'mysqli',
+ 'dbprefix' => '',
+ '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,
+ 'failover' => array(),
+ 'save_queries' => TRUE
+);
diff --git a/application/controllers/Cli.php b/application/controllers/Cli.php
index 4101121a..41d08151 100755
--- a/application/controllers/Cli.php
+++ b/application/controllers/Cli.php
@@ -57,11 +57,13 @@ public function clean_db()
$this->load->database();
echo '====== Task: Empty database'.PHP_EOL;
+ /*
$this->db->truncate('cover_photos');
$this->db->truncate('blog_categories');
$this->db->truncate('blog_tags');
$this->db->truncate('blog_post_tag_rel');
$this->db->truncate('blog_posts');
+ */
echo '====== Task: Empty database (Completed)'.PHP_EOL;
}
diff --git a/application/core/MY_Controller.php b/application/core/MY_Controller.php
index 0092e9b9..9974a490 100755
--- a/application/core/MY_Controller.php
+++ b/application/core/MY_Controller.php
@@ -133,9 +133,6 @@ private function _setup()
}
$this->mConfig = $config;
-
- // fix usage of MY_Form_validation in HMVC structure
- $this->form_validation->CI =& $this;
}
// Verify user login (regardless of user group)
diff --git a/application/core/MY_Lang.php b/application/core/MY_Lang.php
index e6d10640..a7f941b8 100755
--- a/application/core/MY_Lang.php
+++ b/application/core/MY_Lang.php
@@ -7,7 +7,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
@@ -30,9 +30,9 @@
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://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 http://codeigniter.com
+ * @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
@@ -59,7 +59,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 MY_Lang extends CI_Lang {
diff --git a/application/core/MY_Loader.php b/application/core/MY_Loader.php
index fbf2dcc5..be8fd880 100755
--- a/application/core/MY_Loader.php
+++ b/application/core/MY_Loader.php
@@ -3,4 +3,19 @@
/* load the MX_Loader class */
require APPPATH."third_party/MX/Loader.php";
-class MY_Loader extends MX_Loader {}
\ No newline at end of file
+class MY_Loader extends MX_Loader
+{
+ /** Load a module view **/
+ public function view($view, $vars = array(), $return = FALSE)
+ {
+ list($path, $_view) = Modules::find($view, $this->_module, 'views/');
+
+ if ($path != FALSE)
+ {
+ $this->_ci_view_paths = array($path => TRUE) + $this->_ci_view_paths;
+ $view = $_view;
+ }
+
+ return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => ((method_exists($this,'_ci_object_to_array')) ? $this->_ci_object_to_array($vars) : $this->_ci_prepare_view_vars($vars)), '_ci_return' => $return));
+ }
+}
\ No newline at end of file
diff --git a/application/core/MY_Model.php b/application/core/MY_Model.php
index 63d30ab3..1103c6ca 100755
--- a/application/core/MY_Model.php
+++ b/application/core/MY_Model.php
@@ -13,8 +13,7 @@ class MY_Model extends Base_Model {
public $before_get = array('callback_before_get');
public $after_get = array('callback_after_get');
- // Variables from CI Bootstrap
- // (sample usage: see Cover_photo_model, Blog_post_model)
+ // Variables from CI Bootstrap (see demo repo for examples)
protected $where = array();
protected $order_by = array();
protected $upload_fields = array();
diff --git a/application/core/controllers/Admin_Controller.php b/application/core/controllers/Admin_Controller.php
index 39601a14..8f4ce24e 100755
--- a/application/core/controllers/Admin_Controller.php
+++ b/application/core/controllers/Admin_Controller.php
@@ -33,7 +33,7 @@ protected function render($view_file, $layout = 'default')
// additional view data
$this->mViewData['useful_links'] = $this->mUsefulLinks;
- parent::render($view_file);
+ parent::render($view_file, $layout);
}
// Initialize CRUD table via Grocery CRUD library
@@ -158,4 +158,4 @@ protected function render_crud()
$this->mViewData['crud_output'] = $crud_data->output;
$this->render('crud');
}
-}
\ No newline at end of file
+}
diff --git a/application/core/controllers/Api_Controller.php b/application/core/controllers/Api_Controller.php
index e8c4252a..0e68d8df 100755
--- a/application/core/controllers/Api_Controller.php
+++ b/application/core/controllers/Api_Controller.php
@@ -136,7 +136,7 @@ protected function error_method_not_allowed()
$data = array('status' => FALSE);
$this->response($data, REST_Controller::HTTP_METHOD_NOT_ALLOWED);
}
-
+
protected function error_not_implemented($additional_data = array())
{
// show "not implemented" info only during development mode
@@ -162,4 +162,60 @@ protected function error_not_implemented($additional_data = array())
$this->error_not_found();
}
}
+
+ // Functions from codeigniter-restserver
+ protected function _generate_key()
+ {
+ do
+ {
+ // Generate a random salt
+ $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
+ // If an error occurred, then fall back to the previous method
+ if ($salt === FALSE)
+ {
+ $salt = hash('sha256', time() . mt_rand());
+ }
+ $new_key = substr($salt, 0, config_item('rest_key_length'));
+ }
+ while ($this->_key_exists($new_key));
+ return $new_key;
+ }
+
+ protected function _get_key($key)
+ {
+ return $this->db
+ ->where(config_item('rest_key_column'), $key)
+ ->get(config_item('rest_keys_table'))
+ ->row();
+ }
+
+ protected function _key_exists($key)
+ {
+ return $this->db
+ ->where(config_item('rest_key_column'), $key)
+ ->count_all_results(config_item('rest_keys_table')) > 0;
+ }
+
+ protected function _insert_key($key, $data)
+ {
+ $data[config_item('rest_key_column')] = $key;
+ $data['date_created'] = function_exists('now') ? now() : time();
+ return $this->db
+ ->set($data)
+ ->insert(config_item('rest_keys_table'));
+ }
+
+ protected function _update_key($key, $data)
+ {
+ return $this->db
+ ->where(config_item('rest_key_column'), $key)
+ ->update(config_item('rest_keys_table'), $data);
+ }
+
+ protected function _delete_key($key)
+ {
+ return $this->db
+ ->where(config_item('rest_key_column'), $key)
+ ->delete(config_item('rest_keys_table'));
+ }
}
\ No newline at end of file
diff --git a/application/helpers/MY_email_helper.php b/application/helpers/MY_email_helper.php
deleted file mode 100755
index 1cadf7df..00000000
--- a/application/helpers/MY_email_helper.php
+++ /dev/null
@@ -1,39 +0,0 @@
-load->library('email');
- $CI->config->load('email');
- $from_email = $CI->config->item('from_email');
- $from_name = $CI->config->item('from_name');
- $subject = $CI->config->item('subject_prefix').$subject;
-
- // basic parameters
- $CI->email->from($from_email, $from_name);
- $CI->email->to($to_email, $to_name);
- $CI->email->subject($subject);
- //$CI->email->cc($from_email, $from_name);
- //$CI->email->reply_to($from_email, $from_name);
-
- // confirm to send
- $msg = $CI->load->view('email/'.$view, $view_data, TRUE);
- $CI->email->message($msg);
-
- if (ENVIRONMENT=='development')
- {
- $CI->email->send(FALSE);
- echo $CI->email->print_debugger();
- }
- else
- {
- $CI->email->send();
- }
-}
\ No newline at end of file
diff --git a/application/language/english/auth_lang.php b/application/language/english/auth_lang.php
deleted file mode 100755
index 13293287..00000000
--- a/application/language/english/auth_lang.php
+++ /dev/null
@@ -1,144 +0,0 @@
-mPlatform = $platform;
- $this->CI =& get_instance();
- $this->CI->config->load('email');
- }
-
- public function set_platform($platform)
- {
- $this->mPlatform = $platform;
- }
-
- public function send($to_email, $subject, $view, $view_data = NULL)
- {
- switch ($this->mPlatform)
- {
- // Reference: https://github.com/mailgun/mailgun-php
- case 'mailgun':
-
- // create Mailgun object
- $platform_config = $this->CI->config->item($this->mPlatform);
- $api_key = $platform_config['private_api_key'];
- $domain = $platform_config['domain'];
- $from_email = $this->CI->config->item('from_email');
- $from_name = $this->CI->config->item('from_name');
- $mg = new Mailgun\Mailgun($api_key);
-
- // get HTML content from view
- $view_data['from_name'] = $from_name;
- $html = $this->CI->load->view($view, $view_data, TRUE);
-
- // prepend subject
- $subject = $this->CI->config->item('subject_prefix').$subject;
-
- // Mailgun MessageBuilder
- // Reference: https://github.com/mailgun/mailgun-php/blob/master/src/Mailgun/Messages/README.md
- $mb = $mg->MessageBuilder();
- $mb->setFromAddress($from_email, $from_name);
- $mb->addToRecipient($to_email);
- $mb->setSubject($subject);
- $mb->setHtmlBody($html);
-
- // confirm to send message
- $mg->post("{$domain}/messages", $mb->getMessage());
- break;
- }
- }
-}
\ No newline at end of file
diff --git a/application/libraries/MY_Email.php b/application/libraries/MY_Email.php
new file mode 100644
index 00000000..ae248355
--- /dev/null
+++ b/application/libraries/MY_Email.php
@@ -0,0 +1,117 @@
+CI =& get_instance();
+ $this->CI->config->load('ci_bootstrap');
+ }
+
+ // Send email templates using default CodeIgniter setting (e.g. SMTP)
+ // Template folder: /application/views/email/
+ public function send_email_template($to_email, $to_name, $subject, $view, $view_data = NULL)
+ {
+ // load values from config
+ $config = $this->CI->config->item('ci_bootstrap')['email'];
+ $from_email = $config['from_email'];
+ $from_name = $config['from_name'];
+ $subject = $config['subject_prefix'].$subject;
+
+ // basic parameters
+ parent::from($from_email, $from_name);
+ parent::to($to_email, $to_name);
+ parent::subject($subject);
+
+ // append view data
+ $info = new stdClass();
+ $info->from_email = $from_email;
+ $info->from_name = $from_name;
+ $info->to_email = $to_email;
+ $info->to_name = $to_name;
+ $info->subject_prefix = $config['subject_prefix'];
+ $info->subject = $subject;
+ $view_data['email_info'] = $info;
+
+ // get HTML content from view
+ $msg = $this->CI->load->view('email/'.$view, $view_data, TRUE);
+ parent::message($msg);
+
+ // confirm to send
+ if (ENVIRONMENT=='development')
+ {
+ // return result with debug messages
+ $result = parent::send(FALSE);
+ return array(
+ 'result' => $result,
+ 'debug' => parent::print_debugger()
+ );
+ }
+ else
+ {
+ // return only result (TRUE / FALSE)
+ $result = parent::send();
+ return array('result' => $result);
+ }
+ }
+
+ // Send email template using Mailgun HTTP API
+ // Template folder: /application/views/email/
+ public function send_by_mailgun($to_email, $to_name, $subject, $view, $view_data = NULL)
+ {
+ // load values from config
+ $config = $this->CI->config->item('ci_bootstrap')['email'];
+ $mailgun_config = $config['mailgun_api'];
+
+ // config not set correctly
+ if ( empty($mailgun_config['domain']) || empty($mailgun_config['private_api_key']) )
+ {
+ return array(
+ 'result' => FALSE,
+ 'error' => 'Mailgun API config not set'
+ );
+ }
+
+ // other values from config
+ $from_email = $config['from_email'];
+ $from_name = $config['from_name'];
+ $subject = $config['subject_prefix'].$subject;
+
+ // create Mailgun object
+ $api_key = $mailgun_config['private_api_key'];
+ $domain = $mailgun_config['domain'];
+ $mg = new Mailgun\Mailgun($api_key);
+
+ // append view data
+ $info = new stdClass();
+ $info->from_email = $from_email;
+ $info->from_name = $from_name;
+ $info->to_email = $to_email;
+ $info->to_name = $to_name;
+ $info->subject_prefix = $config['subject_prefix'];
+ $info->subject = $subject;
+ $view_data['email_info'] = $info;
+
+ // get HTML content from view
+ $html = $this->CI->load->view('email/'.$view, $view_data, TRUE);
+
+ // Mailgun MessageBuilder
+ // Reference: https://github.com/mailgun/mailgun-php/blob/master/src/Mailgun/Messages/README.md
+ $mb = $mg->MessageBuilder();
+ $mb->setFromAddress($from_email, array('full_name' => $from_name));
+ $mb->addToRecipient($to_email, array('full_name' => $to_name));
+ $mb->setSubject($subject);
+ $mb->setHtmlBody($html);
+
+ // confirm to send
+ $response = $mg->post("{$domain}/messages", $mb->getMessage());
+ return array('result' => ($response->http_response_code==200));
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/MY_Form_validation.php b/application/libraries/MY_Form_validation.php
index 9ede59b9..26ce82a3 100755
--- a/application/libraries/MY_Form_validation.php
+++ b/application/libraries/MY_Form_validation.php
@@ -2,11 +2,17 @@
defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * Base model to enhance form validation library
+ * Enhanced Form Validation library by CI Bootstrap 3
*/
class MY_Form_validation extends CI_Form_validation {
public $CI;
+
+ public function __construct($rules = array())
+ {
+ parent::__construct($rules);
+ $this->CI =& get_instance();
+ }
/**
* Custom rules
diff --git a/application/modules/admin/models/Admin_user_model.php b/application/models/Admin_user_model.php
similarity index 100%
rename from application/modules/admin/models/Admin_user_model.php
rename to application/models/Admin_user_model.php
diff --git a/application/modules/api/models/Api_key_model.php b/application/models/Api_key_model.php
similarity index 100%
rename from application/modules/api/models/Api_key_model.php
rename to application/models/Api_key_model.php
diff --git a/application/modules/admin/config/ci_bootstrap.php b/application/modules/admin/config/ci_bootstrap.php
index aa96079a..9df9a973 100755
--- a/application/modules/admin/config/ci_bootstrap.php
+++ b/application/modules/admin/config/ci_bootstrap.php
@@ -84,6 +84,14 @@
'Admin User Groups' => 'panel/admin_user_group',
)
),
+ 'util' => array(
+ 'name' => 'Utilities',
+ 'url' => 'util',
+ 'icon' => 'fa fa-cogs',
+ 'children' => array(
+ 'Database Versions' => 'util/list_db',
+ )
+ ),
'logout' => array(
'name' => 'Sign Out',
'url' => 'panel/logout',
@@ -102,6 +110,11 @@
'panel/admin_user' => array('webmaster'),
'panel/admin_user_create' => array('webmaster'),
'panel/admin_user_group' => array('webmaster'),
+ 'util' => array('webmaster'),
+ 'util/list_db' => array('webmaster'),
+ 'util/backup_db' => array('webmaster'),
+ 'util/restore_db' => array('webmaster'),
+ 'util/remove_db' => array('webmaster'),
),
// AdminLTE settings
diff --git a/application/modules/admin/config/grocery_crud.php b/application/modules/admin/config/grocery_crud.php
new file mode 100755
index 00000000..6c517384
--- /dev/null
+++ b/application/modules/admin/config/grocery_crud.php
@@ -0,0 +1,63 @@
+ 'Group',
+ 'image_url' => 'Image',
+ 'thumbnail_url' => 'Thumbnail',
+
+ 'author_id' => 'Author',
+ 'category_id' => 'Category',
+ );
diff --git a/application/modules/admin/config/image_crud.php b/application/modules/admin/config/image_crud.php
new file mode 100755
index 00000000..89869785
--- /dev/null
+++ b/application/modules/admin/config/image_crud.php
@@ -0,0 +1,17 @@
+ion_auth->messages();
$this->system_message->set_success($messages);
- redirect('admin');
+ redirect($this->mModule);
}
else
{
diff --git a/application/modules/admin/controllers/Panel.php b/application/modules/admin/controllers/Panel.php
index b130b597..f7f474cb 100755
--- a/application/modules/admin/controllers/Panel.php
+++ b/application/modules/admin/controllers/Panel.php
@@ -32,7 +32,7 @@ public function admin_user()
// only webmaster can reset Admin User password
if ( $this->ion_auth->in_group(array('webmaster', 'admin')) )
{
- $crud->add_action('Reset Password', '', 'admin/panel/admin_user_reset_password', 'fa fa-repeat');
+ $crud->add_action('Reset Password', '', $this->mModule.'/panel/admin_user_reset_password', 'fa fa-repeat');
}
// disable direct create / delete Admin User
@@ -134,12 +134,12 @@ public function admin_user_reset_password($user_id)
public function account()
{
// Update Info form
- $form1 = $this->form_builder->create_form('admin/panel/account_update_info');
+ $form1 = $this->form_builder->create_form($this->mModule.'/panel/account_update_info');
$form1->set_rule_group('panel/account_update_info');
$this->mViewData['form1'] = $form1;
// Change Password form
- $form2 = $this->form_builder->create_form('admin/panel/account_change_password');
+ $form2 = $this->form_builder->create_form($this->mModule.'/panel/account_change_password');
$form1->set_rule_group('panel/account_change_password');
$this->mViewData['form2'] = $form2;
@@ -162,7 +162,7 @@ public function account_update_info()
$this->system_message->set_error($errors);
}
- redirect('admin/panel/account');
+ redirect($this->mModule.'/panel/account');
}
// Submission of Change Password form
@@ -180,7 +180,7 @@ public function account_change_password()
$this->system_message->set_error($errors);
}
- redirect('admin/panel/account');
+ redirect($this->mModule.'/panel/account');
}
/**
@@ -189,6 +189,6 @@ public function account_change_password()
public function logout()
{
$this->ion_auth->logout();
- redirect('admin/login');
+ redirect($this->mConfig['login_url']);
}
}
diff --git a/application/modules/admin/controllers/Util.php b/application/modules/admin/controllers/Util.php
new file mode 100644
index 00000000..cf84545b
--- /dev/null
+++ b/application/modules/admin/controllers/Util.php
@@ -0,0 +1,90 @@
+mBackupSqlFiles = $files;
+ $this->mLatestSqlFile = $sql_path.'/latest.sql';
+
+ $this->mPageTitle = 'Utilities';
+ $this->mViewData['backup_sql_files'] = $this->mBackupSqlFiles;
+ $this->mViewData['latest_sql_file'] = $this->mLatestSqlFile;
+ }
+
+ // List out saved versions of database
+ public function list_db()
+ {
+ $this->render('util/list_db');
+ }
+
+ // Backup current database version
+ public function backup_db()
+ {
+ $this->load->dbutil();
+ $this->load->helper('file');
+
+ // Options: http://www.codeigniter.com/user_guide/database/utilities.html?highlight=csv#setting-backup-preferences
+ $prefs = array('format' => 'txt');
+ $backup = $this->dbutil->backup($prefs);
+ $file_path_1 = FCPATH.'sql/backup/'.date('Y-m-d_H-i-s').'.sql';
+ $result_1 = write_file($file_path_1, $backup);
+
+ // overwrite latest.sql
+ $save_latest = $this->input->get('save_latest');
+ if ( !empty($save_latest) )
+ {
+ $file_path_2 = FCPATH.'sql/latest.sql';
+ $result_2 = write_file($file_path_2, $backup);
+ }
+
+ redirect($this->mModule.'/util/list_db');
+ }
+
+ // Restore specific version of database
+ public function restore_db($file)
+ {
+ $path = '';
+ if ($file=='latest')
+ $path = FCPATH.'sql/latest.sql';
+ else if ( in_array($file, $this->mBackupSqlFiles) )
+ $path = FCPATH.'sql/backup/'.$file;
+
+ // proceed to execute SQL queries
+ if ( !empty($path) && file_exists($path) )
+ {
+ //$sql = file_get_contents($path);
+ //$this->db->query($sql);
+ $username = $this->db->username;
+ $password = $this->db->password;
+ $database = $this->db->database;
+ exec("mysql -u $username -p$password --database $database < $path");
+ }
+
+ redirect($this->mModule.'/util/list_db');
+ }
+
+ // Remove specific database version
+ public function remove_db($file)
+ {
+ if ( in_array($file, $this->mBackupSqlFiles) )
+ {
+ $path = FCPATH.'sql/backup/'.$file;
+
+ $this->load->helper('file');
+ unlink($path);
+ $result = delete_files($path);
+ }
+
+ redirect($this->mModule.'/util/list_db');
+ }
+}
diff --git a/application/modules/admin/libraries/Sortable.php b/application/modules/admin/libraries/Sortable.php
index c06e2b96..f5b633f1 100755
--- a/application/modules/admin/libraries/Sortable.php
+++ b/application/modules/admin/libraries/Sortable.php
@@ -18,7 +18,7 @@ public function __construct()
}
// Get items to be sorted
- public function init($model, $order_field = 'pos')
+ public function init($model, $order_field = 'pos', $order_direction = 'ASC')
{
$this->CI->load->model($model, 'm');
$ids = $this->CI->input->post($this->mPostName);
@@ -37,7 +37,7 @@ public function init($model, $order_field = 'pos')
}
// return all records in sorted order
- $this->CI->db->order_by($order_field, 'ASC');
+ $this->CI->db->order_by($order_field, $order_direction);
$items = $this->CI->m->get_all();
$this->mItems = $items;
diff --git a/application/modules/admin/views/_partials/sidemenu.php b/application/modules/admin/views/_partials/sidemenu.php
index b48151f1..0743afa6 100755
--- a/application/modules/admin/views/_partials/sidemenu.php
+++ b/application/modules/admin/views/_partials/sidemenu.php
@@ -19,7 +19,7 @@
'>
- '>
+ '>
\ No newline at end of file
+
diff --git a/application/modules/admin/views/util/list_db.php b/application/modules/admin/views/util/list_db.php
new file mode 100644
index 00000000..fa30295f
--- /dev/null
+++ b/application/modules/admin/views/util/list_db.php
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/application/modules/api/config/ci_bootstrap.php b/application/modules/api/config/ci_bootstrap.php
index de98bb3d..f3505fd8 100755
--- a/application/modules/api/config/ci_bootstrap.php
+++ b/application/modules/api/config/ci_bootstrap.php
@@ -71,7 +71,7 @@
// Raw PHP Headers
'headers' => array(
'Access-Control-Allow-Origin: *',
- 'Access-Control-Request-Method: GET, POST, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, X-API-KEY',
),
diff --git a/application/modules/api/config/rest.php b/application/modules/api/config/rest.php
index 429af6fb..0426c491 100755
--- a/application/modules/api/config/rest.php
+++ b/application/modules/api/config/rest.php
@@ -7,7 +7,6 @@
*
* The following values are changed to fit with CI Bootstrap:
* - $config['rest_keys_table'] = 'api_keys'; (default: 'keys')
- * - $config['rest_enable_keys'] = TRUE; (default: FALSE)
* - $config['rest_logs_table'] = 'api_logs'; (default: 'logs')
* - $config['rest_access_table'] = 'api_access'; (default: 'access')
* - $config['rest_limits_table'] = 'api_limits'; (default: 'limits')
@@ -324,7 +323,7 @@
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
*/
-$config['rest_enable_keys'] = TRUE;
+$config['rest_enable_keys'] = FALSE;
/*
|--------------------------------------------------------------------------
diff --git a/application/modules/api/swagger/info.php b/application/modules/api/swagger/info.php
index ff8eb136..4650ee05 100755
--- a/application/modules/api/swagger/info.php
+++ b/application/modules/api/swagger/info.php
@@ -20,8 +20,8 @@
* email="info@email.com"
* )
* ),
- * schemes={"http"},
- * host=BASE_URL,
+ * schemes={API_PROTOCOL},
+ * host=API_HOST,
* basePath="/api"
* )
*/
\ No newline at end of file
diff --git a/application/third_party/grocery_crud/README.md b/application/third_party/grocery_crud/README.md
old mode 100644
new mode 100755
diff --git a/application/third_party/grocery_crud/change_log.txt b/application/third_party/grocery_crud/change_log.txt
old mode 100644
new mode 100755
index ea41434a..ecfef7c4
--- a/application/third_party/grocery_crud/change_log.txt
+++ b/application/third_party/grocery_crud/change_log.txt
@@ -1,3 +1,14 @@
+v 1.5.8
+ - #382: Adding custom error message for set_rules()
+ - Two new lang strings for the multiple delete confirmation
+ - #388: Chosen select have 100% width at flexigrid theme
+v 1.5.7
+ - #331: Have a configurable XSS clean option to prevent XSS attacks
+ - #370: A faster way to calculate the totals
+v 1.5.6
+ - Unset bootstrap with more CSS unsets
+ - Languages updates (Portuguese, Italian, Spanish)
+ - #367: Missing translation for Search {column_name}
v 1.5.5
Add Croatian language - translated by: Siniša Dragičević Martinčić
- Small CSS fixes: Datetime and date picker was overflowing in some languages
@@ -19,7 +30,7 @@ v 1.5.0
#211 - Bug if use where clause.
#197 - Properly sanitize filenames for uploads.
#237 - Set Timepicker to 24 hour format.
- #294 - Javascript bug with set_subject().
+ #294 - Javascript bug with set_subject().
Add a new method unset_view that is just an alias to unset_read method.
Multiple delete fields for flexibility for future themes.
Fixing the bug of jquery form plugin with returning the textarea as required.
diff --git a/application/third_party/grocery_crud/config/grocery_crud.php b/application/third_party/grocery_crud/config/grocery_crud.php
index eb4b6ccd..9a09a4f7 100755
--- a/application/third_party/grocery_crud/config/grocery_crud.php
+++ b/application/third_party/grocery_crud/config/grocery_crud.php
@@ -1,63 +1,39 @@
'Group',
- 'image_url' => 'Image',
- 'thumbnail_url' => 'Thumbnail',
-
- 'author_id' => 'Author',
- 'category_id' => 'Category',
- );
+ // For view all the languages go to the folder assets/grocery_crud/languages/
+ $config['grocery_crud_default_language'] = 'english';
+
+ // There are only three choices: "uk-date" (dd/mm/yyyy), "us-date" (mm/dd/yyyy) or "sql-date" (yyyy-mm-dd)
+ $config['grocery_crud_date_format'] = 'uk-date';
+
+ // The default per page when a user firstly see a list page
+ $config['grocery_crud_default_per_page'] = 10;
+
+ $config['grocery_crud_file_upload_allow_file_types'] = 'gif|jpeg|jpg|png|tiff|doc|docx|txt|odt|xls|xlsx|pdf|ppt|pptx|pps|ppsx|mp3|m4a|ogg|wav|mp4|m4v|mov|wmv|flv|avi|mpg|ogv|3gp|3g2';
+ $config['grocery_crud_file_upload_max_file_size'] = '20MB'; //ex. '10MB' (Mega Bytes), '1067KB' (Kilo Bytes), '5000B' (Bytes)
+
+ // You can choose 'ckeditor','tinymce' or 'markitup'
+ $config['grocery_crud_default_text_editor'] = 'ckeditor';
+ // You can choose 'minimal' or 'full'
+ $config['grocery_crud_text_editor_type'] = 'full';
+
+ // The character limiter at the list page, zero(0) value if you don't want character limiter at your list page
+ $config['grocery_crud_character_limiter'] = 30;
+
+ // All the forms are opening with dialog forms without refreshing the page once again.
+ // IMPORTANT: PLease be aware that this functionality is still in BETA phase and it is
+ // not suggested to use this in production mode
+ $config['grocery_crud_dialog_forms'] = false;
+
+ // Having some options at the list paging. This is the default one that all the websites are using.
+ // Make sure that the number of grocery_crud_default_per_page variable is included to this array.
+ $config['grocery_crud_paging_options'] = array('10','25','50','100');
+
+ // Default theme for grocery CRUD
+ $config['grocery_crud_default_theme'] = 'flexigrid';
+
+ // The environment is important so we can have specific configurations for specific environments
+ $config['grocery_crud_environment'] = 'production';
+
+ // Turn XSS clean into true in case you are exposing your CRUD into public. Please be aware that this is
+ // stripping all the HTML and do not just trim the extra javascript
+ $config['grocery_crud_xss_clean'] = false;
diff --git a/application/third_party/grocery_crud/examples_database.sql.zip b/application/third_party/grocery_crud/examples_database.sql.zip
new file mode 100755
index 00000000..0f65c2f3
Binary files /dev/null and b/application/third_party/grocery_crud/examples_database.sql.zip differ
diff --git a/application/third_party/grocery_crud/libraries/Grocery_CRUD.php b/application/third_party/grocery_crud/libraries/Grocery_CRUD.php
index a2260592..24b470c4 100755
--- a/application/third_party/grocery_crud/libraries/Grocery_CRUD.php
+++ b/application/third_party/grocery_crud/libraries/Grocery_CRUD.php
@@ -16,7 +16,7 @@
* @package grocery CRUD
* @copyright Copyright (c) 2010 through 2014, John Skoumbourdis
* @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
- * @version 1.5.4
+ * @version 1.5.8
* @author John Skoumbourdis
*/
@@ -468,7 +468,7 @@ protected function get_type($db_type)
*
* @package grocery CRUD
* @author John Skoumbourdis
- * @version 1.5.4
+ * @version 1.5.8
* @link http://www.grocerycrud.com/documentation
*/
class grocery_CRUD_Model_Driver extends grocery_CRUD_Field_Types
@@ -533,6 +533,15 @@ protected function get_total_results()
return $this->basic_model->get_total_results();
}
+ protected function filter_data_from_xss($post_data) {
+ foreach ($post_data as $field_name => $rawData) {
+ if (!is_array($rawData)) {
+ $post_data[$field_name] = filter_var(strip_tags($rawData));
+ }
+ }
+ return $post_data;
+ }
+
public function set_model($model_name)
{
$ci = &get_instance();
@@ -746,7 +755,7 @@ protected function db_insert_validation()
if(isset($this->validation_rules[$field_name]))
{
$rule = $this->validation_rules[$field_name];
- $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules']);
+ $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules'],$rule['errors']);
}
}
@@ -861,7 +870,7 @@ protected function db_update_validation()
if(isset($this->validation_rules[$field_name]))
{
$rule = $this->validation_rules[$field_name];
- $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules']);
+ $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules'],$rule['errors']);
}
}
@@ -891,6 +900,10 @@ protected function db_insert($state_info)
{
$post_data = $state_info->unwrapped_data;
+ if ($this->config->xss_clean) {
+ $post_data = $this->filter_data_from_xss($post_data);
+ }
+
$add_fields = $this->get_add_fields();
if($this->callback_insert === null)
@@ -1009,6 +1022,10 @@ protected function db_update($state_info)
$post_data = $state_info->unwrapped_data;
$primary_key = $state_info->primary_key;
+ if ($this->config->xss_clean) {
+ $post_data = $this->filter_data_from_xss($post_data);
+ }
+
if($this->callback_update === null)
{
if($this->callback_before_update !== null)
@@ -1517,7 +1534,7 @@ protected function ajax_relation($state_info)
*
* @package grocery CRUD
* @author John Skoumbourdis
- * @version 1.5.4
+ * @version 1.5.8
*/
class grocery_CRUD_Layout extends grocery_CRUD_Model_Driver
{
@@ -2123,6 +2140,8 @@ protected function get_layout()
unset($js_files[sha1($this->default_theme_path.'/bootstrap/js/bootstrap/modal.min.js')]);
unset($css_files[sha1($this->default_theme_path.'/bootstrap/css/bootstrap/bootstrap.css')]);
unset($css_files[sha1($this->default_theme_path.'/bootstrap/css/bootstrap/bootstrap.min.css')]);
+ unset($css_files[sha1($this->default_theme_path.'/bootstrap-v4/css/bootstrap/bootstrap.css')]);
+ unset($css_files[sha1($this->default_theme_path.'/bootstrap-v4/css/bootstrap/bootstrap.min.css')]);
}
if($this->echo_and_die === false)
@@ -2191,21 +2210,25 @@ protected function get_integer_input($field_info,$value)
protected function get_true_false_input($field_info,$value)
{
- $this->set_css($this->default_css_path.'/jquery_plugins/uniform/uniform.default.css');
- $this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.uniform.min.js');
- $this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.uniform.config.js');
-
$value_is_null = empty($value) && $value !== '0' && $value !== 0 ? true : false;
$input = "";
@@ -2251,7 +2274,17 @@ protected function get_text_input($field_info,$value)
$this->set_js_lib($this->default_texteditor_path.'/summernote/summernote.min.js');
$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/summernote.config.js');
break;
-
+ case 'trumbowyg':
+ $this->set_css($this->default_texteditor_path.'/trumbowyg/ui/trumbowyg.min.css');
+ $this->set_js_lib($this->default_texteditor_path.'/trumbowyg/trumbowyg.min.js');
+ $this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/trumbowyg.config.js');
+ // plugins
+ $this->set_js_lib($this->default_texteditor_path.'/trumbowyg/plugins/base64/trumbowyg.base64.min.js');
+ $this->set_js_lib($this->default_texteditor_path.'/trumbowyg/plugins/pasteimage/trumbowyg.pasteimage.min.js');
+ // localization
+ //$this->set_js_lib($this->default_texteditor_path.'/trumbowyg/langs/fr.min.js');
+ break;
+
case 'ckeditor':
$this->set_js_lib($this->default_texteditor_path.'/ckeditor/ckeditor.js');
$this->set_js_lib($this->default_texteditor_path.'/ckeditor/adapters/jquery.js');
@@ -2990,7 +3023,7 @@ protected function get_views_as_string()
*
* @package grocery CRUD
* @author John Skoumbourdis
- * @version 1.5.4
+ * @version 1.5.8
*/
class grocery_CRUD_States extends grocery_CRUD_Layout
{
@@ -3123,7 +3156,8 @@ public function getStateInfo()
{
$state_info->order_by = $_POST['order_by'];
}
- if(!empty($_POST['search_text']))
+ // Updated by CI Bootstrap 3 - fixed searching boolean field by typing zero value
+ if(!empty($_POST['search_text']) || $_POST['search_text']==='0')
{
if(empty($_POST['search_field']))
{
@@ -3419,7 +3453,7 @@ protected function getAjaxRelationManytoManyUrl()
* @package grocery CRUD
* @copyright Copyright (c) 2010 through 2014, John Skoumbourdis
* @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
- * @version 1.5.4
+ * @version 1.5.8
* @author John Skoumbourdis
*/
@@ -3442,7 +3476,7 @@ class Grocery_CRUD extends grocery_CRUD_States
*
* @var string
*/
- const VERSION = "1.5.4";
+ const VERSION = "1.5.8";
const JQUERY = "jquery-1.11.1.min.js";
const JQUERY_UI_JS = "jquery-ui-1.10.3.custom.min.js";
@@ -3533,13 +3567,13 @@ class Grocery_CRUD extends grocery_CRUD_States
protected $callback_before_upload = null;
protected $callback_after_upload = null;
- protected $default_javascript_path = null; //autogenerate, please do not modify
- protected $default_css_path = null; //autogenerate, please do not modify
- protected $default_texteditor_path = null; //autogenerate, please do not modify
- protected $default_theme_path = null; //autogenerate, please do not modify
- protected $default_language_path = 'assets/grocery_crud/languages';
- protected $default_config_path = 'assets/grocery_crud/config';
- protected $default_assets_path = 'assets/grocery_crud';
+ protected $default_javascript_path = null; //autogenerate, please do not modify
+ protected $default_css_path = null; //autogenerate, please do not modify
+ protected $default_texteditor_path = null; //autogenerate, please do not modify
+ protected $default_theme_path = null; //autogenerate, please do not modify
+ protected $default_language_path = 'assets/grocery_crud/languages';
+ protected $default_config_path = 'assets/grocery_crud/config';
+ protected $default_assets_path = 'assets/grocery_crud';
/**
*
@@ -3583,13 +3617,14 @@ public function columns()
* @access public
* @param mixed
* @param string
+ * @oaram array
* @return void
*/
- function set_rules($field, $label = '', $rules = '')
+ function set_rules($field, $label = '', $rules = '', $errors = array())
{
if(is_string($field))
{
- $this->validation_rules[$field] = array('field' => $field, 'label' => $label, 'rules' => $rules);
+ $this->validation_rules[$field] = array('field' => $field, 'label' => $label, 'rules' => $rules, 'errors' => $errors);
}elseif(is_array($field))
{
foreach($field as $num_field => $field_array)
@@ -4403,6 +4438,7 @@ protected function _initialize_variables()
$this->config->paging_options = $ci->config->item('grocery_crud_paging_options');
$this->config->default_theme = $ci->config->item('grocery_crud_default_theme');
$this->config->environment = $ci->config->item('grocery_crud_environment');
+ $this->config->xss_clean = $ci->config->item('grocery_crud_xss_clean');
/** Initialize default paths */
$this->default_javascript_path = $this->default_assets_path.'/js';
diff --git a/application/third_party/grocery_crud/license-gpl3.txt b/application/third_party/grocery_crud/license-gpl3.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/grocery_crud/license-grocery-crud.txt b/application/third_party/grocery_crud/license-grocery-crud.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/grocery_crud/license-mit.txt b/application/third_party/grocery_crud/license-mit.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/grocery_crud/models/Grocery_crud_model.php b/application/third_party/grocery_crud/models/Grocery_crud_model.php
index 1e245430..24930055 100755
--- a/application/third_party/grocery_crud/models/Grocery_crud_model.php
+++ b/application/third_party/grocery_crud/models/Grocery_crud_model.php
@@ -9,11 +9,11 @@
* Please see the corresponding license file for details of these licenses.
* You are free to use, modify and distribute this software, but all copyright information must remain.
*
- * @package grocery CRUD
- * @copyright Copyright (c) 2010 through 2012, John Skoumbourdis
- * @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
- * @version 1.4.2
- * @author John Skoumbourdis
+ * @package grocery CRUD
+ * @copyright Copyright (c) 2010 through 2012, John Skoumbourdis
+ * @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @version 1.4.2
+ * @author John Skoumbourdis
*/
// ------------------------------------------------------------------------
@@ -22,354 +22,359 @@
* Grocery CRUD Model
*
*
- * @package grocery CRUD
- * @author John Skoumbourdis
- * @version 1.5.4
- * @link http://www.grocerycrud.com/documentation
+ * @package grocery CRUD
+ * @author John Skoumbourdis
+ * @version 1.5.6
+ * @link http://www.grocerycrud.com/documentation
*/
class Grocery_crud_model extends CI_Model {
- protected $primary_key = null;
- protected $table_name = null;
- protected $relation = array();
- protected $relation_n_n = array();
- protected $primary_keys = array();
+ protected $primary_key = null;
+ protected $table_name = null;
+ protected $relation = array();
+ protected $relation_n_n = array();
+ protected $primary_keys = array();
- function __construct()
+ function __construct()
{
parent::__construct();
}
function db_table_exists($table_name = null)
{
- return $this->db->table_exists($table_name);
+ return $this->db->table_exists($table_name);
}
function get_list()
{
- if($this->table_name === null)
- return false;
+ if($this->table_name === null)
+ return false;
- $select = "`{$this->table_name}`.*";
+ $select = "`{$this->table_name}`.*";
- //set_relation special queries
- if(!empty($this->relation))
- {
- foreach($this->relation as $relation)
- {
- list($field_name , $related_table , $related_field_title) = $relation;
- $unique_join_name = $this->_unique_join_name($field_name);
- $unique_field_name = $this->_unique_field_name($field_name);
-
- if(strstr($related_field_title,'{'))
- {
- $related_field_title = str_replace(" "," ",$related_field_title);
- $select .= ", CONCAT('".str_replace(array('{','}'),array("',COALESCE({$unique_join_name}.",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $unique_field_name";
- }
- else
- {
- $select .= ", $unique_join_name.$related_field_title AS $unique_field_name";
- }
-
- if($this->field_exists($related_field_title))
- $select .= ", `{$this->table_name}`.$related_field_title AS '{$this->table_name}.$related_field_title'";
- }
- }
+ //set_relation special queries
+ if(!empty($this->relation))
+ {
+ foreach($this->relation as $relation)
+ {
+ list($field_name , $related_table , $related_field_title) = $relation;
+ $unique_join_name = $this->_unique_join_name($field_name);
+ $unique_field_name = $this->_unique_field_name($field_name);
- //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
- if(!empty($this->relation_n_n))
- {
- $select = $this->relation_n_n_queries($select);
- }
+ if(strstr($related_field_title,'{'))
+ {
+ $related_field_title = str_replace(" "," ",$related_field_title);
+ $select .= ", CONCAT('".str_replace(array('{','}'),array("',COALESCE({$unique_join_name}.",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $unique_field_name";
+ }
+ else
+ {
+ $select .= ", $unique_join_name.$related_field_title AS $unique_field_name";
+ }
+
+ if($this->field_exists($related_field_title))
+ $select .= ", `{$this->table_name}`.$related_field_title AS '{$this->table_name}.$related_field_title'";
+ }
+ }
- $this->db->select($select, false);
+ //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
+ if(!empty($this->relation_n_n))
+ {
+ $select = $this->relation_n_n_queries($select);
+ }
- $results = $this->db->get($this->table_name)->result();
+ $this->db->select($select, false);
- return $results;
+ $results = $this->db->get($this->table_name)->result();
+
+ return $results;
}
public function get_row($table_name = null)
{
- $table_name = $table_name === null ? $this->table_name : $table_name;
+ $table_name = $table_name === null ? $this->table_name : $table_name;
- return $this->db->get($table_name)->row();
+ return $this->db->get($table_name)->row();
}
public function set_primary_key($field_name, $table_name = null)
{
- $table_name = $table_name === null ? $this->table_name : $table_name;
+ $table_name = $table_name === null ? $this->table_name : $table_name;
- $this->primary_keys[$table_name] = $field_name;
+ $this->primary_keys[$table_name] = $field_name;
}
protected function relation_n_n_queries($select)
{
- $this_table_primary_key = $this->get_primary_key();
- foreach($this->relation_n_n as $relation_n_n)
- {
- list($field_name, $relation_table, $selection_table, $primary_key_alias_to_this_table,
- $primary_key_alias_to_selection_table, $title_field_selection_table, $priority_field_relation_table) = array_values((array)$relation_n_n);
-
- $primary_key_selection_table = $this->get_primary_key($selection_table);
-
- $field = "";
- $use_template = strpos($title_field_selection_table,'{') !== false;
- $field_name_hash = $this->_unique_field_name($title_field_selection_table);
- if($use_template)
- {
- $title_field_selection_table = str_replace(" ", " ", $title_field_selection_table);
- $field .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$title_field_selection_table))."')";
- }
- else
- {
- $field .= "$selection_table.$title_field_selection_table";
- }
-
- //Sorry Codeigniter but you cannot help me with the subquery!
- $select .= ", (SELECT GROUP_CONCAT(DISTINCT $field) FROM $selection_table "
- ."LEFT JOIN $relation_table ON $relation_table.$primary_key_alias_to_selection_table = $selection_table.$primary_key_selection_table "
- ."WHERE $relation_table.$primary_key_alias_to_this_table = `{$this->table_name}`.$this_table_primary_key GROUP BY $relation_table.$primary_key_alias_to_this_table) AS $field_name";
- }
+ $this_table_primary_key = $this->get_primary_key();
+ foreach($this->relation_n_n as $relation_n_n)
+ {
+ list($field_name, $relation_table, $selection_table, $primary_key_alias_to_this_table,
+ $primary_key_alias_to_selection_table, $title_field_selection_table, $priority_field_relation_table) = array_values((array)$relation_n_n);
+
+ $primary_key_selection_table = $this->get_primary_key($selection_table);
+
+ $field = "";
+ $use_template = strpos($title_field_selection_table,'{') !== false;
+ $field_name_hash = $this->_unique_field_name($title_field_selection_table);
+ if($use_template)
+ {
+ $title_field_selection_table = str_replace(" ", " ", $title_field_selection_table);
+ $field .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$title_field_selection_table))."')";
+ }
+ else
+ {
+ $field .= "$selection_table.$title_field_selection_table";
+ }
- return $select;
+ //Sorry Codeigniter but you cannot help me with the subquery!
+ $select .= ", (SELECT GROUP_CONCAT(DISTINCT $field) FROM $selection_table "
+ ."LEFT JOIN $relation_table ON $relation_table.$primary_key_alias_to_selection_table = $selection_table.$primary_key_selection_table "
+ ."WHERE $relation_table.$primary_key_alias_to_this_table = `{$this->table_name}`.$this_table_primary_key GROUP BY $relation_table.$primary_key_alias_to_this_table) AS $field_name";
+ }
+
+ return $select;
}
function order_by($order_by , $direction)
{
- $this->db->order_by( $order_by , $direction );
+ $this->db->order_by( $order_by , $direction );
}
function where($key, $value = NULL, $escape = TRUE)
{
- $this->db->where( $key, $value, $escape);
+ $this->db->where( $key, $value, $escape);
}
function or_where($key, $value = NULL, $escape = TRUE)
{
- $this->db->or_where( $key, $value, $escape);
+ $this->db->or_where( $key, $value, $escape);
}
function having($key, $value = NULL, $escape = TRUE)
{
- $this->db->having( $key, $value, $escape);
+ $this->db->having( $key, $value, $escape);
}
function or_having($key, $value = NULL, $escape = TRUE)
{
- $this->db->or_having( $key, $value, $escape);
+ $this->db->or_having( $key, $value, $escape);
}
function like($field, $match = '', $side = 'both')
{
- $this->db->like($field, $match, $side);
+ $this->db->like($field, $match, $side);
}
function or_like($field, $match = '', $side = 'both')
{
- $this->db->or_like($field, $match, $side);
+ $this->db->or_like($field, $match, $side);
}
function limit($value, $offset = '')
{
- $this->db->limit( $value , $offset );
+ $this->db->limit( $value , $offset );
}
function get_total_results()
{
- //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
- if(!empty($this->relation_n_n))
- {
- $select = "{$this->table_name}.*";
- $select = $this->relation_n_n_queries($select);
+ // A fast way to calculate the total results
+ $key = $this->get_primary_key();
- $this->db->select($select,false);
- }
+ //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
+ if(!empty($this->relation_n_n))
+ {
+ $select = "{$this->table_name}." . $key;
+ $select = $this->relation_n_n_queries($select);
+ $this->db->select($select,false);
+ } else {
+ $this->db->select($this->table_name . '.' . $key);
+ }
+
return $this->db->get($this->table_name)->num_rows();
}
function set_basic_table($table_name = null)
{
- if( !($this->db->table_exists($table_name)) )
- return false;
+ if( !($this->db->table_exists($table_name)) )
+ return false;
- $this->table_name = $table_name;
+ $this->table_name = $table_name;
- return true;
+ return true;
}
function get_edit_values($primary_key_value)
{
- $primary_key_field = $this->get_primary_key();
- $this->db->where($primary_key_field,$primary_key_value);
- $result = $this->db->get($this->table_name)->row();
- return $result;
+ $primary_key_field = $this->get_primary_key();
+ $this->db->where($primary_key_field,$primary_key_value);
+ $result = $this->db->get($this->table_name)->row();
+ return $result;
}
function join_relation($field_name , $related_table , $related_field_title)
{
- $related_primary_key = $this->get_primary_key($related_table);
+ $related_primary_key = $this->get_primary_key($related_table);
- if($related_primary_key !== false)
- {
- $unique_name = $this->_unique_join_name($field_name);
- $this->db->join( $related_table.' as '.$unique_name , "$unique_name.$related_primary_key = {$this->table_name}.$field_name",'left');
+ if($related_primary_key !== false)
+ {
+ $unique_name = $this->_unique_join_name($field_name);
+ $this->db->join( $related_table.' as '.$unique_name , "$unique_name.$related_primary_key = {$this->table_name}.$field_name",'left');
- $this->relation[$field_name] = array($field_name , $related_table , $related_field_title);
+ $this->relation[$field_name] = array($field_name , $related_table , $related_field_title);
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
function set_relation_n_n_field($field_info)
{
- $this->relation_n_n[$field_info->field_name] = $field_info;
+ $this->relation_n_n[$field_info->field_name] = $field_info;
}
protected function _unique_join_name($field_name)
{
- return 'j'.substr(md5($field_name),0,8); //This j is because is better for a string to begin with a letter and not with a number
+ return 'j'.substr(md5($field_name),0,8); //This j is because is better for a string to begin with a letter and not with a number
}
protected function _unique_field_name($field_name)
{
- return 's'.substr(md5($field_name),0,8); //This s is because is better for a string to begin with a letter and not with a number
+ return 's'.substr(md5($field_name),0,8); //This s is because is better for a string to begin with a letter and not with a number
}
function get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, $limit = null, $search_like = null)
{
- $relation_array = array();
- $field_name_hash = $this->_unique_field_name($field_name);
+ $relation_array = array();
+ $field_name_hash = $this->_unique_field_name($field_name);
- $related_primary_key = $this->get_primary_key($related_table);
+ $related_primary_key = $this->get_primary_key($related_table);
- $select = "$related_table.$related_primary_key, ";
+ $select = "$related_table.$related_primary_key, ";
- if(strstr($related_field_title,'{'))
- {
- $related_field_title = str_replace(" ", " ", $related_field_title);
- $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
- }
- else
- {
- $select .= "$related_table.$related_field_title as $field_name_hash";
- }
+ if(strstr($related_field_title,'{'))
+ {
+ $related_field_title = str_replace(" ", " ", $related_field_title);
+ $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+ }
+ else
+ {
+ $select .= "$related_table.$related_field_title as $field_name_hash";
+ }
- $this->db->select($select,false);
- if($where_clause !== null)
- $this->db->where($where_clause);
+ $this->db->select($select,false);
+ if($where_clause !== null)
+ $this->db->where($where_clause);
- if($where_clause !== null)
- $this->db->where($where_clause);
+ if($where_clause !== null)
+ $this->db->where($where_clause);
- if($limit !== null)
- $this->db->limit($limit);
+ if($limit !== null)
+ $this->db->limit($limit);
- if($search_like !== null)
- $this->db->having("$field_name_hash LIKE '%".$this->db->escape_like_str($search_like)."%'");
+ if($search_like !== null)
+ $this->db->having("$field_name_hash LIKE '%".$this->db->escape_like_str($search_like)."%'");
- $order_by !== null
- ? $this->db->order_by($order_by)
- : $this->db->order_by($field_name_hash);
+ $order_by !== null
+ ? $this->db->order_by($order_by)
+ : $this->db->order_by($field_name_hash);
- $results = $this->db->get($related_table)->result();
+ $results = $this->db->get($related_table)->result();
- foreach($results as $row)
- {
- $relation_array[$row->$related_primary_key] = $row->$field_name_hash;
- }
+ foreach($results as $row)
+ {
+ $relation_array[$row->$related_primary_key] = $row->$field_name_hash;
+ }
- return $relation_array;
+ return $relation_array;
}
function get_ajax_relation_array($search, $field_name , $related_table , $related_field_title, $where_clause, $order_by)
{
- return $this->get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, 10 , $search);
+ return $this->get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, 10 , $search);
}
function get_relation_total_rows($field_name , $related_table , $related_field_title, $where_clause)
{
- if($where_clause !== null)
- $this->db->where($where_clause);
+ if($where_clause !== null)
+ $this->db->where($where_clause);
- return $this->db->count_all_results($related_table);
+ return $this->db->count_all_results($related_table);
}
function get_relation_n_n_selection_array($primary_key_value, $field_info)
{
- $select = "";
- $related_field_title = $field_info->title_field_selection_table;
- $use_template = strpos($related_field_title,'{') !== false;;
- $field_name_hash = $this->_unique_field_name($related_field_title);
- if($use_template)
- {
- $related_field_title = str_replace(" ", " ", $related_field_title);
- $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
- }
- else
- {
- $select .= "$related_field_title as $field_name_hash";
- }
- $this->db->select('*, '.$select,false);
-
- $selection_primary_key = $this->get_primary_key($field_info->selection_table);
-
- if(empty($field_info->priority_field_relation_table))
- {
- if(!$use_template){
- $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
- }
- }
- else
- {
- $this->db->order_by("{$field_info->relation_table}.{$field_info->priority_field_relation_table}");
- }
- $this->db->where($field_info->primary_key_alias_to_this_table, $primary_key_value);
- $this->db->join(
- $field_info->selection_table,
- "{$field_info->relation_table}.{$field_info->primary_key_alias_to_selection_table} = {$field_info->selection_table}.{$selection_primary_key}"
- );
- $results = $this->db->get($field_info->relation_table)->result();
-
- $results_array = array();
- foreach($results as $row)
- {
- $results_array[$row->{$field_info->primary_key_alias_to_selection_table}] = $row->{$field_name_hash};
- }
-
- return $results_array;
+ $select = "";
+ $related_field_title = $field_info->title_field_selection_table;
+ $use_template = strpos($related_field_title,'{') !== false;;
+ $field_name_hash = $this->_unique_field_name($related_field_title);
+ if($use_template)
+ {
+ $related_field_title = str_replace(" ", " ", $related_field_title);
+ $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+ }
+ else
+ {
+ $select .= "$related_field_title as $field_name_hash";
+ }
+ $this->db->select('*, '.$select,false);
+
+ $selection_primary_key = $this->get_primary_key($field_info->selection_table);
+
+ if(empty($field_info->priority_field_relation_table))
+ {
+ if(!$use_template){
+ $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
+ }
+ }
+ else
+ {
+ $this->db->order_by("{$field_info->relation_table}.{$field_info->priority_field_relation_table}");
+ }
+ $this->db->where($field_info->primary_key_alias_to_this_table, $primary_key_value);
+ $this->db->join(
+ $field_info->selection_table,
+ "{$field_info->relation_table}.{$field_info->primary_key_alias_to_selection_table} = {$field_info->selection_table}.{$selection_primary_key}"
+ );
+ $results = $this->db->get($field_info->relation_table)->result();
+
+ $results_array = array();
+ foreach($results as $row)
+ {
+ $results_array[$row->{$field_info->primary_key_alias_to_selection_table}] = $row->{$field_name_hash};
+ }
+
+ return $results_array;
}
function get_relation_n_n_unselected_array($field_info, $selected_values)
{
- $use_where_clause = !empty($field_info->where_clause);
-
- $select = "";
- $related_field_title = $field_info->title_field_selection_table;
- $use_template = strpos($related_field_title,'{') !== false;
- $field_name_hash = $this->_unique_field_name($related_field_title);
-
- if($use_template)
- {
- $related_field_title = str_replace(" ", " ", $related_field_title);
- $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
- }
- else
- {
- $select .= "$related_field_title as $field_name_hash";
- }
- $this->db->select('*, '.$select,false);
-
- if($use_where_clause){
- $this->db->where($field_info->where_clause);
- }
-
- $selection_primary_key = $this->get_primary_key($field_info->selection_table);
+ $use_where_clause = !empty($field_info->where_clause);
+
+ $select = "";
+ $related_field_title = $field_info->title_field_selection_table;
+ $use_template = strpos($related_field_title,'{') !== false;
+ $field_name_hash = $this->_unique_field_name($related_field_title);
+
+ if($use_template)
+ {
+ $related_field_title = str_replace(" ", " ", $related_field_title);
+ $select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+ }
+ else
+ {
+ $select .= "$related_field_title as $field_name_hash";
+ }
+ $this->db->select('*, '.$select,false);
+
+ if($use_where_clause){
+ $this->db->where($field_info->where_clause);
+ }
+
+ $selection_primary_key = $this->get_primary_key($field_info->selection_table);
if(!$use_template)
- $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
+ $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
$results = $this->db->get($field_info->selection_table)->result();
$results_array = array();
@@ -384,199 +389,199 @@ function get_relation_n_n_unselected_array($field_info, $selected_values)
function db_relation_n_n_update($field_info, $post_data ,$main_primary_key)
{
- $this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
- if(!empty($post_data))
- $this->db->where_not_in($field_info->primary_key_alias_to_selection_table , $post_data);
- $this->db->delete($field_info->relation_table);
+ $this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
+ if(!empty($post_data))
+ $this->db->where_not_in($field_info->primary_key_alias_to_selection_table , $post_data);
+ $this->db->delete($field_info->relation_table);
- $counter = 0;
- if(!empty($post_data))
- {
- foreach($post_data as $primary_key_value)
- {
- $where_array = array(
- $field_info->primary_key_alias_to_this_table => $main_primary_key,
- $field_info->primary_key_alias_to_selection_table => $primary_key_value,
- );
-
- $this->db->where($where_array);
- $count = $this->db->from($field_info->relation_table)->count_all_results();
-
- if($count == 0)
- {
- if(!empty($field_info->priority_field_relation_table))
- $where_array[$field_info->priority_field_relation_table] = $counter;
-
- $this->db->insert($field_info->relation_table, $where_array);
-
- }elseif($count >= 1 && !empty($field_info->priority_field_relation_table))
- {
- $this->db->update( $field_info->relation_table, array($field_info->priority_field_relation_table => $counter) , $where_array);
- }
-
- $counter++;
- }
- }
+ $counter = 0;
+ if(!empty($post_data))
+ {
+ foreach($post_data as $primary_key_value)
+ {
+ $where_array = array(
+ $field_info->primary_key_alias_to_this_table => $main_primary_key,
+ $field_info->primary_key_alias_to_selection_table => $primary_key_value,
+ );
+
+ $this->db->where($where_array);
+ $count = $this->db->from($field_info->relation_table)->count_all_results();
+
+ if($count == 0)
+ {
+ if(!empty($field_info->priority_field_relation_table))
+ $where_array[$field_info->priority_field_relation_table] = $counter;
+
+ $this->db->insert($field_info->relation_table, $where_array);
+
+ }elseif($count >= 1 && !empty($field_info->priority_field_relation_table))
+ {
+ $this->db->update( $field_info->relation_table, array($field_info->priority_field_relation_table => $counter) , $where_array);
+ }
+
+ $counter++;
+ }
+ }
}
function db_relation_n_n_delete($field_info, $main_primary_key)
{
- $this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
- $this->db->delete($field_info->relation_table);
+ $this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
+ $this->db->delete($field_info->relation_table);
}
function get_field_types_basic_table()
{
- $db_field_types = array();
- foreach($this->db->query("SHOW COLUMNS FROM `{$this->table_name}`")->result() as $db_field_type)
- {
- $type = explode("(",$db_field_type->Type);
- $db_type = $type[0];
-
- if(isset($type[1]))
- {
- if(substr($type[1],-1) == ')')
- {
- $length = substr($type[1],0,-1);
- }
- else
- {
- list($length) = explode(" ",$type[1]);
- $length = substr($length,0,-1);
- }
- }
- else
- {
- $length = '';
- }
- $db_field_types[$db_field_type->Field]['db_max_length'] = $length;
- $db_field_types[$db_field_type->Field]['db_type'] = $db_type;
- $db_field_types[$db_field_type->Field]['db_null'] = $db_field_type->Null == 'YES' ? true : false;
- $db_field_types[$db_field_type->Field]['db_extra'] = $db_field_type->Extra;
- }
-
- $results = $this->db->field_data($this->table_name);
- foreach($results as $num => $row)
- {
- $row = (array)$row;
- $results[$num] = (object)( array_merge($row, $db_field_types[$row['name']]) );
- }
-
- return $results;
+ $db_field_types = array();
+ foreach($this->db->query("SHOW COLUMNS FROM `{$this->table_name}`")->result() as $db_field_type)
+ {
+ $type = explode("(",$db_field_type->Type);
+ $db_type = $type[0];
+
+ if(isset($type[1]))
+ {
+ if(substr($type[1],-1) == ')')
+ {
+ $length = substr($type[1],0,-1);
+ }
+ else
+ {
+ list($length) = explode(" ",$type[1]);
+ $length = substr($length,0,-1);
+ }
+ }
+ else
+ {
+ $length = '';
+ }
+ $db_field_types[$db_field_type->Field]['db_max_length'] = $length;
+ $db_field_types[$db_field_type->Field]['db_type'] = $db_type;
+ $db_field_types[$db_field_type->Field]['db_null'] = $db_field_type->Null == 'YES' ? true : false;
+ $db_field_types[$db_field_type->Field]['db_extra'] = $db_field_type->Extra;
+ }
+
+ $results = $this->db->field_data($this->table_name);
+ foreach($results as $num => $row)
+ {
+ $row = (array)$row;
+ $results[$num] = (object)( array_merge($row, $db_field_types[$row['name']]) );
+ }
+
+ return $results;
}
function get_field_types($table_name)
{
- $results = $this->db->field_data($table_name);
+ $results = $this->db->field_data($table_name);
- return $results;
+ return $results;
}
function db_update($post_array, $primary_key_value)
{
- $primary_key_field = $this->get_primary_key();
- return $this->db->update($this->table_name,$post_array, array( $primary_key_field => $primary_key_value));
+ $primary_key_field = $this->get_primary_key();
+ return $this->db->update($this->table_name,$post_array, array( $primary_key_field => $primary_key_value));
}
function db_insert($post_array)
{
- $insert = $this->db->insert($this->table_name,$post_array);
- if($insert)
- {
- return $this->db->insert_id();
- }
- return false;
+ $insert = $this->db->insert($this->table_name,$post_array);
+ if($insert)
+ {
+ return $this->db->insert_id();
+ }
+ return false;
}
function db_delete($primary_key_value)
{
- $primary_key_field = $this->get_primary_key();
+ $primary_key_field = $this->get_primary_key();
- if($primary_key_field === false)
- return false;
+ if($primary_key_field === false)
+ return false;
- $this->db->limit(1);
- $this->db->delete($this->table_name,array( $primary_key_field => $primary_key_value));
- if( $this->db->affected_rows() != 1)
- return false;
- else
- return true;
+ $this->db->limit(1);
+ $this->db->delete($this->table_name,array( $primary_key_field => $primary_key_value));
+ if( $this->db->affected_rows() != 1)
+ return false;
+ else
+ return true;
}
function db_file_delete($field_name, $filename)
{
- if( $this->db->update($this->table_name,array($field_name => ''),array($field_name => $filename)) )
- {
- return true;
- }
- else
- {
- return false;
- }
+ if( $this->db->update($this->table_name,array($field_name => ''),array($field_name => $filename)) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
function field_exists($field,$table_name = null)
{
- if(empty($table_name))
- {
- $table_name = $this->table_name;
- }
- return $this->db->field_exists($field,$table_name);
+ if(empty($table_name))
+ {
+ $table_name = $this->table_name;
+ }
+ return $this->db->field_exists($field,$table_name);
}
function get_primary_key($table_name = null)
{
- if($table_name == null)
- {
- if(isset($this->primary_keys[$this->table_name]))
- {
- return $this->primary_keys[$this->table_name];
- }
-
- if(empty($this->primary_key))
- {
- $fields = $this->get_field_types_basic_table();
-
- foreach($fields as $field)
- {
- if($field->primary_key == 1)
- {
- return $field->name;
- }
- }
-
- return false;
- }
- else
- {
- return $this->primary_key;
- }
- }
- else
- {
- if(isset($this->primary_keys[$table_name]))
- {
- return $this->primary_keys[$table_name];
- }
-
- $fields = $this->get_field_types($table_name);
-
- foreach($fields as $field)
- {
- if($field->primary_key == 1)
- {
- return $field->name;
- }
- }
-
- return false;
- }
+ if($table_name == null)
+ {
+ if(isset($this->primary_keys[$this->table_name]))
+ {
+ return $this->primary_keys[$this->table_name];
+ }
+
+ if(empty($this->primary_key))
+ {
+ $fields = $this->get_field_types_basic_table();
+
+ foreach($fields as $field)
+ {
+ if($field->primary_key == 1)
+ {
+ return $field->name;
+ }
+ }
+
+ return false;
+ }
+ else
+ {
+ return $this->primary_key;
+ }
+ }
+ else
+ {
+ if(isset($this->primary_keys[$table_name]))
+ {
+ return $this->primary_keys[$table_name];
+ }
+
+ $fields = $this->get_field_types($table_name);
+
+ foreach($fields as $field)
+ {
+ if($field->primary_key == 1)
+ {
+ return $field->name;
+ }
+ }
+
+ return false;
+ }
}
function escape_str($value)
{
- return $this->db->escape_str($value);
+ return $this->db->escape_str($value);
}
}
diff --git a/application/third_party/image_crud/change_log.txt b/application/third_party/image_crud/change_log.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/image_crud/config/image_crud.php b/application/third_party/image_crud/config/image_crud.php
index 0decbf70..89869785 100755
--- a/application/third_party/image_crud/config/image_crud.php
+++ b/application/third_party/image_crud/config/image_crud.php
@@ -5,8 +5,8 @@
/**
-* Added by CI Bootstrap 3
-*/
+ * Added by CI Bootstrap 3
+ */
// For setting max image size
$config['image_crud_max_width'] = 1024;
diff --git a/application/third_party/image_crud/license-gpl3.txt b/application/third_party/image_crud/license-gpl3.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/image_crud/license-image-crud.txt b/application/third_party/image_crud/license-image-crud.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/image_crud/license-mit.txt b/application/third_party/image_crud/license-mit.txt
old mode 100644
new mode 100755
diff --git a/application/third_party/ion_auth/README.md b/application/third_party/ion_auth/README.md
index 289e8194..2b620886 100755
--- a/application/third_party/ion_auth/README.md
+++ b/application/third_party/ion_auth/README.md
@@ -9,6 +9,11 @@ the code and added new features.
This version drops any backwards compatibility and makes things even more
awesome then you could expect.
+
+##Support
+If you use this to further your career, or put money in your pocket, and would like to support the project please consider a [moral license](https://www.morallicense.com/benedmunds/ion-auth).
+
+
##Documentation
Documentation is located at http://benedmunds.com/ion_auth/
@@ -49,6 +54,11 @@ It is highly recommended that you use encrypted database sessions for security!
It is recommended that you add your identity column as a unique index.
+###Options
+Time Based One-Time Password (TOTP) -
+There is a Time Based One-Time Password (TOTP) implementation compatible with Google Authenticator available. Feature branch maintained by [biscofil](https://github.com/biscofil) and is available at [https://github.com/benedmunds/CodeIgniter-Ion-Auth/tree/otp](https://github.com/benedmunds/CodeIgniter-Ion-Auth/tree/otp)
+
+
Feel free to send me an email if you have any problems.
diff --git a/application/third_party/ion_auth/config/ion_auth_default.php b/application/third_party/ion_auth/config/ion_auth_default.php
index 8ae8f7e6..584946c3 100755
--- a/application/third_party/ion_auth/config/ion_auth_default.php
+++ b/application/third_party/ion_auth/config/ion_auth_default.php
@@ -1,5 +1,4 @@
load->database();
@@ -15,7 +15,7 @@ function __construct()
}
// redirect if needed, otherwise display the user list
- function index()
+ public function index()
{
if (!$this->ion_auth->logged_in())
@@ -45,13 +45,13 @@ function index()
}
// log the user in
- function login()
+ public function login()
{
- $this->data['title'] = "Login";
+ $this->data['title'] = $this->lang->line('login_heading');
//validate form input
- $this->form_validation->set_rules('identity', 'Identity', 'required');
- $this->form_validation->set_rules('password', 'Password', 'required');
+ $this->form_validation->set_rules('identity', str_replace(':', '', $this->lang->line('login_identity_label')), 'required');
+ $this->form_validation->set_rules('password', str_replace(':', '', $this->lang->line('login_password_label')), 'required');
if ($this->form_validation->run() == true)
{
@@ -95,7 +95,7 @@ function login()
}
// log the user out
- function logout()
+ public function logout()
{
$this->data['title'] = "Logout";
@@ -108,7 +108,7 @@ function logout()
}
// change password
- function change_password()
+ public function change_password()
{
$this->form_validation->set_rules('old', $this->lang->line('change_password_validation_old_password_label'), 'required');
$this->form_validation->set_rules('new', $this->lang->line('change_password_validation_new_password_label'), 'required|min_length[' . $this->config->item('min_password_length', 'ion_auth') . ']|max_length[' . $this->config->item('max_password_length', 'ion_auth') . ']|matches[new_confirm]');
@@ -176,9 +176,9 @@ function change_password()
}
// forgot password
- function forgot_password()
+ public function forgot_password()
{
- // setting validation rules by checking wheather identity is username or email
+ // setting validation rules by checking whether identity is username or email
if($this->config->item('identity', 'ion_auth') != 'email' )
{
$this->form_validation->set_rules('identity', $this->lang->line('forgot_password_identity_label'), 'required');
@@ -338,7 +338,7 @@ public function reset_password($code = NULL)
// activate the user
- function activate($id, $code=false)
+ public function activate($id, $code=false)
{
if ($code !== false)
{
@@ -364,7 +364,7 @@ function activate($id, $code=false)
}
// deactivate the user
- function deactivate($id = NULL)
+ public function deactivate($id = NULL)
{
if (!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin())
{
@@ -410,9 +410,9 @@ function deactivate($id = NULL)
}
// create a new user
- function create_user()
+ public function create_user()
{
- $this->data['title'] = "Create User";
+ $this->data['title'] = $this->lang->line('create_user_heading');
if (!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin())
{
@@ -520,9 +520,9 @@ function create_user()
}
// edit a user
- function edit_user($id)
+ public function edit_user($id)
{
- $this->data['title'] = "Edit User";
+ $this->data['title'] = $this->lang->line('edit_user_heading');
if (!$this->ion_auth->logged_in() || (!$this->ion_auth->is_admin() && !($this->ion_auth->user()->row()->id == $id)))
{
@@ -671,7 +671,7 @@ function edit_user($id)
}
// create a new group
- function create_group()
+ public function create_group()
{
$this->data['title'] = $this->lang->line('create_group_title');
@@ -718,7 +718,7 @@ function create_group()
}
// edit a group
- function edit_group($id)
+ public function edit_group($id)
{
// bail if no group id given
if(!$id || empty($id))
@@ -782,7 +782,7 @@ function edit_group($id)
}
- function _get_csrf_nonce()
+ public function _get_csrf_nonce()
{
$this->load->helper('string');
$key = random_string('alnum', 8);
@@ -793,10 +793,10 @@ function _get_csrf_nonce()
return array($key => $value);
}
- function _valid_csrf_nonce()
+ public function _valid_csrf_nonce()
{
- if ($this->input->post($this->session->flashdata('csrfkey')) !== FALSE &&
- $this->input->post($this->session->flashdata('csrfkey')) == $this->session->flashdata('csrfvalue'))
+ $csrfkey = $this->input->post($this->session->flashdata('csrfkey'));
+ if ($csrfkey && $csrfkey == $this->session->flashdata('csrfvalue'))
{
return TRUE;
}
@@ -806,7 +806,7 @@ function _valid_csrf_nonce()
}
}
- function _render_page($view, $data=null, $returnhtml=false)//I think this makes more sense
+ public function _render_page($view, $data=null, $returnhtml=false)//I think this makes more sense
{
$this->viewdata = (empty($data)) ? $this->data: $data;
diff --git a/application/third_party/ion_auth/language/arabic/ion_auth_lang.php b/application/third_party/ion_auth/language/arabic/ion_auth_lang.php
index db2f396b..49da7af3 100755
--- a/application/third_party/ion_auth/language/arabic/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/arabic/ion_auth_lang.php
@@ -35,6 +35,7 @@
$lang['deactivate_unsuccessful'] = 'لا يمكن إيقاف حسابك';
$lang['activation_email_successful'] = 'تم إرسال بريد التفعيل';
$lang['activation_email_unsuccessful'] = 'لا يمكن ارسال بريد التفعيل';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'تم تسجيل الدخول بنجاح';
diff --git a/application/third_party/ion_auth/language/bulgarian/ion_auth_lang.php b/application/third_party/ion_auth/language/bulgarian/ion_auth_lang.php
index 661c5a57..f53737a7 100755
--- a/application/third_party/ion_auth/language/bulgarian/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/bulgarian/ion_auth_lang.php
@@ -37,6 +37,7 @@
$lang['deactivate_unsuccessful'] = 'Неуспешен опит за деактивиране на регистрацията';
$lang['activation_email_successful'] = 'Изпратен е Email за активиране на регистрацията';
$lang['activation_email_unsuccessful'] = 'Неуспешен опит за изпращане на Email за активация';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Успешен вход в системата';
diff --git a/application/third_party/ion_auth/language/catalan/ion_auth_lang.php b/application/third_party/ion_auth/language/catalan/ion_auth_lang.php
index af0edd43..967b8440 100755
--- a/application/third_party/ion_auth/language/catalan/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/catalan/ion_auth_lang.php
@@ -40,6 +40,7 @@
$lang['deactivate_unsuccessful'] = 'No ha estat possible desactivar el compte';
$lang['activation_email_successful'] = 'Email d'activació enviat';
$lang['activation_email_unsuccessful'] = 'No ha estat possible enviar l'email d'activació';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Sessió iniciada amb èxit';
diff --git a/application/third_party/ion_auth/language/croatian/ion_auth_lang.php b/application/third_party/ion_auth/language/croatian/ion_auth_lang.php
index 757c3d64..12d80e88 100755
--- a/application/third_party/ion_auth/language/croatian/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/croatian/ion_auth_lang.php
@@ -40,6 +40,7 @@
$lang['deactivate_unsuccessful'] = 'De-aktivacija računa noje uspjela';
$lang['activation_email_successful'] = 'Email za aktivaciju je poslan';
$lang['activation_email_unsuccessful'] = 'Slanje mail za aktivaciju nije uspjelo';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Uspješno prijavljeni';
diff --git a/application/third_party/ion_auth/language/czech/ion_auth_lang.php b/application/third_party/ion_auth/language/czech/ion_auth_lang.php
index 3ef87f46..b7c15bfe 100755
--- a/application/third_party/ion_auth/language/czech/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/czech/ion_auth_lang.php
@@ -35,6 +35,7 @@
$lang['deactivate_unsuccessful'] = 'Nelze deaktivován účet';
$lang['activation_email_successful'] = 'Aktivační e-mail byl odeslán';
$lang['activation_email_unsuccessful'] = 'Nelze odeslat aktivační e-mail';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Úspěšně přihlášen';
diff --git a/application/third_party/ion_auth/language/danish/ion_auth_lang.php b/application/third_party/ion_auth/language/danish/ion_auth_lang.php
index 13f7225e..c2fd9b55 100755
--- a/application/third_party/ion_auth/language/danish/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/danish/ion_auth_lang.php
@@ -30,6 +30,7 @@
$lang['deactivate_unsuccessful'] = 'Det var ikke muligt at deaktivere kontoen';
$lang['activation_email_successful'] = 'Email vedrørende aktivering af konto er afsendt';
$lang['activation_email_unsuccessful'] = 'Det var ikke muligt at sende email vedrørende aktivering af konto';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Logged ind';
$lang['login_unsuccessful'] = 'Ugyldigt login';
diff --git a/application/third_party/ion_auth/language/dutch/ion_auth_lang.php b/application/third_party/ion_auth/language/dutch/ion_auth_lang.php
index 02700c8d..782d4db5 100755
--- a/application/third_party/ion_auth/language/dutch/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/dutch/ion_auth_lang.php
@@ -39,6 +39,7 @@
$lang['deactivate_unsuccessful'] = 'Accound deactiveren is mislukt';
$lang['activation_email_successful'] = 'Activatie e-mail is verzonden';
$lang['activation_email_unsuccessful'] = 'Activatie e-mail verzenden is mislukt';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'U bent ingelogd';
diff --git a/application/third_party/ion_auth/language/english/ion_auth_lang.php b/application/third_party/ion_auth/language/english/ion_auth_lang.php
index 082089f6..06f8e2a7 100755
--- a/application/third_party/ion_auth/language/english/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/english/ion_auth_lang.php
@@ -27,15 +27,16 @@
$lang['password_change_successful'] = 'Password Successfully Changed';
$lang['password_change_unsuccessful'] = 'Unable to Change Password';
$lang['forgot_password_successful'] = 'Password Reset Email Sent';
-$lang['forgot_password_unsuccessful'] = 'Unable to Reset Password';
+$lang['forgot_password_unsuccessful'] = 'Unable to email the Reset Password link';
// Activation
$lang['activate_successful'] = 'Account Activated';
$lang['activate_unsuccessful'] = 'Unable to Activate Account';
$lang['deactivate_successful'] = 'Account De-Activated';
$lang['deactivate_unsuccessful'] = 'Unable to De-Activate Account';
-$lang['activation_email_successful'] = 'Activation Email Sent';
+$lang['activation_email_successful'] = 'Activation Email Sent. Please check your inbox or spam';
$lang['activation_email_unsuccessful'] = 'Unable to Send Activation Email';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Logged In Successfully';
diff --git a/application/third_party/ion_auth/language/estonian/ion_auth_lang.php b/application/third_party/ion_auth/language/estonian/ion_auth_lang.php
index 185c7209..c2cb5c68 100755
--- a/application/third_party/ion_auth/language/estonian/ion_auth_lang.php
+++ b/application/third_party/ion_auth/language/estonian/ion_auth_lang.php
@@ -38,6 +38,7 @@
$lang['deactivate_unsuccessful'] = 'Konto aktiveerimine ebaõnnestus.';
$lang['activation_email_successful'] = 'Sinu e-postile saadeti kiri edasise juhendiga.';
$lang['activation_email_unsuccessful'] = 'Aktiveerimiskirja saatmine ebaõnnestus.';
+$lang['deactivate_current_user_unsuccessful']= 'You cannot De-Activate your self.';
// Login / Logout
$lang['login_successful'] = 'Oled sisse logitud';
diff --git a/application/third_party/ion_auth/language/filipino/auth_lang.php b/application/third_party/ion_auth/language/filipino/auth_lang.php
new file mode 100755
index 00000000..f1c0bf96
--- /dev/null
+++ b/application/third_party/ion_auth/language/filipino/auth_lang.php
@@ -0,0 +1,144 @@
+load->config('ion_auth', TRUE);
+ $this->config->load('ion_auth', TRUE);
$this->load->library(array('email'));
$this->lang->load('ion_auth');
$this->load->helper(array('cookie', 'language','url'));
@@ -133,7 +131,7 @@ public function __get($var)
* forgotten password feature
*
* @param $identity
- * @return mixed boolian / array
+ * @return mixed boolean / array
* @author Mathew
*/
public function forgotten_password($identity) //changed $email to $identity
@@ -445,7 +443,7 @@ public function logged_in()
{
$this->ion_auth_model->trigger_events('logged_in');
- return (bool) $this->session->userdata('identity');
+ return $this->ion_auth_model->recheck_session();
}
/**
diff --git a/application/third_party/ion_auth/migrations/001_install_ion_auth.php b/application/third_party/ion_auth/migrations/001_install_ion_auth.php
index 6c22eee0..7e92c32f 100755
--- a/application/third_party/ion_auth/migrations/001_install_ion_auth.php
+++ b/application/third_party/ion_auth/migrations/001_install_ion_auth.php
@@ -217,7 +217,7 @@ public function up()
'login' => array(
'type' => 'VARCHAR',
'constraint' => '100',
- 'null', TRUE
+ 'null' => TRUE
),
'time' => array(
'type' => 'INT',
diff --git a/application/third_party/ion_auth/models/Ion_auth_model.php b/application/third_party/ion_auth/models/Ion_auth_model.php
index 3a1085fb..fbd60655 100755
--- a/application/third_party/ion_auth/models/Ion_auth_model.php
+++ b/application/third_party/ion_auth/models/Ion_auth_model.php
@@ -2,8 +2,6 @@
/**
* Name: Ion Auth Model
*
-* Version: 2.5.2
-*
* Author: Ben Edmunds
* ben.edmunds@gmail.com
* @benedmunds
@@ -14,11 +12,6 @@
*
* Created: 10.01.2009
*
-* Last Change: 3.22.13
-*
-* Changelog:
-* * 3-22-13 - Additional entropy added - 52aa456eef8b60ad6754b31fbdcc77bb
-*
* Description: Modified auth system based on redux_auth with extensive customization. This is basically what Redux Auth 2 should be.
* Original Author name has been kept but that does not mean that the method has not been modified.
*
@@ -172,7 +165,7 @@ public function __construct()
{
parent::__construct();
$this->load->database();
- $this->load->config('ion_auth', TRUE);
+ $this->config->load('ion_auth', TRUE);
$this->load->helper('cookie');
$this->load->helper('date');
$this->lang->load('ion_auth');
@@ -381,12 +374,19 @@ public function salt()
$buffer = '';
$buffer_valid = false;
- if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
- $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
- if ($buffer) {
- $buffer_valid = true;
- }
- }
+ if (function_exists('random_bytes')) {
+ $buffer = random_bytes($raw_salt_len);
+ if ($buffer) {
+ $buffer_valid = true;
+ }
+ }
+
+ if (!$buffer_valid && function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
+ $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
+ if ($buffer) {
+ $buffer_valid = true;
+ }
+ }
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
@@ -438,7 +438,7 @@ public function salt()
* Activation functions
*
* Activate : Validates and removes activation code.
- * Deactivae : Updates a users row with an activation code.
+ * Deactivate : Updates a users row with an activation code.
*
* @author Mathew
*/
@@ -524,6 +524,11 @@ public function deactivate($id = NULL)
$this->set_error('deactivate_unsuccessful');
return FALSE;
}
+ elseif($this->ion_auth->logged_in() && $this->user()->row()->id == $id)
+ {
+ $this->set_error('deactivate_current_user_unsuccessful');
+ return FALSE;
+ }
$activation_code = sha1(md5(microtime()));
$this->activation_code = $activation_code;
@@ -906,6 +911,7 @@ public function register($identity, $password, $email, $additional_data = array(
// Users table.
$data = array(
$this->identity_column => $identity,
+ 'username' => $identity,
'password' => $password,
'email' => $email,
'ip_address' => $ip_address,
@@ -928,7 +934,7 @@ public function register($identity, $password, $email, $additional_data = array(
$id = $this->db->insert_id();
- // add in groups array if it doesn't exits and stop adding into default group if default group ids are set
+ // add in groups array if it doesn't exists and stop adding into default group if default group ids are set
if( isset($default_group->id) && empty($groups) )
{
$groups[] = $default_group->id;
@@ -1028,6 +1034,51 @@ public function login($identity, $password, $remember=FALSE)
return FALSE;
}
+ /**
+ * recheck_session verifies if the session should be rechecked according to
+ * the configuration item recheck_timer. If it does, then it will check if the user is still active
+ * @return bool
+ */
+ public function recheck_session()
+ {
+ $recheck = (null !== $this->config->item('recheck_timer', 'ion_auth')) ? $this->config->item('recheck_timer', 'ion_auth') : 0;
+
+ if($recheck!==0)
+ {
+ $last_login = $this->session->userdata('last_check');
+ if($last_login+$recheck < time())
+ {
+ $query = $this->db->select('id')
+ ->where(array($this->identity_column=>$this->session->userdata('identity'),'active'=>'1'))
+ ->limit(1)
+ ->order_by('id', 'desc')
+ ->get($this->tables['users']);
+ if ($query->num_rows() === 1)
+ {
+ $this->session->set_userdata('last_check',time());
+ }
+ else
+ {
+ $this->trigger_events('logout');
+
+ $identity = $this->config->item('identity', 'ion_auth');
+
+ if (substr(CI_VERSION, 0, 1) == '2')
+ {
+ $this->session->unset_userdata( array($identity => '', 'id' => '', 'user_id' => '') );
+ }
+ else
+ {
+ $this->session->unset_userdata( array($identity, 'id', 'user_id') );
+ }
+ return false;
+ }
+ }
+ }
+
+ return (bool) $this->session->userdata('identity');
+ }
+
/**
* is_max_login_attempts_exceeded
* Based on code from Tank Auth, by Ilya Konyukhov (https://github.com/ilkon/Tank-Auth)
@@ -1053,7 +1104,7 @@ public function is_max_login_attempts_exceeded($identity) {
* @param string $identity
* @return int
*/
- function get_attempts_num($identity)
+ public function get_attempts_num($identity)
{
if ($this->config->item('track_login_attempts', 'ion_auth')) {
$ip_address = $this->_prepare_ip($this->input->ip_address());
@@ -1089,9 +1140,10 @@ public function get_last_attempt_time($identity) {
if ($this->config->item('track_login_attempts', 'ion_auth')) {
$ip_address = $this->_prepare_ip($this->input->ip_address());
- $this->db->select_max('time');
+ $this->db->select('time');
if ($this->config->item('track_login_ip_address', 'ion_auth')) $this->db->where('ip_address', $ip_address);
else if (strlen($identity) > 0) $this->db->or_where('login', $identity);
+ $this->db->order_by('id', 'desc');
$qres = $this->db->get($this->tables['login_attempts'], 1);
if($qres->num_rows() > 0) {
@@ -1169,15 +1221,11 @@ public function like($like, $value = NULL, $position = 'both')
{
$this->trigger_events('like');
- if (!is_array($like))
- {
- $like = array($like => array(
- 'value' => $value,
- 'position' => $position,
- ));
- }
-
- array_push($this->_ion_like, $like);
+ array_push($this->_ion_like, array(
+ 'like' => $like,
+ 'value' => $value,
+ 'position' => $position
+ ));
return $this;
}
@@ -1333,7 +1381,7 @@ public function users($groups = NULL)
{
foreach ($this->_ion_like as $like)
{
- $this->db->or_like($like);
+ $this->db->or_like($like['like'], $like['value'], $like['position']);
}
$this->_ion_like = array();
@@ -1643,11 +1691,6 @@ public function delete_user($id)
// delete user from users table should be placed after remove from group
$this->db->delete($this->tables['users'], array('id' => $id));
- // if user does not exist in database then it returns FALSE else removes the user from groups
- if ($this->db->affected_rows() == 0)
- {
- return FALSE;
- }
if ($this->db->trans_status() === FALSE)
{
@@ -1729,7 +1772,8 @@ public function set_session($user)
$this->identity_column => $user->{$this->identity_column},
'email' => $user->email,
'user_id' => $user->id, //everyone likes to overwrite id so we'll use user_id
- 'old_last_login' => $user->last_login
+ 'old_last_login' => $user->last_login,
+ 'last_check' => time(),
);
$this->session->set_userdata($session_data);
@@ -1815,7 +1859,7 @@ public function login_remembered_user()
// get the user
$this->trigger_events('extra_where');
$query = $this->db->select($this->identity_column.', id, email, last_login')
- ->where($this->identity_column, get_cookie($this->config->item('identity_cookie_name', 'ion_auth')))
+ ->where($this->identity_column, urldecode(get_cookie($this->config->item('identity_cookie_name', 'ion_auth'))))
->where('remember_code', get_cookie($this->config->item('remember_cookie_name', 'ion_auth')))
->limit(1)
->order_by('id', 'desc')
diff --git a/application/third_party/rest_server/language/bulgarian/rest_controller_lang.php b/application/third_party/rest_server/language/bulgarian/rest_controller_lang.php
index 6145307d..4ba134d8 100755
--- a/application/third_party/rest_server/language/bulgarian/rest_controller_lang.php
+++ b/application/third_party/rest_server/language/bulgarian/rest_controller_lang.php
@@ -13,5 +13,6 @@
$lang['text_rest_api_key_unauthorized'] = 'API ключът не е оторизиран зо достъп до заявения контролер';
$lang['text_rest_api_key_permissions'] = 'API ключът няма достатъчно права';
$lang['text_rest_api_key_time_limit'] = 'API ключът е изполван с превишаване на времевия лимит за този метод';
+$lang['text_rest_ip_address_time_limit'] = 'За текущия IP адрес е превишен времевия лимит за изпълнение на метода';
$lang['text_rest_unknown_method'] = 'Неизвестен метод';
$lang['text_rest_unsupported'] = 'Неподдържан протокол';
diff --git a/application/third_party/rest_server/language/dutch/index.html b/application/third_party/rest_server/language/dutch/index.html
new file mode 100755
index 00000000..b702fbc3
--- /dev/null
+++ b/application/third_party/rest_server/language/dutch/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/third_party/rest_server/language/dutch/rest_controller_lang.php b/application/third_party/rest_server/language/dutch/rest_controller_lang.php
new file mode 100755
index 00000000..182ca61c
--- /dev/null
+++ b/application/third_party/rest_server/language/dutch/rest_controller_lang.php
@@ -0,0 +1,16 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/third_party/rest_server/language/indonesia/rest_controller_lang.php b/application/third_party/rest_server/language/indonesia/rest_controller_lang.php
new file mode 100755
index 00000000..771c6835
--- /dev/null
+++ b/application/third_party/rest_server/language/indonesia/rest_controller_lang.php
@@ -0,0 +1,18 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/third_party/rest_server/language/italian/rest_controller_lang.php b/application/third_party/rest_server/language/italian/rest_controller_lang.php
new file mode 100755
index 00000000..783f16ab
--- /dev/null
+++ b/application/third_party/rest_server/language/italian/rest_controller_lang.php
@@ -0,0 +1,16 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/third_party/rest_server/language/simplified-chinese/rest_controller_lang.php b/application/third_party/rest_server/language/simplified-chinese/rest_controller_lang.php
new file mode 100755
index 00000000..f32e9e7d
--- /dev/null
+++ b/application/third_party/rest_server/language/simplified-chinese/rest_controller_lang.php
@@ -0,0 +1,18 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/third_party/rest_server/language/turkish/rest_controller_lang.php b/application/third_party/rest_server/language/turkish/rest_controller_lang.php
new file mode 100755
index 00000000..589b28cc
--- /dev/null
+++ b/application/third_party/rest_server/language/turkish/rest_controller_lang.php
@@ -0,0 +1,18 @@
+_data;
}
- // turn off compatibility mode as simple xml throws a wobbly if you don't.
- if (ini_get('zend.ze1_compatibility_mode') == 1)
- {
- ini_set('zend.ze1_compatibility_mode', 0);
- }
-
if ($structure === NULL)
{
$structure = simplexml_load_string("<$basenode />");
@@ -416,12 +410,12 @@ public function to_json($data = NULL)
elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback))
{
// Return the data as encoded json with a callback
- return $callback . '(' . json_encode($data) . ');';
+ return $callback.'('.json_encode($data).');';
}
// An invalid jsonp callback function provided.
// Though I don't believe this should be hardcoded here
- $data['warning'] = 'INVALID JSONP CALLBACK: ' . $callback;
+ $data['warning'] = 'INVALID JSONP CALLBACK: '.$callback;
return json_encode($data);
}
@@ -467,8 +461,8 @@ public function to_php($data = NULL)
// INTERNAL FUNCTIONS
/**
- * @param $data XML string
- * @return SimpleXMLElement XML element object; otherwise, empty array
+ * @param string $data XML string
+ * @return array XML element object; otherwise, empty array
*/
protected function _from_xml($data)
{
@@ -502,7 +496,7 @@ protected function _from_csv($data, $delimiter = ',', $enclosure = '"')
}
/**
- * @param $data Encoded json string
+ * @param string $data Encoded json string
* @return mixed Decoded json string with leading and trailing whitespace removed
*/
protected function _from_json($data)
@@ -511,7 +505,7 @@ protected function _from_json($data)
}
/**
- * @param string Data to unserialized
+ * @param string $data Data to unserialize
* @return mixed Unserialized data
*/
protected function _from_serialize($data)
@@ -520,12 +514,11 @@ protected function _from_serialize($data)
}
/**
- * @param $data Data to trim leading and trailing whitespace
+ * @param string $data Data to trim leading and trailing whitespace
* @return string Data with leading and trailing whitespace removed
*/
protected function _from_php($data)
{
return trim($data);
}
-
}
diff --git a/application/third_party/rest_server/libraries/REST_Controller.php b/application/third_party/rest_server/libraries/REST_Controller.php
index 20052020..08789bc1 100755
--- a/application/third_party/rest_server/libraries/REST_Controller.php
+++ b/application/third_party/rest_server/libraries/REST_Controller.php
@@ -319,6 +319,13 @@ abstract class REST_Controller extends MX_Controller {
*/
protected $_apiuser;
+ /**
+ * Whether or not to perform a CORS check and apply CORS headers to the request
+ *
+ * @var bool
+ */
+ protected $check_cors = NULL;
+
/**
* Enable XSS flag
* Determines whether the XSS filter is always active when
@@ -368,27 +375,12 @@ protected function early_checks()
* @access public
* @param string $config Configuration filename minus the file extension
* e.g: my_rest.php is passed as 'my_rest'
- * @return void
*/
public function __construct($config = 'rest')
{
parent::__construct();
- // Disable XML Entity (security vulnerability)
- libxml_disable_entity_loader(TRUE);
-
- // Check to see if PHP is equal to or greater than 5.4.x
- if (is_php('5.4') === FALSE)
- {
- // CodeIgniter 3 is recommended for v5.4 or above
- throw new Exception('Using PHP v' . PHP_VERSION . ', though PHP v5.4 or greater is required');
- }
-
- // Check to see if this is CI 3.x
- if (explode('.', CI_VERSION, 2)[0] < 3)
- {
- throw new Exception('REST Server requires CodeIgniter 3.x');
- }
+ $this->preflight_checks();
// Set the default value of global xss filtering. Same approach as CodeIgniter 3
$this->_enable_xss = ($this->config->item('global_xss_filtering') === TRUE);
@@ -415,7 +407,7 @@ public function __construct($config = 'rest')
$supported_formats = [];
}
- if (!is_array($supported_formats))
+ if ( ! is_array($supported_formats))
{
$supported_formats = [$supported_formats];
}
@@ -457,10 +449,17 @@ public function __construct($config = 'rest')
// How is this request being made? GET, POST, PATCH, DELETE, INSERT, PUT, HEAD or OPTIONS
$this->request->method = $this->_detect_method();
+ // Check for CORS access request
+ $check_cors = $this->config->item('check_cors');
+ if ($check_cors === TRUE)
+ {
+ $this->_check_cors();
+ }
+
// Create an argument container if it doesn't exist e.g. _get_args
- if (isset($this->{'_' . $this->request->method . '_args'}) === FALSE)
+ if (isset($this->{'_'.$this->request->method.'_args'}) === FALSE)
{
- $this->{'_' . $this->request->method . '_args'} = [];
+ $this->{'_'.$this->request->method.'_args'} = [];
}
// Set up the query parameters
@@ -482,9 +481,12 @@ public function __construct($config = 'rest')
{
$this->request->body = $this->format->factory($this->request->body, $this->request->format)->to_array();
// Assign payload arguments to proper method container
- $this->{'_' . $this->request->method . '_args'} = $this->request->body;
+ $this->{'_'.$this->request->method.'_args'} = $this->request->body;
}
+ //get header vars
+ $this->_head_args = $this->input->request_headers();
+
// Merge both for one mega-args variable
$this->_args = array_merge(
$this->_get_args,
@@ -494,7 +496,7 @@ public function __construct($config = 'rest')
$this->_put_args,
$this->_post_args,
$this->_delete_args,
- $this->{'_' . $this->request->method . '_args'}
+ $this->{'_'.$this->request->method.'_args'}
);
// Which format should the data be returned in?
@@ -540,7 +542,9 @@ public function __construct($config = 'rest')
}
// When there is no specific override for the current class/method, use the default auth value set in the config
- if ($this->auth_override === FALSE && !($this->config->item('rest_enable_keys') && $this->_allow === TRUE) || ($this->config->item('allow_auth_and_keys') === TRUE && $this->_allow === TRUE))
+ if ($this->auth_override === FALSE &&
+ (! ($this->config->item('rest_enable_keys') && $this->_allow === TRUE) ||
+ ($this->config->item('allow_auth_and_keys') === TRUE && $this->_allow === TRUE)))
{
$rest_auth = strtolower($this->config->item('rest_auth'));
switch ($rest_auth)
@@ -581,14 +585,36 @@ public function __destruct()
}
}
+ /**
+ * Checks to see if we have everything we need to run this library.
+ *
+ * @access protected
+ * @@throws Exception
+ */
+ protected function preflight_checks()
+ {
+ // Check to see if PHP is equal to or greater than 5.4.x
+ if (is_php('5.4') === FALSE)
+ {
+ // CodeIgniter 3 is recommended for v5.4 or above
+ throw new Exception('Using PHP v'.PHP_VERSION.', though PHP v5.4 or greater is required');
+ }
+
+ // Check to see if this is CI 3.x
+ if (explode('.', CI_VERSION, 2)[0] < 3)
+ {
+ throw new Exception('REST Server requires CodeIgniter 3.x');
+ }
+ }
+
/**
* Requests are not made to methods directly, the request will be for
* an "object". This simply maps the object and method to the correct
* Controller method
*
* @access public
- * @param string $object_called
- * @param array $arguments The arguments passed to the controller method
+ * @param string $object_called
+ * @param array $arguments The arguments passed to the controller method
*/
public function _remap($object_called, $arguments = [])
{
@@ -602,15 +628,20 @@ public function _remap($object_called, $arguments = [])
}
// Remove the supported format from the function name e.g. index.json => index
- $object_called = preg_replace('/^(.*)\.(?:' . implode('|', array_keys($this->_supported_formats)) . ')$/', '$1', $object_called);
+ $object_called = preg_replace('/^(.*)\.(?:'.implode('|', array_keys($this->_supported_formats)).')$/', '$1', $object_called);
- $controller_method = $object_called . '_' . $this->request->method;
+ $controller_method = $object_called.'_'.$this->request->method;
+ // Does this method exist? If not, try executing an index method
+ if (!method_exists($this, $controller_method)) {
+ $controller_method = "index_" . $this->request->method;
+ array_unshift($arguments, $object_called);
+ }
// Do we want to log this method (if allowed by config)?
- $log_method = !(isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === FALSE);
+ $log_method = ! (isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === FALSE);
// Use keys for this method?
- $use_key = !(isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === FALSE);
+ $use_key = ! (isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === FALSE);
// They provided a key, but it wasn't valid, so get them out of here
if ($this->config->item('rest_enable_keys') && $use_key && $this->_allow === FALSE)
@@ -619,6 +650,11 @@ public function _remap($object_called, $arguments = [])
{
$this->_log_request();
}
+
+ // fix cross site to option request error
+ if($this->request->method == 'options') {
+ exit;
+ }
$this->response([
$this->config->item('rest_status_field_name') => FALSE,
@@ -641,12 +677,12 @@ public function _remap($object_called, $arguments = [])
}
// Sure it exists, but can they do anything with it?
- if (method_exists($this, $controller_method) === FALSE)
+ if (! method_exists($this, $controller_method))
{
$this->response([
$this->config->item('rest_status_field_name') => FALSE,
$this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unknown_method')
- ], self::HTTP_NOT_FOUND);
+ ], self::HTTP_METHOD_NOT_ALLOWED);
}
// Doing key related stuff? Can only do it if they have a key right?
@@ -664,16 +700,24 @@ public function _remap($object_called, $arguments = [])
// If no level is set, or it is lower than/equal to the key's level
$authorized = $level <= $this->rest->level;
-
// IM TELLIN!
if ($this->config->item('rest_enable_logging') && $log_method)
{
$this->_log_request($authorized);
}
+ if($authorized === FALSE)
+ {
+ // They don't have good enough perms
+ $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')];
+ $this->response($response, self::HTTP_UNAUTHORIZED);
+ }
+ }
- // They don't have good enough perms
- $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')];
- $authorized || $this->response($response, self::HTTP_UNAUTHORIZED);
+ //check request limit by ip without login
+ elseif ($this->config->item('rest_limits_method') == "IP_ADDRESS" && $this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE)
+ {
+ $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_address_time_limit')];
+ $this->response($response, self::HTTP_UNAUTHORIZED);
}
// No key stuff, but record that stuff is happening
@@ -690,13 +734,8 @@ public function _remap($object_called, $arguments = [])
catch (Exception $ex)
{
// If the method doesn't exist, then the error will be caught and an error response shown
- $this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => [
- 'classname' => get_class($ex),
- 'message' => $ex->getMessage()
- ]
- ], self::HTTP_INTERNAL_SERVER_ERROR);
+ $_error = &load_class('Exceptions', 'core');
+ $_error->show_exception($ex);
}
}
@@ -711,6 +750,7 @@ public function _remap($object_called, $arguments = [])
*/
public function response($data = NULL, $http_code = NULL, $continue = FALSE)
{
+ ob_start();
// If the HTTP status is not NULL, then cast as an integer
if ($http_code !== NULL)
{
@@ -779,6 +819,10 @@ public function response($data = NULL, $http_code = NULL, $continue = FALSE)
$this->output->_display();
exit;
}
+ else
+ {
+ ob_end_flush();
+ }
// Otherwise dump the output automatically
}
@@ -811,20 +855,20 @@ protected function _detect_input_format()
if (empty($content_type) === FALSE)
{
- // Check all formats against the HTTP_ACCEPT header
- foreach ($this->_supported_formats as $key => $value)
- {
- // $key = format e.g. csv
- // $value = mime type e.g. application/csv
+ // If a semi-colon exists in the string, then explode by ; and get the value of where
+ // the current array pointer resides. This will generally be the first element of the array
+ $content_type = (strpos($content_type, ';') !== FALSE ? current(explode(';', $content_type)) : $content_type);
- // If a semi-colon exists in the string, then explode by ; and get the value of where
- // the current array pointer resides. This will generally be the first element of the array
- $content_type = (strpos($content_type, ';') !== FALSE ? current(explode(';', $content_type)) : $content_type);
+ // Check all formats against the CONTENT-TYPE header
+ foreach ($this->_supported_formats as $type => $mime)
+ {
+ // $type = format e.g. csv
+ // $mime = mime type e.g. application/csv
// If both the mime types match, then return the format
- if ($content_type === $value)
+ if ($content_type === $mime)
{
- return $key;
+ return $type;
}
}
}
@@ -855,7 +899,7 @@ protected function _get_default_output_format()
protected function _detect_output_format()
{
// Concatenate formats to a regex pattern e.g. \.(csv|json|xml)
- $pattern = '/\.(' . implode('|', array_keys($this->_supported_formats)) . ')($|\/)/';
+ $pattern = '/\.('.implode('|', array_keys($this->_supported_formats)).')($|\/)/';
$matches = [];
// Check if a file extension is used e.g. http://example.com/api/index.json?param1=param2
@@ -971,7 +1015,7 @@ protected function _detect_api_key()
// Find the key from server or arguments
if (($key = isset($this->_args[$api_key_variable]) ? $this->_args[$api_key_variable] : $this->input->server($key_name)))
{
- if (!($row = $this->rest->db->where($this->config->item('rest_key_column'), $key)->get($this->config->item('rest_keys_table'))->row()))
+ if ( ! ($row = $this->rest->db->where($this->config->item('rest_key_column'), $key)->get($this->config->item('rest_keys_table'))->row()))
{
return FALSE;
}
@@ -1089,7 +1133,7 @@ protected function _log_request($authorized = FALSE)
* Check if the requests to a controller method exceed a limit
*
* @access protected
- * @param string $controller_method The method being called
+ * @param string $controller_method The method being called
* @return bool TRUE the call limit is below the threshold; otherwise, FALSE
*/
protected function _check_limit($controller_method)
@@ -1101,16 +1145,21 @@ protected function _check_limit($controller_method)
return TRUE;
}
+ $api_key = isset($this->rest->key) ? $this->rest->key : '';
+
switch ($this->config->item('rest_limits_method'))
{
+ case 'IP_ADDRESS':
+ $limited_uri = 'ip-address:' .$this->input->ip_address();
+ $api_key = $this->input->ip_address();
+ break;
+
case 'API_KEY':
- $limited_uri = 'api-key:' . (isset($this->rest->key) ? $this->rest->key : '');
- $limited_method_name = isset($this->rest->key) ? $this->rest->key : '';
+ $limited_uri = 'api-key:' . $api_key;
break;
case 'METHOD_NAME':
$limited_uri = 'method-name:' . $controller_method;
- $limited_method_name = $controller_method;
break;
case 'ROUTED_URL':
@@ -1120,26 +1169,25 @@ protected function _check_limit($controller_method)
{
$limited_uri = substr($limited_uri,0, -strlen($this->response->format) - 1);
}
- $limited_uri = 'uri:' . $limited_uri . ':' . $this->request->method; // It's good to differentiate GET from PUT
- $limited_method_name = $controller_method;
+ $limited_uri = 'uri:'.$limited_uri.':'.$this->request->method; // It's good to differentiate GET from PUT
break;
}
- if (isset($this->methods[$limited_method_name]['limit']) === FALSE )
+ if (isset($this->methods[$controller_method]['limit']) === FALSE )
{
// Everything is fine
return TRUE;
}
// How many times can you get to this method in a defined time_limit (default: 1 hour)?
- $limit = $this->methods[$limited_method_name]['limit'];
+ $limit = $this->methods[$controller_method]['limit'];
- $time_limit = (isset($this->methods[$limited_method_name]['time']) ? $this->methods[$limited_method_name]['time'] : 3600); // 3600 = 60 * 60
+ $time_limit = (isset($this->methods[$controller_method]['time']) ? $this->methods[$controller_method]['time'] : 3600); // 3600 = 60 * 60
// Get data about a keys' usage and limit to one row
$result = $this->rest->db
->where('uri', $limited_uri)
- ->where('api_key', $this->rest->key)
+ ->where('api_key', $api_key)
->get($this->config->item('rest_limits_table'))
->row();
@@ -1149,7 +1197,7 @@ protected function _check_limit($controller_method)
// Create a new row for the following key
$this->rest->db->insert($this->config->item('rest_limits_table'), [
'uri' => $limited_uri,
- 'api_key' => isset($this->rest->key) ? $this->rest->key : '',
+ 'api_key' =>$api_key,
'count' => 1,
'hour_started' => time()
]);
@@ -1161,7 +1209,7 @@ protected function _check_limit($controller_method)
// Reset the started period and count
$this->rest->db
->where('uri', $limited_uri)
- ->where('api_key', isset($this->rest->key) ? $this->rest->key : '')
+ ->where('api_key', $api_key)
->set('hour_started', time())
->set('count', 1)
->update($this->config->item('rest_limits_table'));
@@ -1179,7 +1227,7 @@ protected function _check_limit($controller_method)
// Increase the count by one
$this->rest->db
->where('uri', $limited_uri)
- ->where('api_key', $this->rest->key)
+ ->where('api_key', $api_key)
->set('count', 'count + 1', FALSE)
->update($this->config->item('rest_limits_table'));
}
@@ -1199,12 +1247,12 @@ protected function _auth_override_check()
$auth_override_class_method = $this->config->item('auth_override_class_method');
// Check to see if the override array is even populated
- if (!empty($auth_override_class_method))
+ if ( ! empty($auth_override_class_method))
{
- // check for wildcard flag for rules for classes
- if (!empty($auth_override_class_method[$this->router->class]['*'])) // Check for class overrides
+ // Check for wildcard flag for rules for classes
+ if ( ! empty($auth_override_class_method[$this->router->class]['*'])) // Check for class overrides
{
- // None auth override found, prepare nothing but send back a TRUE override flag
+ // No auth override found, prepare nothing but send back a TRUE override flag
if ($auth_override_class_method[$this->router->class]['*'] === 'none')
{
return TRUE;
@@ -1244,7 +1292,7 @@ protected function _auth_override_check()
}
// Check to see if there's an override value set for the current class/method being called
- if (!empty($auth_override_class_method[$this->router->class][$this->router->method]))
+ if ( ! empty($auth_override_class_method[$this->router->class][$this->router->method]))
{
// None auth override found, prepare nothing but send back a TRUE override flag
if ($auth_override_class_method[$this->router->class][$this->router->method] === 'none')
@@ -1290,10 +1338,10 @@ protected function _auth_override_check()
$auth_override_class_method_http = $this->config->item('auth_override_class_method_http');
// Check to see if the override array is even populated
- if (!empty($auth_override_class_method_http))
+ if ( ! empty($auth_override_class_method_http))
{
// check for wildcard flag for rules for classes
- if(!empty($auth_override_class_method_http[$this->router->class]['*'][$this->request->method]))
+ if ( ! empty($auth_override_class_method_http[$this->router->class]['*'][$this->request->method]))
{
// None auth override found, prepare nothing but send back a TRUE override flag
if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'none')
@@ -1335,7 +1383,7 @@ protected function _auth_override_check()
}
// Check to see if there's an override value set for the current class/method/HTTP-method being called
- if(!empty($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method]))
+ if ( ! empty($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method]))
{
// None auth override found, prepare nothing but send back a TRUE override flag
if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'none')
@@ -1418,6 +1466,10 @@ protected function _parse_put()
if ($this->request->format)
{
$this->request->body = $this->input->raw_input_stream;
+ if ($this->request->format === 'json')
+ {
+ $this->_put_args = json_decode($this->input->raw_input_stream);
+ }
}
else if ($this->input->method() === 'put')
{
@@ -1661,8 +1713,8 @@ public function query($key = NULL, $xss_clean = NULL)
* prevented
*
* @access protected
- * @param string $value Input data
- * @param bool $xss_clean Whether to apply XSS filtering
+ * @param string $value Input data
+ * @param bool $xss_clean Whether to apply XSS filtering
* @return string
*/
protected function _xss_clean($value, $xss_clean)
@@ -1691,8 +1743,8 @@ public function validation_errors()
* Perform LDAP Authentication
*
* @access protected
- * @param string $username The username to validate
- * @param string $password The password to validate
+ * @param string $username The username to validate
+ * @param string $password The password to validate
* @return bool
*/
protected function _perform_ldap_auth($username = '', $password = NULL)
@@ -1722,11 +1774,11 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
$ldapconn = ldap_connect($ldap['host'], $ldap['port']);
if ($ldapconn)
{
- log_message('debug', 'Setting timeout to ' . $ldap['timeout'] . ' seconds');
+ log_message('debug', 'Setting timeout to '.$ldap['timeout'].' seconds');
ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, $ldap['timeout']);
- log_message('debug', 'LDAP Auth: Binding to ' . $ldap['host'] . ' with dn ' . $ldap['rdn']);
+ log_message('debug', 'LDAP Auth: Binding to '.$ldap['host'].' with dn '.$ldap['rdn']);
// Binding to the ldap server
$ldapbind = ldap_bind($ldapconn, $ldap['rdn'], $ldap['pass']);
@@ -1744,13 +1796,13 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
// Search for user
if (($res_id = ldap_search($ldapconn, $ldap['basedn'], "uid=$username")) === FALSE)
{
- log_message('error', 'LDAP Auth: User ' . $username . ' not found in search');
+ log_message('error', 'LDAP Auth: User '.$username.' not found in search');
return FALSE;
}
if (ldap_count_entries($ldapconn, $res_id) !== 1)
{
- log_message('error', 'LDAP Auth: Failure, username ' . $username . 'found more than once');
+ log_message('error', 'LDAP Auth: Failure, username '.$username.'found more than once');
return FALSE;
}
@@ -1773,7 +1825,7 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
return FALSE;
}
- log_message('debug', 'LDAP Auth: Success ' . $user_dn . ' authenticated successfully');
+ log_message('debug', 'LDAP Auth: Success '.$user_dn.' authenticated successfully');
$this->_user_ldap_dn = $user_dn;
@@ -1786,8 +1838,8 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
* Perform Library Authentication - Override this function to change the way the library is called
*
* @access protected
- * @param string $username The username to validate
- * @param string $password The password to validate
+ * @param string $username The username to validate
+ * @param string $password The password to validate
* @return bool
*/
protected function _perform_library_auth($username = '', $password = NULL)
@@ -1825,8 +1877,8 @@ protected function _perform_library_auth($username = '', $password = NULL)
* Check if the user is logged in
*
* @access protected
- * @param string $username The user's name
- * @param bool|string $password The user's password
+ * @param string $username The user's name
+ * @param bool|string $password The user's password
* @return bool
*/
protected function _check_login($username = NULL, $password = FALSE)
@@ -1840,10 +1892,10 @@ protected function _check_login($username = NULL, $password = FALSE)
$rest_auth = strtolower($this->config->item('rest_auth'));
$valid_logins = $this->config->item('rest_valid_logins');
- if (!$this->config->item('auth_source') && $rest_auth === 'digest')
+ if ( ! $this->config->item('auth_source') && $rest_auth === 'digest')
{
// For digest we do not have a password passed as argument
- return md5($username . ':' . $this->config->item('rest_realm') . ':' . (isset($valid_logins[$username]) ? $valid_logins[$username] : ''));
+ return md5($username.':'.$this->config->item('rest_realm').':'.(isset($valid_logins[$username]) ? $valid_logins[$username] : ''));
}
if ($password === FALSE)
@@ -1890,7 +1942,7 @@ protected function _check_php_session()
$key = $this->config->item('auth_source');
// If falsy, then the user isn't logged in
- if (!$this->session->userdata($key))
+ if ( ! $this->session->userdata($key))
{
// Display an error response
$this->response([
@@ -1977,15 +2029,15 @@ protected function _prepare_digest_auth()
preg_match_all('@(username|nonce|uri|nc|cnonce|qop|response)=[\'"]?([^\'",]+)@', $digest_string, $matches);
$digest = (empty($matches[1]) || empty($matches[2])) ? [] : array_combine($matches[1], $matches[2]);
- // For digest authentication the library function should return already stored md5(username:restrealm:password) for that username @see rest.php::auth_library_function config
+ // For digest authentication the library function should return already stored md5(username:restrealm:password) for that username see rest.php::auth_library_function config
$username = $this->_check_login($digest['username'], TRUE);
if (array_key_exists('username', $digest) === FALSE || $username === FALSE)
{
$this->_force_login($unique_id);
}
- $md5 = md5(strtoupper($this->request->method) . ':' . $digest['uri']);
- $valid_response = md5($username . ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' . $md5);
+ $md5 = md5(strtoupper($this->request->method).':'.$digest['uri']);
+ $valid_response = md5($username.':'.$digest['nonce'].':'.$digest['nc'].':'.$digest['cnonce'].':'.$digest['qop'].':'.$md5);
// Check if the string don't compare (case-insensitive)
if (strcasecmp($digest['response'], $valid_response) !== 0)
@@ -2063,15 +2115,15 @@ protected function _force_login($nonce = '')
if (strtolower($rest_auth) === 'basic')
{
// See http://tools.ietf.org/html/rfc2617#page-5
- header('WWW-Authenticate: Basic realm="' . $rest_realm . '"');
+ header('WWW-Authenticate: Basic realm="'.$rest_realm.'"');
}
elseif (strtolower($rest_auth) === 'digest')
{
// See http://tools.ietf.org/html/rfc2617#page-18
header(
- 'WWW-Authenticate: Digest realm="' . $rest_realm
- . '", qop="auth", nonce="' . $nonce
- . '", opaque="' . md5($rest_realm) . '"');
+ 'WWW-Authenticate: Digest realm="'.$rest_realm
+ .'", qop="auth", nonce="'.$nonce
+ .'", opaque="' . md5($rest_realm).'"');
}
// Display an error response
@@ -2130,6 +2182,16 @@ protected function _check_access()
return TRUE;
}
+ //check if the key has all_access
+ $accessRow = $this->rest->db
+ ->where('key', $this->rest->key)
+ ->get($this->config->item('rest_access_table'))->row_array();
+
+ if (!empty($accessRow) && !empty($accessRow['all_access']))
+ {
+ return TRUE;
+ }
+
// Fetch controller based on path and controller name
$controller = implode(
'/', [
@@ -2148,4 +2210,48 @@ protected function _check_access()
->num_rows() > 0;
}
+ /**
+ * Checks allowed domains, and adds appropriate headers for HTTP access control (CORS)
+ *
+ * @access protected
+ * @return void
+ */
+ protected function _check_cors()
+ {
+ // Convert the config items into strings
+ $allowed_headers = implode(' ,', $this->config->item('allowed_cors_headers'));
+ $allowed_methods = implode(' ,', $this->config->item('allowed_cors_methods'));
+
+ // If we want to allow any domain to access the API
+ if ($this->config->item('allow_any_cors_domain') === TRUE)
+ {
+ header('Access-Control-Allow-Origin: *');
+ header('Access-Control-Allow-Headers: '.$allowed_headers);
+ header('Access-Control-Allow-Methods: '.$allowed_methods);
+ }
+ else
+ {
+ // We're going to allow only certain domains access
+ // Store the HTTP Origin header
+ $origin = $this->input->server('HTTP_ORIGIN');
+ if ($origin === NULL)
+ {
+ $origin = '';
+ }
+
+ // If the origin domain is in the allowed_cors_origins list, then add the Access Control headers
+ if (in_array($origin, $this->config->item('allowed_cors_origins')))
+ {
+ header('Access-Control-Allow-Origin: '.$origin);
+ header('Access-Control-Allow-Headers: '.$allowed_headers);
+ header('Access-Control-Allow-Methods: '.$allowed_methods);
+ }
+ }
+
+ // If the request HTTP method is 'OPTIONS', kill the response and send it to the client
+ if ($this->input->method() === 'options')
+ {
+ exit;
+ }
+ }
}
diff --git a/application/third_party/rest_server/libraries/index.html b/application/third_party/rest_server/libraries/index.html
new file mode 100755
index 00000000..b702fbc3
--- /dev/null
+++ b/application/third_party/rest_server/libraries/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/application/views/email/_footer.php b/application/views/email/_footer.php
index 046c5e7c..e3ca784a 100755
--- a/application/views/email/_footer.php
+++ b/application/views/email/_footer.php
@@ -1,6 +1,6 @@
- This email is sent automatically from .
+ This email is sent automatically from from_name; ?>.