Laravel form validation is simple enough, but what if you want to extend the validation and do your own?

It's easy enough to do if you are doing everything in the routing, but that is going to get out of control really quickly. You can even abstract it another level into the controller, and even that becomes repetitive. If you have done any Googling, you have probably seen this tutorial by Jeffrey Way. This will get you about 90% of the way there. But what if you want a CUSTOM validation method? Continuing from where Jeffrey left off, lets say you have the following `$rules`.

<?
public static $rules = [
	'title' => 'required',
	'body' => 'required|divisible_by_two'
];
Notice, the above should be the same as from the custom validation class in the aforementioned tutorial, save for one change. We have added `divisible_by_two`. This is making reference to a not yet created validation rule. Lets go ahead and add that now. I am going to start by adding a new constructor inside the Services\Validators\Post class. Remember we need to include `parent::__construct();` in order to keep the changes from the abstract validator class.

<?
public function __construct() {
	parent::__construct();
	\Validator::extend('divisible_by_two', 'Services\Validators\Post@divisible_by_two');
}
Note: In the above uses namespaces for the second parameter in `Validator::extend()`. This is key, since we are using namespaces, we need to remember them here.

Lastly we need to add our method that does the actual validation.

<?
public function divisible_by_two($attribute, $value, $parameters) {
        return ($value % 2) === 0;
}
And that should be it! Your custom validator should now be in effect. Drink Responsibly!

Laravel 4 is centered almost completely around routing. So organizing it is a must. There is no default organization for routes, but we can easily fix this.

Add the following to your `bootstrap/start.php` file:

<?
/**
 * Require Routes for better organization.
 */
$files = new FilesystemIterator(dirname(dirname(__FILE__)) . '/app/routes');
foreach ($files as $file)
{
    if ($file->isFile())
    {
        require $file->getPathname();
    }
}
Then you can create a `routes` directory inside the `app` folder and save your routes in there. You can name them whatever you want, but I like to name them after the controller I am working on.

Happy coding!

One thing that CakePHP 3 documentation has you do when you install is put the CakePHP Core inside the vendor directory of the app. If you want to share the CakePHP core between multiple apps you can follow these simple steps.

Step 1: Install the CakePHP 3 App

cd {webroot}
composer create-project -s dev cakephp/app ./
Step 2: Move the CakePHP 3 core to somewhere external

In this example, I am going to put it inside `/CakeCore/cakephp` but you can put it wherever.

mkdir /CakeCore
mv {webroot}/vendor/cakephp/cakephp /CakeCore/cakephp
Step 3: Change the Core Definition in your App

Lastly we need to point the app to the newly cloned core.

cd {webroot}/App/Config
vim paths.php
And replace this line (approximately line 73):

define('CAKE_CORE_INCLUDE_PATH', ROOT . '/vendor/cakephp/cakephp');
With this line:

define('CAKE_CORE_INCLUDE_PATH', '/CakeCore/cakephp/');
That's it! Continue on your merry way.

So for the slightly older iPhones, including iPhone4 and iPhone 4s, the parallax affect can take up some battery life. Not much, but with battery power so limited anything helps. If battery isn't a concern for you, maybe you just don't like the effect (which is my case) I feel like they didn't smooth it out enough to be cool. It seemed really jittery, so I was happy to find a setting to turn it off.

To turn it off go into settings:

Click 'General'

IMG_2563

Click 'Accessibility'

IMG_2564

Click 'Reduce Motion'

IMG_2565

And finally turn it off! (It needs to be in the 'enabled' state to turn off)

IMG_2566

Now on your iOS7 iPhone 5, iPhone 5s, iPhone 5c, iPhone 4s or iPhone 4 can turn off this blasted parallax effect that apple has deemed necessary to have out of the box on your newly updated iOS7 iPhone.

Enjoy!

Awesome article I found: http://flippinawesome.org/2013/09/09/retro-game-music-using-web-audio-and-band-js/

Pretty slick.

Here's the JSFiddle for a ZELDA tune in JS.

Sometimes you just need to get the query used by a find, for troubleshooting issues. This is especially true when troubleshooting ajax issues which don't typically have views, so DebugKit doesn't load for that page.

Just add this below the controller:

$log = $this->Model->getDataSource()->getLog(false, false);
debug($log);
Welcome!

I've been playing with all sorts of API's lately, and one of the most complicated (for the sake of being complicated), is the Geocaching API. They use OAuth for connection. To obtain access (Key/Secret) you need to go through their process.

I am using CakePHP for this demonstration, and with CakePHP there is an excellent OAuth component which is what I am using. Find it here.

