GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#141)
by Gwenaël
14:16 queued 08:27
created
myth/CIModules/auth/controllers/Auth.php 1 patch
Indentation   +263 added lines, -263 removed lines patch added patch discarded remove patch
@@ -1,34 +1,34 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 /**
3
- * Sprint
4
- *
5
- * A set of power tools to enhance the CodeIgniter framework and provide consistent workflow.
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a copy
8
- * of this software and associated documentation files (the "Software"), to deal
9
- * in the Software without restriction, including without limitation the rights
10
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- * copies of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be included in
15
- * all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- * THE SOFTWARE.
24
- *
25
- * @package     Sprint
26
- * @author      Lonnie Ezell
27
- * @copyright   Copyright 2014-2015, New Myth Media, LLC (http://newmythmedia.com)
28
- * @license     http://opensource.org/licenses/MIT  (MIT)
29
- * @link        http://sprintphp.com
30
- * @since       Version 1.0
31
- */
3
+	 * Sprint
4
+	 *
5
+	 * A set of power tools to enhance the CodeIgniter framework and provide consistent workflow.
6
+	 *
7
+	 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+	 * of this software and associated documentation files (the "Software"), to deal
9
+	 * in the Software without restriction, including without limitation the rights
10
+	 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+	 * copies of the Software, and to permit persons to whom the Software is
12
+	 * furnished to do so, subject to the following conditions:
13
+	 *
14
+	 * The above copyright notice and this permission notice shall be included in
15
+	 * all copies or substantial portions of the Software.
16
+	 *
17
+	 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+	 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+	 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+	 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+	 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+	 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+	 * THE SOFTWARE.
24
+	 *
25
+	 * @package     Sprint
26
+	 * @author      Lonnie Ezell
27
+	 * @copyright   Copyright 2014-2015, New Myth Media, LLC (http://newmythmedia.com)
28
+	 * @license     http://opensource.org/licenses/MIT  (MIT)
29
+	 * @link        http://sprintphp.com
30
+	 * @since       Version 1.0
31
+	 */
32 32
 
33 33
 use \Myth\Route as Route;
34 34
 use \Myth\Auth\LocalAuthentication as LocalAuthentication;
@@ -36,225 +36,225 @@  discard block
 block discarded – undo
36 36
 class Auth extends \Myth\Controllers\ThemedController
37 37
 {
38 38
 
39
-    public function __construct()
40
-    {
41
-        parent::__construct();
42
-
43
-        $this->config->load('auth');
44
-        $this->lang->load('auth');
45
-        $this->load->library('session');
46
-    }
47
-
48
-    //--------------------------------------------------------------------
49
-
50
-    public function login()
51
-    {
52
-        $this->load->helper('form');
53
-
54
-        $auth = new LocalAuthentication();
55
-        $this->load->model('user_model');
56
-        $auth->useModel($this->user_model);
57
-
58
-        $redirect_url = $this->session->userdata('redirect_url');
59
-
60
-        // No need to login again if they are already logged in...
61
-        if ($auth->isLoggedIn())
62
-        {
63
-            unset($_SESSION['redirect_url']);
64
-            redirect($redirect_url);
65
-        }
66
-
67
-        if ($this->input->post())
68
-        {
69
-            $post_data = [
70
-                'email'    => $this->input->post('email'),
71
-                'password' => $this->input->post('password')
72
-            ];
73
-
74
-            $remember = (bool)$this->input->post('remember');
75
-
76
-            if ($auth->login($post_data, $remember))
77
-            {
78
-	            // Is the user being forced to reset their password?
79
-	            if ($auth->user()['force_pass_reset'] == 1)
80
-	            {
81
-		            redirect( Route::named('change_pass') );
82
-	            }
83
-
84
-                unset($_SESSION['redirect_url']);
85
-                $this->setMessage(lang('auth.did_login'), 'success');
86
-                redirect($redirect_url);
87
-            }
88
-
89
-            $this->setMessage($auth->error(), 'danger');
90
-        }
91
-
92
-        $this->themer->setLayout('login');
93
-        $this->render();
94
-    }
95
-
96
-    //--------------------------------------------------------------------
97
-
98
-    public function logout()
99
-    {
100
-        $auth = new LocalAuthentication();
101
-        $this->load->model('user_model');
102
-        $auth->useModel($this->user_model);
103
-
104
-        if ($auth->isLoggedIn())
105
-        {
106
-            $auth->logout();
107
-
108
-            $this->setMessage(lang('auth.did_logout'), 'success');
109
-        }
110
-
111
-        redirect('/');
112
-    }
113
-
114
-    //--------------------------------------------------------------------
115
-
116
-    public function register()
117
-    {
118
-        $this->load->helper('form');
119
-
120
-        if ($this->input->post())
121
-        {
122
-            $auth = new LocalAuthentication();
123
-            $this->load->model('user_model');
124
-            $auth->useModel($this->user_model);
125
-
126
-            $post_data = [
127
-                'first_name'   => $this->input->post('first_name'),
128
-                'last_name'    => $this->input->post('last_name'),
129
-                'email'        => $this->input->post('email'),
130
-                'username'     => $this->input->post('username'),
131
-                'password'     => $this->input->post('password'),
132
-                'pass_confirm' => $this->input->post('pass_confirm')
133
-            ];
134
-
135
-            if ($auth->registerUser($post_data))
136
-            {
137
-                $this->setMessage(lang('auth.did_register'), 'success');
138
-                redirect( Route::named('login') );
139
-            }
140
-            else
141
-            {
142
-                $this->setMessage($auth->error(), 'danger');
143
-            }
144
-        }
145
-
146
-        $this->addScript('register.js');
147
-        $this->themer->setLayout('login');
148
-        $this->render();
149
-    }
150
-
151
-    //--------------------------------------------------------------------
152
-
153
-    public function activate_user()
154
-    {
155
-        $this->load->helper('form');
156
-
157
-        if ($this->input->post())
158
-        {
159
-            $auth = new LocalAuthentication();
160
-            $this->load->model('user_model');
161
-            $auth->useModel($this->user_model);
162
-
163
-            $post_data = [
164
-                  'email' => $this->input->post('email'),
165
-                  'code'  => $this->input->post('code')
166
-            ];
167
-
168
-            if ($auth->activateUser($post_data))
169
-            {
170
-                $this->setMessage(lang('auth.did_activate'), 'success');
171
-                redirect( Route::named('login') );
172
-            }
173
-            else
174
-            {
175
-                $this->setMessage($auth->error(), 'danger');
176
-            }
177
-        }
178
-
179
-        $data = [
180
-            'email' => $this->input->get('e'),
181
-            'code'  => $this->input->get('code')
182
-        ];
183
-
184
-        $this->themer->setLayout('login');
185
-        $this->render($data);
186
-    }
187
-
188
-    //--------------------------------------------------------------------
189
-
190
-
191
-    public function forgot_password()
192
-    {
193
-        $this->load->helper('form');
194
-
195
-        if ($this->input->post())
196
-        {
197
-            $auth = new LocalAuthentication();
198
-            $this->load->model('user_model');
199
-            $auth->useModel($this->user_model);
200
-
201
-            if ($auth->remindUser($this->input->post('email')))
202
-            {
203
-                $this->setMessage(lang('auth.send_success'), 'success');
204
-                redirect( Route::named('reset_pass') );
205
-            }
206
-            else
207
-            {
208
-                $this->setMessage($auth->error(), 'danger');
209
-            }
210
-        }
211
-
212
-        $this->themer->setLayout('login');
213
-        $this->render();
214
-    }
215
-
216
-    //--------------------------------------------------------------------
217
-
218
-    public function reset_password()
219
-    {
220
-        $this->load->helper('form');
221
-
222
-        if ($this->input->post())
223
-        {
224
-            $auth = new LocalAuthentication();
225
-            $this->load->model('user_model');
226
-            $auth->useModel($this->user_model);
227
-
228
-            $credentials = [
229
-                'email' => $this->input->post('email'),
230
-                'code'  => $this->input->post('code')
231
-            ];
232
-
233
-            $password     = $this->input->post('password');
234
-            $pass_confirm = $this->input->post('pass_confirm');
235
-
236
-            if ($auth->resetPassword($credentials, $password, $pass_confirm))
237
-            {
238
-                $this->setMessage(lang('auth.new_password_success'), 'success');
239
-                redirect( Route::named('login') );
240
-            }
241
-            else
242
-            {
243
-                $this->setMessage($auth->error(), 'danger');
244
-            }
245
-        }
246
-
247
-        $data = [
248
-            'email' => $this->input->get('e'),
249
-            'code'  => $this->input->get('code')
250
-        ];
251
-
252
-        $this->addScript('register.js');
253
-        $this->themer->setLayout('login');
254
-        $this->render($data);
255
-    }
256
-
257
-    //--------------------------------------------------------------------
39
+	public function __construct()
40
+	{
41
+		parent::__construct();
42
+
43
+		$this->config->load('auth');
44
+		$this->lang->load('auth');
45
+		$this->load->library('session');
46
+	}
47
+
48
+	//--------------------------------------------------------------------
49
+
50
+	public function login()
51
+	{
52
+		$this->load->helper('form');
53
+
54
+		$auth = new LocalAuthentication();
55
+		$this->load->model('user_model');
56
+		$auth->useModel($this->user_model);
57
+
58
+		$redirect_url = $this->session->userdata('redirect_url');
59
+
60
+		// No need to login again if they are already logged in...
61
+		if ($auth->isLoggedIn())
62
+		{
63
+			unset($_SESSION['redirect_url']);
64
+			redirect($redirect_url);
65
+		}
66
+
67
+		if ($this->input->post())
68
+		{
69
+			$post_data = [
70
+				'email'    => $this->input->post('email'),
71
+				'password' => $this->input->post('password')
72
+			];
73
+
74
+			$remember = (bool)$this->input->post('remember');
75
+
76
+			if ($auth->login($post_data, $remember))
77
+			{
78
+				// Is the user being forced to reset their password?
79
+				if ($auth->user()['force_pass_reset'] == 1)
80
+				{
81
+					redirect( Route::named('change_pass') );
82
+				}
83
+
84
+				unset($_SESSION['redirect_url']);
85
+				$this->setMessage(lang('auth.did_login'), 'success');
86
+				redirect($redirect_url);
87
+			}
88
+
89
+			$this->setMessage($auth->error(), 'danger');
90
+		}
91
+
92
+		$this->themer->setLayout('login');
93
+		$this->render();
94
+	}
95
+
96
+	//--------------------------------------------------------------------
97
+
98
+	public function logout()
99
+	{
100
+		$auth = new LocalAuthentication();
101
+		$this->load->model('user_model');
102
+		$auth->useModel($this->user_model);
103
+
104
+		if ($auth->isLoggedIn())
105
+		{
106
+			$auth->logout();
107
+
108
+			$this->setMessage(lang('auth.did_logout'), 'success');
109
+		}
110
+
111
+		redirect('/');
112
+	}
113
+
114
+	//--------------------------------------------------------------------
115
+
116
+	public function register()
117
+	{
118
+		$this->load->helper('form');
119
+
120
+		if ($this->input->post())
121
+		{
122
+			$auth = new LocalAuthentication();
123
+			$this->load->model('user_model');
124
+			$auth->useModel($this->user_model);
125
+
126
+			$post_data = [
127
+				'first_name'   => $this->input->post('first_name'),
128
+				'last_name'    => $this->input->post('last_name'),
129
+				'email'        => $this->input->post('email'),
130
+				'username'     => $this->input->post('username'),
131
+				'password'     => $this->input->post('password'),
132
+				'pass_confirm' => $this->input->post('pass_confirm')
133
+			];
134
+
135
+			if ($auth->registerUser($post_data))
136
+			{
137
+				$this->setMessage(lang('auth.did_register'), 'success');
138
+				redirect( Route::named('login') );
139
+			}
140
+			else
141
+			{
142
+				$this->setMessage($auth->error(), 'danger');
143
+			}
144
+		}
145
+
146
+		$this->addScript('register.js');
147
+		$this->themer->setLayout('login');
148
+		$this->render();
149
+	}
150
+
151
+	//--------------------------------------------------------------------
152
+
153
+	public function activate_user()
154
+	{
155
+		$this->load->helper('form');
156
+
157
+		if ($this->input->post())
158
+		{
159
+			$auth = new LocalAuthentication();
160
+			$this->load->model('user_model');
161
+			$auth->useModel($this->user_model);
162
+
163
+			$post_data = [
164
+				  'email' => $this->input->post('email'),
165
+				  'code'  => $this->input->post('code')
166
+			];
167
+
168
+			if ($auth->activateUser($post_data))
169
+			{
170
+				$this->setMessage(lang('auth.did_activate'), 'success');
171
+				redirect( Route::named('login') );
172
+			}
173
+			else
174
+			{
175
+				$this->setMessage($auth->error(), 'danger');
176
+			}
177
+		}
178
+
179
+		$data = [
180
+			'email' => $this->input->get('e'),
181
+			'code'  => $this->input->get('code')
182
+		];
183
+
184
+		$this->themer->setLayout('login');
185
+		$this->render($data);
186
+	}
187
+
188
+	//--------------------------------------------------------------------
189
+
190
+
191
+	public function forgot_password()
192
+	{
193
+		$this->load->helper('form');
194
+
195
+		if ($this->input->post())
196
+		{
197
+			$auth = new LocalAuthentication();
198
+			$this->load->model('user_model');
199
+			$auth->useModel($this->user_model);
200
+
201
+			if ($auth->remindUser($this->input->post('email')))
202
+			{
203
+				$this->setMessage(lang('auth.send_success'), 'success');
204
+				redirect( Route::named('reset_pass') );
205
+			}
206
+			else
207
+			{
208
+				$this->setMessage($auth->error(), 'danger');
209
+			}
210
+		}
211
+
212
+		$this->themer->setLayout('login');
213
+		$this->render();
214
+	}
215
+
216
+	//--------------------------------------------------------------------
217
+
218
+	public function reset_password()
219
+	{
220
+		$this->load->helper('form');
221
+
222
+		if ($this->input->post())
223
+		{
224
+			$auth = new LocalAuthentication();
225
+			$this->load->model('user_model');
226
+			$auth->useModel($this->user_model);
227
+
228
+			$credentials = [
229
+				'email' => $this->input->post('email'),
230
+				'code'  => $this->input->post('code')
231
+			];
232
+
233
+			$password     = $this->input->post('password');
234
+			$pass_confirm = $this->input->post('pass_confirm');
235
+
236
+			if ($auth->resetPassword($credentials, $password, $pass_confirm))
237
+			{
238
+				$this->setMessage(lang('auth.new_password_success'), 'success');
239
+				redirect( Route::named('login') );
240
+			}
241
+			else
242
+			{
243
+				$this->setMessage($auth->error(), 'danger');
244
+			}
245
+		}
246
+
247
+		$data = [
248
+			'email' => $this->input->get('e'),
249
+			'code'  => $this->input->get('code')
250
+		];
251
+
252
+		$this->addScript('register.js');
253
+		$this->themer->setLayout('login');
254
+		$this->render($data);
255
+	}
256
+
257
+	//--------------------------------------------------------------------
258 258
 
259 259
 	/**
260 260
 	 * Allows a logged in user to enter their current password
@@ -320,24 +320,24 @@  discard block
 block discarded – undo
320 320
 	//--------------------------------------------------------------------
321 321
 
322 322
 
323
-    //--------------------------------------------------------------------
324
-    // AJAX Methods
325
-    //--------------------------------------------------------------------
323
+	//--------------------------------------------------------------------
324
+	// AJAX Methods
325
+	//--------------------------------------------------------------------
326 326
 
327
-    /**
328
-     * Checks the password strength and returns pass/fail.
329
-     *
330
-     * @param $str
331
-     */
332
-    public function password_check($str)
333
-    {
334
-        $this->load->helper('auth/password');
327
+	/**
328
+	 * Checks the password strength and returns pass/fail.
329
+	 *
330
+	 * @param $str
331
+	 */
332
+	public function password_check($str)
333
+	{
334
+		$this->load->helper('auth/password');
335 335
 
336
-        $strength = isStrongPassword($str);
336
+		$strength = isStrongPassword($str);
337 337
 
338
-        $this->renderJSON(['status' => $strength ? 'pass' : 'fail']);
339
-    }
338
+		$this->renderJSON(['status' => $strength ? 'pass' : 'fail']);
339
+	}
340 340
 
341
-    //--------------------------------------------------------------------
341
+	//--------------------------------------------------------------------
342 342
 
343 343
 }
Please login to merge, or discard this patch.
myth/CIModules/auth/controllers/Test.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -46,7 +46,7 @@
 block discarded – undo
46 46
 	public function index($target_time = 50)
47 47
 	{
48 48
 		// Convert the milliseconds to seconds.
49
-	    $target_time = $target_time / 1000;
49
+		$target_time = $target_time / 1000;
50 50
 
51 51
 		CLI::write('Testing for password hash value with a target time of '. $target_time .' seconds...');
52 52
 
Please login to merge, or discard this patch.
myth/CIModules/auth/helpers/password_helper.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -32,28 +32,28 @@
 block discarded – undo
32 32
 
33 33
 if (! function_exists('isStrongPassword'))
34 34
 {
35
-    /**
36
-     * Works with Myth\Auth\Password to enforce a strong password.
37
-     * Uses settings from the auth config file.
38
-     *
39
-     * @param $password
40
-     */
41
-    function isStrongPassword($password)
42
-    {
43
-        $min_strength = config_item('auth.min_password_strength');
44
-        $use_dict = config_item('auth.use_dictionary');
35
+	/**
36
+	 * Works with Myth\Auth\Password to enforce a strong password.
37
+	 * Uses settings from the auth config file.
38
+	 *
39
+	 * @param $password
40
+	 */
41
+	function isStrongPassword($password)
42
+	{
43
+		$min_strength = config_item('auth.min_password_strength');
44
+		$use_dict = config_item('auth.use_dictionary');
45 45
 
46
-        $strong = \Myth\Auth\Password::isStrongPassword($password, $min_strength, $use_dict);
46
+		$strong = \Myth\Auth\Password::isStrongPassword($password, $min_strength, $use_dict);
47 47
 
48
-        if (! $strong)
49
-        {
50
-            if (isset(get_instance()->form_validation))
51
-            {
52
-                get_instance()->form_validation->set_message('isStrongPassword', lang('auth.pass_not_strong'));
53
-            }
54
-            return false;
55
-        }
48
+		if (! $strong)
49
+		{
50
+			if (isset(get_instance()->form_validation))
51
+			{
52
+				get_instance()->form_validation->set_message('isStrongPassword', lang('auth.pass_not_strong'));
53
+			}
54
+			return false;
55
+		}
56 56
 
57
-        return true;
58
-    }
57
+		return true;
58
+	}
59 59
 }
Please login to merge, or discard this patch.
myth/CIModules/auth/models/Login_model.php 1 patch
Indentation   +269 added lines, -269 removed lines patch added patch discarded remove patch
@@ -41,274 +41,274 @@
 block discarded – undo
41 41
  */
42 42
 class Login_model extends \Myth\Models\CIDbModel {
43 43
 
44
-    protected $table_name = 'auth_logins';
45
-
46
-    protected $set_created = false;
47
-    protected $set_modified = false;
48
-
49
-    //--------------------------------------------------------------------
50
-
51
-    //--------------------------------------------------------------------
52
-    // Login Attempts
53
-    //--------------------------------------------------------------------
54
-
55
-    /**
56
-     * Records a login attempt. This is used to implement
57
-     * throttling of user login attempts.
58
-     *
59
-     * @param $email
60
-     * @return object
61
-     */
62
-    public function recordLoginAttempt($email)
63
-    {
64
-        $data = [
65
-            'email' => $email,
66
-            'datetime' => date('Y-m-d H:i:s')
67
-        ];
68
-
69
-        return $this->db->insert('auth_login_attempts', $data);
70
-    }
71
-
72
-    //--------------------------------------------------------------------
73
-
74
-    /**
75
-     * Purges all login attempt records from the database.
76
-     *
77
-     * @param $email
78
-     * @return mixed
79
-     */
80
-    public function purgeLoginAttempts($email)
81
-    {
82
-        return $this->db->where('email', $email)
83
-                        ->delete('auth_login_attempts');
84
-    }
85
-
86
-    //--------------------------------------------------------------------
87
-
88
-    /**
89
-     * Checks to see if how many login attempts have been attempted in the
90
-     * last 60 seconds. If over 100, it is considered to be under a
91
-     * brute force attempt.
92
-     *
93
-     * @param $email
94
-     * @return bool
95
-     */
96
-    public function isBruteForced($email)
97
-    {
98
-        $start_time = date('Y-m-d H:i:s', time() - 60);
99
-
100
-        $attempts = $this->db->where('email', $email)
101
-                             ->where('datetime >=', $start_time)
102
-                             ->count_all_results('auth_login_attempts');
103
-
104
-        return $attempts > 100;
105
-    }
106
-
107
-    //--------------------------------------------------------------------
108
-
109
-    /**
110
-     * Attempts to determine if the system is under a distributed
111
-     * brute force attack.
112
-     *
113
-     * To determine if we are in under a brute force attack, we first
114
-     * find the average number of bad logins per day that never converted to
115
-     * successful logins over the last 3 months. Then we compare
116
-     * that to the the average number of logins in the past 24 hours.
117
-     *
118
-     * If the number of attempts in the last 24 hours is more than X (see config)
119
-     * times the average, then institute additional throttling.
120
-     *
121
-     * @return int The time to add to any throttling.
122
-     */
123
-    public function distributedBruteForceTime()
124
-    {
125
-        if (! $time = $this->cache->get('dbrutetime'))
126
-        {
127
-            $time = 0;
128
-
129
-            // Compute our daily average over the last 3 months.
130
-            $avg_start_time = date('Y-m-d 00:00:00', strtotime('-3 months'));
131
-
132
-            $query = $this->db->query("SELECT COUNT(*) / COUNT(DISTINCT DATE(`datetime`)) as num_rows FROM `auth_login_attempts` WHERE `datetime` >= ?", $avg_start_time);
133
-
134
-            if (! $query->num_rows())
135
-            {
136
-                $average = 0;
137
-            }
138
-            else
139
-            {
140
-                $average = $query->row()->num_rows;
141
-            }
142
-
143
-            // Get the total in the last 24 hours
144
-            $today_start_time = date('Y-m-d H:i:s', strtotime('-24 hours'));
145
-
146
-            $attempts = $this->db->where('datetime >=', $today_start_time)
147
-                                 ->count_all_results('auth_login_attempts');
148
-
149
-            if ($attempts > (config_item('auth.dbrute_multiplier') * $average))
150
-            {
151
-                $time = config_item('auth.distributed_brute_add_time');
152
-            }
153
-
154
-            // Cache it for 3 hours.
155
-            $this->cache->save('dbrutetime', $time, 60*60*3);
156
-        }
157
-
158
-        return $time;
159
-    }
160
-
161
-    //--------------------------------------------------------------------
162
-
163
-    //--------------------------------------------------------------------
164
-    // Logins
165
-    //--------------------------------------------------------------------
166
-
167
-    /**
168
-     * Records a successful login. This stores in a table so that a
169
-     * history can be pulled up later if needed for security analyses.
170
-     *
171
-     * @param $user
172
-     */
173
-    public function recordLogin($user)
174
-    {
175
-        $data = [
176
-            'user_id'    => (int)$user['id'],
177
-            'datetime'   => date('Y-m-d H:i:s'),
178
-            'ip_address' => $this->input->ip_address()
179
-        ];
180
-
181
-        return $this->db->insert('auth_logins', $data);
182
-    }
183
-
184
-    //--------------------------------------------------------------------
185
-
186
-    //--------------------------------------------------------------------
187
-    // Tokens
188
-    //--------------------------------------------------------------------
189
-
190
-    /**
191
-     * Generates a new token for the rememberme cookie.
192
-     *
193
-     * The token is based on the user's email address (since everyone will have one)
194
-     * with the '@' turned to a '.', followed by a pipe (|) and a random 128-character
195
-     * string with letters and numbers.
196
-     *
197
-     * @param $user
198
-     * @return mixed
199
-     */
200
-    public function generateRememberToken($user)
201
-    {
202
-        $this->load->helper('string');
203
-
204
-        return str_replace('@', '.', $user['email']) .'|' . random_string('alnum', 128);
205
-    }
206
-
207
-    //--------------------------------------------------------------------
208
-
209
-    /**
210
-     * Hashes the token for the Remember Me Functionality.
211
-     *
212
-     * @param $token
213
-     * @return string
214
-     */
215
-    public function hashRememberToken($token)
216
-    {
217
-        return sha1(config_item('auth.salt') . $token);
218
-    }
219
-
220
-    //--------------------------------------------------------------------
221
-
222
-    /**
223
-     * Deletes a single token that matches the email/token combo.
224
-     *
225
-     * @param $email
226
-     * @param $token
227
-     * @return mixed
228
-     */
229
-    public function deleteRememberToken($email, $token)
230
-    {
231
-        $where = [
232
-            'email' => $email,
233
-            'hash'  => $this->hashRememberToken($token)
234
-        ];
235
-
236
-        $this->db->delete('auth_tokens', $where);
237
-    }
238
-
239
-    //--------------------------------------------------------------------
240
-
241
-    /**
242
-     * Removes all persistent login tokens (RememberMe) for a single user
243
-     * across all devices they may have logged in with.
244
-     *
245
-     * @param $email
246
-     * @return mixed
247
-     */
248
-    public function purgeRememberTokens($email)
249
-    {
250
-        return $this->db->delete('auth_tokens', ['email' => $email]);
251
-    }
252
-
253
-    //--------------------------------------------------------------------
254
-
255
-
256
-    /**
257
-     * Purges the 'auth_tokens' table of any records that are too old
258
-     * to be of any use anymore. This equates to 1 week older than
259
-     * the remember_length set in the config file.
260
-     */
261
-    public function purgeOldRememberTokens()
262
-    {
263
-        if (! config_item('auth.allow_remembering'))
264
-        {
265
-            return;
266
-        }
267
-
268
-        $date = time() - config_item('auth.remember_length') - 604800; // 1 week
269
-        $date = date('Y-m-d 00:00:00', $date);
270
-
271
-        $this->db->where('created <=', $date)
272
-                 ->delete('auth_tokens');
273
-    }
274
-
275
-    //--------------------------------------------------------------------
276
-
277
-    /**
278
-     * Gets the timestamp of the last attempted login for this user.
279
-     *
280
-     * @param $email
281
-     * @return int|null
282
-     */
283
-    public function lastLoginAttemptTime($email)
284
-    {
285
-        $query = $this->db->where('email', $email)
286
-                          ->order_by('datetime', 'desc')
287
-                          ->limit(1)
288
-                          ->get('auth_login_attempts');
289
-
290
-        if (! $query->num_rows())
291
-        {
292
-            return 0;
293
-        }
294
-
295
-        return strtotime($query->row()->datetime);
296
-    }
297
-
298
-    //--------------------------------------------------------------------
299
-
300
-    /**
301
-     * Returns the number of failed login attempts for a single email.
302
-     *
303
-     * @param $email
304
-     * @return int
305
-     */
306
-    public function countLoginAttempts($email)
307
-    {
308
-        return $this->db->where('email', $email)
309
-                        ->count_all_results('auth_login_attempts');
310
-    }
311
-
312
-    //--------------------------------------------------------------------
44
+	protected $table_name = 'auth_logins';
45
+
46
+	protected $set_created = false;
47
+	protected $set_modified = false;
48
+
49
+	//--------------------------------------------------------------------
50
+
51
+	//--------------------------------------------------------------------
52
+	// Login Attempts
53
+	//--------------------------------------------------------------------
54
+
55
+	/**
56
+	 * Records a login attempt. This is used to implement
57
+	 * throttling of user login attempts.
58
+	 *
59
+	 * @param $email
60
+	 * @return object
61
+	 */
62
+	public function recordLoginAttempt($email)
63
+	{
64
+		$data = [
65
+			'email' => $email,
66
+			'datetime' => date('Y-m-d H:i:s')
67
+		];
68
+
69
+		return $this->db->insert('auth_login_attempts', $data);
70
+	}
71
+
72
+	//--------------------------------------------------------------------
73
+
74
+	/**
75
+	 * Purges all login attempt records from the database.
76
+	 *
77
+	 * @param $email
78
+	 * @return mixed
79
+	 */
80
+	public function purgeLoginAttempts($email)
81
+	{
82
+		return $this->db->where('email', $email)
83
+						->delete('auth_login_attempts');
84
+	}
85
+
86
+	//--------------------------------------------------------------------
87
+
88
+	/**
89
+	 * Checks to see if how many login attempts have been attempted in the
90
+	 * last 60 seconds. If over 100, it is considered to be under a
91
+	 * brute force attempt.
92
+	 *
93
+	 * @param $email
94
+	 * @return bool
95
+	 */
96
+	public function isBruteForced($email)
97
+	{
98
+		$start_time = date('Y-m-d H:i:s', time() - 60);
99
+
100
+		$attempts = $this->db->where('email', $email)
101
+							 ->where('datetime >=', $start_time)
102
+							 ->count_all_results('auth_login_attempts');
103
+
104
+		return $attempts > 100;
105
+	}
106
+
107
+	//--------------------------------------------------------------------
108
+
109
+	/**
110
+	 * Attempts to determine if the system is under a distributed
111
+	 * brute force attack.
112
+	 *
113
+	 * To determine if we are in under a brute force attack, we first
114
+	 * find the average number of bad logins per day that never converted to
115
+	 * successful logins over the last 3 months. Then we compare
116
+	 * that to the the average number of logins in the past 24 hours.
117
+	 *
118
+	 * If the number of attempts in the last 24 hours is more than X (see config)
119
+	 * times the average, then institute additional throttling.
120
+	 *
121
+	 * @return int The time to add to any throttling.
122
+	 */
123
+	public function distributedBruteForceTime()
124
+	{
125
+		if (! $time = $this->cache->get('dbrutetime'))
126
+		{
127
+			$time = 0;
128
+
129
+			// Compute our daily average over the last 3 months.
130
+			$avg_start_time = date('Y-m-d 00:00:00', strtotime('-3 months'));
131
+
132
+			$query = $this->db->query("SELECT COUNT(*) / COUNT(DISTINCT DATE(`datetime`)) as num_rows FROM `auth_login_attempts` WHERE `datetime` >= ?", $avg_start_time);
133
+
134
+			if (! $query->num_rows())
135
+			{
136
+				$average = 0;
137
+			}
138
+			else
139
+			{
140
+				$average = $query->row()->num_rows;
141
+			}
142
+
143
+			// Get the total in the last 24 hours
144
+			$today_start_time = date('Y-m-d H:i:s', strtotime('-24 hours'));
145
+
146
+			$attempts = $this->db->where('datetime >=', $today_start_time)
147
+								 ->count_all_results('auth_login_attempts');
148
+
149
+			if ($attempts > (config_item('auth.dbrute_multiplier') * $average))
150
+			{
151
+				$time = config_item('auth.distributed_brute_add_time');
152
+			}
153
+
154
+			// Cache it for 3 hours.
155
+			$this->cache->save('dbrutetime', $time, 60*60*3);
156
+		}
157
+
158
+		return $time;
159
+	}
160
+
161
+	//--------------------------------------------------------------------
162
+
163
+	//--------------------------------------------------------------------
164
+	// Logins
165
+	//--------------------------------------------------------------------
166
+
167
+	/**
168
+	 * Records a successful login. This stores in a table so that a
169
+	 * history can be pulled up later if needed for security analyses.
170
+	 *
171
+	 * @param $user
172
+	 */
173
+	public function recordLogin($user)
174
+	{
175
+		$data = [
176
+			'user_id'    => (int)$user['id'],
177
+			'datetime'   => date('Y-m-d H:i:s'),
178
+			'ip_address' => $this->input->ip_address()
179
+		];
180
+
181
+		return $this->db->insert('auth_logins', $data);
182
+	}
183
+
184
+	//--------------------------------------------------------------------
185
+
186
+	//--------------------------------------------------------------------
187
+	// Tokens
188
+	//--------------------------------------------------------------------
189
+
190
+	/**
191
+	 * Generates a new token for the rememberme cookie.
192
+	 *
193
+	 * The token is based on the user's email address (since everyone will have one)
194
+	 * with the '@' turned to a '.', followed by a pipe (|) and a random 128-character
195
+	 * string with letters and numbers.
196
+	 *
197
+	 * @param $user
198
+	 * @return mixed
199
+	 */
200
+	public function generateRememberToken($user)
201
+	{
202
+		$this->load->helper('string');
203
+
204
+		return str_replace('@', '.', $user['email']) .'|' . random_string('alnum', 128);
205
+	}
206
+
207
+	//--------------------------------------------------------------------
208
+
209
+	/**
210
+	 * Hashes the token for the Remember Me Functionality.
211
+	 *
212
+	 * @param $token
213
+	 * @return string
214
+	 */
215
+	public function hashRememberToken($token)
216
+	{
217
+		return sha1(config_item('auth.salt') . $token);
218
+	}
219
+
220
+	//--------------------------------------------------------------------
221
+
222
+	/**
223
+	 * Deletes a single token that matches the email/token combo.
224
+	 *
225
+	 * @param $email
226
+	 * @param $token
227
+	 * @return mixed
228
+	 */
229
+	public function deleteRememberToken($email, $token)
230
+	{
231
+		$where = [
232
+			'email' => $email,
233
+			'hash'  => $this->hashRememberToken($token)
234
+		];
235
+
236
+		$this->db->delete('auth_tokens', $where);
237
+	}
238
+
239
+	//--------------------------------------------------------------------
240
+
241
+	/**
242
+	 * Removes all persistent login tokens (RememberMe) for a single user
243
+	 * across all devices they may have logged in with.
244
+	 *
245
+	 * @param $email
246
+	 * @return mixed
247
+	 */
248
+	public function purgeRememberTokens($email)
249
+	{
250
+		return $this->db->delete('auth_tokens', ['email' => $email]);
251
+	}
252
+
253
+	//--------------------------------------------------------------------
254
+
255
+
256
+	/**
257
+	 * Purges the 'auth_tokens' table of any records that are too old
258
+	 * to be of any use anymore. This equates to 1 week older than
259
+	 * the remember_length set in the config file.
260
+	 */
261
+	public function purgeOldRememberTokens()
262
+	{
263
+		if (! config_item('auth.allow_remembering'))
264
+		{
265
+			return;
266
+		}
267
+
268
+		$date = time() - config_item('auth.remember_length') - 604800; // 1 week
269
+		$date = date('Y-m-d 00:00:00', $date);
270
+
271
+		$this->db->where('created <=', $date)
272
+				 ->delete('auth_tokens');
273
+	}
274
+
275
+	//--------------------------------------------------------------------
276
+
277
+	/**
278
+	 * Gets the timestamp of the last attempted login for this user.
279
+	 *
280
+	 * @param $email
281
+	 * @return int|null
282
+	 */
283
+	public function lastLoginAttemptTime($email)
284
+	{
285
+		$query = $this->db->where('email', $email)
286
+						  ->order_by('datetime', 'desc')
287
+						  ->limit(1)
288
+						  ->get('auth_login_attempts');
289
+
290
+		if (! $query->num_rows())
291
+		{
292
+			return 0;
293
+		}
294
+
295
+		return strtotime($query->row()->datetime);
296
+	}
297
+
298
+	//--------------------------------------------------------------------
299
+
300
+	/**
301
+	 * Returns the number of failed login attempts for a single email.
302
+	 *
303
+	 * @param $email
304
+	 * @return int
305
+	 */
306
+	public function countLoginAttempts($email)
307
+	{
308
+		return $this->db->where('email', $email)
309
+						->count_all_results('auth_login_attempts');
310
+	}
311
+
312
+	//--------------------------------------------------------------------
313 313
 
314 314
 }
Please login to merge, or discard this patch.
myth/CIModules/cron/controllers/Cron.php 1 patch
Indentation   +304 added lines, -304 removed lines patch added patch discarded remove patch
@@ -37,325 +37,325 @@
 block discarded – undo
37 37
 // todo Add ability to log actual cron jobs to database to verify when they ran for sure.
38 38
 class Cron extends \Myth\Controllers\CLIController {
39 39
 
40
-    protected $descriptions = [
41
-        'show'  => ['show [all/<task>]', 'Lists the names one or more tasks, with run times.'],
42
-        'run'   => ['run [<task>]', 'Runs all scheduled tasks. If <task> is present only runs that task.'],
43
-        'disable'   => ['disable', 'Disables the cron system and will not run any tasks.'],
44
-        'enable'    => ['enable', 'Enables the cron system and will run tasks again.'],
45
-        'suspend'   => ['suspend <task>', 'Stops a single task from running until resumed.'],
46
-        'resume'    => ['resume <task>', 'Resumes execution of a single suspended task.']
47
-    ];
48
-
49
-    protected $long_descriptions = [
50
-        'show'  => '',
51
-        'run'   => '',
52
-        'disable'   => '',
53
-        'enable'    => '',
54
-        'suspend'   => '',
55
-        'resume'    => ''
56
-    ];
57
-
58
-    //--------------------------------------------------------------------
59
-
60
-    public function __construct()
61
-    {
62
-        parent::__construct();
63
-
64
-        // Load our tasks into the sytem.
65
-        require APPPATH .'config/cron.php';
66
-    }
67
-
68
-    //--------------------------------------------------------------------
69
-
70
-    /**
71
-     * Runs all of the tasks (after checking their time, of course...)
72
-     *
73
-     * @param string $alias
74
-     * @return mixed
75
-     */
76
-    public function run($alias=null)
77
-    {
78
-        // Has the system been disabled?
79
-        if (Settings::get('is_disabled', 'cron') == 'y')
80
-        {
81
-            return CLI::error('The cron system has been disabled. No tasks were run.');
82
-        }
83
-
84
-        $force_run = false;
85
-
86
-        // Run one task or all?
87
-        if (! empty($alias))
88
-        {
89
-            $tasks = \Myth\Cron\CronManager::task($alias);
90
-
91
-            if (is_null($tasks))
92
-            {
93
-                return CLI::error("Unable to find the task: '{$alias}'.");
94
-            }
95
-
96
-            $tasks = [ $alias => $tasks];
97
-            $force_run = true;
98
-        }
99
-        else
100
-        {
101
-            $tasks = \Myth\Cron\CronManager::tasks();
102
-        }
103
-
104
-        if (empty($tasks))
105
-        {
106
-            return CLI::write("There are no tasks to run at this time.");
107
-        }
108
-
109
-        // We need to be able to check against suspended tasks.
110
-        $suspended = Settings::get('suspended_tasks', 'cron');
111
-
112
-        if (! is_array($suspended))
113
-        {
114
-            $suspended = array($suspended);
115
-        }
116
-
117
-        // Loop over all of our tasks, checking them against the
118
-        // suspended tasks to see if they're okay to run.
119
-
120
-        // Collect the output of the actions so that we can make
121
-        // it available to the event (for sending emails and the like)
122
-        $output = '';
123
-
124
-        echo CLI::write('Starting Tasks...');
125
-
126
-        foreach ($tasks as $alias => $task)
127
-        {
128
-            if (in_array($alias, $suspended))
129
-            {
130
-                echo CLI::write("\t[Suspended] {$alias} will not run until resumed.", 'yellow');
131
-                $output .= "[Suspended] {$alias} will not run until resumed.";
132
-                continue;
133
-            }
134
-
135
-            echo CLI::write("\tRunning task: {$alias}...");
136
-            $output .= \Myth\Cron\CronManager::run($alias, $force_run);
137
-        }
138
-
139
-        // Give other people a chance to respond.
140
-        echo CLI::write('Done. Firing the event so others can play too...');
141
-
142
-        Events::trigger('afterCron', [$output]);
143
-
144
-        // And we're out of here boys and girls!
145
-        echo CLI::write('Done');
146
-    }
147
-
148
-    //--------------------------------------------------------------------
149
-
150
-
151
-    /**
152
-     * Lists one or more tasks with their scheduled run times.
153
-     *
154
-     * @param null $task
155
-     * @return mixed
156
-     */
157
-    public function show($task=null)
158
-    {
159
-        if (empty($task))
160
-        {
161
-            return $this->listTaskNames();
162
-        }
163
-
164
-        if (trim(strtolower($task)) == 'all')
165
-        {
166
-            $tasks = \Myth\Cron\CronManager::listAll();
167
-        }
168
-        else
169
-        {
170
-            $tasks = \Myth\Cron\CronManager::task($task);
171
-        }
172
-
173
-        if (! is_array($tasks))
174
-        {
175
-            $tasks = [ $task => [
176
-                'next_run'  => $tasks->nextRunDate(),
177
-                'prev_run'  => $tasks->previousRunDate()
178
-            ]];
179
-        }
180
-
181
-        if (! count($tasks))
182
-        {
183
-            return CLI::found('No tasks found.', 'red');
184
-        }
185
-
186
-        $suspended = Settings::get('suspended_tasks', 'cron');
187
-
188
-        if (empty($suspended))
189
-        {
190
-            $suspended = [];
191
-        }
192
-        /*
40
+	protected $descriptions = [
41
+		'show'  => ['show [all/<task>]', 'Lists the names one or more tasks, with run times.'],
42
+		'run'   => ['run [<task>]', 'Runs all scheduled tasks. If <task> is present only runs that task.'],
43
+		'disable'   => ['disable', 'Disables the cron system and will not run any tasks.'],
44
+		'enable'    => ['enable', 'Enables the cron system and will run tasks again.'],
45
+		'suspend'   => ['suspend <task>', 'Stops a single task from running until resumed.'],
46
+		'resume'    => ['resume <task>', 'Resumes execution of a single suspended task.']
47
+	];
48
+
49
+	protected $long_descriptions = [
50
+		'show'  => '',
51
+		'run'   => '',
52
+		'disable'   => '',
53
+		'enable'    => '',
54
+		'suspend'   => '',
55
+		'resume'    => ''
56
+	];
57
+
58
+	//--------------------------------------------------------------------
59
+
60
+	public function __construct()
61
+	{
62
+		parent::__construct();
63
+
64
+		// Load our tasks into the sytem.
65
+		require APPPATH .'config/cron.php';
66
+	}
67
+
68
+	//--------------------------------------------------------------------
69
+
70
+	/**
71
+	 * Runs all of the tasks (after checking their time, of course...)
72
+	 *
73
+	 * @param string $alias
74
+	 * @return mixed
75
+	 */
76
+	public function run($alias=null)
77
+	{
78
+		// Has the system been disabled?
79
+		if (Settings::get('is_disabled', 'cron') == 'y')
80
+		{
81
+			return CLI::error('The cron system has been disabled. No tasks were run.');
82
+		}
83
+
84
+		$force_run = false;
85
+
86
+		// Run one task or all?
87
+		if (! empty($alias))
88
+		{
89
+			$tasks = \Myth\Cron\CronManager::task($alias);
90
+
91
+			if (is_null($tasks))
92
+			{
93
+				return CLI::error("Unable to find the task: '{$alias}'.");
94
+			}
95
+
96
+			$tasks = [ $alias => $tasks];
97
+			$force_run = true;
98
+		}
99
+		else
100
+		{
101
+			$tasks = \Myth\Cron\CronManager::tasks();
102
+		}
103
+
104
+		if (empty($tasks))
105
+		{
106
+			return CLI::write("There are no tasks to run at this time.");
107
+		}
108
+
109
+		// We need to be able to check against suspended tasks.
110
+		$suspended = Settings::get('suspended_tasks', 'cron');
111
+
112
+		if (! is_array($suspended))
113
+		{
114
+			$suspended = array($suspended);
115
+		}
116
+
117
+		// Loop over all of our tasks, checking them against the
118
+		// suspended tasks to see if they're okay to run.
119
+
120
+		// Collect the output of the actions so that we can make
121
+		// it available to the event (for sending emails and the like)
122
+		$output = '';
123
+
124
+		echo CLI::write('Starting Tasks...');
125
+
126
+		foreach ($tasks as $alias => $task)
127
+		{
128
+			if (in_array($alias, $suspended))
129
+			{
130
+				echo CLI::write("\t[Suspended] {$alias} will not run until resumed.", 'yellow');
131
+				$output .= "[Suspended] {$alias} will not run until resumed.";
132
+				continue;
133
+			}
134
+
135
+			echo CLI::write("\tRunning task: {$alias}...");
136
+			$output .= \Myth\Cron\CronManager::run($alias, $force_run);
137
+		}
138
+
139
+		// Give other people a chance to respond.
140
+		echo CLI::write('Done. Firing the event so others can play too...');
141
+
142
+		Events::trigger('afterCron', [$output]);
143
+
144
+		// And we're out of here boys and girls!
145
+		echo CLI::write('Done');
146
+	}
147
+
148
+	//--------------------------------------------------------------------
149
+
150
+
151
+	/**
152
+	 * Lists one or more tasks with their scheduled run times.
153
+	 *
154
+	 * @param null $task
155
+	 * @return mixed
156
+	 */
157
+	public function show($task=null)
158
+	{
159
+		if (empty($task))
160
+		{
161
+			return $this->listTaskNames();
162
+		}
163
+
164
+		if (trim(strtolower($task)) == 'all')
165
+		{
166
+			$tasks = \Myth\Cron\CronManager::listAll();
167
+		}
168
+		else
169
+		{
170
+			$tasks = \Myth\Cron\CronManager::task($task);
171
+		}
172
+
173
+		if (! is_array($tasks))
174
+		{
175
+			$tasks = [ $task => [
176
+				'next_run'  => $tasks->nextRunDate(),
177
+				'prev_run'  => $tasks->previousRunDate()
178
+			]];
179
+		}
180
+
181
+		if (! count($tasks))
182
+		{
183
+			return CLI::found('No tasks found.', 'red');
184
+		}
185
+
186
+		$suspended = Settings::get('suspended_tasks', 'cron');
187
+
188
+		if (empty($suspended))
189
+		{
190
+			$suspended = [];
191
+		}
192
+		/*
193 193
          * Headers
194 194
          */
195
-        echo CLI::write("Task\t\t\t\tNext Run\t\tPrevious Run");
196
-        echo CLI::write( str_repeat('-', 80) );
197
-
198
-        foreach ($tasks as $alias => $task)
199
-        {
200
-            // Suspended?
201
-            $color = 'yellow';
202
-            $extra = '';
203
-
204
-            if (in_array($alias, $suspended) )
205
-            {
206
-                $color = 'blue';
207
-                $extra = "\t[Suspended]";
208
-            }
209
-
210
-            // Alias can only be 24 chars long.
211
-            $alias = strlen($alias) >= 32 ? substr($alias, 0, 28) .'... ' : $alias . str_repeat(" ", 32 - strlen($alias));
212
-
213
-            $next = date('D Y-m-d H:i', $task['next_run']);
214
-            $prev = date('D Y-m-d H:i', $task['prev_run']);
215
-
216
-            echo CLI::write("{$alias}{$next}\t{$prev}{$extra}", $color);
217
-        }
218
-    }
219
-
220
-    //--------------------------------------------------------------------
221
-
222
-    /**
223
-     * Stops a task from being executed during the normal cron runs.
224
-     *
225
-     * @param $alias
226
-     */
227
-    public function suspend($alias)
228
-    {
229
-        // Verify the task actually exists.
230
-        $task = \Myth\Cron\CronManager::task($alias);
231
-
232
-        if (is_null($task))
233
-        {
234
-            return CLI::error("Unable to find the task: {$alias}.");
235
-        }
236
-
237
-        // Update the existing setting.
238
-        $suspended = Settings::get('suspended_tasks', 'cron');
239
-
240
-        if (empty($suspended))
241
-        {
242
-            $suspended = [];
243
-        }
244
-
245
-        $suspended[] = $alias;
246
-
247
-        if (Settings::save('suspended_tasks', $suspended, 'cron') )
248
-        {
249
-            return CLI::write('Done');
250
-        }
251
-
252
-        echo CLI::error('Unkown problem saving the settings.');
253
-    }
254
-
255
-    //--------------------------------------------------------------------
256
-
257
-    /**
258
-     * Allows the execution of a suspended task to continue again
259
-     * during normal cron execution.
260
-     *
261
-     * @param $alias
262
-     */
263
-    public function resume($alias)
264
-    {
265
-        // Verify the task actually exists.
266
-        $task = \Myth\Cron\CronManager::task($alias);
267
-
268
-        if (is_null($task))
269
-        {
270
-            return CLI::error("Unable to find the task: {$alias}.");
271
-        }
272
-
273
-        // Update the existing setting.
274
-        $suspended = Settings::get('suspended_tasks', 'cron');
275
-
276
-        if (! empty($suspended))
277
-        {
278
-            unset($suspended[ array_search($alias, $suspended) ]);
279
-
280
-            if (! Settings::save('suspended_tasks', $suspended, 'cron') )
281
-            {
282
-                return CLI::error('Unkown problem saving the settings.');
283
-            }
284
-        }
285
-
286
-        return CLI::write('Done');
287
-    }
288
-
289
-    //--------------------------------------------------------------------
290
-
291
-    /**
292
-     * Disables the cron tasks and stops the system from running any tasks.
293
-     * To start the system allowing it to run again, use the `enable` command.
294
-     */
295
-    public function disable()
296
-    {
297
-        if (! Settings::save('is_disabled', 'y', 'cron'))
298
-        {
299
-            return CLI::error('Unknown problem saving the setting. '. CLI::color('Cron jobs will still run!', 'yellow'));
300
-        }
301
-
302
-        CLI::write('Done');
303
-    }
195
+		echo CLI::write("Task\t\t\t\tNext Run\t\tPrevious Run");
196
+		echo CLI::write( str_repeat('-', 80) );
197
+
198
+		foreach ($tasks as $alias => $task)
199
+		{
200
+			// Suspended?
201
+			$color = 'yellow';
202
+			$extra = '';
203
+
204
+			if (in_array($alias, $suspended) )
205
+			{
206
+				$color = 'blue';
207
+				$extra = "\t[Suspended]";
208
+			}
209
+
210
+			// Alias can only be 24 chars long.
211
+			$alias = strlen($alias) >= 32 ? substr($alias, 0, 28) .'... ' : $alias . str_repeat(" ", 32 - strlen($alias));
212
+
213
+			$next = date('D Y-m-d H:i', $task['next_run']);
214
+			$prev = date('D Y-m-d H:i', $task['prev_run']);
215
+
216
+			echo CLI::write("{$alias}{$next}\t{$prev}{$extra}", $color);
217
+		}
218
+	}
219
+
220
+	//--------------------------------------------------------------------
221
+
222
+	/**
223
+	 * Stops a task from being executed during the normal cron runs.
224
+	 *
225
+	 * @param $alias
226
+	 */
227
+	public function suspend($alias)
228
+	{
229
+		// Verify the task actually exists.
230
+		$task = \Myth\Cron\CronManager::task($alias);
231
+
232
+		if (is_null($task))
233
+		{
234
+			return CLI::error("Unable to find the task: {$alias}.");
235
+		}
236
+
237
+		// Update the existing setting.
238
+		$suspended = Settings::get('suspended_tasks', 'cron');
239
+
240
+		if (empty($suspended))
241
+		{
242
+			$suspended = [];
243
+		}
244
+
245
+		$suspended[] = $alias;
246
+
247
+		if (Settings::save('suspended_tasks', $suspended, 'cron') )
248
+		{
249
+			return CLI::write('Done');
250
+		}
251
+
252
+		echo CLI::error('Unkown problem saving the settings.');
253
+	}
254
+
255
+	//--------------------------------------------------------------------
256
+
257
+	/**
258
+	 * Allows the execution of a suspended task to continue again
259
+	 * during normal cron execution.
260
+	 *
261
+	 * @param $alias
262
+	 */
263
+	public function resume($alias)
264
+	{
265
+		// Verify the task actually exists.
266
+		$task = \Myth\Cron\CronManager::task($alias);
267
+
268
+		if (is_null($task))
269
+		{
270
+			return CLI::error("Unable to find the task: {$alias}.");
271
+		}
272
+
273
+		// Update the existing setting.
274
+		$suspended = Settings::get('suspended_tasks', 'cron');
275
+
276
+		if (! empty($suspended))
277
+		{
278
+			unset($suspended[ array_search($alias, $suspended) ]);
279
+
280
+			if (! Settings::save('suspended_tasks', $suspended, 'cron') )
281
+			{
282
+				return CLI::error('Unkown problem saving the settings.');
283
+			}
284
+		}
285
+
286
+		return CLI::write('Done');
287
+	}
288
+
289
+	//--------------------------------------------------------------------
290
+
291
+	/**
292
+	 * Disables the cron tasks and stops the system from running any tasks.
293
+	 * To start the system allowing it to run again, use the `enable` command.
294
+	 */
295
+	public function disable()
296
+	{
297
+		if (! Settings::save('is_disabled', 'y', 'cron'))
298
+		{
299
+			return CLI::error('Unknown problem saving the setting. '. CLI::color('Cron jobs will still run!', 'yellow'));
300
+		}
301
+
302
+		CLI::write('Done');
303
+	}
304 304
     
305
-    //--------------------------------------------------------------------
305
+	//--------------------------------------------------------------------
306 306
 
307
-    /**
308
-     * Resumes the running of tasks after the system has been disabled
309
-     * with the `disable` command.
310
-     */
311
-    public function enable()
312
-    {
313
-        if (! Settings::save('is_disabled', 'n', 'cron'))
314
-        {
315
-            return CLI::error('Unknown problem saving the setting. '. CLI::color('Cron jobs will NOT run!', 'yellow'));
316
-        }
307
+	/**
308
+	 * Resumes the running of tasks after the system has been disabled
309
+	 * with the `disable` command.
310
+	 */
311
+	public function enable()
312
+	{
313
+		if (! Settings::save('is_disabled', 'n', 'cron'))
314
+		{
315
+			return CLI::error('Unknown problem saving the setting. '. CLI::color('Cron jobs will NOT run!', 'yellow'));
316
+		}
317 317
 
318
-        CLI::write('Done');
319
-    }
318
+		CLI::write('Done');
319
+	}
320 320
 
321
-    //--------------------------------------------------------------------
321
+	//--------------------------------------------------------------------
322 322
 
323 323
 
324
-    //--------------------------------------------------------------------
325
-    // Private Methods
326
-    //--------------------------------------------------------------------
324
+	//--------------------------------------------------------------------
325
+	// Private Methods
326
+	//--------------------------------------------------------------------
327 327
 
328
-    /**
329
-     * Lists out all available tasks, names only.
330
-     */
331
-    private function listTaskNames()
332
-    {
333
-        $suspended = Settings::get('suspended_tasks', 'cron');
328
+	/**
329
+	 * Lists out all available tasks, names only.
330
+	 */
331
+	private function listTaskNames()
332
+	{
333
+		$suspended = Settings::get('suspended_tasks', 'cron');
334 334
 
335
-        if (empty($suspended))
336
-        {
337
-            $suspended = [];
338
-        }
335
+		if (empty($suspended))
336
+		{
337
+			$suspended = [];
338
+		}
339 339
 
340
-        $tasks = \Myth\Cron\CronManager::listAll();
340
+		$tasks = \Myth\Cron\CronManager::listAll();
341 341
 
342
-        echo CLI::write("\nAvailable Tasks:");
342
+		echo CLI::write("\nAvailable Tasks:");
343 343
 
344
-        foreach ($tasks as $alias => $task)
345
-        {
346
-            $color = 'yellow';
347
-            $extra = '';
344
+		foreach ($tasks as $alias => $task)
345
+		{
346
+			$color = 'yellow';
347
+			$extra = '';
348 348
 
349
-            if (in_array($alias, $suspended) )
350
-            {
351
-                $color = 'blue';
352
-                $extra = "[Suspended]";
353
-            }
349
+			if (in_array($alias, $suspended) )
350
+			{
351
+				$color = 'blue';
352
+				$extra = "[Suspended]";
353
+			}
354 354
 
355
-            echo CLI::write("\t{$extra} {$alias}", $color);
356
-        }
357
-    }
355
+			echo CLI::write("\t{$extra} {$alias}", $color);
356
+		}
357
+	}
358 358
 
359
-    //--------------------------------------------------------------------
359
+	//--------------------------------------------------------------------
360 360
 
361 361
 }
Please login to merge, or discard this patch.
myth/CIModules/database/controllers/Database.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -35,207 +35,207 @@  discard block
 block discarded – undo
35 35
 class Database extends \Myth\Controllers\CLIController
36 36
 {
37 37
 
38
-    protected $descriptions = [
39
-        'migrate'       => ['migrate [$to]',        'Runs the migrations up or down until schema at version \$to'],
40
-        'quietMigrate'  => ['quiteMigrate [$to]',   'Same as migrate but without any feedback.'],
41
-        'refresh'       => ['refresh',              'Runs migrations back to version 0 (uninstall) and then back to the most recent migration.'],
42
-        'newMigration'  => ['newMigration [$name]', 'Creates a new migration file.'],
43
-        'seed'          => ['seed [$name]',         'Runs the named database seeder.']
44
-    ];
45
-
46
-    protected $long_descriptions = [
47
-        'migrate'       => '',
48
-        'quietMigrate'  => '',
49
-        'refresh'       => '',
50
-        'newMigration'  => '',
51
-        'seed'          => ''
52
-    ];
53
-
54
-    //-------------------------------------------------------------------
55
-
56
-    //--------------------------------------------------------------------
57
-    // Migration Methods
58
-    //--------------------------------------------------------------------
59
-
60
-    /**
61
-     * Provides a command-line interface to the migration scripts.
62
-     * If no $to is provided, will migrate to the latest version.
63
-     *
64
-     * Example:
65
-     *      > php index.php database migrate
66
-     *
67
-     * @param string $type 'app', 'myth', 'all' or {module_name}
68
-     * @param null $to
69
-     * @param bool $silent If TRUE, will NOT display any prompts for verification.
70
-     * @return bool|void
71
-     */
72
-    public function migrate($type=null, $to = null, $silent = false)
73
-    {
74
-        $this->load->library('migration');
75
-
76
-        if (empty($type))
77
-        {
78
-            $type = CLI::prompt("Migration group to refresh?", $this->migration->default_migration_path());
79
-
80
-            if (empty($type))
81
-            {
82
-                return $silent ? false : CLI::error("\tYou must supply a group to refresh.");
83
-            }
84
-        }
85
-
86
-        // We need to append 'mod:' to properly handle modules, if
87
-        // the $type is not one of the recognized migration groups.
88
-        $this->config->load('migration');
89
-        $groups = config_item('migration_paths');
90
-        $groups = array_keys($groups);
91
-
92
-        // If it's not in the groups list, then assume it's a module.
93
-        if (! in_array($type, $groups))
94
-        {
95
-            if (strpos($type, 'mod:') !== 0)
96
-            {
97
-                $type = 'mod:'. $type;
98
-            }
99
-        }
100
-
101
-        unset($groups);
102
-
103
-        // Get our stats on the migrations
104
-        $latest = $this->migration->get_latest($type);
105
-        $latest = empty($latest) ? 0 : substr($latest, 0, strpos($latest, '_'));
106
-
107
-        if (empty($latest)) {
108
-            return CLI::write("\tNo migrations found.", 'yellow');
109
-        }
110
-
111
-        $current = $this->migration->get_version($type);
112
-
113
-        // Already at the desired version?
114
-        if ((! is_null($to) && $current == $to) OR (is_null($to) && $current == $latest))
115
-        {
116
-            return $silent ? true : CLI::write("\tDatabase is already at the desired version ({$current})", 'yellow');
117
-        }
118
-
119
-        $target = is_null($to) ? $latest : $to;
120
-
121
-        // Just to be safe, verify with the user they want to migrate
122
-        // to the latest version.
123
-        if (is_null($to)) {
124
-            // If we're in silent mode, don't prompt, just go to the latest...
125
-            if (! $silent) {
126
-                $go_ahead = CLI::prompt('Migrate to the latest available version?', array('y', 'n'));
127
-
128
-                if ($go_ahead == 'n') {
129
-                    return CLI::write('Bailing...', 'yellow');
130
-                }
131
-            }
132
-
133
-            if (! $this->migration->latest($type)) {
134
-                return CLI::error("\n\tERROR: " . $this->migration->error_string() . "\n");
135
-            }
136
-        } else {
137
-            if ($this->migration->version($type, $to) === false) {
138
-                return CLI::error("\n\tERROR: " . $this->migration->error_string() . "\n");
139
-            }
140
-        }
141
-
142
-        return $silent ? true :
143
-            CLI::write("\n\tSuccessfully migrated database from version {$current} to {$target}.\n", 'green');
144
-    }
145
-
146
-    //--------------------------------------------------------------------
147
-
148
-    /**
149
-     * Performs a migration that does not prompt for any information.
150
-     * Suitable for use within automated scripts that can't be
151
-     * bothered with answering questions.
152
-     *
153
-     * @param string $type 'app', 'myth', 'all' or {module_name}
154
-     * @param null $to
155
-     * @return bool|void
156
-     */
157
-    public function quietMigrate($type='app', $to = null)
158
-    {
159
-        return $this->migrate($type, $to, true);
160
-    }
161
-
162
-    //--------------------------------------------------------------------
163
-
164
-
165
-    /**
166
-     * Migrates the database back to 0, then back up to the latest version.
167
-     *
168
-     * @param string $type  The group or module to refresh.
169
-     * @return mixed
170
-     */
171
-    public function refresh($type=null)
172
-    {
173
-        $this->load->library('migration');
174
-
175
-        if (empty($type))
176
-        {
177
-            $type = CLI::prompt("Migration group to refresh?", $this->migration->default_migration_path());
178
-
179
-            if (empty($type))
180
-            {
181
-                return CLI::error("\tYou must supply a group to refresh.");
182
-            }
183
-        }
184
-
185
-        if ($this->migration->version($type, 0) === false) {
186
-            return CLI::error("\tERROR: " . $this->migration->error_string());
187
-        }
188
-
189
-        CLI::write(CLI::color("\tCleared the database.", 'green'));
190
-
191
-        if ($this->migration->latest($type) === false) {
192
-            return CLI::error("\tERROR: " . $this->migration->error_string());
193
-        }
194
-
195
-        CLI::write("\tRe-installed the database to the latest migration.", 'green');
196
-    }
197
-
198
-    //--------------------------------------------------------------------
199
-
200
-    /**
201
-     * Creates a new migration file ready to be used.
202
-     *
203
-     * @param $name
204
-     */
205
-    public function newMigration($name = null, $type = 'app')
206
-    {
207
-        if (empty($name)) {
208
-            $name = CLI::prompt('Migration name? ');
209
-
210
-            if (empty($name)) {
211
-                return CLI::error("\tYou must provide a migration name.", 'red');
212
-            }
213
-        }
214
-
215
-        $this->load->library('migration');
216
-
217
-        $path = $this->migration->determine_migration_path($type);
218
-
219
-        // Does the alias path exist in our config?
220
-        if (! $path) {
221
-            return CLI::error("\tThe migration path for '{$type}' does not exist.'");
222
-        }
223
-
224
-        // Does the path really exist?
225
-        if (! is_dir($path)) {
226
-            return CLI::error("\tThe path for '{$type}' is not a directory.");
227
-        }
228
-
229
-        // Is the folder writeable?
230
-        if (! is_writeable($path)) {
231
-            return CLI::error("\tThe folder for '{$type}' migrations is not writeable.");
232
-        }
233
-
234
-        $file = $this->migration->make_name($name);
235
-
236
-        $path = rtrim($path, '/') .'/'. $file;
237
-
238
-        $contents = <<<EOT
38
+	protected $descriptions = [
39
+		'migrate'       => ['migrate [$to]',        'Runs the migrations up or down until schema at version \$to'],
40
+		'quietMigrate'  => ['quiteMigrate [$to]',   'Same as migrate but without any feedback.'],
41
+		'refresh'       => ['refresh',              'Runs migrations back to version 0 (uninstall) and then back to the most recent migration.'],
42
+		'newMigration'  => ['newMigration [$name]', 'Creates a new migration file.'],
43
+		'seed'          => ['seed [$name]',         'Runs the named database seeder.']
44
+	];
45
+
46
+	protected $long_descriptions = [
47
+		'migrate'       => '',
48
+		'quietMigrate'  => '',
49
+		'refresh'       => '',
50
+		'newMigration'  => '',
51
+		'seed'          => ''
52
+	];
53
+
54
+	//-------------------------------------------------------------------
55
+
56
+	//--------------------------------------------------------------------
57
+	// Migration Methods
58
+	//--------------------------------------------------------------------
59
+
60
+	/**
61
+	 * Provides a command-line interface to the migration scripts.
62
+	 * If no $to is provided, will migrate to the latest version.
63
+	 *
64
+	 * Example:
65
+	 *      > php index.php database migrate
66
+	 *
67
+	 * @param string $type 'app', 'myth', 'all' or {module_name}
68
+	 * @param null $to
69
+	 * @param bool $silent If TRUE, will NOT display any prompts for verification.
70
+	 * @return bool|void
71
+	 */
72
+	public function migrate($type=null, $to = null, $silent = false)
73
+	{
74
+		$this->load->library('migration');
75
+
76
+		if (empty($type))
77
+		{
78
+			$type = CLI::prompt("Migration group to refresh?", $this->migration->default_migration_path());
79
+
80
+			if (empty($type))
81
+			{
82
+				return $silent ? false : CLI::error("\tYou must supply a group to refresh.");
83
+			}
84
+		}
85
+
86
+		// We need to append 'mod:' to properly handle modules, if
87
+		// the $type is not one of the recognized migration groups.
88
+		$this->config->load('migration');
89
+		$groups = config_item('migration_paths');
90
+		$groups = array_keys($groups);
91
+
92
+		// If it's not in the groups list, then assume it's a module.
93
+		if (! in_array($type, $groups))
94
+		{
95
+			if (strpos($type, 'mod:') !== 0)
96
+			{
97
+				$type = 'mod:'. $type;
98
+			}
99
+		}
100
+
101
+		unset($groups);
102
+
103
+		// Get our stats on the migrations
104
+		$latest = $this->migration->get_latest($type);
105
+		$latest = empty($latest) ? 0 : substr($latest, 0, strpos($latest, '_'));
106
+
107
+		if (empty($latest)) {
108
+			return CLI::write("\tNo migrations found.", 'yellow');
109
+		}
110
+
111
+		$current = $this->migration->get_version($type);
112
+
113
+		// Already at the desired version?
114
+		if ((! is_null($to) && $current == $to) OR (is_null($to) && $current == $latest))
115
+		{
116
+			return $silent ? true : CLI::write("\tDatabase is already at the desired version ({$current})", 'yellow');
117
+		}
118
+
119
+		$target = is_null($to) ? $latest : $to;
120
+
121
+		// Just to be safe, verify with the user they want to migrate
122
+		// to the latest version.
123
+		if (is_null($to)) {
124
+			// If we're in silent mode, don't prompt, just go to the latest...
125
+			if (! $silent) {
126
+				$go_ahead = CLI::prompt('Migrate to the latest available version?', array('y', 'n'));
127
+
128
+				if ($go_ahead == 'n') {
129
+					return CLI::write('Bailing...', 'yellow');
130
+				}
131
+			}
132
+
133
+			if (! $this->migration->latest($type)) {
134
+				return CLI::error("\n\tERROR: " . $this->migration->error_string() . "\n");
135
+			}
136
+		} else {
137
+			if ($this->migration->version($type, $to) === false) {
138
+				return CLI::error("\n\tERROR: " . $this->migration->error_string() . "\n");
139
+			}
140
+		}
141
+
142
+		return $silent ? true :
143
+			CLI::write("\n\tSuccessfully migrated database from version {$current} to {$target}.\n", 'green');
144
+	}
145
+
146
+	//--------------------------------------------------------------------
147
+
148
+	/**
149
+	 * Performs a migration that does not prompt for any information.
150
+	 * Suitable for use within automated scripts that can't be
151
+	 * bothered with answering questions.
152
+	 *
153
+	 * @param string $type 'app', 'myth', 'all' or {module_name}
154
+	 * @param null $to
155
+	 * @return bool|void
156
+	 */
157
+	public function quietMigrate($type='app', $to = null)
158
+	{
159
+		return $this->migrate($type, $to, true);
160
+	}
161
+
162
+	//--------------------------------------------------------------------
163
+
164
+
165
+	/**
166
+	 * Migrates the database back to 0, then back up to the latest version.
167
+	 *
168
+	 * @param string $type  The group or module to refresh.
169
+	 * @return mixed
170
+	 */
171
+	public function refresh($type=null)
172
+	{
173
+		$this->load->library('migration');
174
+
175
+		if (empty($type))
176
+		{
177
+			$type = CLI::prompt("Migration group to refresh?", $this->migration->default_migration_path());
178
+
179
+			if (empty($type))
180
+			{
181
+				return CLI::error("\tYou must supply a group to refresh.");
182
+			}
183
+		}
184
+
185
+		if ($this->migration->version($type, 0) === false) {
186
+			return CLI::error("\tERROR: " . $this->migration->error_string());
187
+		}
188
+
189
+		CLI::write(CLI::color("\tCleared the database.", 'green'));
190
+
191
+		if ($this->migration->latest($type) === false) {
192
+			return CLI::error("\tERROR: " . $this->migration->error_string());
193
+		}
194
+
195
+		CLI::write("\tRe-installed the database to the latest migration.", 'green');
196
+	}
197
+
198
+	//--------------------------------------------------------------------
199
+
200
+	/**
201
+	 * Creates a new migration file ready to be used.
202
+	 *
203
+	 * @param $name
204
+	 */
205
+	public function newMigration($name = null, $type = 'app')
206
+	{
207
+		if (empty($name)) {
208
+			$name = CLI::prompt('Migration name? ');
209
+
210
+			if (empty($name)) {
211
+				return CLI::error("\tYou must provide a migration name.", 'red');
212
+			}
213
+		}
214
+
215
+		$this->load->library('migration');
216
+
217
+		$path = $this->migration->determine_migration_path($type);
218
+
219
+		// Does the alias path exist in our config?
220
+		if (! $path) {
221
+			return CLI::error("\tThe migration path for '{$type}' does not exist.'");
222
+		}
223
+
224
+		// Does the path really exist?
225
+		if (! is_dir($path)) {
226
+			return CLI::error("\tThe path for '{$type}' is not a directory.");
227
+		}
228
+
229
+		// Is the folder writeable?
230
+		if (! is_writeable($path)) {
231
+			return CLI::error("\tThe folder for '{$type}' migrations is not writeable.");
232
+		}
233
+
234
+		$file = $this->migration->make_name($name);
235
+
236
+		$path = rtrim($path, '/') .'/'. $file;
237
+
238
+		$contents = <<<EOT
239 239
 <?php
240 240
 
241 241
 /**
@@ -262,36 +262,36 @@  discard block
 block discarded – undo
262 262
 
263 263
 }
264 264
 EOT;
265
-        $contents = str_replace('{name}', $name, $contents);
266
-        $contents = str_replace('{date}', date('Y-m-d H:i:s a'), $contents);
267
-        $contents = str_replace('{clean_name}', ucwords(str_replace('_', ' ', $name)), $contents);
265
+		$contents = str_replace('{name}', $name, $contents);
266
+		$contents = str_replace('{date}', date('Y-m-d H:i:s a'), $contents);
267
+		$contents = str_replace('{clean_name}', ucwords(str_replace('_', ' ', $name)), $contents);
268 268
 
269
-        $this->load->helper('file');
269
+		$this->load->helper('file');
270 270
 
271
-        if (write_file($path, $contents)) {
272
-            return CLI::write("\tNew migration created: " . CLI::color($file, 'yellow'), 'green');
273
-        }
271
+		if (write_file($path, $contents)) {
272
+			return CLI::write("\tNew migration created: " . CLI::color($file, 'yellow'), 'green');
273
+		}
274 274
 
275
-        return CLI::error("\tUnkown error trying to create migration: {$file}", 'red');
276
-    }
275
+		return CLI::error("\tUnkown error trying to create migration: {$file}", 'red');
276
+	}
277 277
 
278
-    //--------------------------------------------------------------------
278
+	//--------------------------------------------------------------------
279 279
 
280
-    //--------------------------------------------------------------------
281
-    // Seeding Methods
282
-    //--------------------------------------------------------------------
280
+	//--------------------------------------------------------------------
281
+	// Seeding Methods
282
+	//--------------------------------------------------------------------
283 283
 
284
-    /**
285
-     * Installs any database seeds stored in database/seeds. Seeds just need to
286
-     * extend the Seeder class and have a method named run.
287
-     */
288
-    public function seed($name = null)
289
-    {
290
-        $this->load->library('seeder');
284
+	/**
285
+	 * Installs any database seeds stored in database/seeds. Seeds just need to
286
+	 * extend the Seeder class and have a method named run.
287
+	 */
288
+	public function seed($name = null)
289
+	{
290
+		$this->load->library('seeder');
291 291
 
292
-        $this->seeder->call($name);
293
-    }
292
+		$this->seeder->call($name);
293
+	}
294 294
 
295
-    //--------------------------------------------------------------------
295
+	//--------------------------------------------------------------------
296 296
 
297 297
 }
Please login to merge, or discard this patch.
myth/CIModules/database/libraries/Seeder.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -39,92 +39,92 @@
 block discarded – undo
39 39
  */
40 40
 class Seeder {
41 41
 
42
-    public $error_string    = '';
42
+	public $error_string    = '';
43 43
 
44
-    protected $ci;
44
+	protected $ci;
45 45
 
46
-    protected $is_cli = false;
46
+	protected $is_cli = false;
47 47
 
48
-    protected $db;
49
-    protected $dbforge;
48
+	protected $db;
49
+	protected $dbforge;
50 50
 
51
-    //--------------------------------------------------------------------
51
+	//--------------------------------------------------------------------
52 52
 
53
-    public function __construct ()
54
-    {
55
-        $this->ci =& get_instance();
53
+	public function __construct ()
54
+	{
55
+		$this->ci =& get_instance();
56 56
 
57
-        $this->is_cli = $this->ci->input->is_cli_request();
57
+		$this->is_cli = $this->ci->input->is_cli_request();
58 58
 
59
-        if ($this->is_cli)
60
-        {
61
-            $cli = new CLI();
62
-            $cli::_init();
63
-        }
59
+		if ($this->is_cli)
60
+		{
61
+			$cli = new CLI();
62
+			$cli::_init();
63
+		}
64 64
 
65
-        $this->ci->load->dbforge();
65
+		$this->ci->load->dbforge();
66 66
 
67
-        // Setup some convenience vars.
68
-        $this->db       =& $this->ci->db;
69
-        $this->dbforge  =& $this->ci->dbforge;
70
-    }
67
+		// Setup some convenience vars.
68
+		$this->db       =& $this->ci->db;
69
+		$this->dbforge  =& $this->ci->dbforge;
70
+	}
71 71
 
72
-    //--------------------------------------------------------------------
72
+	//--------------------------------------------------------------------
73 73
 
74 74
 
75
-    /**
76
-     * Run the database seeds. It's where the magic happens.
77
-     * This method MUST be overridden by child classes.
78
-     */
79
-    public function run ()
80
-    {
75
+	/**
76
+	 * Run the database seeds. It's where the magic happens.
77
+	 * This method MUST be overridden by child classes.
78
+	 */
79
+	public function run ()
80
+	{
81 81
 
82
-    }
82
+	}
83 83
 
84
-    //--------------------------------------------------------------------
84
+	//--------------------------------------------------------------------
85 85
 
86
-    /**
87
-     * Loads the class file and calls the run() method
88
-     * on the class.
89
-     *
90
-     * @param $class
91
-     */
92
-    public function call ($class)
93
-    {
94
-        if (empty($class))
95
-        {
96
-            // Ask the user...
97
-            $class = trim( CLI::prompt("Seeder name") );
86
+	/**
87
+	 * Loads the class file and calls the run() method
88
+	 * on the class.
89
+	 *
90
+	 * @param $class
91
+	 */
92
+	public function call ($class)
93
+	{
94
+		if (empty($class))
95
+		{
96
+			// Ask the user...
97
+			$class = trim( CLI::prompt("Seeder name") );
98 98
 
99
-            if (empty($class)) {
100
-                return CLI::error("\tNo Seeder was specified.");
101
-            }
102
-        }
99
+			if (empty($class)) {
100
+				return CLI::error("\tNo Seeder was specified.");
101
+			}
102
+		}
103 103
 
104
-        $path = APPPATH .'database/seeds/'. str_replace('.php', '', $class) .'.php';
104
+		$path = APPPATH .'database/seeds/'. str_replace('.php', '', $class) .'.php';
105 105
 
106
-        if ( ! is_file($path))
107
-        {
108
-            return CLI::error("\tUnable to find seed class: ". $class);
109
-        }
106
+		if ( ! is_file($path))
107
+		{
108
+			return CLI::error("\tUnable to find seed class: ". $class);
109
+		}
110 110
 
111
-        try {
112
-            require $path;
111
+		try {
112
+			require $path;
113 113
 
114
-            $seeder = new $class();
114
+			$seeder = new $class();
115 115
 
116
-            $seeder->run();
116
+			$seeder->run();
117 117
 
118
-            unset($seeder);
119
-        }
120
-        catch (\Exception $e)
121
-        {
122
-            show_error($e->getMessage(), $e->getCode());
123
-        }
118
+			unset($seeder);
119
+		}
120
+		catch (\Exception $e)
121
+		{
122
+			show_error($e->getMessage(), $e->getCode());
123
+		}
124 124
 
125
-        return Cli::write("\tSeeded: $class", 'green');
126
-    }
125
+		return Cli::write("\tSeeded: $class", 'green');
126
+	}
127 127
 
128
-    //--------------------------------------------------------------------
128
+	//--------------------------------------------------------------------
129 129
 
130 130
 }
Please login to merge, or discard this patch.
myth/CIModules/docs/config/docs.php 1 patch
Indentation   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -57,8 +57,8 @@
 block discarded – undo
57 57
 | if realpath cannot find/read the folder.
58 58
 */
59 59
 $config['docs.folders'] = [
60
-    'application'   => APPPATH .'docs',
61
-    'developer'     => APPPATH .'../myth/_docs_src'
60
+	'application'   => APPPATH .'docs',
61
+	'developer'     => APPPATH .'../myth/_docs_src'
62 62
 ];
63 63
 
64 64
 /*
Please login to merge, or discard this patch.
myth/CIModules/docs/controllers/Docs.php 1 patch
Indentation   +259 added lines, -259 removed lines patch added patch discarded remove patch
@@ -33,284 +33,284 @@
 block discarded – undo
33 33
 class Docs extends \Myth\Controllers\ThemedController
34 34
 {
35 35
 
36
-    protected $ignoreFiles = array('_404.md');
36
+	protected $ignoreFiles = array('_404.md');
37 37
 
38
-    protected $tocFile;
38
+	protected $tocFile;
39 39
 
40
-    protected $doc_folders = [];
40
+	protected $doc_folders = [];
41 41
 
42
-    protected $current_group = null;
42
+	protected $current_group = null;
43 43
 
44
-    protected $current_path = null;
44
+	protected $current_path = null;
45 45
 
46
-    private $showAppDocs;
46
+	private $showAppDocs;
47 47
 
48
-    private $showDevDocs;
48
+	private $showDevDocs;
49 49
 
50
-    protected $theme = 'docs';
50
+	protected $theme = 'docs';
51 51
 
52
-    protected $auto_escape = false;
52
+	protected $auto_escape = false;
53 53
 
54
-    //--------------------------------------------------------------------------
54
+	//--------------------------------------------------------------------------
55 55
 
56
-    /**
57
-     * Constructor
58
-     *
59
-     * @return \Docs
60
-     */
61
-    public function __construct()
62
-    {
63
-        parent::__construct();
56
+	/**
57
+	 * Constructor
58
+	 *
59
+	 * @return \Docs
60
+	 */
61
+	public function __construct()
62
+	{
63
+		parent::__construct();
64 64
 
65
-        $this->load->config('docs');
66
-        $this->lang->load('docs');
65
+		$this->load->config('docs');
66
+		$this->lang->load('docs');
67 67
 
68
-        // Save our folders
69
-        $this->doc_folders = config_item('docs.folders');
68
+		// Save our folders
69
+		$this->doc_folders = config_item('docs.folders');
70 70
 
71
-        list($this->current_group, $this->current_path) = $this->determineFromURL();
71
+		list($this->current_group, $this->current_path) = $this->determineFromURL();
72 72
 
73
-        $this->determineVisibleGroups($this->current_group, $this->current_path);
73
+		$this->determineVisibleGroups($this->current_group, $this->current_path);
74 74
 
75
-        $this->load->helper('form');
76
-        $this->load->helper('language');
75
+		$this->load->helper('form');
76
+		$this->load->helper('language');
77 77
 
78
-        $this->docbuilder = new \Myth\Docs\Builder( array('apppath' => APPPATH) );
78
+		$this->docbuilder = new \Myth\Docs\Builder( array('apppath' => APPPATH) );
79 79
 
80
-        $formatter = function ($str) {
81
-            $converter = new \League\CommonMark\CommonMarkConverter();
82
-            return $converter->convertToHtml($str);
83
-        };
84
-        $this->docbuilder->registerFormatter($formatter, true);
85
-    }
80
+		$formatter = function ($str) {
81
+			$converter = new \League\CommonMark\CommonMarkConverter();
82
+			return $converter->convertToHtml($str);
83
+		};
84
+		$this->docbuilder->registerFormatter($formatter, true);
85
+	}
86 86
 
87
-    //--------------------------------------------------------------------
87
+	//--------------------------------------------------------------------
88 88
 
89
-    /**
90
-     * Display the list of documents available and the current document
91
-     *
92
-     * @return void
93
-     */
94
-    public function index()
95
-    {
96
-        $data = array();
89
+	/**
90
+	 * Display the list of documents available and the current document
91
+	 *
92
+	 * @return void
93
+	 */
94
+	public function index()
95
+	{
96
+		$data = array();
97 97
 
98
-        // Make sure the builder knows where to look
99
-        foreach ($this->doc_folders as $alias => $folder) {
100
-            $this->docbuilder->addDocFolder($alias, $folder);
101
-        }
102
-
103
-        try {
104
-            $content = $this->docbuilder->readPage($this->current_path, $this->current_group);
105
-            $content = $this->docbuilder->postProcess($content, site_url(), current_url());
106
-
107
-            $data['sidebar'] = $this->buildSidebar($content);
108
-            $data['toc']     = $this->buildTOC();
109
-            $data['content'] = $content;
110
-            $data['page_title'] = $this->docbuilder->pageTitle();
111
-        } catch (Exception $e) {
112
-            $this->setMessage($e->getMessage(), 'warning');
113
-        }
114
-
115
-        $this->render($data, config_item('docs.cache_time'));
116
-    }
117
-
118
-    //--------------------------------------------------------------------
119
-
120
-    /**
121
-     * Display search results and handles the search itself.
122
-     *
123
-     * @return void
124
-     */
125
-    public function search()
126
-    {
127
-        $this->benchmark->mark('search_start');
128
-        $this->docsearch = new \Myth\Docs\Search();
129
-        $this->load->helper('markdown_extended');
130
-        $this->docsearch->registerFormatter('MarkdownExtended', true);
131
-
132
-        $data = array();
133
-
134
-        $terms = $this->input->post('search_terms');
135
-
136
-        if ($terms) {
137
-            $search_folders = $this->doc_folders;
138
-
139
-            $data['results'] = $this->docsearch->search($terms, $search_folders);
140
-        }
141
-
142
-        $this->benchmark->mark('search_end');
143
-
144
-        $data['search_time']  = $this->benchmark->elapsed_time('search_start', 'search_end');
145
-        $data['search_terms'] = $terms;
146
-        $data['page_title'] = 'Search Results';
147
-
148
-        $this->render($data);
149
-    }
150
-
151
-    //--------------------------------------------------------------------------
152
-    // Private Methods
153
-    //--------------------------------------------------------------------------
154
-
155
-    /**
156
-     * Determines which groups are allowed to be viewed by the current system
157
-     * and the user/environment.
158
-     *
159
-     * todo Allow docs groups to be shown/hidden per-environment, using assoc-array for permitted environments
160
-     */
161
-    private function determineVisibleGroups($current_group, $current_path)
162
-    {
163
-        // Is displaying docs permitted for this environment?
164
-        if (config_item('docs.permitted_environments')
165
-            && !in_array(ENVIRONMENT, config_item('docs.permitted_environments'))
166
-        ) {
167
-            $this->setMessage(lang('docs_env_disabled'), 'error');
168
-            redirect();
169
-        }
170
-
171
-        $this->showAppDocs = config_item('docs.show_app_docs');
172
-        $this->showDevDocs = config_item('docs.show_dev_docs');
173
-        $this->tocFile     = config_item('docs.toc_file') ?: '_toc.ini';
174
-
175
-        // Make sure we can still get to the search method.
176
-        if ($current_group == 'search') {
177
-            $this->current_group = false;
178
-        } // Are we allowed to show developer docs in this environment?
179
-        elseif ($current_group == 'developer'
180
-                && !$this->showDevDocs
181
-                && ENVIRONMENT != 'development'
182
-        ) {
183
-            if ($this->showAppDocs) {
184
-                $this->setMessage(lang('docs_not_allowed_dev'), 'warning');
185
-
186
-                redirect('docs/application');
187
-            }
188
-
189
-            show_error(lang('docs_not_allowed'));
190
-        }
191
-    }
192
-
193
-    //--------------------------------------------------------------------
194
-
195
-    /**
196
-     * Determines the current doc group and file path from the current URL.
197
-     *
198
-     * Returns an array with the group and file path in the 0 and 1 positions, respectively.
199
-     *
200
-     * @return array
201
-     */
202
-    private function determineFromURL()
203
-    {
204
-        $return = [
205
-            '', // Group
206
-            '', // File Path
207
-        ];
208
-
209
-        $segments = $this->uri->segment_array();
210
-
211
-        // Remove the 'docs' from the array
212
-        // for now, we assume this is the first one
213
-        // since that is how Bonfire is setup to show docs
214
-        // @todo Make it so the path can be modified and this still works.
215
-        array_shift($segments);
216
-
217
-        // If nothing left, then assign the default group and redirect to
218
-        // a page we can do something with...
219
-        if (!count($segments)) {
220
-            redirect('docs/' . config_item('docs.default_group'));
221
-        }
222
-
223
-        // Do we have a group specified? Bonfire Docs requires that a group
224
-        // be part of the URI so it should be the first element on the array.
225
-        $return[0] = array_shift($segments);
226
-
227
-        // If there's any more left, then join them together and they'll
228
-        // form the path to the file. This will allow for subfolders with the
229
-        // docs folder itself.
230
-        $return[1] = count($segments) ? implode('/', $segments) : 'index';
231
-
232
-        return $return;
233
-    }
234
-
235
-    //--------------------------------------------------------------------
236
-
237
-    /**
238
-     * Builds a TOC for the sidebar out of files found in the following folders:
239
-     *      - application/docs
240
-     *      - bonfire/docs
241
-     *      - {module}/docs
242
-     *
243
-     * @param $content  The HTML generated for the page content.
244
-     * @return string   The HTML for the sidebar.
245
-     */
246
-    private function buildSidebar(&$content)
247
-    {
248
-        $data = [];
249
-
250
-        // Set the remaining data for the view
251
-        $data['docsDir'] = 'docs/' . $this->current_group . '/';
252
-        $data['docsExt'] = config_item('docs.extension');
253
-
254
-        $data['docMap'] = $this->docbuilder->buildDocumentMap($content);
255
-
256
-        return $this->docbuilder->postProcess(
257
-            $this->load->view('docs/_document_map', $data, true),
258
-            site_url(),
259
-            current_url()
260
-        );
261
-    }
262
-
263
-    //--------------------------------------------------------------------
264
-
265
-    /**
266
-     * Builds out the nested lists of items that are needed
267
-     */
268
-    private function buildTOC()
269
-    {
270
-        $folder = $this->doc_folders[$this->current_group] . '/';
271
-
272
-        $map = $this->docbuilder->buildTOC($folder);
273
-
274
-        return $this->docbuilder->postProcess(
275
-            $this->load->view('docs/_toc', ['map' => $map], true),
276
-            site_url(),
277
-            current_url()
278
-        );
279
-    }
280
-
281
-    //--------------------------------------------------------------------
282
-
283
-    /**
284
-     * Checks all modules to see if they include docs and prepares their doc
285
-     * information for use in the sidebar.
286
-     *
287
-     * @return array
288
-     */
289
-    private function get_module_docs()
290
-    {
291
-        $docs_modules = array();
292
-        foreach (\Bonfire\Modules::list_modules() as $module) {
293
-            $ignored_folders = array();
294
-            $path            = \Bonfire\Modules::path($module) . $this->docsDir;
295
-
296
-            // If these are developer docs, add the folder to the path.
297
-            if ($this->current_group == $this->docsTypeBf) {
298
-                $path .= '/' . $this->docsTypeBf;
299
-            } // For Application docs, ignore the 'developers' folder.
300
-            else {
301
-                $ignored_folders[] = $this->docsTypeBf;
302
-            }
303
-
304
-            if (is_dir($path)) {
305
-                $files = $this->get_folder_files($path, $module, $ignored_folders);
306
-                if (is_array($files) && count($files)) {
307
-                    $docs_modules[$module] = $files;
308
-                }
309
-            }
310
-        }
311
-
312
-        return $docs_modules;
313
-    }
314
-    //--------------------------------------------------------------------
98
+		// Make sure the builder knows where to look
99
+		foreach ($this->doc_folders as $alias => $folder) {
100
+			$this->docbuilder->addDocFolder($alias, $folder);
101
+		}
102
+
103
+		try {
104
+			$content = $this->docbuilder->readPage($this->current_path, $this->current_group);
105
+			$content = $this->docbuilder->postProcess($content, site_url(), current_url());
106
+
107
+			$data['sidebar'] = $this->buildSidebar($content);
108
+			$data['toc']     = $this->buildTOC();
109
+			$data['content'] = $content;
110
+			$data['page_title'] = $this->docbuilder->pageTitle();
111
+		} catch (Exception $e) {
112
+			$this->setMessage($e->getMessage(), 'warning');
113
+		}
114
+
115
+		$this->render($data, config_item('docs.cache_time'));
116
+	}
117
+
118
+	//--------------------------------------------------------------------
119
+
120
+	/**
121
+	 * Display search results and handles the search itself.
122
+	 *
123
+	 * @return void
124
+	 */
125
+	public function search()
126
+	{
127
+		$this->benchmark->mark('search_start');
128
+		$this->docsearch = new \Myth\Docs\Search();
129
+		$this->load->helper('markdown_extended');
130
+		$this->docsearch->registerFormatter('MarkdownExtended', true);
131
+
132
+		$data = array();
133
+
134
+		$terms = $this->input->post('search_terms');
135
+
136
+		if ($terms) {
137
+			$search_folders = $this->doc_folders;
138
+
139
+			$data['results'] = $this->docsearch->search($terms, $search_folders);
140
+		}
141
+
142
+		$this->benchmark->mark('search_end');
143
+
144
+		$data['search_time']  = $this->benchmark->elapsed_time('search_start', 'search_end');
145
+		$data['search_terms'] = $terms;
146
+		$data['page_title'] = 'Search Results';
147
+
148
+		$this->render($data);
149
+	}
150
+
151
+	//--------------------------------------------------------------------------
152
+	// Private Methods
153
+	//--------------------------------------------------------------------------
154
+
155
+	/**
156
+	 * Determines which groups are allowed to be viewed by the current system
157
+	 * and the user/environment.
158
+	 *
159
+	 * todo Allow docs groups to be shown/hidden per-environment, using assoc-array for permitted environments
160
+	 */
161
+	private function determineVisibleGroups($current_group, $current_path)
162
+	{
163
+		// Is displaying docs permitted for this environment?
164
+		if (config_item('docs.permitted_environments')
165
+			&& !in_array(ENVIRONMENT, config_item('docs.permitted_environments'))
166
+		) {
167
+			$this->setMessage(lang('docs_env_disabled'), 'error');
168
+			redirect();
169
+		}
170
+
171
+		$this->showAppDocs = config_item('docs.show_app_docs');
172
+		$this->showDevDocs = config_item('docs.show_dev_docs');
173
+		$this->tocFile     = config_item('docs.toc_file') ?: '_toc.ini';
174
+
175
+		// Make sure we can still get to the search method.
176
+		if ($current_group == 'search') {
177
+			$this->current_group = false;
178
+		} // Are we allowed to show developer docs in this environment?
179
+		elseif ($current_group == 'developer'
180
+				&& !$this->showDevDocs
181
+				&& ENVIRONMENT != 'development'
182
+		) {
183
+			if ($this->showAppDocs) {
184
+				$this->setMessage(lang('docs_not_allowed_dev'), 'warning');
185
+
186
+				redirect('docs/application');
187
+			}
188
+
189
+			show_error(lang('docs_not_allowed'));
190
+		}
191
+	}
192
+
193
+	//--------------------------------------------------------------------
194
+
195
+	/**
196
+	 * Determines the current doc group and file path from the current URL.
197
+	 *
198
+	 * Returns an array with the group and file path in the 0 and 1 positions, respectively.
199
+	 *
200
+	 * @return array
201
+	 */
202
+	private function determineFromURL()
203
+	{
204
+		$return = [
205
+			'', // Group
206
+			'', // File Path
207
+		];
208
+
209
+		$segments = $this->uri->segment_array();
210
+
211
+		// Remove the 'docs' from the array
212
+		// for now, we assume this is the first one
213
+		// since that is how Bonfire is setup to show docs
214
+		// @todo Make it so the path can be modified and this still works.
215
+		array_shift($segments);
216
+
217
+		// If nothing left, then assign the default group and redirect to
218
+		// a page we can do something with...
219
+		if (!count($segments)) {
220
+			redirect('docs/' . config_item('docs.default_group'));
221
+		}
222
+
223
+		// Do we have a group specified? Bonfire Docs requires that a group
224
+		// be part of the URI so it should be the first element on the array.
225
+		$return[0] = array_shift($segments);
226
+
227
+		// If there's any more left, then join them together and they'll
228
+		// form the path to the file. This will allow for subfolders with the
229
+		// docs folder itself.
230
+		$return[1] = count($segments) ? implode('/', $segments) : 'index';
231
+
232
+		return $return;
233
+	}
234
+
235
+	//--------------------------------------------------------------------
236
+
237
+	/**
238
+	 * Builds a TOC for the sidebar out of files found in the following folders:
239
+	 *      - application/docs
240
+	 *      - bonfire/docs
241
+	 *      - {module}/docs
242
+	 *
243
+	 * @param $content  The HTML generated for the page content.
244
+	 * @return string   The HTML for the sidebar.
245
+	 */
246
+	private function buildSidebar(&$content)
247
+	{
248
+		$data = [];
249
+
250
+		// Set the remaining data for the view
251
+		$data['docsDir'] = 'docs/' . $this->current_group . '/';
252
+		$data['docsExt'] = config_item('docs.extension');
253
+
254
+		$data['docMap'] = $this->docbuilder->buildDocumentMap($content);
255
+
256
+		return $this->docbuilder->postProcess(
257
+			$this->load->view('docs/_document_map', $data, true),
258
+			site_url(),
259
+			current_url()
260
+		);
261
+	}
262
+
263
+	//--------------------------------------------------------------------
264
+
265
+	/**
266
+	 * Builds out the nested lists of items that are needed
267
+	 */
268
+	private function buildTOC()
269
+	{
270
+		$folder = $this->doc_folders[$this->current_group] . '/';
271
+
272
+		$map = $this->docbuilder->buildTOC($folder);
273
+
274
+		return $this->docbuilder->postProcess(
275
+			$this->load->view('docs/_toc', ['map' => $map], true),
276
+			site_url(),
277
+			current_url()
278
+		);
279
+	}
280
+
281
+	//--------------------------------------------------------------------
282
+
283
+	/**
284
+	 * Checks all modules to see if they include docs and prepares their doc
285
+	 * information for use in the sidebar.
286
+	 *
287
+	 * @return array
288
+	 */
289
+	private function get_module_docs()
290
+	{
291
+		$docs_modules = array();
292
+		foreach (\Bonfire\Modules::list_modules() as $module) {
293
+			$ignored_folders = array();
294
+			$path            = \Bonfire\Modules::path($module) . $this->docsDir;
295
+
296
+			// If these are developer docs, add the folder to the path.
297
+			if ($this->current_group == $this->docsTypeBf) {
298
+				$path .= '/' . $this->docsTypeBf;
299
+			} // For Application docs, ignore the 'developers' folder.
300
+			else {
301
+				$ignored_folders[] = $this->docsTypeBf;
302
+			}
303
+
304
+			if (is_dir($path)) {
305
+				$files = $this->get_folder_files($path, $module, $ignored_folders);
306
+				if (is_array($files) && count($files)) {
307
+					$docs_modules[$module] = $files;
308
+				}
309
+			}
310
+		}
311
+
312
+		return $docs_modules;
313
+	}
314
+	//--------------------------------------------------------------------
315 315
 
316 316
 }
Please login to merge, or discard this patch.