Kohana 3 ORM Callbacks, Filters, Rules and Labels

In Kohana 3′s new ORM, you can have it automatically create the Validation object in ORM. You just pass in your values to the model like so:

$model->values($_POST);

Then you can check the values like so:

$model->check();

But more importantly, what is the format for the ORM? Heathco does a great wiki on the ORM as he was heavily involved with it, but this is more for relationships and whatnot.  But this page does have a great code snippet that will get you started in no time:

class Model_User extends ORM
{
  protected $_rules = array('name' => array('not_empty' => NULL), 'username' => array('not_empty' => NULL, 'alphanumeric' => NULL));
  protected $_filters = array(TRUE => array('trim' => NULL));
}

$user = ORM::factory('user');
$user->values($_POST);
$user->check();
Reblog this post [with Zemanta]

NiNite Software Installation When Cleaning Your Computer

Oh this is an awesome tool. It basically goes like this:

  1. Select the software you want installed
  2. Download the installer
  3. Install.

How awesome is that.  It will install the majority of the software on your newly installed Windows 7 or XP, or Vista.  Even better:  For network administrators and IT managers, you can specify a network location to download the installation files by doing the following:

  1. Create a Ninite.ini next to the installer
  2. Put this in the INI file:
    [Cache]
    path=your cache path goes here
  3. Then run the installer.

It will save the files to that location on the network so every computer doesn’t need to download that software. How tight is that? Now we can play games while we restore our computer. W00T!

I would definatley check it out: http://ninite.com/

Reblog this post [with Zemanta]

Dynamic Javascript Array Errors in Internet Explorer

Just a quick hint… If your data is not showing up or not being entered into an array in internet explorer, but its working in every other browser under the sun, try checking your code to make sure that when you are creating your arrays that you remove the trailing comma from the last element:

var array = [
['item1', 'item content'],
['item2', 'item content 2'],
['item3', 'item content 3'], // this is the issue, there should be no trailing "," on the last element
];
Reblog this post [with Zemanta]

ATTN: BuddyPress Fans

So I thought I would try out the BuddyPress plugin for WordPress MU. It is a cool little plugin that lets your users sign up for blogs etc. However there are a few drawbacks to how it is structured:

1. Each time a user is registered, the wordpress tables are duplicated with their ID. So for each user you will have some 7 new database tables. This can become very dense as you get many many users going, especially for database backups and whatnot.

2. Be sure to implement some sort of spam protection or registration cap immediately. I just installed it on a side blog of mine, but somehow a friend sent it out, it got indexed, and then it got spammed like crazy. Before you know it, I had 3000+ users and 30k tables in my database and it was craaaawlling. So be sure to implement a captcha or something effective.

Good day.
Jonathan

Reblog this post [with Zemanta]

IPhone Autorotate To Interface Orientation Bug in OS3.0

So there seems to be a bug in the XCode update for OS3.0 The application had a view that would show an image, and if the Orientation of the IPhone changed it would rotate to view the image Landscape or Portrait respectively. But if you removed that popup view, and then added it again, the callbacks:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

Would not get triggered.

The workaround for this issue is to use the NSNotificationCenter to call a @selector() and then put your logic inside. Example:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

-(void) receivedRotate: (NSNotification *) notification {
    NSLog(@"ORIENTATION CHANGE");

    UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];

        if(interfaceOrientation == UIDeviceOrientationPortrait) {
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
                self.view.bounds = CGRectMake(0, 0, 320, 480);
        }
        else if(interfaceOrientation == UIDeviceOrientationLandscapeLeft) {
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
                self.view.bounds = CGRectMake(0, 0, 480, 320);
        }
        else if(interfaceOrientation == UIDeviceOrientationLandscapeRight) {
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
                self.view.bounds = CGRectMake(0, 0, 480, 320);
        }
}
Reblog this post [with Zemanta]

Dynamically Loading Fonts from SWF in Flash AS3

When you have a textfield sitting on the stage, it gets painful to go through and embed all the fonts into the textfield.  It gets even worse when you have a bunch of dynamically created textfields in a bunch of SWFs and the client suddenly decides they want to use a sans-serif font instead of a serif font.  Brilliant!  But I assure you, if it hasn’t happened to you yet, it will– Let me know when it does hahaha.

So here is the solution:  You have an external swf with the font embeded, then you load in that swf to each flash file and extract the font from the library, then you apply that font in a TextFormat. » Read more…

Making General Google Map Markers from Exact Gmap Markers

If you have more than 10k markers on your map, you definitely don’t want to display all of them while the user is zoomed out as far as they can zoom. This is where your awesome math skills come into play. With a javascript plugin called MarkerManager you can create levels of markers that will display as the user zooms in.

For example:  You have a map with addresses in Europe and USA.  You can display a USA flag on the US continent and a EURO flag over Europe– And as the user zooms in, those icons disappear (because you can’t see both USA and Europe), and your addresses begin to appear.  But even at the country view, there may still be 5-10k markers to display.  Here is how you can create some general markers that will somewhat group your exact addresses into a single marker.

This explanation  assumes you already have a database with latitude and longitude setup.  If you need to convert your addresses, id check out this tutorial first.

What we will do is create a nifty SQL query that will group the locations by rounding them to a certain threshold:

SELECT *, ROUND(latitude + longitude, ?) as distance_group FROM your_address_table GROUP BY distance_group;

