My (mostly technical) blog

Today, I was trying to password protect a directory on a website that operated the cPanel software on Bluehost and I went ahead and used the “Generate Password” function which generated this nice looking password

w7WY/a3HIUx>

Now when I was trying to login with this password, whatever I tried to do it gave me a 401 Authorization required. It just didn’t accept my password. I contacted the support of Bluehost but they weren’t able to help!

After some searching, I found this forum post http://forums.cpanel.net/showthread.php?t=112117 which makes me wonder why hasn’t cPanel fixed that bug so far?

If your password or the generated password contains greater than (<) or less than (>) characters (or maybe other ones that I haven’t discovered yet), they will be filtered out by cPanel before the password is saved, effectivley changing the password you set.

As a work around if you really need to use those characters (I liked the generated password :P) you can set it through the shell

htpasswd -n username
New password: w7WY/a3HIUx>
Re-type new password: w7WY/a3HIUx> 

username:hash

Then copy the last line (username:hash) into your .htpasswd file which you can find by editing the .htaccess file in the directory that you were trying to protect. (Does this make sense?)

Advertisements
Tags:

I have never been more in need of a proper PHP debugger in my whole life. I have been stuck with a very mysterious behavior with CakePHP for the past 4 hours.

I was editing a model, then saving it. For some reason, my form action was changing from

/controller/edit/1
to
/controller/add

it was making me go crazy!

After seaching around (finally) I found this: https://trac.cakephp.org/ticket/5871
I came to realize that I have actually omitted the

<?= form->input('id'); ?>

from my edit view because I thought “why the hell do I need to edit the primary key?”

As it turns out, CakePHP needs a field (hidden or not) with the name ID or else it will revert to the ADD form.

Luckily though, it is smart enough to render it as a hidden field.

Google is your friend.

Tags: ,

This was my bachelor thesis that I have done as part of my studies for a B.Sc. degree in Computer Science and Engineering from the German University in Cairo.

Download presentation:
Indoor Localization Using Wireless LAN/WiFi Infrastructure

Download thesis:
Indoor Localization using Wireless LAN/WiFi Infrastructure

Abstract:
The rapid advances in wireless technology as well as in the manufacturing of portable devices caused a growing interest in location aware services. A location sensing
system responsible for locating a mobile user, is a crucial factor for the success of such services. With the prevalence of wireless hotspots and wireless area networks, the use of a wireless network infrastructure as basis for an indoor positioning system becomes a viable option. In this work, we propose an indoor guide system that provides information about points of interest and objects within the vicinity of the user. Our system can be deployed on a university campus or inside a museum equipped with a wireless network.

The system uses the fingerprinting technique to associate position dependent information such as the strength of the received signal with a location. A range based matching algorithm for matching the physical signal strength with the fingerprints in the database is used and its performance is compared to an Euclidean distance based matching algorithm. The properties of the wireless signals and their distribution under several controlled experiments are analyzed.

I got asked this question during an interview last week. I think I gave a wrong answer in the interview but I decided I needed to find the correct answer! I searched and found this solution which involved bit manipulations, though I didn’t find it intuitive.

I came up with this simple solution

public class PowerOfTwo {
	public static void main(String args[]){
		for(int n=0,limit=16; n<Math.pow(2, limit);n++)
			if(isPowerOfTwo(n))
				System.out.println(n);
	}

	private static boolean isPowerOfTwo(int n) {
		double logNbase2 =  Math.log(n)/Math.log(2);	
		int logNbase2Integer = (int) (Math.floor(logNbase2));
		
		if(logNbase2-logNbase2Integer==0)
			return true;
		else
			return false;
	}
}
&#91;/sourcecode&#93;

maybe not quite as elegant as the bit hack, but I understand it!

<b>Update:</b>
Actually, I understood how the bit hack function below works:

	private static boolean isPowerOfTwoFast(int n) {
		return ((n!=0) && (n&(n-1))==0);
	}

Note that powers of two have only 1 bit set to one:

1:  000001
2:  000010
4:  000100
8:  001000
16: 010000
32: 100000

