Issues (114)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

protected/controllers/SiteController.php (11 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
class SiteController extends CiiController
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
{
5
	public function filters()
6
	{
7
		return CMap::mergeArray(parent::filters(), array('accessControl'));
8
	}
9
10
	/**
11
	 * Setup access controls to prevent guests from changing their emaila ddress
12
	 */
13
	public function accessRules()
14
	{
15
		return array(
16
		   array('deny',  // The user mut be authenticated to approve an email address change
17
				'users'=>array('*'),
18
				'expression'=>'Yii::app()->user->isGuest==true',
19
				'actions' => array('emailchange')
20
			)
21
		);
22
	}
23
24
	/**
25
	 * beforeAction method, performs operations before an action is presented
26
	 * @param $action, the action being called
27
	 * @see http://www.yiiframework.com/doc/api/1.1/CController#beforeAction-detail
28
	 */
29
	public function beforeAction($action)
30
	{
31
		if (!Yii::app()->getRequest()->isSecureConnection && Cii::getConfig('forceSecureSSL', false))
32
			$this->redirect('https://' . Yii::app()->getRequest()->serverName . Yii::app()->getRequest()->requestUri);
33
34
		return parent::beforeAction($action);
35
	}
36
37
	/**
38
	 * This is the action to handle external exceptions.
39
	 */
40
	public function actionError($code=NULL)
41
	{
42
		$this->layout = '//layouts/main';
43
44
		if($error=Yii::app()->errorHandler->error)
45
		{
46
			if(Yii::app()->request->isAjaxRequest)
47
				echo $error['message'];
48
			else
49
			{
50
				$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}} {{code}}', array(
51
					'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
52
					'{{label}}'    => Yii::t('ciims.controllers.Site', 'Error'),
53
					'{{code}}'     => $error['code']
54
				)));
55
56
				$this->render('error', array(
57
					'error' => $error
58
				));
59
			}
60
		}
61
		else
62
		{
63
			$message = Yii::app()->user->getFlash('error_code');
64
			Yii::app()->user->setFlash('error_code', $message);
65
			throw new CHttpException($code, $message);
66
		}
67
	}
68
69
	/**
70
	 * Provides basic sitemap functionality via XML
71
	 */
72
	public function actionSitemap()
73
	{
74
		ob_end_clean();
75
		Yii::app()->log->routes[0]->enabled = false;
76
		header('Content-type: text/xml; charset=utf-8');
77
		$url = Yii::app()->getBaseUrl(true);
78
		$this->setLayout(null);
79
		$content 	= Yii::app()->db
80
								->createCommand('SELECT slug, password, type_id, updated FROM content AS t WHERE vid=(SELECT MAX(vid) FROM content WHERE id=t.id) AND status = 1 AND published <= UTC_TIMESTAMP();')
81
								->queryAll();
82
83
		$categories = Yii::app()->db
84
								->createCommand('SELECT slug, updated FROM categories;')
85
								->queryAll();
86
87
		$this->renderPartial('sitemap', array(
88
			'content' 	 => $content,
89
			'categories' => $categories,
90
			'url' 		 => $url
91
		));
92
93
		Yii::app()->end();
94
	}
95
96
	/**
97
	 * Provides basic searching functionality
98
	 * @param int $id   The search pagination id
99
	 */
100
	public function actionSearch($id=1)
0 ignored issues
show
actionSearch uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
101
	{
102
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
103
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
104
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Search')
105
		)));
106
107
		$this->layout = '//layouts/default';
108
		$data = array();
109
		$pages = array();
110
		$itemCount = 0;
111
		$pageSize = Cii::getConfig('searchPaginationSize', 10);
112
113
		if (Cii::get($_GET, 'q', false))
114
		{
115
			$criteria = new CDbCriteria;
116
			$criteria->addCondition('status = 1')
117
					 ->addCondition('published <= UTC_TIMESTAMP()');
118
119
			if (strpos($_GET['q'], 'user_id') !== false)
120
			{
121
				$criteria->addCondition('author_id = :author_id')
122
						 ->addCondition("vid=(SELECT MAX(vid) FROM content AS v WHERE v.id=t.id)");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal vid=(SELECT MAX(vid) FRO...t AS v WHERE v.id=t.id) does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
123
				$criteria->params = array(
124
					':author_id' => str_replace('user_id:', '', Cii::get($_GET, 'q', 0))
125
				);
126
			}
127
			else
128
			{
129
				$param = Cii::get($_GET, 'q', 0);
130
				$criteria->addCondition("vid=(SELECT MAX(vid) FROM content AS v WHERE v.id=t.id) AND ((t.content LIKE :param) OR (t.title LIKE :param2))");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal vid=(SELECT MAX(vid) FRO...(t.title LIKE :param2)) does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
131
				$criteria->params = array(
132
					':param' 	=> '%' . $param . '%',
133
					':param2'	=> '%' . $param . '%'
134
				);
135
			}
136
137
			$criteria->addCondition('password = ""');
138
			$criteria->limit = $pageSize;
139
			$criteria->order = 'id DESC';
140
			$itemCount = Content::model()->count($criteria);
141
			$pages = new CPagination($itemCount);
142
			$pages->pageSize=$pageSize;
143
144
			$criteria->offset = $criteria->limit*($pages->getCurrentPage());
145
			$data = Content::model()->findAll($criteria);
146
			$pages->applyLimit($criteria);
147
		}
