<?xml version="1.0"?>
<News hasArchived="true" page="7968" pageCount="10848" pageSize="10" timestamp="Fri, 02 Oct 2026 09:26:57 -0400" url="https://my3.my.umbc.edu/posts.xml?mode=activity&amp;page=7968&amp;range=30">
<NewsItem contentIssues="false" id="40553" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40553">
<Title>Women's Recreation Locker Room Closed Saturday, January 25th</Title>
<Tagline>Women's Recreation Locker Room Closed Saturday, January 25th</Tagline>
<Body>
<![CDATA[
    <div class="html-content">All UMBC Students, Faculty, Staff, and RAC Members:<br><br>The Women's Recreation Locker Room will be <u><strong>CLOSED</strong></u> from 11am-3:30pm on Saturday, January 25th for a basketball game. <br><br>Please use the Women's Pool Locker Room during that time.<br><br>Thank you for your cooperation!<br><br>--<br>RAC Staff<br>
    </div>
]]>
</Body>
<Summary>All UMBC Students, Faculty, Staff, and RAC Members:  The Women's Recreation Locker Room will be CLOSED from 11am-3:30pm on Saturday, January 25th for a basketball game.   Please use the Women's...</Summary>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40553/guest@my.umbc.edu/9378c6b25fc40772375e8c685d3cf0b2/api/pixel</TrackingUrl>
<Group token="recsports">Recreation at the RAC</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/recsports</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/xsmall.png?1661189624</AvatarUrl>
<AvatarUrl size="original">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/original.png?1661189624</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/xxlarge.png?1661189624</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/xlarge.png?1661189624</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/large.png?1661189624</AvatarUrl>
<AvatarUrl size="medium">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/medium.png?1661189624</AvatarUrl>
<AvatarUrl size="small">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/small.png?1661189624</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/xsmall.png?1661189624</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/257/f9c91c92f9b48ff33e640906e80bc588/xxsmall.png?1661189624</AvatarUrl>
<Sponsor>Recreation at the RAC</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 15:21:01 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40552" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40552">
<Title>Validation and Exception Handling: From the UI to the Backend</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=36697&amp;c=1626737202" rel="nofollow external" class="bo"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=36697&amp;c=1626737202" alt="" style="max-width: 100%; height: auto;"></a><p>Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached a point when we had to take architectural actions to accommodate all the exceptional cases our quite large software project needed to handle. Below is a list of practices we came to value and apply when it comes to validation and exception handling.</p>
    <p></p>
    <hr>
    <h2>Validation vs. Exception Handling</h2>
    <p>When we started discussing our problem, one thing surfaced very quickly. What is validation and what is exception handling? For example in a user registration form, we have some rules for the password (it must contain both numbers and letters). If the user enters only letters, is that a validation issue or an exception. Should the UI validate that, or just pass it to the backend and catch any exceptions that my be thrown?</p>
    <p>We reached a common conclusion that validation refers to rules defined by the system and verified against user provided data. A validation should not care about how the business logic works, or how the system for that matter works. For example, our operating system may expect, without any protests, a password composed of plain letters. However we want to enforce a combination of letters and numbers. This is a case for validation, a rule we want to impose.</p>
    <p>On the other hand, exceptions are cases when our system may function in an unpredicted way, wrongly, or not at all if some specific data is provided in a wrong format. For example, in the above example, if the username already exists on the system, it is a case of an exception. Our business logic should be able to throw the appropriate exception and the UI catch and handle it so that the user will see a nice message.</p>
    <hr>
    <h2>Validating in the User Interface</h2>
    <p>Now that we made clear what our goals are, let’s see some examples based on the same user registration form idea.</p>
    <h3>Validating in JavaScript</h3>
    <p>To most of today’s browsers, JavaScript is second nature. There is almost no webpage without some degree of JavaScript in it. One good practice is to validate some basic things in JavaScript.</p>
    <p>Let’s say we have a simple user registration form in <code>index.php</code>, as described below.</p>
    <pre>&lt;!DOCTYPE html&gt;&#x000A;    &lt;html&gt;&#x000A;    	&lt;head&gt;&#x000A;    		&lt;title&gt;User Registration&lt;/title&gt;&#x000A;    		&lt;meta charset="UTF-8"&gt;&#x000A;    	&lt;/head&gt;&#x000A;    	&lt;body&gt;&#x000A;    		&lt;h3&gt;Register new account&lt;/h3&gt;&#x000A;    		&lt;form&gt;&#x000A;    			Username:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="text" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			Password:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="password" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			Confirm:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="password" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    		&lt;/form&gt;&#x000A;    	&lt;/body&gt;&#x000A;    &lt;/html&gt;&#x000A;    </pre>
    <p>This will output something similar to the image below:</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/RegistrationForm.png" alt="RegistrationForm" width="244" height="227" style="max-width: 100%; height: auto;"><br> <p>Every such form should validate that the text entered in the two password fields are equal. Obviously this is to ensure the user does not make a mistake when typing in his or her password. With JavaScript, doing the validation is quite simple.</p>
    <p>First we need to update a little bit of our HTML code.</p>
    <pre>&lt;form onsubmit="return validatePasswords(this);"&gt;&#x000A;    	Username:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="text" /&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	Password:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="password" name="password"/&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	Confirm:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="password" name="confirm"/&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    &lt;/form&gt;&#x000A;    </pre>
    <p>We added names to the password input fields so we can identify them. Then we specified that on submit the form should return the result of a function called <code>validatePasswords()</code>. This function is the JavaScript we’ll write. Simple scripts like this can be kept in the HTML file, other, more sophisticated ones should go in their own JavaScript files.</p>
    <pre>&lt;script&gt;&#x000A;    	function validatePasswords(form) {&#x000A;    		if (form.password.value !== form.confirm.value) {&#x000A;    			alert("Passwords do not match");&#x000A;    			return false;&#x000A;    		}&#x000A;    		return true;&#x000A;    	}&#x000A;    &#x000A;    &lt;/script&gt;&#x000A;    </pre>
    <p>The only thing we do here is to compare the values of the two input fields named “<code>password</code>” and “<code>confirm</code>“. We can reference the form by the parameter we send in when calling the function. We used “<code>this</code>” in the form’s <code>onsubmit</code> attribute, so the form itself is sent to the function.</p>
    <p>When the values are the same, <code>true</code> will be returned and the form will be submitted, otherwise an alert message will be shown telling the user the passwords do not match.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/PasswordDoNotMatchAlert.png" alt="PasswordDoNotMatchAlert" width="471" height="227" style="max-width: 100%; height: auto;"><br> <h3>HTML5 Validations</h3>
    <p>While we can use JavaScript to validate most of our inputs, there are cases when we want to go on an easier path. Some degree of input validation is available in HTML5, and most browsers are happy to apply them. Using HTML5 validation is simpler in some cases, though it offers less flexibility.</p>
    <pre>&lt;head&gt;&#x000A;    	&lt;title&gt;User Registration&lt;/title&gt;&#x000A;    	&lt;meta charset="UTF-8"&gt;&#x000A;    	&lt;style&gt;&#x000A;    		input {&#x000A;    			width: 200px;&#x000A;    		}&#x000A;    		input:required:valid {&#x000A;    			border-color: mediumspringgreen;&#x000A;    		}&#x000A;    		input:required:invalid {&#x000A;    			border-color: lightcoral;&#x000A;    		}&#x000A;    	&lt;/style&gt;&#x000A;    &lt;/head&gt;&#x000A;    &lt;body&gt;&#x000A;    	&lt;h3&gt;Register new account&lt;/h3&gt;&#x000A;    	&lt;form onsubmit="return validatePasswords(this);"&gt;&#x000A;    		Username:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="text" name="userName" required/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Password:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="password" name="password"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Confirm:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="password" name="confirm"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Email Address:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="email" name="email" required placeholder="A Valid Email Address"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Website:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="url" name="website" required pattern="https?://.+"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    	&lt;/form&gt;&#x000A;    &lt;/body&gt;&#x000A;    </pre>
    <p>To demonstrate several validation cases, we extended our form a little bit. We added an email address and a website also. HTML validations were set on three fields.</p>
    <ul>
    <li> The text input <code>username</code> is just simply required. It will validate with any string longer than zero characters.</li>
    <li> The email address field is of type “<code>email</code>” and when we specify the “<code>required</code>” attribute, browsers will apply a validation to the field.</li>
    <li> Finally, the website field is of type “<code>url</code>“. We also specified a “<code>pattern</code>” attribute where you can write your regular expressions that validate the required fields.</li>
    </ul>
    <p>To make the user aware of the state of the fields, we also used a little bit of CSS to color the borders of the inputs in red or green, depending on the state of the required validation.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HTMLValidations.png" alt="HTMLValidations" width="251" height="324" style="max-width: 100%; height: auto;"><br> <p>The problem with HTML validations is that different browsers behave differently when you try to submit the form. Some browsers will just apply the CSS to inform the users, others will prevent the submission of the form altogether. I recommend you to test your HTML validations thoroughly in different browsers and if needed also provide a JavaScript fallback for those browsers that are not smart enough.</p>
    <hr>
    <h2>Validating in Models</h2>
    <p>By now many people know about Robert C. Martin’s clean architecture proposal, in which the MVC framework is only for presentation and not for business logic.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesign1.png" alt="HighLevelDesign" width="1142" height="739" style="max-width: 100%; height: auto;"><br> <p>Essentially, your business logic should reside in a separate, well isolated place, organized to reflect the architecture of your application, while the framework’s views and controllers should control the delivery of the content to the user and models could be dropped altogether or, if needed, used only to perform delivery related operations. One such operation is validation. Most frameworks have great validation features. It would be a shame to not put your models at work and do a little validation there.</p>
    <p>We will not install several MVC web frameworks to demonstrate how to validate our previous forms, but here are two approximate solutions in Laravel and CakePHP.</p>
    <h3>Validation in a Laravel Model</h3>
    <p>Laravel is designed so that you have more access to validation in the Controller where you also have direct access to the input from the user. The built-in validator kind of prefers to be used there. However there are suggestions on the Internet that validating in models is still a good thing to do in Laravel. A complete example and solution by Jeffrey Way can be found on <a href="https://github.com/JeffreyWay/Laravel-Model-Validation" rel="nofollow external" class="bo">his Github repository</a>.</p>
    <p>If you prefer to write your own solution, you could do something similar to the model below.</p>
    <pre>class UserACL extends Eloquent {&#x000A;        private $rules = array(&#x000A;            'userName' =&gt; 'required|alpha|min:5',&#x000A;            'password'  =&gt; 'required|min:6',&#x000A;    		'confirm' =&gt; 'required|min:6',&#x000A;    		'email' =&gt; 'required|email',&#x000A;    		'website' =&gt; 'url'&#x000A;        );&#x000A;    &#x000A;        private $errors;&#x000A;    &#x000A;        public function validate($data) {&#x000A;            $validator = Validator::make($data, $this-&gt;rules);&#x000A;    &#x000A;            if ($validator-&gt;fails()) {&#x000A;                $this-&gt;errors = $validator-&gt;errors;&#x000A;                return false;&#x000A;            }&#x000A;            return true;&#x000A;        }&#x000A;    &#x000A;        public function errors() {&#x000A;            return $this-&gt;errors;&#x000A;        }&#x000A;    }</pre>
    <p>You can use this from your controller by simply creating the <code>UserACL</code> object and call validate on it. You will probably have the “<code>register</code>” method also on this model, and the <code>register</code> will just delegate the already validated data to your business logic.</p>
    <h3>Validation in a CakePHP Model</h3>
    <p>CakePHP promotes validation in models as well. It has extensive validation functionality at model level. Here is about how a validation for our form would look like in CakePHP.</p>
    <pre>class UserACL extends AppModel {&#x000A;    &#x000A;        public $validate = [&#x000A;    		'userName' =&gt; [&#x000A;    			'rule' =&gt; ['minLength', 5],&#x000A;    			'required' =&gt; true,&#x000A;    			'allowEmpty' =&gt; false,&#x000A;    			'on' =&gt; 'create',&#x000A;    			'message' =&gt; 'User name must be at least 5 characters long.'&#x000A;    		],&#x000A;            'password' =&gt; [&#x000A;                'rule'    =&gt; ['equalsTo', 'confirm'],&#x000A;                'message' =&gt; 'The two passwords do not match. Please re-enter them.'&#x000A;            ]&#x000A;        ];&#x000A;    &#x000A;        public function equalsTo($checkedField, $otherField = null) {&#x000A;    		$value = $this-&gt;getFieldValue($checkedField);&#x000A;            return $value === $this-&gt;data[$this-&gt;name][$otherField];&#x000A;        }&#x000A;    &#x000A;    	private function getFieldValue($fieldName) {&#x000A;    	    return array_values($otherField)[0];&#x000A;    	}&#x000A;    }</pre>
    <p>We only exemplified the rules partially. It is enough to highlight the power of validation in the model. CakePHP is particularly good at this. It has a great number of built-in validation functions like “<code>minLength</code>” in the example and various ways to provide feedback to the user. Even more, concepts like “<code>required</code>” or “<code>allowEmpty</code>” are not actually validation rules. Cake will look at these when generating your view and put HTML validations also on fields marked with these parameters. However rules are great and can easily be extended by just simply creating methods on the model class as we did to compare the two password fields. Finally, you can always specify the message you want to send to the views in case of validation failure. More on CakePHP validation in <a href="http://book.cakephp.org/2.0/en/models/data-validation.html" rel="nofollow external" class="bo">the cookbook</a>.</p>
    <p>Validation in general at the model level has its advantages. Each framework provides easy access to the input fields and creates the mechanism to notify the user in case of validation failure. No need for try-catch statements or any other sophisticated steps. Validation on the server side also assures that the data gets validated, no matter what. The user can not trick our software any more as with HTML or JavaScript. Of course, each server side validation comes with the cost of a network round-trip and computing power on the provider’s side instead of the client’s side.</p>
    <hr>
    <h2>Throwing Exceptions from the Business Logic</h2>
    <p>The final step in checking data before committing it to the system is at the level of our business logic. Information that reaches this part of the system should be sanitized enough to be usable. The business logic should only check for cases that are critical for it. For example, adding a user that already exists is a case when we throw an exception. Checking the length of the user to be at least five characters should not happen at this level. We can safely assume that such limitations were enforced at higher levels.</p>
    <p>On the other hand, comparing the two passwords is a matter for discussion. For example, if we just encrypt and save the password near the user in a database, we could drop the check and assume previous layers made sure the passwords are equal. However, if we create a real user on the operating system using an API or a CLI tool that actually requires a username, password, and password confirmation, we may want to take the second entry also and send it to a CLI tool. Let it re-validate if the passwords match and be ready to throw an exception if they do not. This way we modeled our business logic to match how the real operating system behaves.</p>
    <h3>Throwing Exceptions from PHP</h3>
    <p>Throwing exceptions from PHP is very easy. Let’s create our user access control class, and demonstrate how to implement a user addition functionality.</p>
    <pre>class UserControlTest extends PHPUnit_Framework_TestCase {&#x000A;    	function testBehavior() {&#x000A;    		$this-&gt;assertTrue(true);&#x000A;    	}&#x000A;    }</pre>
    <p>I always like to start with something simple that gets me going. Creating a stupid test is a great way to do so. It also forces me to think about what I want to implement. A test named <code>UserControlTest</code> means I thought I will need a <code>UserControl</code> class to implement my method.</p>
    <pre>require_once __DIR__ . '/../UserControl.php';&#x000A;    class UserControlTest extends PHPUnit_Framework_TestCase {&#x000A;    &#x000A;    	/**&#x000A;    	 * @expectedException Exception&#x000A;    	 * @expectedExceptionMessage User can not be empty&#x000A;    	 */&#x000A;    	function testEmptyUsernameWillThrowException() {&#x000A;    		$userControl = new UserControl();&#x000A;    		$userControl-&gt;add('');&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>The next test to write is a degenerative case. We will not test for a specific user length, but we want to make sure we do not want to add an empty user. It is sometimes easy to lose the content of a variable from view to business, over all those layers of our application. This code will obviously fail, because we do not have a class yet.</p>
    <pre>PHP Warning:  require_once([long-path-here]/Test/../UserControl.php):&#x000A;    failed to open stream: No such file or directory in&#x000A;    [long-path-here]/Test/UserControlTest.php on line 2</pre>
    <p>Let’s create the class and run our tests. Now we have another problem.</p>
    <pre>PHP Fatal error:  Call to undefined method UserControl::add()</pre>
    <p>But we can fix that, too, in just a couple of seconds.</p>
    <pre>class UserControl {&#x000A;    &#x000A;    	public function add($username) {&#x000A;    &#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>Now we can have a nice test failure telling us the whole story of our code.</p>
    <pre>1) UserControlTest::testEmptyUsernameWillThrowException&#x000A;    Failed asserting that exception of type "Exception" is thrown.</pre>
    <p>Finally we can do some actual coding.</p>
    <pre>public function add($username) {&#x000A;    	if(!$username) {&#x000A;    		throw new Exception();&#x000A;    	}&#x000A;    }</pre>
    <p>That makes the expectation for the exception pass, but without specifying a message the test will still fail.</p>
    <pre>1) UserControlTest::testEmptyUsernameWillThrowException&#x000A;    Failed asserting that exception message '' contains 'User can not be empty'.</pre>
    <p>Time to write the Exception’s message</p>
    <pre>public function add($username) {&#x000A;    	if(!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    }</pre>
    <p>Now, that makes our test pass. As you can observe, PHPUnit verifies that the expected exception message is contained in the actually thrown exception. This is useful because it allows us to dynamically construct messages and only check for the stable part. A common example is when you throw an error with a base text and at the end you specify the reason for that exception. Reasons are usually provided by third party libraries or application.</p>
    <pre>/**&#x000A;     * @expectedException Exception&#x000A;     * @expectedExceptionMessage Cannot add user George&#x000A;     */&#x000A;    function testWillNotAddAnAlreadyExistingUser() {&#x000A;    	$command = \Mockery::mock('SystemCommand');&#x000A;    	$command-&gt;shouldReceive('execute')-&gt;once()-&gt;with('adduser George')-&gt;andReturn(false);&#x000A;    	$command-&gt;shouldReceive('getFailureMessage')-&gt;once()-&gt;andReturn('User already exists on the system.');&#x000A;    	$userControl = new UserControl($command);&#x000A;    	$userControl-&gt;add('George');&#x000A;    }</pre>
    <p>Throwing errors on duplicate users will allow us to explore this message construction a step further. The test above creates a mock which will simulate a system command, it will fail and on request, it will return a nice failure message. We will inject this command to the <code>UserControl</code> class for internal use.</p>
    <pre>class UserControl {&#x000A;    &#x000A;    	private $systemCommand;&#x000A;    &#x000A;    	public function __construct(SystemCommand $systemCommand = null) {&#x000A;    		$this-&gt;systemCommand = $systemCommand ? : new SystemCommand();&#x000A;    	}&#x000A;    &#x000A;    	public function add($username) {&#x000A;    		if (!$username) {&#x000A;    			throw new Exception('User can not be empty!');&#x000A;    		}&#x000A;    	}&#x000A;    &#x000A;    }&#x000A;    &#x000A;    class SystemCommand {&#x000A;    &#x000A;    }</pre>
    <p>Injecting the a <code>SystemCommand</code> instance was quite easy. We also created a <code>SystemCommand</code> class inside our test just to avoid syntax problems. We won’t implement it. Its scope exceeds this tutorial’s topic. However, we have another test failure message.</p>
    <pre>1) UserControlTest::testWillNotAddAnAlreadyExistingUser&#x000A;    Failed asserting that exception of type "Exception" is thrown.</pre>
    <p>Yep. We are not throwing any exceptions. The logic to call the system command and try to add the user is missing.</p>
    <pre>public function add($username) {&#x000A;    	if (!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    &#x000A;    	if(!$this-&gt;systemCommand-&gt;execute(sprintf('adduser %s', $username))) {&#x000A;    		throw new Exception(&#x000A;    				sprintf('Cannot add user %s. Reason: %s',&#x000A;    						$username,&#x000A;    						$this-&gt;systemCommand-&gt;getFailureMessage()&#x000A;    				)&#x000A;    			);&#x000A;    	}&#x000A;    }</pre>
    <p>Now, those modifications to the <code>add()</code> method can do the trick. We try to execute our command on the system, no matter what, and if the system says it can not add the user for whatever reason we throw an exception. This exception’s message will be part hard-coded, with the user’s name attached and then the reason from the system command concatenated at the end. As you can see, this code makes our test pass.</p>
    <h3>Custom Exceptions</h3>
    <p>Throwing exceptions with different messages is enough in most cases. However, when you have a more complex system you also need to catch these exceptions and take different actions based on them. Analyzing an exception’s message and taking action solely on that can lead to some annoying problems. First, strings are part of the UI, presentation, and they have a volatile nature. Basing logic on ever changing strings will lead to dependency management nightmare. Second, calling a <code>getMessage()</code> method on the caught exception each time is also a strange way to decide what to do next.</p>
    <p>With all these in mind, creating our own exceptions is the next logical step to take.</p>
    <pre>/**&#x000A;     * @expectedException ExceptionCannotAddUser&#x000A;     * @expectedExceptionMessage Cannot add user George&#x000A;     */&#x000A;    function testWillNotAddAnAlreadyExistingUser() {&#x000A;    	$command = \Mockery::mock('SystemCommand');&#x000A;    	$command-&gt;shouldReceive('execute')-&gt;once()-&gt;with('adduser George')-&gt;andReturn(false);&#x000A;    	$command-&gt;shouldReceive('getFailureMessage')-&gt;once()-&gt;andReturn('User already exists on the system.');&#x000A;    	$userControl = new UserControl($command);&#x000A;    	$userControl-&gt;add('George');&#x000A;    }</pre>
    <p>We modified our test to expect our own custom exception, <code>ExceptionCannotAddUser</code>. The rest of the test is unchanged.</p>
    <pre>class ExceptionCannotAddUser extends Exception {&#x000A;    &#x000A;    	public function __construct($userName, $reason) {&#x000A;    		$message = sprintf(&#x000A;    			'Cannot add user %s. Reason: %s',&#x000A;    			$userName, $reason&#x000A;    		);&#x000A;    		parent::__construct($message, 13, null);&#x000A;    	}&#x000A;    }</pre>
    <p>The class that implements our custom exception is like any other class, but it has to extend <code>Exception</code>. Using custom exceptions also provides us a great place to do all the presentation related string manipulation. Moving the concatenation here, we also eliminated presentation from the business logic and respected the single responsibility principle.</p>
    <pre>public function add($username) {&#x000A;    	if (!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    &#x000A;    	if(!$this-&gt;systemCommand-&gt;execute(sprintf('adduser %s', $username))) {&#x000A;    		throw new ExceptionCannotAddUser($username, $this-&gt;systemCommand-&gt;getFailureMessage());&#x000A;    	}&#x000A;    }</pre>
    <p>Throwing our own exception is just a matter of changing the old “<code>throw</code>” command to the new one and sending in two parameters instead of composing the message here. Of course all tests are passing.</p>
    <pre>PHPUnit 3.7.28 by Sebastian Bergmann.&#x000A;    &#x000A;    ..&#x000A;    &#x000A;    Time: 18 ms, Memory: 3.00Mb&#x000A;    &#x000A;    OK (2 tests, 4 assertions)&#x000A;    &#x000A;    Done.</pre>
    <h3>Catching Exceptions in Your MVC</h3>
    <p>Exceptions must be caught at some point, unless you want your user to see them as they are. If you are using an MVC framework you will probably want to catch exceptions in the controller or model. After the exception is caught, it is transformed in a message to the user and rendered inside your view. A common way to achieve this is to create a “<code>tryAction($action)</code>” method in your application’s base controller or model and always call it with the current action. In that method you can do the catching logic and nice message generation to suit your framework.</p>
    <p>If you do not use a web framework, or a web interface for that matter, your presentation layer should take care of catching and transforming these exceptions.</p>
    <p>If you develop a library, catching your exceptions will be the responsibility of your clients.</p>
    <hr>
    <h2>Final Thoughts</h2>
    <p>That’s it. We traversed all the layers of our application. We validated in JavaScript, HTML and in our models. We’ve thrown and caught exceptions from our business logic and even created our own custom exceptions. This approach to validation and exception handling can be applied from small to big projects without any severe problems. However if your validation logic is getting very complex, and different parts of your project uses overlapping parts of logic, you may consider extracting all validations that can be done at a specific level to a validation service or validation provider. These levels may include, but not need to be limited to JavaScript validator, backend PHP validator, third party communication validator and so on.</p>
    <p>Thank you for reading. Have a nice day.</p>
    </div>
]]>
</Body>
<Summary>Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached...</Summary>
<Website>http://feedproxy.google.com/~r/nettuts/~3/Xj4eVNKZjvw/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40552/guest@my.umbc.edu/e92bcd53ee5d1b1502f2dac1184318c7/api/pixel</TrackingUrl>
<Tag>css</Tag>
<Tag>development</Tag>
<Tag>exception-handling</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>tutorials</Tag>
<Tag>validation-handling</Tag>
<Tag>wed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 14:41:29 -0500</PostedAt>
<EditAt>Thu, 23 Jan 2014 14:41:29 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="41059" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41059">
<Title>Validation and Exception Handling: From the UI to the Backend</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached a point when we had to take architectural actions to accommodate all the exceptional cases our quite large software project needed to handle. Below is a list of practices we came to value and apply when it comes to validation and exception handling.</p>
    <p></p>
    <hr>
    <h2>Validation vs. Exception Handling</h2>
    <p>When we started discussing our problem, one thing surfaced very quickly. What is validation and what is exception handling? For example in a user registration form, we have some rules for the password (it must contain both numbers and letters). If the user enters only letters, is that a validation issue or an exception. Should the UI validate that, or just pass it to the backend and catch any exceptions that my be thrown?</p>
    <p>We reached a common conclusion that validation refers to rules defined by the system and verified against user provided data. A validation should not care about how the business logic works, or how the system for that matter works. For example, our operating system may expect, without any protests, a password composed of plain letters. However we want to enforce a combination of letters and numbers. This is a case for validation, a rule we want to impose.</p>
    <p>On the other hand, exceptions are cases when our system may function in an unpredicted way, wrongly, or not at all if some specific data is provided in a wrong format. For example, in the above example, if the username already exists on the system, it is a case of an exception. Our business logic should be able to throw the appropriate exception and the UI catch and handle it so that the user will see a nice message.</p>
    <hr>
    <h2>Validating in the User Interface</h2>
    <p>Now that we made clear what our goals are, let's see some examples based on the same user registration form idea.</p>
    <h3>Validating in JavaScript</h3>
    <p>To most of today's browsers, JavaScript is second nature. There is almost no webpage without some degree of JavaScript in it. One good practice is to validate some basic things in JavaScript.</p>
    <p>Let's say we have a simple user registration form in <code>index.php</code>, as described below.</p>
    <pre>&lt;!DOCTYPE html&gt;&#x000A;    &lt;html&gt;&#x000A;    	&lt;head&gt;&#x000A;    		&lt;title&gt;User Registration&lt;/title&gt;&#x000A;    		&lt;meta charset="UTF-8"&gt;&#x000A;    	&lt;/head&gt;&#x000A;    	&lt;body&gt;&#x000A;    		&lt;h3&gt;Register new account&lt;/h3&gt;&#x000A;    		&lt;form&gt;&#x000A;    			Username:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="text" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			Password:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="password" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			Confirm:&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="password" /&gt;&#x000A;    			&lt;br/&gt;&#x000A;    			&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    		&lt;/form&gt;&#x000A;    	&lt;/body&gt;&#x000A;    &lt;/html&gt;</pre>
    <p>This will output something similar to the image below:</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/RegistrationForm.png" alt="RegistrationForm" width="244" height="227" style="max-width: 100%; height: auto;"><br>
    
    <p>Every such form should validate that the text entered in the two password fields are equal. Obviously this is to ensure the user does not make a mistake when typing in his or her password. With JavaScript, doing the validation is quite simple.</p>
    <p>First we need to update a little bit of our HTML code.</p>
    <pre>&lt;form onsubmit="return validatePasswords(this);"&gt;&#x000A;    	Username:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="text" /&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	Password:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="password" name="password"/&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	Confirm:&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="password" name="confirm"/&gt;&#x000A;    	&lt;br/&gt;&#x000A;    	&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    &lt;/form&gt;</pre>
    <p>We added names to the password input fields so we can identify them. Then we specified that on submit the form should return the result of a function called <code>validatePasswords()</code>. This function is the JavaScript we'll write. Simple scripts like this can be kept in the HTML file, other, more sophisticated ones should go in their own JavaScript files.</p>
    <pre>&lt;script&gt;&#x000A;    	function validatePasswords(form) {&#x000A;    		if (form.password.value !== form.confirm.value) {&#x000A;    			alert("Passwords do not match");&#x000A;    			return false;&#x000A;    		}&#x000A;    		return true;&#x000A;    	}&#x000A;    &#x000A;    &lt;/script&gt;</pre>
    <p>The only thing we do here is to compare the values of the two input fields named "<code>password</code>" and "<code>confirm</code>". We can reference the form by the parameter we send in when calling the function. We used "<code>this</code>" in the form's <code>onsubmit</code> attribute, so the form itself is sent to the function.</p>
    <p>When the values are the same, <code>true</code> will be returned and the form will be submitted, otherwise an alert message will be shown telling the user the passwords do not match.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/PasswordDoNotMatchAlert.png" alt="PasswordDoNotMatchAlert" width="471" height="227" style="max-width: 100%; height: auto;"><br>
    
    <h3>HTML5 Validations</h3>
    <p>While we can use JavaScript to validate most of our inputs, there are cases when we want to go on an easier path. Some degree of input validation is available in HTML5, and most browsers are happy to apply them. Using HTML5 validation is simpler in some cases, though it offers less flexibility.</p>
    <pre>&lt;head&gt;&#x000A;    	&lt;title&gt;User Registration&lt;/title&gt;&#x000A;    	&lt;meta charset="UTF-8"&gt;&#x000A;    	&lt;style&gt;&#x000A;    		input {&#x000A;    			width: 200px;&#x000A;    		}&#x000A;    		input:required:valid {&#x000A;    			border-color: mediumspringgreen;&#x000A;    		}&#x000A;    		input:required:invalid {&#x000A;    			border-color: lightcoral;&#x000A;    		}&#x000A;    	&lt;/style&gt;&#x000A;    &lt;/head&gt;&#x000A;    &lt;body&gt;&#x000A;    	&lt;h3&gt;Register new account&lt;/h3&gt;&#x000A;    	&lt;form onsubmit="return validatePasswords(this);"&gt;&#x000A;    		Username:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="text" name="userName" required/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Password:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="password" name="password"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Confirm:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="password" name="confirm"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Email Address:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="email" name="email" required placeholder="A Valid Email Address"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		Website:&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="url" name="website" required pattern="https?://.+"/&gt;&#x000A;    		&lt;br/&gt;&#x000A;    		&lt;input type="submit" name="register" value="Register"&gt;&#x000A;    	&lt;/form&gt;&#x000A;    &lt;/body&gt;</pre>
    <p>To demonstrate several validation cases, we extended our form a little bit. We added an email address and a website also. HTML validations were set on three fields.</p>
    <ul>
    <li>
    		The text input <code>username</code> is just simply required. It will validate with any string longer than zero characters.
    	</li>
    <li>
    		The email address field is of type "<code>email</code>" and when we specify the "<code>required</code>" attribute, browsers will apply a validation to the field.
    	</li>
    <li>
    		Finally, the website field is of type "<code>url</code>". We also specified a "<code>pattern</code>" attribute where you can write your regular expressions that validate the required fields.
    	</li>
    </ul>
    <p>To make the user aware of the state of the fields, we also used a little bit of CSS to color the borders of the inputs in red or green, depending on the state of the required validation.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HTMLValidations.png" alt="HTMLValidations" width="251" height="324" style="max-width: 100%; height: auto;"><br>
    
    <p>The problem with HTML validations is that different browsers behave differently when you try to submit the form. Some browsers will just apply the CSS to inform the users, others will prevent the submission of the form altogether. I recommend you to test your HTML validations thoroughly in different browsers and if needed also provide a JavaScript fallback for those browsers that are not smart enough.</p>
    <hr>
    <h2>Validating in Models</h2>
    <p>By now many people know about Robert C. Martin's clean architecture proposal, in which the MVC framework is only for presentation and not for business logic.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesign1.png" alt="HighLevelDesign" width="1142" height="739" style="max-width: 100%; height: auto;"><br>
    
    <p>Essentially, your business logic should reside in a separate, well isolated place, organized to reflect the architecture of your application, while the framework's views and controllers should control the delivery of the content to the user and models could be dropped altogether or, if needed, used only to perform delivery related operations. One such operation is validation. Most frameworks have great validation features. It would be a shame to not put your models at work and do a little validation there.</p>
    <p>We will not install several MVC web frameworks to demonstrate how to validate our previous forms, but here are two approximate solutions in Laravel and CakePHP.</p>
    <h3>Validation in a Laravel Model</h3>
    <p>Laravel is designed so that you have more access to validation in the Controller where you also have direct access to the input from the user. The built-in validator kind of prefers to be used there. However there are suggestions on the Internet that validating in models is still a good thing to do in Laravel. A complete example and solution by Jeffrey Way can be found on <a href="https://github.com/JeffreyWay/Laravel-Model-Validation" rel="nofollow external" class="bo">his Github repository</a>.</p>
    <p>If you prefer to write your own solution, you could do something similar to the model below.</p>
    <pre>class UserACL extends Eloquent {&#x000A;        private $rules = array(&#x000A;            'userName' =&gt; 'required|alpha|min:5',&#x000A;            'password'  =&gt; 'required|min:6',&#x000A;    		'confirm' =&gt; 'required|min:6',&#x000A;    		'email' =&gt; 'required|email',&#x000A;    		'website' =&gt; 'url'&#x000A;        );&#x000A;    &#x000A;        private $errors;&#x000A;    &#x000A;        public function validate($data) {&#x000A;            $validator = Validator::make($data, $this-&gt;rules);&#x000A;    &#x000A;            if ($validator-&gt;fails()) {&#x000A;                $this-&gt;errors = $validator-&gt;errors;&#x000A;                return false;&#x000A;            }&#x000A;            return true;&#x000A;        }&#x000A;    &#x000A;        public function errors() {&#x000A;            return $this-&gt;errors;&#x000A;        }&#x000A;    }</pre>
    <p>You can use this from your controller by simply creating the <code>UserACL</code> object and call validate on it. You will probably have the "<code>register</code>" method also on this model, and the <code>register</code> will just delegate the already validated data to your business logic.</p>
    <h3>Validation in a CakePHP Model</h3>
    <p>CakePHP promotes validation in models as well. It has extensive validation functionality at model level. Here is about how a validation for our form would look like in CakePHP.</p>
    <pre>class UserACL extends AppModel {&#x000A;    &#x000A;        public $validate = [&#x000A;    		'userName' =&gt; [&#x000A;    			'rule' =&gt; ['minLength', 5],&#x000A;    			'required' =&gt; true,&#x000A;    			'allowEmpty' =&gt; false,&#x000A;    			'on' =&gt; 'create',&#x000A;    			'message' =&gt; 'User name must be at least 5 characters long.'&#x000A;    		],&#x000A;            'password' =&gt; [&#x000A;                'rule'    =&gt; ['equalsTo', 'confirm'],&#x000A;                'message' =&gt; 'The two passwords do not match. Please re-enter them.'&#x000A;            ]&#x000A;        ];&#x000A;    &#x000A;        public function equalsTo($checkedField, $otherField = null) {&#x000A;    		$value = $this-&gt;getFieldValue($checkedField);&#x000A;            return $value === $this-&gt;data[$this-&gt;name][$otherField];&#x000A;        }&#x000A;    &#x000A;    	private function getFieldValue($fieldName) {&#x000A;    	    return array_values($otherField)[0];&#x000A;    	}&#x000A;    }</pre>
    <p>We only exemplified the rules partially. It is enough to highlight the power of validation in the model. CakePHP is particularly good at this. It has a great number of built-in validation functions like "<code>minLength</code>" in the example and various ways to provide feedback to the user. Even more, concepts like "<code>required</code>" or "<code>allowEmpty</code>" are not actually validation rules. Cake will look at these when generating your view and put HTML validations also on fields marked with these parameters. However rules are great and can easily be extended by just simply creating methods on the model class as we did to compare the two password fields. Finally, you can always specify the message you want to send to the views in case of validation failure. More on CakePHP validation in <a href="http://book.cakephp.org/2.0/en/models/data-validation.html" rel="nofollow external" class="bo">the cookbook</a>.</p>
    <p>Validation in general at the model level has its advantages. Each framework provides easy access to the input fields and creates the mechanism to notify the user in case of validation failure. No need for try-catch statements or any other sophisticated steps. Validation on the server side also assures that the data gets validated, no matter what. The user can not trick our software any more as with HTML or JavaScript. Of course, each server side validation comes with the cost of a network round-trip and computing power on the provider's side instead of the client's side.</p>
    <hr>
    <h2>Throwing Exceptions from the Business Logic</h2>
    <p>The final step in checking data before committing it to the system is at the level of our business logic. Information that reaches this part of the system should be sanitized enough to be usable. The business logic should only check for cases that are critical for it. For example, adding a user that already exists is a case when we throw an exception. Checking the length of the user to be at least five characters should not happen at this level. We can safely assume that such limitations were enforced at higher levels.</p>
    <p>On the other hand, comparing the two passwords is a matter for discussion. For example, if we just encrypt and save the password near the user in a database, we could drop the check and assume previous layers made sure the passwords are equal. However, if we create a real user on the operating system using an API or a CLI tool that actually requires a username, password, and password confirmation, we may want to take the second entry also and send it to a CLI tool. Let it re-validate if the passwords match and be ready to throw an exception if they do not. This way we modeled our business logic to match how the real operating system behaves.</p>
    <h3>Throwing Exceptions from PHP</h3>
    <p>Throwing exceptions from PHP is very easy. Let's create our user access control class, and demonstrate how to implement a user addition functionality.</p>
    <pre>class UserControlTest extends PHPUnit_Framework_TestCase {&#x000A;    	function testBehavior() {&#x000A;    		$this-&gt;assertTrue(true);&#x000A;    	}&#x000A;    }</pre>
    <p>I always like to start with something simple that gets me going. Creating a stupid test is a great way to do so. It also forces me to think about what I want to implement. A test named <code>UserControlTest</code> means I thought I will need a <code>UserControl</code> class to implement my method.</p>
    <pre>require_once __DIR__ . '/../UserControl.php';&#x000A;    class UserControlTest extends PHPUnit_Framework_TestCase {&#x000A;    &#x000A;    	/**&#x000A;    	 * @expectedException Exception&#x000A;    	 * @expectedExceptionMessage User can not be empty&#x000A;    	 */&#x000A;    	function testEmptyUsernameWillThrowException() {&#x000A;    		$userControl = new UserControl();&#x000A;    		$userControl-&gt;add('');&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>The next test to write is a degenerative case. We will not test for a specific user length, but we want to make sure we do not want to add an empty user. It is sometimes easy to lose the content of a variable from view to business, over all those layers of our application. This code will obviously fail, because we do not have a class yet.</p>
    <pre>PHP Warning:  require_once([long-path-here]/Test/../UserControl.php):&#x000A;    failed to open stream: No such file or directory in&#x000A;    [long-path-here]/Test/UserControlTest.php on line 2</pre>
    <p>Let's create the class and run our tests. Now we have another problem.</p>
    <pre>PHP Fatal error:  Call to undefined method UserControl::add()</pre>
    <p>But we can fix that, too, in just a couple of seconds.</p>
    <pre>class UserControl {&#x000A;    &#x000A;    	public function add($username) {&#x000A;    &#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>Now we can have a nice test failure telling us the whole story of our code.</p>
    <pre>1) UserControlTest::testEmptyUsernameWillThrowException&#x000A;    Failed asserting that exception of type "Exception" is thrown.</pre>
    <p>Finally we can do some actual coding.</p>
    <pre>public function add($username) {&#x000A;    	if(!$username) {&#x000A;    		throw new Exception();&#x000A;    	}&#x000A;    }</pre>
    <p>That makes the expectation for the exception pass, but without specifying a message the test will still fail.</p>
    <pre>1) UserControlTest::testEmptyUsernameWillThrowException&#x000A;    Failed asserting that exception message '' contains 'User can not be empty'.</pre>
    <p>Time to write the Exception's message</p>
    <pre>public function add($username) {&#x000A;    	if(!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    }</pre>
    <p>Now, that makes our test pass. As you can observe, PHPUnit verifies that the expected exception message is contained in the actually thrown exception. This is useful because it allows us to dynamically construct messages and only check for the stable part. A common example is when you throw an error with a base text and at the end you specify the reason for that exception. Reasons are usually provided by third party libraries or application.</p>
    <pre>/**&#x000A;     * @expectedException Exception&#x000A;     * @expectedExceptionMessage Cannot add user George&#x000A;     */&#x000A;    function testWillNotAddAnAlreadyExistingUser() {&#x000A;    	$command = \Mockery::mock('SystemCommand');&#x000A;    	$command-&gt;shouldReceive('execute')-&gt;once()-&gt;with('adduser George')-&gt;andReturn(false);&#x000A;    	$command-&gt;shouldReceive('getFailureMessage')-&gt;once()-&gt;andReturn('User already exists on the system.');&#x000A;    	$userControl = new UserControl($command);&#x000A;    	$userControl-&gt;add('George');&#x000A;    }</pre>
    <p>Throwing errors on duplicate users will allow us to explore this message construction a step further. The test above creates a mock which will simulate a system command, it will fail and on request, it will return a nice failure message. We will inject this command to the <code>UserControl</code> class for internal use.</p>
    <pre>class UserControl {&#x000A;    &#x000A;    	private $systemCommand;&#x000A;    &#x000A;    	public function __construct(SystemCommand $systemCommand = null) {&#x000A;    		$this-&gt;systemCommand = $systemCommand ? : new SystemCommand();&#x000A;    	}&#x000A;    &#x000A;    	public function add($username) {&#x000A;    		if (!$username) {&#x000A;    			throw new Exception('User can not be empty!');&#x000A;    		}&#x000A;    	}&#x000A;    &#x000A;    }&#x000A;    &#x000A;    class SystemCommand {&#x000A;    &#x000A;    }</pre>
    <p>Injecting the a <code>SystemCommand</code> instance was quite easy. We also created a <code>SystemCommand</code> class inside our test just to avoid syntax problems. We won't implement it. Its scope exceeds this tutorial's topic. However, we have another test failure message.</p>
    <pre>1) UserControlTest::testWillNotAddAnAlreadyExistingUser&#x000A;    Failed asserting that exception of type "Exception" is thrown.</pre>
    <p>Yep. We are not throwing any exceptions. The logic to call the system command and try to add the user is missing.</p>
    <pre>public function add($username) {&#x000A;    	if (!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    &#x000A;    	if(!$this-&gt;systemCommand-&gt;execute(sprintf('adduser %s', $username))) {&#x000A;    		throw new Exception(&#x000A;    				sprintf('Cannot add user %s. Reason: %s',&#x000A;    						$username,&#x000A;    						$this-&gt;systemCommand-&gt;getFailureMessage()&#x000A;    				)&#x000A;    			);&#x000A;    	}&#x000A;    }</pre>
    <p>Now, those modifications to the <code>add()</code> method can do the trick. We try to execute our command on the system, no matter what, and if the system says it can not add the user for whatever reason we throw an exception. This exception's message will be part hard-coded, with the user's name attached and then the reason from the system command concatenated at the end. As you can see, this code makes our test pass.</p>
    <h3>Custom Exceptions</h3>
    <p>Throwing exceptions with different messages is enough in most cases. However, when you have a more complex system you also need to catch these exceptions and take different actions based on them. Analyzing an exception's message and taking action solely on that can lead to some annoying problems. First, strings are part of the UI, presentation, and they have a volatile nature. Basing logic on ever changing strings will lead to dependency management nightmare. Second, calling a <code>getMessage()</code> method on the caught exception each time is also a strange way to decide what to do next.</p>
    <p>With all these in mind, creating our own exceptions is the next logical step to take.</p>
    <pre>/**&#x000A;     * @expectedException ExceptionCannotAddUser&#x000A;     * @expectedExceptionMessage Cannot add user George&#x000A;     */&#x000A;    function testWillNotAddAnAlreadyExistingUser() {&#x000A;    	$command = \Mockery::mock('SystemCommand');&#x000A;    	$command-&gt;shouldReceive('execute')-&gt;once()-&gt;with('adduser George')-&gt;andReturn(false);&#x000A;    	$command-&gt;shouldReceive('getFailureMessage')-&gt;once()-&gt;andReturn('User already exists on the system.');&#x000A;    	$userControl = new UserControl($command);&#x000A;    	$userControl-&gt;add('George');&#x000A;    }</pre>
    <p>We modified our test to expect our own custom exception, <code>ExceptionCannotAddUser</code>. The rest of the test is unchanged.</p>
    <pre>class ExceptionCannotAddUser extends Exception {&#x000A;    &#x000A;    	public function __construct($userName, $reason) {&#x000A;    		$message = sprintf(&#x000A;    			'Cannot add user %s. Reason: %s',&#x000A;    			$userName, $reason&#x000A;    		);&#x000A;    		parent::__construct($message, 13, null);&#x000A;    	}&#x000A;    }</pre>
    <p>The class that implements our custom exception is like any other class, but it has to extend <code>Exception</code>. Using custom exceptions also provides us a great place to do all the presentation related string manipulation. Moving the concatenation here, we also eliminated presentation from the business logic and respected the single responsibility principle.</p>
    <pre>public function add($username) {&#x000A;    	if (!$username) {&#x000A;    		throw new Exception('User can not be empty!');&#x000A;    	}&#x000A;    &#x000A;    	if(!$this-&gt;systemCommand-&gt;execute(sprintf('adduser %s', $username))) {&#x000A;    		throw new ExceptionCannotAddUser($username, $this-&gt;systemCommand-&gt;getFailureMessage());&#x000A;    	}&#x000A;    }</pre>
    <p>Throwing our own exception is just a matter of changing the old "<code>throw</code>" command to the new one and sending in two parameters instead of composing the message here. Of course all tests are passing.</p>
    <pre>PHPUnit 3.7.28 by Sebastian Bergmann.&#x000A;    &#x000A;    ..&#x000A;    &#x000A;    Time: 18 ms, Memory: 3.00Mb&#x000A;    &#x000A;    OK (2 tests, 4 assertions)&#x000A;    &#x000A;    Done.</pre>
    <h3>Catching Exceptions in Your MVC</h3>
    <p>Exceptions must be caught at some point, unless you want your user to see them as they are. If you are using an MVC framework you will probably want to catch exceptions in the controller or model. After the exception is caught, it is transformed in a message to the user and rendered inside your view. A common way to achieve this is to create a "<code>tryAction($action)</code>" method in your application's base controller or model and always call it with the current action. In that method you can do the catching logic and nice message generation to suit your framework.</p>
    <p>If you do not use a web framework, or a web interface for that matter, your presentation layer should take care of catching and transforming these exceptions.</p>
    <p>If you develop a library, catching your exceptions will be the responsibility of your clients.</p>
    <hr>
    <h2>Final Thoughts</h2>
    <p>That's it. We traversed all the layers of our application. We validated in JavaScript, HTML and in our models. We've thrown and caught exceptions from our business logic and even created our own custom exceptions. This approach to validation and exception handling can be applied from small to big projects without any severe problems. However if your validation logic is getting very complex, and different parts of your project uses overlapping parts of logic, you may consider extracting all validations that can be done at a specific level to a validation service or validation provider. These levels may include, but not need to be limited to JavaScript validator, backend PHP validator, third party communication validator and so on.</p>
    <p>Thank you for reading. Have a nice day.</p>
    </div>
]]>
</Body>
<Summary>Sooner or later in your programming career you will be faced with the dilemma of validation and exception handling. This was the case with me and my team also. A couple or so years ago we reached...</Summary>
<Website>http://code.tutsplus.com/tutorials/validation-and-exception-handling-from-the-ui-to-the-backend--net-36697</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41059/guest@my.umbc.edu/ef8d7a6da4e3f7ebd8467b7d3dfda187/api/pixel</TrackingUrl>
<Tag>css</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>wed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 14:41:29 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="109862" important="false" status="posted" url="https://my3.my.umbc.edu/posts/109862">
<Title>Ken Corbett &#8217;14, Media and Communication Studies, on WYPR&#8217;s Maryland Morning</Title>
<Body>
<![CDATA[
    <div class="html-content">American jazz singer and songwriter Billie Holiday has a Baltimore connection. She spent the bulk of her childhood on a block of South Durham Street in Upper Fells Point. Residents and artists in that neighborhood are honoring her by starting a project that pays tribute to Holiday while also bringing new life to the block. Media and communication studies student Ken Corbett is an intern for WYPR’s Maryland Morning and produced and narrated a story about the project that aired on the program January 17. In December, Corbett spent a day on Holiday’s block on South Durham Street and put together …</div>
]]>
</Body>
<Summary>American jazz singer and songwriter Billie Holiday has a Baltimore connection. She spent the bulk of her childhood on a block of South Durham Street in Upper Fells Point. Residents and artists in...</Summary>
<Website>https://news.umbc.edu/ken-corbett-14-media-and-communication-studies-on-wyprs-maryland-morning/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/109862/guest@my.umbc.edu/4ed2d69844c40b208a2fb5ecdfc51d18/api/pixel</TrackingUrl>
<Tag>cahss</Tag>
<Tag>mcs</Tag>
<Tag>policy-and-society</Tag>
<Group token="umbc-news">UMBC News</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/original.png?1632921809</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/large.png?1632921809</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/medium.png?1632921809</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/small.png?1632921809</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxsmall.png?1632921809</AvatarUrl>
<Sponsor>UMBC News</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 14:27:22 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40551" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40551">
<Title>Bits Blog: IBM Happy to Be Rid of Low-End Server Business</Title>
<Body>
<![CDATA[
    <div class="html-content">Cheap servers were a drag on Big Blue. Now the company plans to focus on computer hardware with better profit margins.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fbits.blogs.nytimes.com%2F2014%2F01%2F23%2Fibm-happy-to-be-rid-of-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=Bits+Blog%3A+IBM+Happy+to+Be+Rid+of+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fbits.blogs.nytimes.com%2F2014%2F01%2F23%2Fibm-happy-to-be-rid-of-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=Bits+Blog%3A+IBM+Happy+to+Be+Rid+of+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fbits.blogs.nytimes.com%2F2014%2F01%2F23%2Fibm-happy-to-be-rid-of-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=Bits+Blog%3A+IBM+Happy+to+Be+Rid+of+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fbits.blogs.nytimes.com%2F2014%2F01%2F23%2Fibm-happy-to-be-rid-of-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=Bits+Blog%3A+IBM+Happy+to+Be+Rid+of+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fbits.blogs.nytimes.com%2F2014%2F01%2F23%2Fibm-happy-to-be-rid-of-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=Bits+Blog%3A+IBM+Happy+to+Be+Rid+of+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/sc/21/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529514097/u/0/f/640387/c/34625/s/36467f48/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>Cheap servers were a drag on Big Blue. Now the company plans to focus on computer hardware with better profit margins.      </Summary>
<Website>http://bits.blogs.nytimes.com/2014/01/23/ibm-happy-to-be-rid-of-low-end-server-business/?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40551/guest@my.umbc.edu/666d77193871ace38d088868bf0a5bc6/api/pixel</TrackingUrl>
<Tag>cloud-computing</Tag>
<Tag>enterprise-computing</Tag>
<Tag>international-business-machines-corporation</Tag>
<Tag>lenovo-group</Tag>
<Tag>mills-steve</Tag>
<Tag>new</Tag>
<Tag>technology</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 14:19:07 -0500</PostedAt>
<EditAt>Thu, 23 Jan 2014 17:59:53 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="false" id="40550" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40550">
<Title>"The Loving Story", "Dr.Claudrena Harold,"Alvin Ailey Dance"</Title>
<Tagline>UMBC CAMPUS COMMUNITY NEWS</Tagline>
<Body>
<![CDATA[
    <div class="html-content">The Africana Studies Department and The Albin O. Kuhn Library &amp; Gallery at UMBC announce two programs made possible by a grant for the “<a href="http://www.neh.gov/divisions/public/grant-news/created-equal-americas-civil-rights-struggle-program-sites-announced" rel="nofollow external" class="bo">Created Equal Project</a>.” Both programs will be free and the community is invited to join us.<p>On <u><strong><span><span>February 10th, 2014 from 12:00 noon – 1:30 pm</span></span>, “The Loving Story”</strong></u> will be shown in the Gallery in Special Collections at the Albin O. Kuhn Library.</p>
    <p>On <span><span><u><strong>February 11th, 2014 at 4:30 pm</strong></u></span></span>, we will host a panel discussion with historian <u><strong>Dr. Claudrena N. Harold</strong></u>. Professor Harold is Associate Professor in the Department of History at the University of Virginia. She recently co-directed a short film called “Sugarcoated Arsenic” with her colleague Professor Kevin Everson. The film is an “exploration of African American intellectual, social, and political life at the University of Virginia during the 1970s”. For more information about the film, visit <a href="http://history.virginia.edu/node/2956" rel="nofollow external" class="bo">http://history.virginia.edu/node/2956</a>.</p>
    <p>AFST will give one <u><strong><span>FREE</span> orchestra <span>ticket</span> to an AFST major or minor</strong></u> who is interested in attending the Sa<span><span>turday, <span><span>February 8, 2014</span></span></span></span>, performance of the Alvin Ailey American Dance Theater to be held at the John F. Kennedy Center for the Performing Arts. The <span>ticket</span> includes a pre-show reception at <span><span>6 pm</span></span> sponsored by the Chapter of Black and Latino Alumni of UMBC. Show at <span><span>7:30 pm</span></span>.</p>
    <div> </div>
    <div><div>
    <div>The captivating performances include Jirí Kylián's sensual and surprising <em>Petite Mort</em>; in-demand choreographer Aszure Barton's exhilarating D.C. premiere of <em>LIFT</em>; and Alvin Ailey's enduring classic, <em>Revelations</em>. <br><br>
    </div>
    <div>Students interested in the <span>free</span> <span>ticket</span> must contact Dr. King-Meadows by <span><span>January 31st</span></span>. Graduating seniors are especially encouraged to inquire about the <span>free</span> <span>ticket</span>. The <span>ticket</span> does not include transportation to or from the Kennedy Center. The <span>free</span> <span>ticket</span> represents an $85 value and is not transferable. </div>
    <div> </div>
    <div>Award recipient must sit within the orchestra block assigned to the Chapter of Black and Latino Alumni. <u><em><strong>Award recipient must also submit to AFST a 500-word essay about their experiences at the dance performance no later than one week following the event.</strong></em></u>  </div>
    </div></div>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p>Questions? Call the Africana Studies Department at <a rel="nofollow external" class="bo"><u>(410) 455-2158</u></a>, or the Library at <a rel="nofollow external" class="bo"><u>(410) 455-2346</u></a>.</p>
    </div>
]]>
</Body>
<Summary>The Africana Studies Department and The Albin O. Kuhn Library &amp; Gallery at UMBC announce two programs made possible by a grant for the “Created Equal Project.” Both programs will be free and...</Summary>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40550/guest@my.umbc.edu/077fa91172e38cf31dde6641870b887f/api/pixel</TrackingUrl>
<Group token="degree-in-africana-studies">Africana Studies</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/degree-in-africana-studies</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/xsmall.png?1389301374</AvatarUrl>
<AvatarUrl size="original">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/original.gif?1389301374</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/xxlarge.png?1389301374</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/xlarge.png?1389301374</AvatarUrl>
<AvatarUrl size="large">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/large.png?1389301374</AvatarUrl>
<AvatarUrl size="medium">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/medium.png?1389301374</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/small.png?1389301374</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/xsmall.png?1389301374</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/629/8bf9e40efcdb369a498342e2bb0ae9f2/xxsmall.png?1389301374</AvatarUrl>
<Sponsor>Africana Studies</Sponsor>
<PawCount>2</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 14:15:51 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="109863" important="false" status="posted" url="https://my3.my.umbc.edu/posts/109863">
<Title>Donald Norris, Public Policy, in The Baltimore Sun</Title>
<Body>
<![CDATA[
    <div class="html-content">There has been growing speculation in recent weeks that Rep. John Delaney (D-MD) has plans on entering the Maryland race for governor. Delaney is a first-time lawmaker and a former banking executive. Donald Norris, public policy professor and chair, was interviewed for an article published January 22 in The Baltimore Sun about the possibility of Delaney entering the race. He commented that Delaney is likely attempting to boost his recognition for a statewide race some time in the future. “Because it’s this late, it would suggest to me that he won’t do it,” Norris said. “Were he to do it — …</div>
]]>
</Body>
<Summary>There has been growing speculation in recent weeks that Rep. John Delaney (D-MD) has plans on entering the Maryland race for governor. Delaney is a first-time lawmaker and a former banking...</Summary>
<Website>https://news.umbc.edu/donald-norris-public-policy-in-the-baltimore-sun-26/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/109863/guest@my.umbc.edu/b082063ddd5c23d98ba751d1e0fa7f5b/api/pixel</TrackingUrl>
<Tag>cahss</Tag>
<Tag>policy-and-society</Tag>
<Tag>publicpolicy</Tag>
<Group token="umbc-news">UMBC News</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/original.png?1632921809</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/large.png?1632921809</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/medium.png?1632921809</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/small.png?1632921809</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxsmall.png?1632921809</AvatarUrl>
<Sponsor>UMBC News</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 13:27:18 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="40549" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40549">
<Title>Mobile Software Learns Your Phone&#8217;s Habits to Catch New Malware</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>Zimperium believes its machine-learning approach to mobile security can outwit hackers.</p>
    <p>A mobile security startup is launching software that learns how your smartphone behaves in order to better spot and stop new security threats before they can cause harm or spread to other handsets.</p>
    </div>
]]>
</Body>
<Summary>Zimperium believes its machine-learning approach to mobile security can outwit hackers.  A mobile security startup is launching software that learns how your smartphone behaves in order to better...</Summary>
<Website>http://www.technologyreview.com/news/523831/mobile-software-learns-your-phones-habits-to-catch-new-malware/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40549/guest@my.umbc.edu/41161e6e40932824da1d21dea584280c/api/pixel</TrackingUrl>
<Tag>development</Tag>
<Tag>internet</Tag>
<Tag>mit</Tag>
<Tag>technology</Tag>
<Tag>web</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 12:30:00 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40547" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40547">
<Title>Deal of the week: Respublika font family</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><img alt="respublika_thumbnail" src="http://netdna.webdesignerdepot.com/uploads/2014/01/respublika_thumbnail.jpg" width="200" height="160" style="max-width: 100%; height: auto;">It’s often difficult to settle on a strong sans-serif. So many carry a lot of baggage with them; Helvetica is everywhere, Arial is Helvetica, Verdana really only works on screen, and everything else is hugely expensive.</p> <p>So we were really excited when our sister-site, <a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo">MightyDeals.com,</a> arranged this sensational deal on the beautifully balanced <a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo">Respublika typeface,</a> designed by Gregori Vincens and Malou Verlomme.</p> <p>Respublika is a humanist sans-serif, featuring a simple overall form, but packed with little details that impart its character. Just take a look at the cursive-style finials on the lowercase ‘a’, ‘h’, ‘m’ and ’n’. Zoom in close and look at the way the ends of the vertical stems have been curved to create a friendly welcoming feel.</p> <p>Respublika is the perfect contemporary corporate typeface. Simple, modern and legible; whilst being warm, friendly and approachable; Respublika is the ideal choice for branding anything from an engineering firm, to an accountancy practice, to a dentist’s office.</p> <p>Superbly legible, especially online, Respublika features 10 different fonts: light, light italic, regular, italic, bold, bold italic, extra bold, extra bold italic, black and black italic; giving you a full range of expressive possibilities. What’s more, each font comes with a full range of analphabetic characters, enabling its use for most western languages.</p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0021.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0031.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0041.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0051.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0061.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p><a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/01/0071.jpg" width="650" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"></a></p> <p>Desktop fonts are delivered as .otf and .ttf and work on Windows and Mac, webfonts comes as .eot, .svg, .ttf and .woff and will work with @font-face CSS rules.</p> <p>This great typeface normally retails at $390 for just the desktop fonts, but act quickly, and you can <a href="http://www.mightydeals.com/deal/respublika-fy-font.html?ref=wddpostrespublika" rel="nofollow external" class="bo">download all 10 fonts from MightyDeals</a> for an incredible $47, that’s 88% off! Alternately, why not opt for the desktop and web versions for just $67?</p> <p> </p> <p><em><strong>Have you used Respublika in a project? What uses do you envisage for it? Let us know in the comments.</strong></em></p> <p><br><br> </p>
    <table width="100%"> <tbody>
    <tr> <td> <a href="http://www.mightydeals.com/deal/softease-photo-deluxe-bundle.html?ref=inwidget" rel="nofollow external" class="bo"><strong>Mac Photo Bundle: 4 Popular Photo Apps – only $24!</strong></a> </td> <td> <a href="http://www.mightydeals.com/?ref=inwidget" rel="nofollow external" class="bo"><br> <img src="http://mightydeals.com/web/images/widget-logo.png" height="40" width="90" alt="Deal of the week: Respublika font family" style="max-width: 100%; height: auto;"><br> </a> </td> </tr> </tbody>
    </table> <p><br> </p> <a href="http://www.webdesignerdepot.com/2014/01/deal-of-the-week-respublika-font-family/" rel="nofollow external" class="bo">Source</a> <br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F01%2Fdeal-of-the-week-respublika-font-family%2F&amp;t=Deal+of+the+week%3A+Respublika+font+family" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F01%2Fdeal-of-the-week-respublika-font-family%2F&amp;t=Deal+of+the+week%3A+Respublika+font+family" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F01%2Fdeal-of-the-week-respublika-font-family%2F&amp;t=Deal+of+the+week%3A+Respublika+font+family" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F01%2Fdeal-of-the-week-respublika-font-family%2F&amp;t=Deal+of+the+week%3A+Respublika+font+family" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F01%2Fdeal-of-the-week-respublika-font-family%2F&amp;t=Deal+of+the+week%3A+Respublika+font+family" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/sc/4/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529555111/u/49/f/661066/c/35285/s/36458c9f/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>It’s often difficult to settle on a strong sans-serif. So many carry a lot of baggage with them; Helvetica is everywhere, Arial is Helvetica, Verdana really only works on screen, and everything...</Summary>
<Website>http://rss.feedsportal.com/c/35285/f/661066/s/36458c9f/sc/4/l/0L0Swebdesignerdepot0N0C20A140C0A10Cdeal0Eof0Ethe0Eweek0Erespublika0Efont0Efamily0C/story01.htm</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40547/guest@my.umbc.edu/a9520d2ae4bdcf9c38849639301491de/api/pixel</TrackingUrl>
<Tag>art</Tag>
<Tag>cheap-fonts</Tag>
<Tag>css</Tag>
<Tag>deals</Tag>
<Tag>design</Tag>
<Tag>development</Tag>
<Tag>font-deals</Tag>
<Tag>html</Tag>
<Tag>html5</Tag>
<Tag>illustrator</Tag>
<Tag>javascript</Tag>
<Tag>mightydeals</Tag>
<Tag>mightydeals-com</Tag>
<Tag>mysql</Tag>
<Tag>oracle</Tag>
<Tag>photoshop</Tag>
<Tag>php</Tag>
<Tag>respublika</Tag>
<Tag>sans-serif</Tag>
<Tag>sql</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 12:15:16 -0500</PostedAt>
<EditAt>Thu, 23 Jan 2014 12:15:16 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="40545" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40545">
<Title>New Paid Student Internship: Recycling Promotions, Feb-March</Title>
<Tagline>Seeking student to lead outreach efforts for recyclemania</Tagline>
<Body>
<![CDATA[
    <div class="html-content">
    <p><span>We are excited to announce a new paid opportunity for a student dedicated to helping protect the environment by reducing waste and raising awareness on Reycling! </span></p>
    <p><span></span> </p>
    <p><span>Help to engage the campus and raise awarness on issues such as how to sort waste, how to reduce waste, ways to reuse, why recycling is important, gaining commitments through pledges, and what happens to our waste at UMBC.</span></p>
    <p><strong><span></span></strong> </p>
    <p><span>The primary role of this position is to facilitate UMBC's participation in <a href="http://my.umbc.edu/news/39998" rel="nofollow external" class="bo">Recyclemania</a> in 2014. Recyclemania is fully funding this position. </span></p>
    <p><strong></strong> </p>
    <p><strong><span>Sustainability Outreach and Communications Intern:</span></strong></p>
    <p><span></span></p>
    <p><span>Intern will report to the Recycling Manager in Facilities Management. The position will be 4 hours per week. Hours may vary to accommodate meetings, and events. Additional tasks may be assigned. Intern must demonstrate evidence of interest and background in sustainability and must feel comfortable reaching out to professionals, peers, and faculty. Intern must be a current UMBC student. The internship will last from February 1<sup>st</sup> to March 30<sup>th</sup> during Recyclemania. Upon completion, the student will recieve a $250 stipend for the 8 week period, working at least 4 hours per week.</span></p>
    <p><span></span></p>
    <p><span>The will assist in promoting recycling on campus through design, online marketing, and events. During the period of Recyclemania the student will:</span></p>
    <p><span><span>-</span></span><span>Plan and promote events such as a parade, luncheon, and other outreach activities</span></p>
    <p><span><span>-</span></span><span>Set up and manage a weekly table on mainstreet</span></p>
    <p><span><span>-</span></span><span>Recruit, develop, and coordinate volunteers and partners</span></p>
    <p><span><span>-</span></span><span>Collect pledges, and take and post photographs</span></p>
    <p><span><span>-</span></span><span>Utilize the Recyclemania materials such as ‘event in box’</span></p>
    <p><span><span>-</span></span><span>Update press releases and blog posts</span></p>
    <p><span><span>-</span></span><span>Small amount of data entry to report weekly numbers to the Recyclemania website</span></p>
    <p><span><span>-</span></span><span>Post and manage engaging content on social media</span></p>
    <p><span></span></p>
    <p><strong><span>Desired skills and qualifications:</span></strong></p>
    <p><span>- Experience or interest in learning about planning and coordinating events</span></p>
    <p><span>-</span><span> </span><span>Strong writing and communication skills<br>-</span><span> </span><span>Strong organizational and time management skills<br>-</span><span> </span><span>Ability to work independently and in a team<br>-</span><span> </span><span>Creativity and design skills<br>-</span><span> </span><span>Related coursework in related area such as Environmental Studies, Communications and Design desired but not required<br>-</span><span> </span><span>Awareness of environmental issues<br>-</span><span> </span><span>Involvement in campus sustainability </span></p>
    <p><span>-Enthusiastic, outgoing, and positive </span></p>
    <p><strong><span>Examples of Tasks and Responsibilities: </span></strong></p>
    <p><span>Events:</span></p>
    <p><span>- Event planning and logistics</span></p>
    <p><span>- Tabling, coordinating sign-up sheets, pledges, and photo booths</span></p>
    <p><span>Writing:</span></p>
    <p><span>- Assist with writing press releases, articles and event summaries </span></p>
    <p><span>- Assist with conducting interviews and creating articles </span></p>
    <p><span>Design:</span></p>
    <p><span>- Assist with posters, designs and fliers</span></p>
    <p><span>Social Media: </span></p>
    <p><span>- Assist with updates to myUMBC and Facebook Events Calendar</span></p>
    <p><span>- Assist with creating and posting of spotlights</span></p>
    <p><span>- Posting photos and updates following events</span></p>
    <p><span>- Expand followers on myUMBC and social media</span></p>
    <p><span>Photography:</span></p>
    <p><span>- Assist with taking photographs, editing, organizing and uploading content </span></p>
    <p> </p>
    <p><span><strong>To Apply:</strong></span></p>
    <p><span>Please submit a resume and a cover letter to <a href="mailto:recycle@umbc.edu" rel="nofollow external" class="bo">recycle@umbc.edu</a></span></p>
    <p><span>In your cover letter please include the following: </span></p>
    <p><span>1) why this position interests you </span></p>
    <p><span>2) what related skills and experiences you possess </span></p>
    <p><span>3) any other groups, activities, jobs or time commitments you are currently juggling and how you plan to manage your time</span></p>
    <p> </p>
    <p><span>Deadline: January 30<sup>th</sup></span></p>
    <p><span></span> </p>
    </div>
]]>
</Body>
<Summary>We are excited to announce a new paid opportunity for a student dedicated to helping protect the environment by reducing waste and raising awareness on Reycling!      Help to engage the campus and...</Summary>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40545/guest@my.umbc.edu/bffdfc60f70731bd4780036c36582ce5/api/pixel</TrackingUrl>
<Tag>recycle</Tag>
<Tag>reduce</Tag>
<Tag>reuse</Tag>
<Tag>waste</Tag>
<Group token="sustainability">Sustainability Matters at UMBC</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/sustainability</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/xsmall.png?1586269437</AvatarUrl>
<AvatarUrl size="original">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/original.png?1586269437</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/xxlarge.png?1586269437</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/xlarge.png?1586269437</AvatarUrl>
<AvatarUrl size="large">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/large.png?1586269437</AvatarUrl>
<AvatarUrl size="medium">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/medium.png?1586269437</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/small.png?1586269437</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/xsmall.png?1586269437</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/086/91091ac32f525d88daa6d6b721420ac1/xxsmall.png?1586269437</AvatarUrl>
<Sponsor>Sustainability Matters @UMBC</Sponsor>
<ThumbnailUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/xxlarge.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/xlarge.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="large">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/large.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="medium">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/medium.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="small">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/small.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="xsmall">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/xsmall.jpg?1390496603</ThumbnailUrl>
<ThumbnailUrl size="xxsmall">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/040/545/f8e8ce58b493febecbbf3c12b18353dc/xxsmall.jpg?1390496603</ThumbnailUrl>
<PawCount>1</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Thu, 23 Jan 2014 12:04:14 -0500</PostedAt>
<EditAt>Thu, 23 Jan 2014 12:04:53 -0500</EditAt>
</NewsItem>

</News>