and so on, so we need to check if the number only has one bit that is set, and that the number is not 0 (because zero is not a power of two).

We can count the number of set bits (which is another interview question!), and if the number of set bits is one, then the number is a power of two. A smarter way to do it would be bitwise ANDing of the number and the number-1, and then check that the result == 0.

For example, to check that 32 is a power of 2, convert 32 to binary to be 100000, convert 31 to binary to be 011111. Bitwise ANDing of those 2 numbers would obviously result in 0.

UPDATE 2: Dear all, the code is now released under MIT license and is version controlled on github thanks to TuteC!

7/7/2009.

UPDATE: Please check this comment for a more updated example.

Component code updated on 30/4/2009, check the posted code or the download links.

I revisited the code I used to develop the old image resize component because I found a bug in the resize code. I used the resize function from the PImageComponent by Wendy and ended up with the current version I’m using at my websites:
Code download at the bottom of the post.

<?php
/*
 File: /app/controllers/components/image.php
*/
class ImageComponent extends Object
{
	/*
	*	Uploads an image and its thumbnail into $folderName/big and $folderName/small respectivley.
	* 	Also uploads a zoom cropped image into $folderName/home. You could easily modify it to suit your needs!
	
	* 	Directions:
	*	In view where you upload the image, make sure your form creation is similar to the following
	*	<?= $form->create('ControllerName',array('type' => 'file')); ?>
	

	*	In view where you upload the image, make sure that you have a file input similar to the following
	*	<?= $form->file('Image/image1'); ?>
	
	
	*	In the controller, add the component to your components array
	*	var $components = array("Image");
	

	*	In your controller action (the parameters are expained below)
	*	$image_path = $this->Image->upload_image_and_thumbnail($this->data,"name1", 573,380,80,80, "sets");
	*	this returns the file name of the result image.  You can  store this file name in the database
	*
	*	Note that your image will be stored in 3 locations:
	*	Image: /webroot/img/$folderName/big/$image_path 
	*	Thumbnail:  /webroot/img/$folderName/small/$image_path 
	*	Homepage:  /webroot/img/$folderName/home/$image_path  
	*
	*	You could easily add more locations or remove locations you don't need


	*	Finally in the view where you want to see the images
	*	<?= $html->image('sets/big/'.$furnitureSet['FurnitureSet']['image_path']);
	* 	where "sets" is the folder name we saved our pictures in, and $furnitureSet['FurnitureSet']['image_path'] is the file name we stored in the database
	

	*	Parameters:
	*	$data: the image data array from the form
	*	$maxw: the maximum width that you want your picture to be resized to
	*	$maxh: the maximum width that you want your picture to be resized to
	*	$thumbscalew: the maximum width hat you want your thumbnail to be resized to
	*	$thumbscaleh: the maximum height that you want your thumbnail to be resized to
	*	$folderName: the name of the parent folder of the images. The images will be stored to /webroot/img/$folderName/big/ and  /webroot/img/$folderName/small/
	*/	
	function upload_image_and_thumbnail($data, $maxw, $maxh, $thumbscalew, $thumbscaleh, $folderName) {
		if (strlen($data['name'])>4){ 
					$error = 0;
					$tempuploaddir = "img/temp"; // the /temp/ directory, should delete the image after we upload
					$homeuploaddir = "img/".$folderName."/home"; // the /home/ directory
					$biguploaddir = "img/".$folderName."/big"; // the /big/ directory
					$smalluploaddir = "img/".$folderName."/small"; // the /small/ directory for thumbnails
					
					// Make sure the required directories exist, and create them if necessary
					if(!is_dir($tempuploaddir)) mkdir($tempuploaddir,0755,true);
					if(!is_dir($homeuploaddir)) mkdir($homeuploaddir,0755,true);
					if(!is_dir($biguploaddir)) mkdir($biguploaddir,0755,true);
					if(!is_dir($smalluploaddir)) mkdir($smalluploaddir,0755,true);
					
					$filetype = $this->getFileExtension($data['name']);
					$filetype = strtolower($filetype);
 
					if (($filetype != "jpeg")  && ($filetype != "jpg") && ($filetype != "gif") && ($filetype != "png"))
					{
						// verify the extension
						return;
					}
					else
					{
						// Get the image size
						$imgsize = GetImageSize($data['tmp_name']);
					}

					// Generate a unique name for the image (from the timestamp)
					//$id_unic = str_replace(".", "", strtotime ("now"));
					$id_unic = $uuid = String::uuid();
					$filename = $id_unic;
					  
					settype($filename,"string");
					$filename.= ".";
					$filename.=$filetype;
					$tempfile = $tempuploaddir . "/$filename";
					$homefile = $homeuploaddir . "/$filename";
					$resizedfile = $biguploaddir . "/$filename";
					$croppedfile = $smalluploaddir . "/$filename";
					
					
					if (is_uploaded_file($data['tmp_name']))
                    {                    
						// Copy the image into the temporary directory
                        if (!copy($data['tmp_name'],"$tempfile"))
                        {
                            //print "Error Uploading File!.";
							unset($filename);
							unlink($tempfile);
                            exit(); 
                        }
						else {				
							/*
							 *	Generate the home page version of the image center cropped
							 */
							$this->resizeImage('resizeCrop', $tempuploaddir, $filename, $homeuploaddir, $filename, 886, 473, 85);
							/*
							 *	Generate the big version of the image with max of $imgscale in either directions
							 */
							$this->resizeImage('resize', $tempuploaddir, $filename, $biguploaddir, $filename, $maxw, $maxh, 85);							

							/*
							 *	Generate the small thumbnail version of the image with scale of $thumbscalew and $thumbscaleh
							 */
							$this->resizeImage('resizeCrop', $tempuploaddir, $filename, $smalluploaddir, $filename, $thumbscalew, $thumbscaleh, 75);
													
							// Delete the temporary image
							unlink($tempfile);
						}
                    }
 
                     // Image uploaded, return the file name
					 return $filename;   
		}
	}
	