148
149
		$this->render('search', array(
150
			'url' 		=> 'search',
151
			'id' 		=> $id,
152
			'data' 		=> $data,
153
			'itemCount' => $itemCount,
154
			'pages' 	=> $pages
155
		));
156
	}
157
158
	/**
159
	 * Provides functionality to log a user into the system
160
	 */
161
	public function actionLogin()
0 ignored issues
show
actionLogin uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
162
	{
163
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
164
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
165
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Login to your account')
166
		)));
167
168
		$this->layout = '//layouts/main';
169
		$model = new LoginForm;
170
171
		if (Cii::get($_POST, 'LoginForm', false))
172
		{
173
			$model->attributes = Cii::get($_POST, 'LoginForm', array());
174
			if ($model->login())
175
				$this->redirect($this->_getNext() ?: Yii::app()->user->returnUrl);
176
		}
177
178
		$this->render('login', array(
179
			'model' => $model
180
		));
181
	}
182
183
	/**
184
	 * Provides functionality to log a user out
185
	 */
186
	public function actionLogout()
187
	{
188
		if (Yii::app()->request->getParam('next', false))
189
			$redirect = $this->createUrl('site/login', array('next' => $this->_getNext()));
190
		else
191
			$redirect = Yii::app()->user->returnUrl;
192
193
		// Purge the active sessions API Key
194
		$apiKey = UserMetadata::model()->findByAttributes(array('user_id' => Yii::app()->user->id, 'key' => 'api_key'));
195
196
		if ($apiKey != NULL)
197
			$apiKey->delete();
198
199
200
		Yii::app()->user->logout();
201
		$this->redirect($redirect);
202
	}
203
204
	/**
205
	 * Handles resetting a users password should they forgot it
206
	 */
207
	public function actionForgot()
0 ignored issues
show
actionForgot uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
208
	{
209
		$this->layout = '//layouts/main';
210
211
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
212
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
213
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Forgot Your Password?')
214
		)));
215
216
		$model = new ForgotForm;
217
218
		if (Cii::get($_POST, 'ForgotForm', false))
219
		{
220
			$model->attributes = $_POST['ForgotForm'];
221
222
			if ($model->initPasswordResetProcess())
223
			{
224
				Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Site', 'A password reset link has been sent to your email address'));
225
				$this->redirect($this->createUrl('site/login'));
226
			}
227
		}
228
229
		$this->render('forgot', array(
230
			'model' => $model
231
		));
232
	}
233
234
	/**
235
	 * Alows a user to reset their password if they initiated a forgot password request
236
	 * @param string $id
237
	 */
238
	public function actionResetPassword($id=NULL)
0 ignored issues
show
actionResetPassword uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
239
	{
240
		$this->layout = '//layouts/main';
241
242
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
243
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
244
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Reset Your password')
245
		)));
246
247
		$model = new PasswordResetForm;
248
		$model->reset_key = $id;
249
250
		if (!$model->validateResetKey())
251
			throw new CHttpException(403, Yii::t('ciims.controllers.Site', 'The password reset key provided is invalid'));
252
253
		if (Cii::get($_POST, 'PasswordResetForm', false))
254
		{
255
			$model->attributes = $_POST['PasswordResetForm'];
256
257
			if ($model->save())
258
			{
259
				Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Site', 'Your password has been reset, and you may now login with your new password'));
260
				$this->redirect($this->createUrl('site/login'));
261
			}
262
		}
263
264
		$this->render('resetpassword', array(
265
			'model' => $model
266
		));
267
	}
268
269
	/**
270
	 * Allows the user to securely change their email address
271
	 * @param  string $key the user's secure key
272
	 */
273
	public function actionEmailChange($key=null)
0 ignored issues
show
actionEmailChange uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
274
	{
275
		$this->layout = '//layouts/main';
276
277
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
278
		   '{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
279
		   '{{label}}'    => Yii::t('ciims.controllers.Site', 'Change Your Email Address')
280
	   )));
281
282
		$model = new EmailChangeForm;
283
		$model->setUser(Users::model()->findByPk(Yii::app()->user->id));
284
		$model->verificationKey = $key;
285
286
		if (!$model->validateVerificationKey())
