<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-3326160732880350623</id><updated>2012-05-07T05:23:34.755-07:00</updated><category term="Howto" /><category term="flash" /><category term="I18n" /><category term="workaround" /><category term="Javascript" /><category term="ajax" /><category term="bug" /><category term="security" /><category term="aie" /><category term="as3" /><category term="fileupload" /><category term="Fun" /><category term="jsThumbnailPlugin" /><category term="Programming" /><category term="PHP" /><category term="Canvas" /><category term="Doctrine" /><category term="Firefox" /><category term="css" /><category term="tutorials" /><category term="plugin" /><category term="html" /><category term="Projects" /><category term="drupal" /><category term="Symfony" /><category term="ajax image editor" /><category term="ExtJS" /><category term="HTML5" /><category term="google" /><title type="text">julianstricker.com</title><subtitle type="html">I work as Senior Software Engineer at one of the biggest online marketing agencies in Italy. My primary responsibility is the programming of internet applications using AJAX, PHP, Symfony, Javascript, Prototype.js, Scriptaculous, jQuery, ExtJS, Flash, Flex, Away3D.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.julianstricker.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.julianstricker.com/" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/wwwjulianstrickercom" /><feedburner:info uri="wwwjulianstrickercom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-7582955549078499907</id><published>2010-11-15T11:47:00.000-08:00</published><updated>2012-03-26T13:38:09.549-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="Howto" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">How to add a "Save and List" Action Button to Symfony Admin Generator Form.</title><content type="html">To improve the workflow sometimes it may be better to redirect the user back to the list after the Save-action. This tutorial shows how to implement this in Symfony 1.3 and 1.4&lt;br /&gt;&lt;br /&gt;First copy the "processForm"-function from the action.class.php in your cache-directory ( /cache/dev/modules/auto[Modulename]/actions/actions.class.php ) to your action.class.php and change the lines:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;      if ($request-&gt;hasParameter('_save_and_add'))&lt;br /&gt;      {&lt;br /&gt;        $this-&gt;getUser()-&gt;setFlash('notice', $notice.' You can add another one below.');&lt;br /&gt;&lt;br /&gt;        $this-&gt;redirect('@[Modulename]_new');&lt;br /&gt;      }      &lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;        $this-&gt;getUser()-&gt;setFlash('notice', $notice);&lt;br /&gt;&lt;br /&gt;        $this-&gt;redirect(array('sf_route' =&gt; '[Modulename]_edit', 'sf_subject' =&gt; $[Modulename]));&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;&lt;br /&gt;      if ($request-&gt;hasParameter('_save_and_add'))&lt;br /&gt;      {&lt;br /&gt;        $this-&gt;getUser()-&gt;setFlash('notice', $notice.' You can add another one below.');&lt;br /&gt;&lt;br /&gt;        $this-&gt;redirect('@[Modulename]_new');&lt;br /&gt;      }&lt;br /&gt;      else if ($request-&gt;hasParameter('_save_and_list'))&lt;br /&gt;      {&lt;br /&gt;        $this-&gt;getUser()-&gt;setFlash('notice', $notice);&lt;br /&gt;&lt;br /&gt;        $this-&gt;redirect('@[Modulename]');&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;        $this-&gt;getUser()-&gt;setFlash('notice', $notice);&lt;br /&gt;&lt;br /&gt;        $this-&gt;redirect(array('sf_route' =&gt; '[Modulename]_edit', 'sf_subject' =&gt; $[Modulename]));&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Open the file /apps/[Appname]/modules/[Modulename]/lib/[Modulename]GeneratorHelper.class.php and add the function:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;public function linkToSaveAndList($object, $params)&lt;br /&gt;  {&lt;br /&gt;    &lt;br /&gt;    return '&lt;li class="sf_admin_action_save_and_list"&gt;&lt;input type="submit" value="'.__($params['label'], array(), 'sf_admin').'" name="_save_and_list" /&gt;&lt;/li&gt;';&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In /apps/[Appname]/modules/[Modulename]/config/generator.yml:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;    ...&lt;br /&gt;    config:&lt;br /&gt;      ...&lt;br /&gt;      form:&lt;br /&gt;        actions:&lt;br /&gt;           save_and_list: ~&lt;br /&gt;           ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now there is a new button "Save and list" at the bottom of the Edit-form that will redirect the user to the list after saving the form. Maybe it would be useful to change the generator-classes to auto generate this button for every module.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-7582955549078499907?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/rQqskn2D8Vo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/7582955549078499907/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2010/11/how-to-add-save-and-list-action-button.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/7582955549078499907" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/7582955549078499907" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/rQqskn2D8Vo/how-to-add-save-and-list-action-button.html" title="How to add a &quot;Save and List&quot; Action Button to Symfony Admin Generator Form." /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2010/11/how-to-add-save-and-list-action-button.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-2004198694619367738</id><published>2010-09-14T08:51:00.001-07:00</published><updated>2012-03-26T13:36:37.485-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="HTML5" /><category scheme="http://www.blogger.com/atom/ns#" term="Fun" /><category scheme="http://www.blogger.com/atom/ns#" term="Canvas" /><title type="text">Fun with HTML5 Canvas Effects</title><content type="html">During my work on the new AIE Ajax Image Editor, I have done some experiments with the new HTML5 features, especially the new Canvas tag. This script is basically a new implementation in JavaScript of a old Director-Movie which I have made about 10 years ago.
&lt;br /&gt;
&lt;br /&gt;&lt;img id="canvasSource" src="http://www.julianstricker.com/tests/a941a55af.6398154.jpg" alt="Canvas Source" style="display:none" /&gt;
&lt;br /&gt;&lt;canvas id="area" width="140" height="185" style="margin-right:5px" align="left"&gt;&lt;/canvas&gt;Simply move over the image to distort it. Click to switch effect.
&lt;br /&gt;    &lt;!-- Javascript Code --&gt;
&lt;br /&gt;    &lt;script type="text/javascript" src="http://www.julianstricker.com/tests/canvaseffecttest.js"&gt;&lt;/script&gt;
&lt;br /&gt;The script is very simple: first it gets the content of a image ("getImageData"-function). 
&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;
&lt;br /&gt;window.onload = function() {
&lt;br /&gt;  canvas = document.getElementById("area");
&lt;br /&gt;  context = canvas.getContext("2d");
&lt;br /&gt;  image = document.getElementById("canvasSource");
&lt;br /&gt;  context.drawImage(image, 0, 0);
&lt;br /&gt;  imgdo = context.getImageData(0, 0, imgsizex, imgsizey);
&lt;br /&gt;  document.getElementById("area").onmousemove=draw;
&lt;br /&gt;  document.getElementById("area").onclick=function(){ mode++; if(mode&gt;2) mode=0; }; 
&lt;br /&gt;};
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;Then it distorts the image using some trigonometric functions:
&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;
&lt;br /&gt;function draw(){
&lt;br /&gt;  var imgd = context.getImageData(0, 0, imgsizex, imgsizey);
&lt;br /&gt;
&lt;br /&gt;  var opix = imgdo.data;
&lt;br /&gt;  var npix = imgd.data;
&lt;br /&gt;
&lt;br /&gt;  var mpos={x:100,y:100};
&lt;br /&gt;  var area=document.getElementById("area");
&lt;br /&gt;  mpos.x=Mouse.x-area.offsetLeft;
&lt;br /&gt;  mpos.y=Mouse.y-area.offsetTop;
&lt;br /&gt;  for (iy=0; iy&lt;imgsizey; iy++){
&lt;br /&gt;    for (ix=0; ix&lt;imgsizex; ix++){
&lt;br /&gt;      var a=(ix - mpos.x);
&lt;br /&gt;      var b=(iy - mpos.y);
&lt;br /&gt;      var c=Math.abs(Math.sqrt(Math.abs(a*a)+Math.abs(b*b)));
&lt;br /&gt;      var w=getwinkel(a,b);
&lt;br /&gt;      if (mode==0) {
&lt;br /&gt;              var wd=90-(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w+wd/1);
&lt;br /&gt;              var newa=Math.sin(neww)*c;
&lt;br /&gt;              var newb=Math.cos(neww)*c;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }else if (mode==1){
&lt;br /&gt;              var wd=90-(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w);
&lt;br /&gt;              var newc=c+wd/10;
&lt;br /&gt;              var newa=Math.sin(neww)*newc;
&lt;br /&gt;              var newb=Math.cos(neww)*newc;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }else{
&lt;br /&gt;              var wd=(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w);
&lt;br /&gt;              var newc=c+wd/10;
&lt;br /&gt;              var newa=Math.sin(neww)*newc;
&lt;br /&gt;              var newb=Math.cos(neww)*newc;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }
&lt;br /&gt;      npix[z  ] = opix[nz  ] || 0; 	// red
&lt;br /&gt;      npix[z+1] = opix[nz+1] || 0; 	// green
&lt;br /&gt;      npix[z+2] = opix[nz+2] || 0; 	// blue
&lt;br /&gt;
&lt;br /&gt;    }
&lt;br /&gt;  }
&lt;br /&gt;  var a=10;
&lt;br /&gt;  var b=10;
&lt;br /&gt;  var c=Math.sqrt(a*a+b*b);        
&lt;br /&gt;  context.putImageData(imgd, 0, 0);
&lt;br /&gt;}
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;It basically calculates the distance and the angle to the mouse position of every pixel. Then it adds a percentage of the distance to the angle and recalculates the new pixel-position. Then it copies the RGB-value of the pixel at the calculated position in the original image to the pixel in the new image.
&lt;br /&gt;
&lt;br /&gt;I have made those functions to convert between Rad and grad and to calculate the angle:
&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;
&lt;br /&gt;function rad2grad(rad){
&lt;br /&gt;  return rad*180/Math.PI;
&lt;br /&gt;}
&lt;br /&gt;function grad2rad(grad){
&lt;br /&gt;  return grad*Math.PI/180;
&lt;br /&gt;}
&lt;br /&gt;function getwinkel(a,b){
&lt;br /&gt;  var c=Math.abs(Math.sqrt(Math.abs(a*a)+Math.abs(b*b)));
&lt;br /&gt;  var nw=rad2grad(Math.asin(a/c));
&lt;br /&gt;  if (a&lt;0 &amp;&amp; b&lt;0){
&lt;br /&gt;    nw= -nw-180;
&lt;br /&gt;  }else if (b&lt;0){
&lt;br /&gt;    nw= 180-nw;
&lt;br /&gt;  }
&lt;br /&gt;  return nw;
&lt;br /&gt;}
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;...and the complete Code:
&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;
&lt;br /&gt;&lt;!--
&lt;br /&gt;Fun with HTML5 Canvas Effects Example
&lt;br /&gt;Author: 2010 Julian Stricker - http://www.julianstricker.com/
&lt;br /&gt;--&gt;
&lt;br /&gt;&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;br /&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;br /&gt;  &lt;head&gt;
&lt;br /&gt;    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;br /&gt;    &lt;title&gt;Fun with HTML5 Canvas Effects&lt;/title&gt;
&lt;br /&gt;  &lt;/head&gt;
&lt;br /&gt;
&lt;br /&gt;  &lt;body&gt;
&lt;br /&gt;    Fun with HTML5 Canvas Effects - Example &lt;br/&gt;
&lt;br /&gt;    Author: 2010 Julian Stricker - &lt;a href="http://www.julianstricker.com/" title="www.julianstricker.com"&gt;www.julianstricker.com&lt;/a&gt;&lt;br/&gt;
&lt;br /&gt;    &lt;img id="canvasSource" src="http://www.julianstricker.com/tests/a941a55af.6398154.jpg" alt="Canvas Source" /&gt;
&lt;br /&gt;
&lt;br /&gt;    &lt;canvas id="area" width="140" height="185"&gt;&lt;/canvas&gt;
&lt;br /&gt;
&lt;br /&gt;    &lt;!-- Javascript Code --&gt;
&lt;br /&gt;    &lt;script type="text/javascript"&gt;
&lt;br /&gt;      //mouse-positon (with scroll-pos on ie)
&lt;br /&gt;      var Mouse = {x:0, y:0};
&lt;br /&gt;      document.onmousemove = function (evt) {
&lt;br /&gt;        var e = window.event || evt;
&lt;br /&gt;        Mouse.x = e.x || e.pageX || 0;
&lt;br /&gt;        Mouse.y = e.y || e.pageY || 0;        
&lt;br /&gt;      }
&lt;br /&gt;      canvas = false;
&lt;br /&gt;      context = false;
&lt;br /&gt;      image = false;
&lt;br /&gt;      imgdo = false;
&lt;br /&gt;      imgsizex=140;
&lt;br /&gt;      imgsizey=185;
&lt;br /&gt;      mode=1;
&lt;br /&gt;      function draw(){
&lt;br /&gt;        var imgd = context.getImageData(0, 0, imgsizex, imgsizey);
&lt;br /&gt;        var opix = imgdo.data;
&lt;br /&gt;        var npix = imgd.data;
&lt;br /&gt;        var mpos={x:100,y:100};
&lt;br /&gt;        var area=document.getElementById("area");
&lt;br /&gt;        mpos.x=Mouse.x-area.offsetLeft;
&lt;br /&gt;        mpos.y=Mouse.y-area.offsetTop;
&lt;br /&gt;        for (iy=0; iy&lt;imgsizey; iy++){
&lt;br /&gt;          for (ix=0; ix&lt;imgsizex; ix++){
&lt;br /&gt;            var a=(ix - mpos.x);
&lt;br /&gt;            var b=(iy - mpos.y);
&lt;br /&gt;            var c=Math.abs(Math.sqrt(Math.abs(a*a)+Math.abs(b*b)));
&lt;br /&gt;            var w=getwinkel(a,b);
&lt;br /&gt;            
&lt;br /&gt;            
&lt;br /&gt;            if (mode==0) {
&lt;br /&gt;              var wd=90-(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w+wd/1);
&lt;br /&gt;              var newa=Math.sin(neww)*c;
&lt;br /&gt;              var newb=Math.cos(neww)*c;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }else if (mode==1){
&lt;br /&gt;              var wd=90-(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w);
&lt;br /&gt;              var newc=c+wd/10;
&lt;br /&gt;              var newa=Math.sin(neww)*newc;
&lt;br /&gt;              var newb=Math.cos(neww)*newc;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }else{
&lt;br /&gt;              var wd=(c);
&lt;br /&gt;              if (wd&lt;0) wd=0;
&lt;br /&gt;              if (wd&gt;90) wd=90;
&lt;br /&gt;              var neww=grad2rad(w);
&lt;br /&gt;              var newc=c+wd/10;
&lt;br /&gt;              var newa=Math.sin(neww)*newc;
&lt;br /&gt;              var newb=Math.cos(neww)*newc;
&lt;br /&gt;              var z=(iy*imgsizex+ix)*4;
&lt;br /&gt;              var nz=Math.round((Math.round(mpos.y+newb)*imgsizex+Math.round(mpos.x+newa)))*4;
&lt;br /&gt;            }
&lt;br /&gt;            //if (iy==0)console.log(Math.round(mpos.y+newb), Math.round(mpos.x+newa),iy,ix);
&lt;br /&gt;            npix[z  ] = opix[nz  ] || 0; 	// red
&lt;br /&gt;            npix[z+1] = opix[nz+1] || 0; 	// green
&lt;br /&gt;            npix[z+2] = opix[nz+2] || 0; 	// blue
&lt;br /&gt;          }
&lt;br /&gt;        }
&lt;br /&gt;        var a=10;
&lt;br /&gt;        var b=10;
&lt;br /&gt;        var c=Math.sqrt(a*a+b*b);
&lt;br /&gt;        context.putImageData(imgd, 0, 0);
&lt;br /&gt;      }
&lt;br /&gt;
&lt;br /&gt;      window.onload = function() {
&lt;br /&gt;        canvas = document.getElementById("area");
&lt;br /&gt;        context = canvas.getContext("2d");
&lt;br /&gt;        image = document.getElementById("canvasSource");
&lt;br /&gt;        context.drawImage(image, 0, 0);        
&lt;br /&gt;        imgdo = context.getImageData(0, 0, imgsizex, imgsizey);
&lt;br /&gt;        document.getElementById("area").onmousemove=draw; 
&lt;br /&gt;        document.getElementById("area").onclick=function(){ mode++; if(mode&gt;2) mode=0; };
&lt;br /&gt;      };
&lt;br /&gt;      function rad2grad(rad){
&lt;br /&gt;        return rad*180/Math.PI;
&lt;br /&gt;      }
&lt;br /&gt;      function grad2rad(grad){
&lt;br /&gt;        return grad*Math.PI/180;
&lt;br /&gt;      }
&lt;br /&gt;      function getwinkel(a,b){
&lt;br /&gt;        var c=Math.abs(Math.sqrt(Math.abs(a*a)+Math.abs(b*b)));
&lt;br /&gt;        var nw=rad2grad(Math.asin(a/c));
&lt;br /&gt;        if (a&lt;0 &amp;&amp; b&lt;0){
&lt;br /&gt;          nw= -nw-180;
&lt;br /&gt;        }else if (b&lt;0){
&lt;br /&gt;          nw= 180-nw;
&lt;br /&gt;        }
&lt;br /&gt;        return nw;
&lt;br /&gt;      }
&lt;br /&gt;    &lt;/script&gt;
&lt;br /&gt;  &lt;/body&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/html&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;!--[if IE]&gt;&lt;script src="excanvas.compiled.js"&gt;&lt;/script&gt;&lt;![endif]--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-2004198694619367738?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/pxIV1NCmwJo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/2004198694619367738/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2010/09/fun-with-html5-canvas-effects.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2004198694619367738" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2004198694619367738" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/pxIV1NCmwJo/fun-with-html5-canvas-effects.html" title="Fun with HTML5 Canvas Effects" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2010/09/fun-with-html5-canvas-effects.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-6708328569262118996</id><published>2010-06-24T13:41:00.000-07:00</published><updated>2012-03-26T13:29:05.278-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="fileupload" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">Validate size of a uploaded Image in Symfony 1.3/1.4</title><content type="html">The sfValidatorFile has no options to check the size of a image in pixel. For that I have written a simple validator that extends the sfValidatorFile-class.&lt;br /&gt;&lt;br /&gt;Create the file jsValidatorImage.php in your /lib directory:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;class jsValidatorImage extends sfValidatorFile&lt;br /&gt;{&lt;br /&gt;  protected function configure($options = array(), $messages = array())&lt;br /&gt;  {&lt;br /&gt;    parent::configure($options, $messages);&lt;br /&gt;    &lt;br /&gt;    $this-&gt;addOption('minx', false);&lt;br /&gt;    $this-&gt;addOption('miny', false);&lt;br /&gt;    $this-&gt;addOption('maxx', false);&lt;br /&gt;    $this-&gt;addOption('maxy', false);&lt;br /&gt;    &lt;br /&gt;    $this-&gt;addMessage('not_a_image', 'The file is not a image.');&lt;br /&gt;    $this-&gt;addMessage('minx', 'Das Bild muss mindestens %minx% Pixel breit sein.');&lt;br /&gt;    $this-&gt;addMessage('maxx', 'Das Bild darf maximal %maxx% Pixel breit sein.');&lt;br /&gt;    $this-&gt;addMessage('miny', 'Das Bild muss mindestens %miny% Pixel hoch sein.');&lt;br /&gt;    $this-&gt;addMessage('maxy', 'Das Bild darf maximal %maxy% Pixel hoch sein.');   &lt;br /&gt;    &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; &lt;br /&gt;  protected function doClean($value)&lt;br /&gt;  {&lt;br /&gt;    $validatedFile = parent::doClean($value);   &lt;br /&gt;    &lt;br /&gt;    // check image size&lt;br /&gt;    &lt;br /&gt;    $imagedata=getimagesize($value['tmp_name']);&lt;br /&gt;    &lt;br /&gt;    if (!$imagedata){&lt;br /&gt;      throw new sfValidatorError($this, 'not_a_image');&lt;br /&gt;    }&lt;br /&gt;    if ($this-&gt;hasOption('minx') &amp;&amp; $this-&gt;getOption('minx')!==false &amp;&amp; $imagedata[0] &lt; $this-&gt;getOption('minx'))&lt;br /&gt;    {&lt;br /&gt;      throw new sfValidatorError($this, 'minx', array('minx' =&gt; $this-&gt;getOption('minx'), 'size' =&gt; (int) $imagedata[0]));&lt;br /&gt;    }&lt;br /&gt;    if ($this-&gt;hasOption('maxx') &amp;&amp; $this-&gt;getOption('maxx')!==false &amp;&amp; $imagedata[0] &gt; $this-&gt;getOption('maxx'))&lt;br /&gt;    {&lt;br /&gt;      throw new sfValidatorError($this, 'maxx', array('maxx' =&gt; $this-&gt;getOption('maxx'), 'size' =&gt; (int) $imagedata[0]));&lt;br /&gt;    }&lt;br /&gt;    if ($this-&gt;hasOption('miny') &amp;&amp; $this-&gt;getOption('miny')!==false &amp;&amp; $imagedata[1] &lt; $this-&gt;getOption('miny'))&lt;br /&gt;    {&lt;br /&gt;      throw new sfValidatorError($this, 'miny', array('miny' =&gt; $this-&gt;getOption('miny'), 'size' =&gt; (int) $imagedata[1]));&lt;br /&gt;    }&lt;br /&gt;    if ($this-&gt;hasOption('maxy') &amp;&amp; $this-&gt;getOption('maxy')!==false &amp;&amp; $imagedata[1] &gt; $this-&gt;getOption('maxy'))&lt;br /&gt;    {&lt;br /&gt;      throw new sfValidatorError($this, 'maxy', array('maxy' =&gt; $this-&gt;getOption('maxy'), 'size' =&gt; (int) $imagedata[1]));&lt;br /&gt;    }&lt;br /&gt;      &lt;br /&gt;    return $validatedFile;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In your [model]Form.class.php extend the "configure()"-function with something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;  public function configure()&lt;br /&gt;  {&lt;br /&gt;    ...&lt;br /&gt;    $this-&gt;widgetSchema['img'] = new sfWidgetFormInputFileEditable(array(&lt;br /&gt;      ...&lt;br /&gt;    ));        &lt;br /&gt;    $this-&gt;validatorSchema['img'] = new jsValidatorImage(array(&lt;br /&gt;      'required'        =&gt; true, &lt;br /&gt;      'path'            =&gt; sfConfig::get('sf_upload_dir').'/images',              &lt;br /&gt;      'mime_categories' =&gt; 'web_images',&lt;br /&gt;      'minx'            =&gt; 100,&lt;br /&gt;      'maxx'            =&gt; 120,&lt;br /&gt;      'miny'            =&gt; 80,&lt;br /&gt;      'maxy'            =&gt; 90&lt;br /&gt;      &lt;br /&gt;    ));&lt;br /&gt;    ...&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The validator will now throw a error if the image-width is not between 100 and 120 pixel or the image-height is not between 80 and 90 pixel&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-6708328569262118996?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/32dROxRV4a0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/6708328569262118996/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2010/06/validate-size-of-uploaded-image-in.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6708328569262118996" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6708328569262118996" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/32dROxRV4a0/validate-size-of-uploaded-image-in.html" title="Validate size of a uploaded Image in Symfony 1.3/1.4" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2010/06/validate-size-of-uploaded-image-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-2279548445334486465</id><published>2010-05-20T09:17:00.000-07:00</published><updated>2012-03-26T13:27:50.218-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title type="text">Googles Web Fonts</title><content type="html">Increasing the diversity of fonts on the web using the Google Font API, the Google Font Directory and the Webfont Loader.&lt;br /&gt;&lt;br /&gt;The selection of fonts used on the Web is very small. This has changed with the new in CSS3 defined @font-face. This allows fonts to be loaded from the web, which works in all modern browsers. This mechanism requires appropriate fonts and the right to make them available on the web or to download from other sources. For this Google has created his Google Font Directory and the Google Font API.&lt;br /&gt;&lt;br /&gt;http://code.google.com/intl/de/apis/webfonts/&lt;br /&gt;&lt;br /&gt;Embedding the font into your page is very easy. Embed the right stylesheet of the font in your page:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html;"&gt;&lt;br /&gt;&lt;link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simply use the font in your CSS font stack like any other font, for example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: css;"&gt;&lt;br /&gt;h1 { font-family: 'Lobster', arial, serif; }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-2279548445334486465?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/BIcfALWJ-j4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/2279548445334486465/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2010/05/googles-web-fonts.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2279548445334486465" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2279548445334486465" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/BIcfALWJ-j4/googles-web-fonts.html" title="Googles Web Fonts" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2010/05/googles-web-fonts.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-4555612846298429287</id><published>2010-03-31T07:45:00.000-07:00</published><updated>2012-03-26T13:26:36.139-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="Doctrine" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">Filter Admin-List in Symfony 1.4 + Doctrine</title><content type="html">Some time ago I wrote an article about filtering the admin-list in Symfony 1.0 and Propel. Now in Symfony 1.4 and Doctrine the steps to do this are completely different:&lt;br /&gt;&lt;br /&gt;First we have to change the auto-generated file in apps/[APP]/modules/[MODULE]/actions/actions.class.php and to add a function "buildQuery()" to the [module]Actions-class:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;class hotelActions extends autoHotelActions&lt;br /&gt;{&lt;br /&gt;  protected function buildQuery()&lt;br /&gt;  { &lt;br /&gt;    $query = parent::buildQuery();&lt;br /&gt;    //Here you can extend your $query to filter the result.&lt;br /&gt;    return $query;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So if we have a "creator_id"-field in our schema and we want to filter the result to show only the entries created by the current user, we have to add the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;class hotelActions extends autoHotelActions&lt;br /&gt;{&lt;br /&gt;  protected function buildQuery()&lt;br /&gt;  { &lt;br /&gt;    $query = parent::buildQuery();&lt;br /&gt;    $rootAlias = $query-&gt;getRootAlias(); &lt;br /&gt;    $query-&gt;andWhereIn($rootAlias.'.creator_id', Array($this-&gt;getUser()-&gt;getGuardUser()-&gt;getId()));&lt;br /&gt;    return $query;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-4555612846298429287?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/6ujW-wj_k4A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/4555612846298429287/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2010/03/filter-admin-list-in-symfony-14.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4555612846298429287" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4555612846298429287" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/6ujW-wj_k4A/filter-admin-list-in-symfony-14.html" title="Filter Admin-List in Symfony 1.4 + Doctrine" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2010/03/filter-admin-list-in-symfony-14.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-8717715953005520327</id><published>2009-11-27T11:31:00.000-08:00</published><updated>2012-03-26T13:25:31.001-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Firefox" /><title type="text">Firefox implements new W3C File API specification</title><content type="html">Web applications can access local files and upload multiple files.&lt;br /&gt;&lt;br /&gt;The current fourth beta of Firefox 3.6 comes with support for the File API. The relevant W3C draft specification is from Mozilla developer Arun Ranganathan. The File API provides different objects. This includes FileList containing an array of individually responsive files. It should be integrated over an input tag in HTML 5 pages. Several files can be uploaded at once. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This allows Firefox to upload via drag and drop, so that files can be moved easily from the desktop into a corresponding area in a website. It is also possible to directly create smaller thumbnails in the browser and display, even during the upload of files running in the background.&lt;br /&gt;&lt;br /&gt;Checkout &lt;a href="https://developer.mozilla.org/en/Using_files_from_web_applications"&gt;developer.mozilla.org&lt;/a&gt; for examples for using the File API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-8717715953005520327?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/yv-1hJI5GpY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/8717715953005520327/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/11/firefox-implements-new-w3c-file-api.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/8717715953005520327" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/8717715953005520327" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/yv-1hJI5GpY/firefox-implements-new-w3c-file-api.html" title="Firefox implements new W3C File API specification" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/11/firefox-implements-new-w3c-file-api.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-6286710865023750542</id><published>2009-06-25T13:33:00.000-07:00</published><updated>2012-03-26T13:24:31.706-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="as3" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="bug" /><category scheme="http://www.blogger.com/atom/ns#" term="workaround" /><category scheme="http://www.blogger.com/atom/ns#" term="flash" /><category scheme="http://www.blogger.com/atom/ns#" term="I18n" /><title type="text">Workaround for Flash CS3 Bug in internationalization using Strings Panel : Error 1009</title><content type="html">Flash CS3 has a Bug when creating multilanguage projects using the Strings-Panel with String-replacement-setting set to "Automatically at Runtime".&lt;br /&gt;&lt;br /&gt;A Bug description can be found at http://www.kirupa.com/forum/showthread.php?t=281170&lt;br /&gt;I did spend a lot of time on trying to find a solution for that problem:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Assuming you have a dynamic textbox linked to a Strings-Panel-ID in Frame 1 - 5 you will receive a TypeError #1009 if the Player comes to frame 6. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: javascript;"&gt;&lt;br /&gt;TypeError: Error #1009: Cannot access a property or method of a null object reference.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Workaround: The error does not occur if the textbox is embedded in a movieclip that has only one frame.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-6286710865023750542?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/46die78Pw3c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/6286710865023750542/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/06/workaround-for-flash-cs3-bug-in.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6286710865023750542" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6286710865023750542" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/46die78Pw3c/workaround-for-flash-cs3-bug-in.html" title="Workaround for Flash CS3 Bug in internationalization using Strings Panel : Error 1009" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/06/workaround-for-flash-cs3-bug-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-5244317513480762099</id><published>2009-06-23T08:50:00.000-07:00</published><updated>2012-03-26T13:23:21.336-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="fileupload" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title type="text">Filter filename on fileupload and prevent execution of uploaded files</title><content type="html">Its a good way to allways rename uploaded files using something like a MD5-hash and store the original filename in a database.&lt;br /&gt;&lt;br /&gt;If for some reason you dont want to rename it using a hash, you should filter the filename using some code like this one:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;$filename = strip_tags($_FILES["upload"]["name"]);&lt;br /&gt;$filename = str_replace(array('|','&lt;','&gt;','"','\'',':','\\','/','*','?'),'',$filename); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's a good idea to deny the execution of all uploaded files: place a .htaccess file in your upload-directory:&lt;br /&gt;&lt;pre class="brush: bash;"&gt;&lt;br /&gt;RemoveHandler .cgi .shtm .shtml&lt;br /&gt;RemoveType .php .php3 .php4 .php5&lt;br /&gt;&lt;FilesMatch "\.(pl|cgi|py|php|php3|php4|php5|phtml?|shtml?)$"&gt;&lt;br /&gt;deny from all&lt;br /&gt;&lt;/FilesMatch&gt;&lt;br /&gt;&lt;Files ~ "\.htaccess$"&gt;&lt;br /&gt;order deny,allow&lt;br /&gt;deny from all&lt;br /&gt;&lt;/Files&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-5244317513480762099?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/crb0RA6Ysws" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/5244317513480762099/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/06/filter-filename-on-fileupload-and.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/5244317513480762099" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/5244317513480762099" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/crb0RA6Ysws/filter-filename-on-fileupload-and.html" title="Filter filename on fileupload and prevent execution of uploaded files" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/06/filter-filename-on-fileupload-and.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-6732321818328455782</id><published>2009-06-17T12:29:00.000-07:00</published><updated>2012-03-26T13:22:17.365-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax image editor" /><category scheme="http://www.blogger.com/atom/ns#" term="drupal" /><category scheme="http://www.blogger.com/atom/ns#" term="aie" /><title type="text">AIE AJAX Image Editor for Drupal</title><content type="html">Today I found this great tutorial on how to integrate my AIE (Ajax Image Editor) into the Drupal imagefield module:&lt;br /&gt;&lt;br /&gt;http://drupal.org/node/442800&lt;br /&gt;&lt;br /&gt;As expected, it seems to be pretty easy to integrate AIE into Drupal :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-6732321818328455782?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/ngkv5h7UsXw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/6732321818328455782/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/06/aie-ajax-image-editor-for-drupal.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6732321818328455782" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/6732321818328455782" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/ngkv5h7UsXw/aie-ajax-image-editor-for-drupal.html" title="AIE AJAX Image Editor for Drupal" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/06/aie-ajax-image-editor-for-drupal.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-5447310586549449019</id><published>2009-05-19T08:48:00.000-07:00</published><updated>2012-03-26T13:21:07.320-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">Symfony 1.0 Admin List: Highlight last edited entry</title><content type="html">To highlight the last created or edited entry in a Admin-Generator-List copy the _list.php file from cache to your /apps/[APPNAME]/modules[MODULENAME]/templates directory and modify the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;tbody&amp;gt;&lt;br /&gt;&lt;?php $i = 1; foreach ($pager-&gt;getResults() as $mymodel): $odd = fmod(++$i, 2) ?&gt;&lt;br /&gt;&amp;lt;tr class="sf_admin_row_&lt;?php echo $odd ?&gt;&lt;strong&gt;&lt;?php if($sf_request-&gt;getParameter("id",0)==$mymodel-&gt;getId()) echo " rowsel"; ?&gt;&lt;/strong&gt;"&amp;gt;&lt;br /&gt;&lt;?php include_partial('list_td_tabular', array('mymodel' =&gt; $mymodel)) ?&gt;&lt;br /&gt;&lt;?php include_partial('list_td_actions', array('mymodel' =&gt; $mymodel)) ?&gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&lt;?php endforeach; ?&gt;&lt;br /&gt;&amp;lt;/tbody&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Add a stylesheet like this:&lt;br /&gt;&lt;pre class="brush: css;"&gt;&lt;br /&gt;#sf_admin_container .sf_admin_list .rowsel td {&lt;br /&gt;border-bottom:1px solid #DDDDDD;&lt;br /&gt;border-right:1px solid #DDDDDD;&lt;br /&gt;padding:3px;&lt;br /&gt;background-color: #DDDDEE !important;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-5447310586549449019?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/UFLD8K6yqDA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/5447310586549449019/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/05/symfony-10-admin-list-highlight-last.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/5447310586549449019" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/5447310586549449019" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/UFLD8K6yqDA/symfony-10-admin-list-highlight-last.html" title="Symfony 1.0 Admin List: Highlight last edited entry" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/05/symfony-10-admin-list-highlight-last.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-4727449434729604975</id><published>2009-05-18T11:50:00.000-07:00</published><updated>2012-03-26T13:19:38.129-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="I18n" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">Symfony Sortable I18n-field in Admin-List</title><content type="html">Works with Symfony 1.0&lt;br /&gt;&lt;br /&gt;This Article shows how to make a I18n Field in a Symfony-Admin-List Sortable.&lt;br /&gt;In this example i use the "name"-field as I18n-field.&lt;br /&gt;&lt;br /&gt;First, open the file apps/[APPNAME]/modules/[MODULENAME]/action/actions.class.php and add the function:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;protected function addSortCriteria($c)&lt;br /&gt;  {&lt;br /&gt;    if ($sort_column = $this-&gt;getUser()-&gt;getAttribute('sort', null, 'sf_admin/[MODULENAME]/sort'))&lt;br /&gt;    {&lt;br /&gt;      if ($sort_column=='name'){      &lt;br /&gt;        if (strlen(sfContext::getInstance()-&gt;getUser()-&gt;getCulture())==2) {&lt;br /&gt;          $culture=sfContext::getInstance()-&gt;getUser()-&gt;getCulture();&lt;br /&gt;        }else{&lt;br /&gt;          $culture="de";&lt;br /&gt;        }&lt;br /&gt;        $culture=strtolower($culture);        &lt;br /&gt;        $c-&gt;addJoin([MODULENAME]I18nPeer::ID,[MODULENAME]Peer::ID);&lt;br /&gt;        $c-&gt;add([MODULENAME]I18nPeer::CULTURE, $culture);&lt;br /&gt;        $sort_column=[MODULENAME]I18nPeer::NAME;&lt;br /&gt;      }else{&lt;br /&gt;        $sort_column = [MODULENAME]Peer::translateFieldName($sort_column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);&lt;br /&gt;      }&lt;br /&gt;      if ($this-&gt;getUser()-&gt;getAttribute('type', null, 'sf_admin/[MODULENAME]/sort') == 'asc')&lt;br /&gt;      {&lt;br /&gt;        $c-&gt;addAscendingOrderByColumn($sort_column);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;        $c-&gt;addDescendingOrderByColumn($sort_column);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create a __toString function in /lib/model/[MODULENAME].php:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;public function __toString () {&lt;br /&gt;    if (strlen(sfContext::getInstance()-&gt;getUser()-&gt;getCulture())==2) {&lt;br /&gt;      $culture=sfContext::getInstance()-&gt;getUser()-&gt;getCulture();&lt;br /&gt;    }else{&lt;br /&gt;      $culture="de";&lt;br /&gt;    }&lt;br /&gt;    $culture=strtolower($culture);&lt;br /&gt;    $culture[0]=strtoupper($culture[0]);&lt;br /&gt;    return $this-&gt;__call("getNameI18n".$culture,"");&lt;br /&gt;  }   &lt;br /&gt;  public function __call($m, $a)&lt;br /&gt;  {&lt;br /&gt;    $data = @split('I18n', $m, 2);&lt;br /&gt;    if( count($data) != 2 ) &lt;br /&gt;      throw new Exception('Tried to call unknown method '.get_class($this).'::'.$m);&lt;br /&gt;    list( $method, $culture ) = $data;&lt;br /&gt;    $this-&gt;setCulture( $culture );&lt;br /&gt;    return call_user_func_array(array($this, $method), $a);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next, create a File "_name.php" in apps/[APPNAME]/modules/[MODULENAME]/templates/_name.php:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;echo $[MODELNAME]-&gt;__toString();&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In generator.yml add the _name-field to the display section in list:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;...&lt;br /&gt;  list:&lt;br /&gt;    display: [_name, ... ]&lt;br /&gt;....&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next, copy the _list_th_tabular.php file from the cache-directory to your apps/[APPNAME]/modules/[MODULENAME]/templates directory and change the &amp;lt;th /&amp;gt;-tag of the name-field to something like this:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;th id="sf_admin_list_th_name"&amp;gt;&lt;br /&gt;        &lt;?php if ($sf_user-&gt;getAttribute('sort', null, 'sf_admin/[MODULENAME]/sort') == 'name'): ?&gt;&lt;br /&gt;      &lt;?php echo link_to(__('Name'), '[MODULENAME]/list?sort=name&amp;type='.($sf_user-&gt;getAttribute('type', 'asc', 'sf_admin/[MODULENAME]/sort') == 'asc' ? 'desc' : 'asc')) ?&gt;&lt;br /&gt;      (&lt;?php echo __($sf_user-&gt;getAttribute('type', 'asc', 'sf_admin/[MODULENAME]/sort')) ?&gt;)&lt;br /&gt;      &lt;?php else: ?&gt;&lt;br /&gt;      &lt;?php echo link_to(__('Name'), '[MODULENAME]/list?sort=name&amp;type=asc') ?&gt;&lt;br /&gt;      &lt;?php endif; ?&gt;        &lt;br /&gt;&amp;lt;/th&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-4727449434729604975?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/17coIxUPGHM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/4727449434729604975/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2009/05/symfony-sortable-i18n-field-in-admin.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4727449434729604975" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4727449434729604975" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/17coIxUPGHM/symfony-sortable-i18n-field-in-admin.html" title="Symfony Sortable I18n-field in Admin-List" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2009/05/symfony-sortable-i18n-field-in-admin.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-2747619742457976541</id><published>2008-12-03T16:37:00.000-08:00</published><updated>2012-03-26T13:18:22.410-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="jsThumbnailPlugin" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">New version of jsThumbnailPlugin released</title><content type="html">Today I have released version 1.1.0 of the jsThumbnailPlugin for the Symfony framework. It contains a important bugfix for Symfony 1.1 and a new feature.&lt;br /&gt;&lt;br /&gt;I fixed a bug with the sfFileCache object: In version 1.0 the sfFileCache wants a string as $file_cache_dir parameter, but version 1.1 wants a Array containing the parameters:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;Symfony 1.0: $cache = new sfFileCache($file_cache_dir);&lt;br /&gt;Symfony 1.1: $cache = new sfFileCache(Array('cache_dir'=&gt;$file_cache_dir));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem was to find out which version of Symfony is running. I solved the problem by checking if the function "setFileLocking" exists. This function exists only in version 1.0 of Symfony:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;br /&gt;if (method_exists('sfFileCache', 'setFileLocking')){ //symfony 1.0&lt;br /&gt;$cache = new sfFileCache($file_cache_dir);&lt;br /&gt;}else{ //symfony 1.1&lt;br /&gt;$cache = new sfFileCache(array('cache_dir' =&gt; $file_cache_dir));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;jsThumbnailPlugin 1.1.0 accepts a new parameter "mode". This parameter can be set to  "normal", "crop" or "stretch".&lt;br /&gt;normal: Sets the image to the maximum height or width, without changing the width/height proportion;&lt;br /&gt;crop: The image will be cropped exactly to the given height and width without changing the width/height proportion;&lt;br /&gt;stretch: Sets the image to the maximum height or width, the width/height proportion changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-2747619742457976541?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/SPfooQIzq-g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/2747619742457976541/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2012/03/new-version-of-jsthumbnailplugin.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2747619742457976541" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/2747619742457976541" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/SPfooQIzq-g/new-version-of-jsthumbnailplugin.html" title="New version of jsThumbnailPlugin released" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2012/03/new-version-of-jsthumbnailplugin.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-4231149811346415874</id><published>2008-12-02T17:59:00.000-08:00</published><updated>2012-03-26T13:16:27.937-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorials" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">New great set of 24 Symfony tutorials</title><content type="html">The Symfony team has released a new set of 24 tutorials published day-by-day between December 1st and Christmas, like the "&lt;a href="http://www.symfony-project.org/askeet/1_0/en/"&gt;Askeet tutorial&lt;/a&gt;" in 2005.&lt;br /&gt;&lt;br /&gt;As for askeet, every day including week-ends, a new tutorial will be published. Each tutorial is meant to last about one hour, and will be the occasion to learn symfony by coding a real web application, from start to finish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-4231149811346415874?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/RniYCd71NsI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/4231149811346415874/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2008/12/new-great-set-of-24-symfony-tutorials.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4231149811346415874" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4231149811346415874" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/RniYCd71NsI/new-great-set-of-24-symfony-tutorials.html" title="New great set of 24 Symfony tutorials" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2008/12/new-great-set-of-24-symfony-tutorials.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-1916753602762836604</id><published>2008-11-04T19:48:00.000-08:00</published><updated>2012-03-26T13:15:00.483-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="plugin" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">New Symfony Plugin "jsThumbnailPlugin" for on-the-fly Thumbnails Creation</title><content type="html">&lt;span&gt;Today I have released my first plugin for the Symfony-Framework. The jsThumbnailPlugin creates Thumbnails on the fly using the GD library. It uses the Symfony cache system to cache the thumbnails.&lt;/span&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;The plugin consists of a action and a helper. It creates a thumbnail of a image in the given size and stores it in cache for the next calls, until the image changes. You can download it from http://www.symfony-project.org/plugins/jsThumbnailPlugin&lt;br /&gt;&lt;br /&gt;The use is very simple:&lt;br /&gt;1. Install it:&lt;br /&gt;&lt;pre class="brush: php;"&gt;$ symfony plugin-install http://plugins.symfony-project.com/jsThumbnailPlugin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. Enable the module in the setting.yml file of your application:&lt;br /&gt;&lt;pre class="brush: php;"&gt;all:&lt;br /&gt; .settings:&lt;br /&gt;   enabled_modules:        [ default, jsThumbnail ]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3. Now you can view the thumbnail simply by open a link like this:&lt;br /&gt;&lt;pre class="brush: php;"&gt;http://www.yourhost.com/yourapp.php/jsThumbnail/thumbnail?img=uploads/pictures/image.jpg&amp;amp;maxx=100&amp;amp;maxy=80&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4. The plugin has a helper that creates a image-tag for a thumbnail. Include the helper in your template-file:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;!--?php use_helper('Thumbnail') ?--&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Call the Helper. The helper needs some params: the imagepath on server, maximum-width and maximum-height. The last parameter are additional HTML compliant &lt;img src="" /&gt; tag parameters:&lt;br /&gt;&lt;pre class="brush: php;"&gt;&lt;!--?php echo thumbnail_tag('uploads/pictures/image.jpg',100, 80, array('style' =--&gt; 'border: 1px solid #ff0000')) ?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. The Plugin automatically checks if the Original image was modificated.&lt;br /&gt;&lt;br /&gt;7. To delete the cached thumbnails call:&lt;br /&gt;&lt;pre class="brush: bash;"&gt;$ symfony cc&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-1916753602762836604?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/oFdhEsbumvU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/1916753602762836604/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2008/11/new-symfony-plugin-jsthumbnailplugin.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/1916753602762836604" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/1916753602762836604" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/oFdhEsbumvU/new-symfony-plugin-jsthumbnailplugin.html" title="New Symfony Plugin &quot;jsThumbnailPlugin&quot; for on-the-fly Thumbnails Creation" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2008/11/new-symfony-plugin-jsthumbnailplugin.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-901870382787412268</id><published>2008-10-22T12:21:00.000-07:00</published><updated>2012-03-26T13:00:30.092-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="aie" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><title type="text">Akoie is now AIE (Ajax-Image-Editor)!</title><content type="html">&lt;span &gt;Akoie´s new name is AIE (Ajax-Image-Editor)! Also akoie moved from akoie.akanai.eu to his new official domain http://www.ajax-image-editor.com! New version comming soon!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-901870382787412268?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/oQZ4PWaShac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/901870382787412268/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2008/10/akoie-is-now-aie-ajax-image-editor.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/901870382787412268" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/901870382787412268" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/oQZ4PWaShac/akoie-is-now-aie-ajax-image-editor.html" title="Akoie is now AIE (Ajax-Image-Editor)!" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2008/10/akoie-is-now-aie-ajax-image-editor.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-4041984429286886873</id><published>2008-09-03T23:51:00.000-07:00</published><updated>2012-03-26T12:58:16.939-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Symfony" /><title type="text">Symfony - Listen im Admin Generator filtern</title><content type="html">&lt;p style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(229, 229, 229); "&gt;Einträge in Selectboxen einer foreignTable filtern (z.B. nach creator):&lt;/p&gt;&lt;p style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(229, 229, 229); "&gt;schema.yml:&lt;/p&gt;&lt;p style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(229, 229, 229); "&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(229, 229, 229); "&gt;&lt;/p&gt;&lt;pre style="color: rgb(0, 0, 0); text-align: -webkit-auto; "&gt;&lt;blockquote&gt;propel:     project:     _attributes:            { phpName: Project }     id:     creator_id:                { type: integer, foreignTable: creator foreignReference: id, required: true, onDelete: cascade }       name:                   { type: VARCHAR, size: 255, required: true }     description:            { type: VARCHAR, size: 255, required: true } ...&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt; &lt;span style="color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; text-align: left; white-space: normal; "&gt;/lib/model/ProjectPeer.php:&lt;/span&gt; &lt;/pre&gt;&lt;pre style="color: rgb(0, 0, 0); text-align: -webkit-auto; "&gt;&lt;span style="color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; text-align: left; white-space: normal; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="color: rgb(0, 0, 0); text-align: -webkit-auto; "&gt;&lt;pre&gt;&lt;blockquote&gt;class ProjectPeer extends BaseProjectPeer {   public static function getCreatorfiltered() {   $c = new Criteria();        $c-&amp;gt;add(ProjectPeer::CREATOR_ID, sfContext::getInstance()-&amp;gt;getUser()-&amp;gt;getGuardUser()-&amp;gt;getId());      //oder Creator ID     }   return ProjectPeer::doSelect($c);  } }&lt;/blockquote&gt;&lt;/pre&gt;  &lt;span style="color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; text-align: left; white-space: normal; "&gt;generator.yml:&lt;/span&gt; &lt;/pre&gt;&lt;pre style="color: rgb(0, 0, 0); text-align: -webkit-auto; "&gt;&lt;pre&gt;&lt;blockquote&gt;..     fields:                project_id:               params:           name:         Project           peer_method:  getCreatorfiltered&lt;/blockquote&gt;&lt;/pre&gt; &lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-4041984429286886873?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/h5KL89oRcuE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/4041984429286886873/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2008/09/symfony-listen-im-admin-generator.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4041984429286886873" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/4041984429286886873" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/h5KL89oRcuE/symfony-listen-im-admin-generator.html" title="Symfony - Listen im Admin Generator filtern" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2008/09/symfony-listen-im-admin-generator.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-3326160732880350623.post-8363560359137602873</id><published>2008-08-22T13:02:00.001-07:00</published><updated>2012-03-26T12:58:55.089-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Projects" /><category scheme="http://www.blogger.com/atom/ns#" term="ExtJS" /><title type="text">Akoie 0.5</title><content type="html">&lt;span style="color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(229, 229, 229); "&gt;Recently, I have released version 0.5 of my online image editor "Akoie". Because of the great interest and the many positive reactions, I'm already working on the next version. The new Version will use the Canvas tag to make possible a lot of new features for client-side image manipulation. This allows the free rotation of text and watermarks in smaller steps than 90°.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3326160732880350623-8363560359137602873?l=www.julianstricker.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/wwwjulianstrickercom/~4/bQXpGxmCySI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.julianstricker.com/feeds/8363560359137602873/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://www.julianstricker.com/2008/08/akoie-05.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/8363560359137602873" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3326160732880350623/posts/default/8363560359137602873" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/wwwjulianstrickercom/~3/bQXpGxmCySI/akoie-05.html" title="Akoie 0.5" /><author><name>Julian</name><uri>http://www.blogger.com/profile/18324374134853544087</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.julianstricker.com/2008/08/akoie-05.html</feedburner:origLink></entry></feed>