	/*
	*	Deletes the image and its associated thumbnail
	*	Example in controller action:	$this->Image->delete_image("1210632285.jpg","sets");
	*
	*	Parameters:
	*	$filename: The file name of the image
	*	$folderName: the name of the parent folder of the images. The images will be stored to /webroot/img/$folderName/big/ and  /webroot/img/$folderName/small/
	*/
	function delete_image($filename,$folderName) {
		if(is_file("img/".$folderName."/home/".$filename))
			unlink("img/".$folderName."/home/".$filename);
		if(is_file("img/".$folderName."/big/".$filename))
			unlink("img/".$folderName."/big/".$filename);
		if(is_file("img/".$folderName."/small/".$filename))
			unlink("img/".$folderName."/small/".$filename);
	}
 
    function getFileExtension($str) {
 
        $i = strrpos($str,".");
        if (!$i) { return ""; }
        $l = strlen($str) - $i;
        $ext = substr($str,$i+1,$l);
        return $ext;
    }

	/*
	 * @param $cType - the conversion type: resize (default), resizeCrop (square), crop (from center) 
	 * @param $id - image filename
	 * @param $imgFolder  - the folder where the image is
	 * @param $newName - include extension (if desired)
	 * @param $newWidth - the  max width or crop width
	 * @param $newHeight - the max height or crop height
	 * @param $quality - the quality of the image
	 * @param $bgcolor - this was from a previous option that was removed, but required for backward compatibility
	 */
	function resizeImage($cType = 'resize', $srcfolder, $srcname, $dstfolder, $dstname = false, $newWidth=false, $newHeight=false, $quality = 75)
	{
		$srcimg = $srcfolder.DS.$srcname;
		list($oldWidth, $oldHeight, $type) = getimagesize($srcimg); 
		$ext = $this->image_type_to_extension($type);
		
		//check to make sure that the file is writeable, if so, create destination image (temp image)
		if (is_writeable($dstfolder))
		{
			$dstimg = $dstfolder.DS.$dstname;
		}
		else
		{
			//if not let developer know
			debug("You must allow proper permissions for image processing. And the folder has to be writable.");
			debug("Run \"chmod 777 on '$dstfolder' folder\"");
			exit();
		}
		
		//check to make sure that something is requested, otherwise there is nothing to resize.
		//although, could create option for quality only
		if ($newWidth OR $newHeight)
		{
			/*
			 * check to make sure temp file doesn't exist from a mistake or system hang up.
			 * If so delete.
			 */
			if(file_exists($dstimg))
			{
				unlink($dstimg);
			}
			else
			{
				switch ($cType){
					default:
					case 'resize':
						# Maintains the aspect ration of the image and makes sure that it fits
						# within the maxW(newWidth) and maxH(newHeight) (thus some side will be smaller)
						$widthScale = 2;
						$heightScale = 2;
						
						// Check to see that we are not over resizing, otherwise, set the new scale
						if($newWidth) {
							if($newWidth > $oldWidth) $newWidth = $oldWidth;
							$widthScale = 	$newWidth / $oldWidth;
						}
						if($newHeight) {
							if($newHeight > $oldHeight) $newHeight = $oldHeight;
							$heightScale = $newHeight / $oldHeight;
						}
						//debug("W: $widthScale  H: $heightScale<br>");
						if($widthScale < $heightScale) {
							$maxWidth = $newWidth;
							$maxHeight = false;							
						} elseif ($widthScale > $heightScale ) {
							$maxHeight = $newHeight;
							$maxWidth = false;
						} else {
							$maxHeight = $newHeight;
							$maxWidth = $newWidth;
						}
						
						if($maxWidth > $maxHeight){
							$applyWidth = $maxWidth;
							$applyHeight = ($oldHeight*$applyWidth)/$oldWidth;
						} elseif ($maxHeight > $maxWidth) {
							$applyHeight = $maxHeight;
							$applyWidth = ($applyHeight*$oldWidth)/$oldHeight;
						} else {
							$applyWidth = $maxWidth; 
								$applyHeight = $maxHeight;
						}
						$startX = 0;
						$startY = 0;
						break;
					case 'resizeCrop':
					
						// Check to see that we are not over resizing, otherwise, set the new scale						
						// -- resize to max, then crop to center
						if($newWidth > $oldWidth) $newWidth = $oldWidth;	
							$ratioX = $newWidth / $oldWidth;
						
						if($newHeight > $oldHeight) $newHeight = $oldHeight;
							$ratioY = $newHeight / $oldHeight;									
	
						if ($ratioX < $ratioY) { 
							$startX = round(($oldWidth - ($newWidth / $ratioY))/2);
							$startY = 0;
							$oldWidth = round($newWidth / $ratioY);
							$oldHeight = $oldHeight;
						} else { 
							$startX = 0;
							$startY = round(($oldHeight - ($newHeight / $ratioX))/2);
							$oldWidth = $oldWidth;
							$oldHeight = round($newHeight / $ratioX);
						}
						$applyWidth = $newWidth;
						$applyHeight = $newHeight;
						break;
					case 'crop':
						// -- a straight centered crop
						$startY = ($oldHeight - $newHeight)/2;
						$startX = ($oldWidth - $newWidth)/2;
						$oldHeight = $newHeight;
						$applyHeight = $newHeight;
						$oldWidth = $newWidth; 
						$applyWidth = $newWidth;
						break;
				}
				
				switch($ext)
				{
					case 'gif' :
						$oldImage = imagecreatefromgif($srcimg);
						break;
					case 'png' :
						$oldImage = imagecreatefrompng($srcimg);
						break;
					case 'jpg' :
					case 'jpeg' :
						$oldImage = imagecreatefromjpeg($srcimg);
						break;
					default :
						//image type is not a possible option
						return false;
						break;
				}
				
				//create new image
				$newImage = imagecreatetruecolor($applyWidth, $applyHeight);
								
				//put old image on top of new image
				imagecopyresampled($newImage, $oldImage, 0,0 , $startX, $startY, $applyWidth, $applyHeight, $oldWidth, $oldHeight);
				
					switch($ext)
					{
						case 'gif' :
							imagegif($newImage, $dstimg, $quality);
							break;
						case 'png' :
							imagepng($newImage, $dstimg, $quality);
							break;
						case 'jpg' :
						case 'jpeg' :
							imagejpeg($newImage, $dstimg, $quality);
							break;
						default :
							return false;
							break;
					}
				
				imagedestroy($newImage);
				imagedestroy($oldImage);
								
				return true;
			}

		} else {
			return false;
		}
		

	}

