Hi,
you are doing a web app or something that requires the creation of a subdomain for a account/user feature/action and don’t know how to do it? i will give you some tips about it
normally, when you create a subdomain, you do it in your dns files/manager adding a CNAME record, that redirect to a new folder under your account or server. this is the normal process but is not dynamic/flexible to create subdomains on the fly, why require to touch server configuration files in the best of the cases (if you have a vps or a dedicated, why if you are on a shared account you need to use the control panel of your hosting company to do this).
in this case, we will be able to dynamically create/edit/delete any subdomain on the fly, using some persistence method to save the existent domains (like DB, files, variables etc..)
first of all, the biggest requirement is to config your domain as a wildcard domain, so any prefix added to the domain will be taken as valid. if you have access to the apache configuration files, open the one that have the virtualhost declaration of the domain and add the line:
ServerAlias *.your-domain-name.com
save and restart apache. if you are on a shared account, ask your hosting provider to do it, most of them will do it.
after this, we will create a .htaccess on the root of your web directory of the domain and paste this content in it:
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !www.your-domain-name.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-_]+).your-domain-name.com [NC]
RewriteRule (.*) \/index.php?subdomain=%1 [QSA,L]
this code, will do the following:
1) check the the domain is not the domain + www prefix
2)check that the domain is a valid string (numbers, sign – _ and letters)
3) redirect to the index.php passing the subdomain as a GET parameters
this has been coded to send the subdomain as a get parameter to the php script, there you can check if the subdomain exists agains a db or any other persistent data as config files and do the necessary actions. of course that this subdomain detection can be done with php, but if you are in some conflict with other code, this solution could be handy, clean and effective.
i hope it help you in some way.
Regards,
Shadow.
Related Post
Hi,
i’m still with the images stuff
now i needed to integrate a crop image script using js. so i started to look for a premade solution. you can find several of them here, here and here. i was looking for a mootools based solution and i found 4. for my surprise,one didn’t exist anymore, one of them didn’t worked with mootools 1.2, the others was too complicated and not flexible and none offer what i really needed, that was able to offer “mirrors” as preview of the crop in 2 different sizes. in my adventure, i tried to fix the first one (MooCrop) porting it to 1.2 but i leave it why it would take me too much work, then i tried to modify cwCrop but the code structure seems to be less flexible, and finally i decided to go with uvumiCrop, as it already have a mirror function and just need to be converted into a multi-div function.
so for those who want the mirror feature in the uvumiCrop script, here are the functions and code you need to replace:
Add this to the class var declaration
previewImageArray:new Array(),
On some place around line 102, paste this
this.previewImageArray = new Array();
replace with this from lines 285 to 354
if(this.options.preview){
if(isArray(this.options.preview)){
var previewImgObjArray=new Array();
this.options.preview.each(function (item,index){
var initWidth= $(item).getStyle('width');
var initHeight= $(item).getStyle('height');
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
var previewWrapperObj = new Element('div',{
styles:{
height:initHeight
}
}).wraps($(item));
//Setting the preview container
$(item).setStyles({
display:'block',
position:'relative',
width:initWidth,
height:initHeight,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:1,
visibility: 'visible'
});
//cloning the original image for the preview
var previewImageObJ = this.target.clone();
previewImageObJ.set('id','imgObj_'+index);
previewImageObJ.removeProperties('width','height').setStyle('position','absolute').inject($(item));
previewImgObjArray.push(new Array('imgObj_'+index,item,initWidth,initHeight));
}.bind(this));
this.previewImageArray=previewImgObjArray;
}else{
if($(this.options.preview)){
this.preview = $(this.options.preview);
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
this.previewWrapper = new Element('div',{
styles:{
height:this.previewSize.y+2*this.preview.getStyle('border-width').toInt()+this.preview.getStyle('margin-top').toInt()+this.preview.getStyle('margin-bottom').toInt()
}
}).wraps(this.preview);
}else{
var previewWrapper = new Element('div',{
'class':'preview'
}).inject(this.toolBox,'top');
this.preview = new Element('div').inject(previewWrapper)
}
//Setting the preview container
this.preview.setStyles({
display:'block',
position:'relative',
width:this.previewSize.x,
height:this.previewSize.y,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:0
});
//cloning the original image for the preview
this.previewImage = this.target.clone();
this.previewImage.removeProperties('width','height').setStyle('position','absolute').inject(this.preview);
// this.addEvent('onPreview',this.updatePreview.bind(this));
}
this.addEvent('onPreview',this.updatePreview.bind(this));
}
replace updatePreview function with this code below:
//Function to update the preview
updatePreview: function(top,left,width,height){
if(this.previewImageArray.length>0){
this.previewImageArray.each(function (item,index){
if(height*item[2].toInt()/width<item[3]){
$(item[1]).setStyles({
width:item[2],
height:(item[3].toInt()*height/width).toInt()
});
$(item[0]).setStyles({
width:(this.target_coord.width*item[2].toInt()*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*item[2].toInt()/width).toInt(),
left:-(left*item[2].toInt()/width).toInt()
});
}else{
$(item[1]).setStyles({
height:item[3],
width:item[3]
});
$(item[0]).setStyles({
height:(this.target_coord.height*item[3].toInt()*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*item[3].toInt()/height).toInt(),
left:-(left*item[3].toInt()/height).toInt()
});
}
}.bind(this));
}else{
if(height*this.previewSize.x/width<this.previewSize.y){
this.preview.setStyles({
width:this.previewSize.x,
height:(this.previewSize.x*height/width).toInt()
});
this.previewImage.setStyles({
width:(this.target_coord.width*this.previewSize.x*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*this.previewSize.x/width).toInt(),
left:-(left*this.previewSize.x/width).toInt()
});
}else{
this.preview.setStyles({
height:this.previewSize.y,
width:(this.previewSize.y*width/height).toInt()
});
this.previewImage.setStyles({
height:(this.target_coord.height*this.previewSize.y*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*this.previewSize.y/height).toInt(),
left:-(left*this.previewSize.y/height).toInt()
});
}
}
},
and the isArray() function used at the beginning of the code:
function isArray(obj) {
return obj.constructor == Array;
}
so, now in the initialization of the uvumiCrop object, you set the preview property as a array ( new Array(‘id1′,’id2′) ) with the id’s of the divs that will be used as mirrors. is important that you set the width and height of each div before you create the uvumiCrop object. this code will maintain the original behavior of the original script, you can still have the floating mirror and the unique mirror.
is also important to mention that i changed the code so the container don’t get the width and height deformed and work as a container hiding the rest of the image. is done like this so the user can know really how it will look after the crop process.
i have sent this post to the developer, so maybe he include it on the next release
i hope you find this useful and save you some time
Regards,
Shadow.
Related Post
Hi,
on the web app i have been working this past months, we allow the users to upload avatar photos, and some other pictures that are shown at the site. so, i implemented the code i always use to resize the images. it have done the job well on the testing phase but we found that we have bad quality images when the users uploaded their photos. so i looked for a solution and i found phpThumb. this class/script generate resized images in a quickly and easy way. it comes in 2 flavors, in a ready to use script where you pass the parameters of where is the source image, destination, measures etc.. and will print you the image (can be used in img tags as source). and also you have the class where you can manually convert the files and save it on a file or print it etc..
the class use as input the location of the source image, the binary data or a GD resource. also, phpThumb will try to use imagemagick if is installed on the server (that will give you a better quality image) and if is not available, will use GD automatically. i have tried it and i need to say that the best configuration i made to get the best quality image possibly was:
$phpThumb->setParameter('output_interlace',true);
$phpThumb->setParameter('config_output_format', 'png');
$phpThumb->setParameter('fltr', 'q|95');
$phpThumb->setParameter('config_imagemagick_path', '/usr/bin/convert');
i have tried to use jpeg format, but sometimes i get some ugly and pixelated grey background at the thin lines of the image (like words etc..) so the best option was to use png.
you can download phpThumb from here
Regards,
Shadow.
Related Post
Hi,
this time i will write you a mini-howto install murmur and a administration panel, called MumPI.
What is murmur?
murmur is the server part of the open source voip communication program called Mumble. Mumble is a low latency voip program, that allow you communicate with several people on the same channel. murmur is the server part, the app that handle the communication between users.
Murmur installation
in debian is pretty easy to install it, just run the following apt-get
apt-get install mumble-server
that line will install murmur and set up as a service (like apache, mysql etc..) and run each time the machine booth. as any service, you can stop it, restart it, doing a /etc/init.d/mumble-server start|restart|reload|stop
now we need to install that will be the middle man between mumble server and MumPI, the php administration panel.
for this, just use this apt-get line:
apt-get install icecpp libzeroc-ice32 php-zeroc-ice lzma
for the current version of mumble and MumPI, check that you are installing ice 3.4, if not, go to ICEphp for a updated deb package. after the installation, open with your favorite editor:
/etc/mumble-server.ini
and look for a string like this:
ice="tcp -h 127.0.0.1 -p 6502"
if you don’t have it, add it after the dbus declaration.
now come the last step, go to MumPI website and download/extract the last version on your web end directory (i assume you already have apache and php configured for some domain)
after the extraction, just open the location with your browser and MumPI will be installed.
now, open
/etc/php5/conf.d/IcePHP.ini
and change the declaration of ice.slice to:
ice.slice=/path/to/MumPI/libs/Murmur122_fixed.ice
and that all folks ! now you can manage users, create virtual servers and enjoy of one of the best open source voip app out there
Regards,
Shadow.
Related Post
Hi,
long time since my last post right? sorry about that, too much work and things happening lately
.
this time i’m here to share the discover of a great tool that a friend of mine told me some days ago. is called selenium IDE. this tools comes in several formats, but what i’m interested in the FF addon version. this addon let you record user actions in a website, as login into a site, submit a form, click a link etc.. all of this can be recorded and reproduced anytime. this is useful why you can create a test suite of diferent’s actions for your app, and after you added some change or feature, you can run the test’s and know if something is not working.
selenium also accept scripting,in a markup language like xml where you can manually define actions, as waiting for some DOM object to show up, or some value to get set to launch an action.
i recommend you to take a look at it, will save you time and headaches in the future
you can download it from here.
Regards,
Shadow.
Related Post
Hi,
today i was playing with inkscape, and i created some shiny balls to share with my readers
are not a big deal, but could be useful for some project that you maybe have. the good thing about this shiny balls, is that you can just change the color of the ball itself (not of the white half transparent ellipses) , and you will have balls of any color
the file is on SVG format and the license of this is free for any purpose, commercial or not.
you can download it from here.
i hope you enjoy it.
Regards,
Shadow.
Related Post
Hi,
like the last year, i made a countdown widget for the EVA of this year
here is the code if you want it for your site:
<object width="446" height="386"> <param name="movie" value="http://shadow.y-developments.info/eva.swf"></param> <embed src="http://shadow.y-developments.info/eva.swf" type="application/x-shockwave-flash" width="446" height="386"></embed> </object>
Related Post
Hi,
recently building a app i was need to suggest data to the user when trying to fill a input. so i look for a js script for this. i usually use mootools for my development in js, so looking for a plugin i found this: Meio.Autocomplete plugin for mootools
is a really nice plugin, between their features, support the inbuilt ajax calls using the Request.JSON method from the mootools framework. also support to set up filter for the returned data, the set of field parameter to look for the input by the user, the minimum of characters that the user need to enter to start looking for it, delay between the ajax call and the search in the data and many other properties. you can also customize the look and feel of how the options are displayed.
from their web page you can download the source code and the compressed version for production environments. also there you can see plenty of documentation explaining each property of the plugin and several examples to see and try online.
i hope it help you in some way
Regards,
Shadow.
Related Post
Hi,
today i received a complaint from a user, that was receiving bounced errors to the emails sent to the server. so looking at the server, i see something like this:
Nov 21 17:36:00 li72-241 amavis[18844]: (18844-01) (!!)TROUBLE in check_mail: parts_decode_ext FAILED: file(1) utility (/usr/bin/file) error: run_command (open pipe): Can’t fork at /usr/lib/perl/5.10/IO/File.pm line 66, <GEN33> line 71. at /usr/sbin/amavisd-new line 2892, <GEN33> line 71.
so looking at google for some clues, as i didn’t changed anything on the server, i saw that this is a memory/resources related problem, so making a cat under /proc/meminfo i saw that the physical memory was low and the swap memory was all occupied, so i upgraded the swap memory. upgrading the physical memory will do the same but in this case it cost money
Regards,
Shadow.