Lets say you have the Consumer Key/Secret now. Their OAuth process is a little funky, if you've ever used one before. Here's the broad-strokes view:

  1. You connect to their staging server, passing them your Consumer Key and Consumer Secret. Url is https://staging.geocaching.com/OAuth/oauth.ashx
  2. Their server will respond with a request token object. You pass the Token's key and the user to -- the same url you got the request token from: https://staging.geocaching.com/OAuth/oauth.ashx
  3. Once the user okay's your application, Geocaching.com will redirect the user back to the callback url with the OAuth verifier and the OAuth Token. ALMOST there.
  4. Send the request token (From step 2) and the OAuth Verifier and OAuth Token (Step 3) to what url? Oh it's https://staging.geocaching.com/OAuth/oauth.ashx again.
  5. The response from step 4) will look the same as the response from step 2, but alas, you are finally finished. They Access Token is the "Key" property in the OAuth Token Object. Save this to the user's session and use it for all requests to their API.


The following is the code in CakePHP.

<?
public function getGeoKey() {
		$this->HttpSocket = $this->__createClient();
		$requestToken = $this->HttpSocket->getRequestToken('https://staging.geocaching.com/OAuth/oauth.ashx', 'http://localhost/hubstats/hubs/callback');
		if ($requestToken) {
			$this->Session->write('geocache_request_token', $requestToken);
			$this->redirect('https://staging.geocaching.com/OAuth/oauth.ashx?oauth_token=' . $requestToken->key);
		} else {
			// an error occured when obtaining a request token
		}
	}
  public function callback() {
		$requestToken = $this->Session->read('geocache_request_token');
		$this->HttpSocket = $this->__createClient();
		$params = array(
			'oauth_verifier' => $_GET['oauth_verifier'],
			'oauth_token' => $_GET['oauth_token'],
		);
		$accessToken = $this->HttpSocket->getAccessToken('https://staging.geocaching.com/OAuth/oauth.ashx', $requestToken, 'POST', $params);
		$this->Session->write('access_token', $accessToken->key);
		$this->redirect(array('action' => 'index'));
	}
	private function __createClient() {
		return new OAuthClient('Consumer_Key', 'Consumer_Secret');
	}

Sending a POST request to geocaching.com

Geocaching.com's API is a little clunky in terms of POST requests. A few things to remember.

  • When sending a request, the Content-Type must be 'application/json'
  • Even though its a POST request, in order to get the format back in jason, you must append the url (Like a GET request) eg: https://geocaching.com/api/geocaches?format=Json


Enough talk. Here is a sample POST request.

<?
public function index() {
		$data = array(
			'AccessToken' => $this->Session->read('access_token'),
			'MaxPerPage' => 10,
			'PointRadius' => array(
				'DistanceInMeters' => 20 * 1609, //There are 1609.34 Meters in a mile. Miles x Meters
				'Point' => array(
					'Latitude' => '46.06502',
					'Longitude' => '46.06502',
				),
			),
		);
		$request = array(
			'header' => array(
				'Content-Type' => 'application/json',
			),
		);
		$data = json_encode($data);
		$response = $this->HttpSocket->post('https://staging.api.groundspeak.com/Live/V6Beta/geocaching.svc/SearchForGeocaches?format=Json', $data, $request);
		pr($response->body());
		exit;
	}

GET requests


As for GET requests, there's nothing magic about those:

<?
public function index() {
		$data = array(
			'AccessToken' => $this->Session->read('access_token'),
			'format' => 'Json'
		)
		$response = $this->HttpSocket->get('https://staging.api.groundspeak.com/Live/V6Beta/geocaching.svc/GetAPILimits', $data);
		pr($response->body());
		exit;
	}
Notice 'format' key/value pair has been moved into the $data array. This is because we are using the GET method in HttpSocket. The $data is url encoded and passed as part of the URL for the get request, so putting it in the $data as expected, unlike when using POST.

Conclusion


Definitely one of the weirder API's I have run into, but Geocaching is awesome, and I encourage everyone to get out there and try it. Developers should definitely tap into the API and see what kinda cool stuff you can do with it! Happy Geocaching!

Most websites I see go in and over-explain how to grab data, eg. json, from an external website. This is a simple explanation of the SIMPLEST way to nab data.

This is going to go in and grab my gists from github and return the json data.

var url = 'https://api.github.com/users/alairock/gists';
  httpr = new XMLHttpRequest();
  httpr.open('GET',url, false);
  httpr.send();
  var statusText = httpr.statusText;
  var response = httpr.response;
  console.log(response);
What is giong on? Line-for-line:
1) Get the url we want to nab data from
2) instantiate the XMLHttpRequest object, which is used to go get and handle our data
3) the open method prepares our data to be retrieved and
4) the send method executes our prepared action
5) simply assigns the response message (If successful it will receive "ok")
6) Is the response. This is where all our json data from line 1 is stored.
7) Just outputs the data to our console.