	function image_type_to_extension($imagetype)
	{
	if(empty($imagetype)) return false;
		switch($imagetype)
		{
			case IMAGETYPE_GIF    : return 'gif';
			case IMAGETYPE_JPEG    : return 'jpg';
			case IMAGETYPE_PNG    : return 'png';
			case IMAGETYPE_SWF    : return 'swf';
			case IMAGETYPE_PSD    : return 'psd';
			case IMAGETYPE_BMP    : return 'bmp';
			case IMAGETYPE_TIFF_II : return 'tiff';
			case IMAGETYPE_TIFF_MM : return 'tiff';
			case IMAGETYPE_JPC    : return 'jpc';
			case IMAGETYPE_JP2    : return 'jp2';
			case IMAGETYPE_JPX    : return 'jpf';
			case IMAGETYPE_JB2    : return 'jb2';
			case IMAGETYPE_SWC    : return 'swc';
			case IMAGETYPE_IFF    : return 'aiff';
			case IMAGETYPE_WBMP    : return 'wbmp';
			case IMAGETYPE_XBM    : return 'xbm';
			default                : return false;
		}
	}
	} 
?>

to use it in your controller,


<?php
class FurnitureSetsController extends AppController {

	var $name = 'FurnitureSets';
var $components = array("Image","RequestHandler");

function admin_add() {
 if (!empty($this->data)) { 
  $this->FurnitureSet->create();
   if ($this->FurnitureSet->save($this->data)) {
    // resize the image to 573x380 and create a square thumbnail 80x80
       $image_path = $this->Image->upload_image_and_thumbnail($this->data,"name1", 573,380,80,80, "sets");
    if(isset($image_path)) {
     $this->FurnitureSet->saveField('image_path',$image_path);
    }
    else {
     $this->Session->setFlash(__('The image for the set could not be saved. Please, try again.', true));
    }     

   }

 }
}

Note that you can modify the resize settings in the upload_image_and_thumbnail method.

The view..

<div class="furnitureSets form">
    <?php echo $form->create('FurnitureSet',array('type' => 'file'));?>
    <fieldset>
        <legend>
            <?php __('Add Furniture set');?>
        </legend>
        <?php
		echo $form->input('name');
		echo $form->input('country_id');
			?>
		<div class="input">
		<label for="Image/name1">Image</label>
		<?php
		echo $form->file('Image/name1', array('size' => '40'));
		?>
		</div>
		<?php
		echo $form->input('is_featured');
		echo $form->input('furniture_material_id');
		echo $form->input('furniture_category_id');
		echo $form->input('is_indoor');
		echo $form->input('is_outdoor');		
		echo $form->input('CustomerType');
	?>
    </fieldset>
    <?php echo $form->end('Submit');?>
</div>

Now as promised, the code!
30/4/2009: after modification from comments
17/7/2008: Old version

Again, thanks Wendy for your code!

I shamelessly ripped of the form designed at this excellent blog to use a somehow modified CSS structure.

The CSS button classes are customizable to allow positive/negative action buttons with different CSS images.

body{
font-family:"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
font-size:12px;
}

p, h1, form, button{border:0; margin:0; padding:0;}
.spacer{clear:both; height:1px;}

form.cleanform{
	margin:0 auto;
	width:400px;
	padding:14px;
	border:solid 2px #b7ddf2;
	background:#EAFFD5;
}

form.cleanform div.header {
	border-bottom:solid 1px #b7ddf2;
	font-size:11px;
	margin-bottom:20px;
}

form.cleanform div.header h1 {
	font-size:14px;
	font-weight:bold;
	margin-bottom:8px;
}

form.cleanform div.header .description {
	color: #666666;
}

form.cleanform p{
	font-size:11px;
	margin-bottom:20px;
}

form.cleanform label{
	display:block;
	font-weight:bold;
	text-align:right;
	width:140px;
	float:left;
}

form.cleanform .small{
	color:#666666;
	display:block;
	font-size:11px;
	font-weight:normal;
	text-align:right;
	width:140px;
}

form.cleanform input{
	float:left;
	font-size:12px;
	padding:4px 2px;
	border:solid 1px #aacfe4;
	width:200px;
	margin:2px 0 20px 10px;
}

/* Button main class */
form.cleanform input.button {
	float:none;
	width:125px;
	height:30px;
	text-align:left;
	line-height:20px;
	color:#FFFFFF;
	font-size:11px;
	font-weight:bold;
	
	background-color:#f5f5f5;
    border:1px solid #dedede;
    border-top:1px solid #eee;
    border-left:1px solid #eee;
	
	font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
    font-size:90%;
    text-decoration:none;
    font-weight:bold;
    color:#565656;
    cursor:pointer;
	
	background-position: 6px;
	background-repeat:no-repeat;
	text-indent:30px;
	
	margin: 0;
	padding: 0;
}


/* Positive button */
form.cleanform input.button.positive {
	color::#529214;	
}

form.cleanform input.button:hover.positive {
	background-color:#E6EFC2;
    border:1px solid #C6D880;
    color:#529214;
}

/* Negative button */
form.cleanform input.button.negative {
	color::#d12f19;	
}

form.cleanform input.button:hover.negative {
	background-color:#fbe3e4;
    border:1px solid #fbc2c4;
    color:#d12f19;
}

/* Button images */
form.cleanform input.button.add {
	background-image:url(add.png);
}

form.cleanform input.button.delete {
	background-image:url(delete.png);
}
<form class="cleanform" name="form" method="post" action="form.html">
		