Replace the question mark with a number like 1 or 0 in order to group the locations in a wider radius or a smaller radius.  Basically what this is doing is taking a latitude and longitude that would accurately be: 37.8273849, -117.3928473 and rounding them to 37.8, -117.4 and then adding them: -79.6.  That number is just a key to group locations.  Any numbers around this latitude and longitude will add up to -79.6 which means the latitude and longitude will be represented by a grouping icon / marker.

Then with marker manager, you would setup your script to where the top zoom levels (0->5) would be the map, (6-9) would be the general markers that you rounded (previous paragraph), and (10+) would be your exact address locations.

This means that as your user zooms in, they will go through the top zoom images (your flags), then the approximated icons (your generated markers), and then reach their final views of your exact addresses.

Example extracted from marker manager blog.

function setupMap() {
 if (GBrowserIsCompatible()) {
   map = new GMap2(document.getElementById("map"));
   map.addControl(new GLargeMapControl());
   map.setCenter(new GLatLng(41, -98), 4);
   window.setTimeout(setupWeatherMarkers, 0);
 }
}

function getWeatherMarkers(n) {
  var batch = [];
  for (var i = 0; i < n; ++i) {
    batch.push(new GMarker(getRandomPoint(),
      { icon: getWeatherIcon() }));
  }
  return batch;
}

function setupWeatherMarkers() {
  mgr = new GMarkerManager(map);
  mgr.addMarkers(getWeatherMarkers(20), 3);
  mgr.addMarkers(getWeatherMarkers(200), 6);
  mgr.addMarkers(getWeatherMarkers(1000), 8);
  mgr.refresh();
}
Reblog this post [with Zemanta]

Word Censor Helper

This function just censors text. As of right now it is made to work with PHPbb and the table phpbb_words. You can create an associative array instead if you arn’t using phpbb– or you can create a table in a database with fields `word` and `replacement` and that will work as well– it doesn’t need to use phpbb’s. Here is the example function for using phpbb to filter your words:

echo text::censor('What will it censor? a$$ <- this!');

And the code (I would still recommend downloading the file, some of the functions dont appear in wordpress):

class text extends text_Core
{
	/**
	 * Replaces the vulgar string with censored string
	 *
	 * @param  string  String you want to censor
	 * @return  censored string
	 */
	public static function censor($text)
	{
		static $censors;

		# check to see if the words have been initialized
		# this function is made to work with phpbb's table
		# you can make it use an associative array w/o cache
		if(!isset($censors) || !is_array($censors)) {
			$cache = new Cache;

			if(!$censors = $cache->get('phpbb.censors')) {
				$db = new Database;

				$results = $db->select(array('word', 'replacement'))
					->from('phpbb_words')
					->get();

				$censors = array();
				foreach($results as $word) {
					$censors['match'][] = '#(?word, '#')) . ')(?!\w)#i';
					$censors['replace'][] = $word->replacement;
				}

				$cache->set('phpbb.censors', $censors);
			}
		}

		if(sizeof($censors))
			return preg_replace($censors['match'], $censors['replace'], $text);

		return $text;
	}
}

As of right now, you see that the class extends text_Core. This is Kohana’s built in text module. You can just have the class as a core class and it will still work. For the sake of multiuse, I also changed it to use an assoc array below:

class text
{
	/**
	 * Replaces the vulgar string with censored string
	 *
	 * @param  string  String you want to censor
	 * @return  censored string
	 */
	public static function censor($text)
	{
		static $censors;

		# check to see if the words have been initialized
		if(!isset($censors) || !is_array($censors)) {
			$censors = array(
				'match' => array('bad', 'words', 'here'),
				'replace' => array('replace', 'words', 'here)
			);
		}

		if(sizeof($censors))
			return preg_replace($censors['match'], $censors['replace'], $text);

		return $text;
	}
}
Reblog this post [with Zemanta]

Actionscript 3 Countdown Class

I got kinda bored a minute ago so I decided to write a date countdown AS3 class. Pass in a Date() object and it will countdown to that date at a specified interval of updating. Feel free to use it as you want. Here is an example usage:

import Countdown;

var endDate:Date = new Date(2009,12,24);
var countdown:Countdown = new Countdown(endDate);
countdown.addEventListener(Countdown.UPDATE_CLOCK, function(e:Event) {
	var info:Object = countdown.data;
	trace(info.days, info.hours, info.minutes, info.seconds);
});

Right click here to download the AS3 class.

Reblog this post [with Zemanta]

You must Re GeoCode!

[youtube:http://www.youtube.com/watch?v=FNhVu2oeInc]

So Google announced some cool features today for the google maps that includes the capability for parcel information, some campus enhancements, etc.  Its pretty awesome.  But they also improved their GeoCoding accuracy, so if it looks like your map locations are not working, you may need to re encode their latitude and longitudeCheck this article for more.

You do not have to reencode your addresses if you are using v2 of the GMaps api and never updating address latitude and longitude.  However, if you add any more addresses, the GEOCoder will return information for v3 of the API.  If this is the case, you can use geocoder to reencode all of your addresses and then use v3 of the GMaps API. And if your using KohanaPHP + ORM + GMaps module, here is a function you can use:

public function process_latlng() {
	$locations = ORM::factory('location')->find_all();

	foreach($locations as $location) {
		if($location->latitude == "" || $location->longitude == "") {
			$latlng = GMap::address_to_ll($location->location_address);

			$location->latitude = $latlng[0];
			$location->longitude = $latlng[1];

			$location->save();

			echo Kohana::debug($location);
		}
	}
}
Reblog this post [with Zemanta]