287
			throw new CHttpException(403, Yii::t('ciims.controllers.Site', 'The verification key provided is invalid.'));
288
289
		if (Cii::get($_POST, 'EmailChangeForm', false))
290
		{
291
			$model->attributes = $_POST['EmailChangeForm'];
292
293
			if ($model->save())
294
			{
295
				Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Site', 'Your new email address has been verified.'));
296
297
				$loginForm = new LoginForm;
298
				$loginForm->attributes = array(
299
					'username' => Users::model()->findByPk(Yii::app()->user->id)->email,
300
					'password' => $model->password,
301
				);
302
303
				if ($loginForm->login())
304
					return $this->redirect(Yii::app()->homeUrl);
305
306
				throw new CHttpException(400, Yii::t('ciims.controllers.Site', 'Unable to re-authenticated user.'));
307
			}
308
		}
309
310
		$this->render('emailchange', array(
311
			'model' => $model
312
		));
313
	}
314
315
	/**
316
	 * Activates a new user's account
317
	 * @param mixed $id 			The activation key
318
	 */
319
	public function actionActivation($id=NULL)
0 ignored issues
show
actionActivation uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
320
	{
321
		$this->layout = '//layouts/main';
322
323
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
324
		   '{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
325
		   '{{label}}'    => Yii::t('ciims.controllers.Site', 'Activate Your Account')
326
	   )));
327
328
		$model = new ActivationForm;
329
		$model->activationKey = $id;
330
331
		if (!$model->validateKey())
332
			throw new CHttpException(403, Yii::t('ciims.models.ActivationForm', 'The activation key you provided is invalid.'));
333
334
		if (Cii::get($_POST, 'ActivationForm', false))
335
		{
336
			$model->attributes = $_POST['ActivationForm'];
337
338
			if ($model->save())
339
			{
340
				Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Site', 'Your account has successfully been activated. You may now login'));
341
				$this->redirect($this->createUrl('site/login'));
342
			}
343
		}
344
345
		$this->render('activation', array(
346
			'model' => $model
347
		));
348
	}
349
350
	/**
351
	 * Handles the registration of new users on the site
352
	 */
353
	public function actionRegister()
0 ignored issues
show
actionRegister uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
354
	{
355
		$this->layout = '//layouts/main';
356
357
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
358
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
359
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Sign Up')
360
		)));
361
362
		$model = new RegisterForm;
363
364
		if (Cii::get($_POST, 'RegisterForm', false))
365
		{
366
			$model->attributes = $_POST['RegisterForm'];
367
368
			// Save the user's information
369
			if ($model->save())
370
			{
371
				// Set a flash message
372
				Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Site', 'You have successfully registered an account. Before you can login, please check your email for activation instructions'));
373
				$this->redirect($this->createUrl('site/login'));
374
			}
375
		}
376
377
		$this->render('register', array(
378
			'model'=>$model
379
		));
380
	}
381
382
	/**
383
	 * Enables users who have recieved an invitation to setup a new account
384
	 * @param string $id	The activation id the of the user that we want to activate
385
	 */
386
	public function actionAcceptInvite($id=NULL)
0 ignored issues
show
actionAcceptInvite uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
387
	{
388
		$this->layout = '//layouts/main';
389
390
		$this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array(
391
			'{{app_name}}' => Cii::getConfig('name', Yii::app()->name),
392
			'{{label}}'    => Yii::t('ciims.controllers.Site', 'Accept Invitation')
393
		)));
394
395
		if ($id === NULL)
396
			throw new CHttpException(400, Yii::t('ciims.controllers.Site', 'There was an error fulfilling your request.'));
397
398
		// Make sure we have a user first
399
		$meta = UserMetadata::model()->findByAttributes(array('key' => 'invitationKey', 'value' => $id));
400
		if ($meta === NULL)
401
			throw new CHttpException(400, Yii::t('ciims.controllers.Site', 'There was an error fulfilling your request.'));
402
403
		$model = new InviteForm;
404
		$model->email = Users::model()->findByPk($meta->user_id)->email;
405
406
		if (Cii::get($_POST, 'InviteForm', NULL) !== NULL)
407
		{
408
			$model->attributes = Cii::get($_POST, 'InviteForm', NULL);
409
			$model->id = $meta->user_id;
410
411
			if ($model->acceptInvite())
412
			{
413
				$meta->delete();
414
				return $this->render('invitesuccess');
415
			}
416
		}
417
418
		$this->render('acceptinvite', array(
419
			'model' => $model
420
		));
421
	}
422
	
423
	/**
424
	 * Returns a sanitized $_GET['next'] URL if it is set.
425
	 * @return mixed
426
	 */
427
	private function _getNext()
428
	{
429
		return str_replace('ftp://', '', str_replace('http://', '', str_replace('https://', '', Yii::app()->request->getParam('next', false))));
430
	}
431
}
432