			<div class="header">
				<h1>Sign-up form</h1>
				<p class="description">This is the basic look of my form without table</p>
			</div>
			
			<p>
				<label>Name
					<span class="small">Add your name</span>
				</label>
				<input type="text" name="name" id="name" />
			</p>
			
			<p>
				<label>Email
					<span class="small">Add a valid address</span>
				</label>
				<input type="text" name="email" id="email" />
			</p>
			
			<p>
				<label>Password
					<span class="small">Min. size 6 chars</span>
				</label>
				<input type="password" name="password" id="password" />
			</p>
			
			<div style="float:right">
				<input type="submit" name="submit" class="button positive add" value="Sign-up" />
				<input type="submit" name="submit" class="button negative delete" value="Cancel" />
			</div>
			
			<div class="spacer"></div>
			
		</form>

Download here

Tags: , ,

I made up this solution inspired by the post and comments on this excellent blog

<a href="#" class="button add">Add</a>
<a href="#" class="button delete">Delete</a>
a.button{
	display:block;	
	background-position: 6px;
	background-repeat:no-repeat;
	font-weight:bold;
	font-family: Trebuchet MS, Tahoma, sans-serif;
	font-size: 0.7em;	
	text-decoration:none;
	text-indent:30px;
	color:#555555;
	background-color:#EAEAD7;
	border:#CCCCCC solid 1px;
	height:30px;
	width:190px;
	line-height:30px;
}
	
a:hover{
	background-color:#F3F3E9;
	color:#737373;
}

.add {
	background-image:url(add.png);
}

.delete {
	background-image:url(delete.png);
}

any idea how can I put those buttons next to each other instead of below each other?
I tried removing the display:block from the but the button collapsed!

Update:
If you want to align the buttons next to each other, add

float:left;

to the CSS class of a.button, thanks to Stephan!

Download here

Tags: , ,
Ahmed Sabbour's Facebook profile
December 2017
S M T W T F S
« Jul    
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Tweets

RSS StackOverflow

Recently bookmarked