<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>phTagr</title>
	<atom:link href="http://www.phtagr.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phtagr.org</link>
	<description>Tag your photos once. Find them forever.</description>
	<lastBuildDate>Fri, 06 Jan 2012 11:10:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Release 2.1.3</title>
		<link>http://www.phtagr.org/2011/01/14/release-2-1-3/</link>
		<comments>http://www.phtagr.org/2011/01/14/release-2-1-3/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 10:19:34 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[announce]]></category>
		<category><![CDATA[info]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=453</guid>
		<description><![CDATA[I&#8217;m proud to announce the release of phtagr version 2.1.3 You can download the new version from sourceforge  at Sourceforge. Read How To Migrate for migration help. Here are the improvements since 2.1.2 Bread Crumb Search The search term is splitted into single search bread crumbs. The search crumbs simplifies the customization of the search [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m proud to announce the release of phtagr version 2.1.3</p>
<p>You can download the new version from sourceforge  at <a href="https://sourceforge.net/projects/phtagr/files">Sourceforge</a>. Read <a href="http://trac.phtagr.org/wiki/HowToMigratePhtagr">How To Migrate</a> for migration help.</p>
<p>Here are the improvements since 2.1.2</p>
<ul>
<li><strong>Bread Crumb Search</strong> The search term is splitted into single search  bread crumbs. The search crumbs simplifies the customization of the search</li>
<li><strong>Fast preview file responder</strong> Now the images are loaded faster and are  fast as hell. It by-passes the MVC CakePHP framework stack based on the  HTTP session</li>
<li><strong>Translations</strong> Added Estonian (Craig), Polish (Bartosz Fenski aka  fEnIo), Italian (Francesco Piraneo G) translation</li>
<li><strong>Mobile Device Support</strong> If your are open the gallery with your mobile  device a new customized mobile theme is loaded automatically.</li>
<li><strong>Email Notification</strong> Add email notification for new media which could  be triggered by cron job. The notification interval could be set from  half an hour to once a month</li>
<li><strong>Improved Group Handing</strong> The creation and managing of groups is  simplified which makes the gallery more social. Try it!</li>
<li><strong>SMTP Configuration</strong> You can now configure your own SMTP configuration  in app/config/core.php to enable email functionality to your web gallery</li>
<li>Improved the preview manager. Now a preview might depend on the next  larger preview and a preview is not always calculated by the original  file which saves a lot of time for smaller previews.</li>
<li>Add interval search in the explorer. If you already set a time limit  of your search you can easily add another time bound for an interval search.</li>
<li>View media based on upload path</li>
<li>Add sync shell task to sync all media at once (console based)</li>
<li>Add fallback of image size. In rare cases the image size could not  extracted correcly. Now getimagesize() should fix this gap.</li>
<li>Auto completion for tag, category, and location &#8211; also in bread crumbs.</li>
<li>And lots of bug fixes&#8230;</li>
</ul>
<p>The next release should get a face lift with a backend and easy  customizable frontend &#8211; besides tagging, sharing and searching  improvements <img src='http://www.phtagr.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2011/01/14/release-2-1-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Success story: Migration from Zen Photos to phTagr</title>
		<link>http://www.phtagr.org/2011/01/08/success-story-migration-from-zen-photos-to-phtagr/</link>
		<comments>http://www.phtagr.org/2011/01/08/success-story-migration-from-zen-photos-to-phtagr/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 08:47:28 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[success story]]></category>
		<category><![CDATA[zen photo]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=448</guid>
		<description><![CDATA[My quest for an open source photo gallery started when my flickr pro account needed renewal, I already had a domain and website, and I thought to myself: &#8220;I don&#8217;t need to pay flickr, I can do it myself&#8220;. So I downloaded all of my flickr photos (about 2 gigs worth) to my local computer [...]]]></description>
			<content:encoded><![CDATA[<p>My quest for an open source photo gallery started when my <a href="http://www.flickr.com">flickr</a> pro account needed renewal, I already had a domain and website, and I thought to myself: &#8220;<em>I don&#8217;t need to pay flickr, I can do it myself</em>&#8220;. So I downloaded all of my flickr photos (about 2 gigs worth) to my local computer and they were organized in directories as they were on flickr. Then I started the search for an open source solution that would be easy to migrate all of my photos to, and what I settled on<br />
was <a href="http://www.zenphoto.org">zen photo</a> because I could basically just upload everything with FTP and it would be organized as it was on flickr. It was quick and easy to get setup, however over time what I found was that managing the photos in zen photo was a real pain. The user interface is very cumbersome, and clunky, often times I would make some sort of change only to find later that the change never took because I didn&#8217;t scroll waaaay down and hit the &#8220;save&#8221; button. I also found zenphoto visually<br />
unappealing, even though I could potentially create my own theme, I am not a web designer or an artist so any theme I come up with would be even uglier.</p>
<p>After about a year with zen photo, I decided to start looking around again and that is when I found <a href="http://www.phtagr.org">phtagr</a>, it is a very attractive solution, mass editing and mass  uploads are easy, the user interface is intuitive, and is much more flickr like. The best part is that when I first started using it, I couldn&#8217;t get it to work on my webhost, so I e-mailed the phtagr mailing list and Xemle responded quickly and was able to fix my problem. Now it works flawlessly&#8230;</p>
<p>Thanks for the hard work.</p>
<p><em>&#8211; by Chris Desjardins</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2011/01/08/success-story-migration-from-zen-photos-to-phtagr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phtagr risponde in italiano</title>
		<link>http://www.phtagr.org/2011/01/03/phtagr-risponde-in-italiano/</link>
		<comments>http://www.phtagr.org/2011/01/03/phtagr-risponde-in-italiano/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 19:36:27 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[info]]></category>
		<category><![CDATA[user]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=436</guid>
		<description><![CDATA[Happy New Year to All! By today phTagr has now an Italian translation &#8211; thanks to Francesco Piraneo G. for his great contribution. The newly updated zip file could be downloaded from SourceForge. If your language is missing, see How To Translate in the wiki. Enjoy!]]></description>
			<content:encoded><![CDATA[<p>Happy New Year to All!</p>
<p>By today phTagr has now an Italian translation &#8211; thanks to Francesco Piraneo G. for his great contribution. The newly updated <a href="http://sourceforge.net/projects/phtagr/files/latest">zip</a> file could be downloaded from <a href="http://sourceforge.net/projects/phtagr/files">SourceForge</a>.</p>
<p>If your language is missing, see <a href="http://trac.phtagr.org/wiki/HowToTranslate">How To Translate</a> in the wiki.</p>
<p>Enjoy!</p>
<p><a href="http://demo.phtagr.org/images/view/263"><img title="Polish Translation" src="http://demo.phtagr.org/media/preview/263" alt="" width="400" height="281" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2011/01/03/phtagr-risponde-in-italiano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free Online HTML and PHP Editor for CakePHP</title>
		<link>http://www.phtagr.org/2010/12/11/free-online-html-and-php-editor-for-cakephp/</link>
		<comments>http://www.phtagr.org/2010/12/11/free-online-html-and-php-editor-for-cakephp/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 21:59:59 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[info]]></category>
		<category><![CDATA[baker]]></category>
		<category><![CDATA[editor]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=425</guid>
		<description><![CDATA[Baker &#8211; The Simple and Free Online Source Editor for CakePHP is published! Baker is a basic online text editor to write text, HTML, or PHP server files online. It&#8217;s a CakePHP application and you can do most basic text editor operations. You can view syntax highlighted source files or edit them. Create, copy, rename, [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a href="https://github.com/xemle/cakephp-baker">Baker</a></strong> &#8211; The Simple and Free Online Source Editor for <a href="http://cakephp.org">CakePHP</a> is published! Baker is a basic online text editor to write text, HTML, or PHP server files online. It&#8217;s a CakePHP application and you can do most basic text editor operations.</p>
<p>You can view syntax highlighted source files or edit them. Create, copy, rename, move and delete of files and directories are supported, too. You can upload files and extract ZIP archive. Baker has everything of your need to have a quick change of your PHP or HTML source code.</p>
<p><strong>Baker&#8217;s Core Features</strong></p>
<ul>
<li>Syntax highlighting of PHP and HTML files (through <a href="http://qbnz.com/highlighter">Geshi</a>, thanks to Mark for his <a href="http://mark-story.com/posts/view/geshi-helper-for-cakephp">plugin</a>)</li>
<li>Create, Edit, Copy, Rename, Move, Delete files and directories</li>
<li>Upload files</li>
<li>Extract ZIP archive on server side</li>
<li>HTTP User Authentication</li>
<li>Filter file list</li>
<li>Different virtual directory roots</li>
</ul>
<p>You can visit the demo page at <a href="http://baker.phtagr.org">http://baker.phtagr.org</a> or download the source from <a href="https://github.com/xemle/cakephp-baker">GitHub</a>. Screenshots are available <a href="http://demo.phtagr.org/explorer/tag/baker">here</a>. See <a href="https://github.com/xemle/cakephp-baker">here</a> for installation instructions.</p>
<p>Feel free to use it and to modify it.</p>
<p>Baker was very useful when I developed on <a href="../">phTagr</a>, the free social web gallery, while being in a Internet café far far away with a slow Internet connection. I would love if someone adds <a href="http://mozillalabs.com/skywriter/">SkyWrite</a> Editor (AKA Bespin) to it. For sure <a href="https://codenrun.com/">Code &#8216;n Run</a> is more fancy, but it&#8217;s not free and coding is fun <img src='http://www.phtagr.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div class="wp-caption alignnone" style="width: 430px"><strong><a href="http://demo.phtagr.org/explorer/tag/baker"><img class="  " src="http://demo.phtagr.org/media/preview/260" alt="" width="420" height="309" /></a></strong><p class="wp-caption-text">Baker - The Simple and Free Online Source Editor for CakePHP</p></div>
<div class="wp-caption alignnone" style="width: 430px"><a href="http://demo.phtagr.org/explorer/tag/baker"><img class=" " src="http://demo.phtagr.org/media/preview/261" alt="" width="420" height="297" /></a><p class="wp-caption-text">Directory actions with move, copy, and delete</p></div>
<div class="wp-caption alignnone" style="width: 430px"><a href="http://demo.phtagr.org/images/view/257/tag:baker"><img class="     " src="http://demo.phtagr.org/media/preview/257" alt="" width="420" height="297" /></a><p class="wp-caption-text">Syntax Highlighting in the View Mode</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/12/11/free-online-html-and-php-editor-for-cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improved Preview Handling</title>
		<link>http://www.phtagr.org/2010/10/10/improved-preview-handling/</link>
		<comments>http://www.phtagr.org/2010/10/10/improved-preview-handling/#comments</comments>
		<pubDate>Sun, 10 Oct 2010 12:59:51 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[user]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=418</guid>
		<description><![CDATA[Recently the preview handling was improved and partly rewritten. The speed boost by the Fast File Responder was previously described here. Before r632 each preview was rendered by the original image which consumed a lot of time. Now an image preview manager was introduced which reuses existing down sampled images to gain speed. While each [...]]]></description>
			<content:encoded><![CDATA[<p>Recently the preview handling was improved and partly rewritten. The speed boost by the Fast File  Responder was previously described <a href="http://www.phtagr.org/2010/10/03/fast-file-responder-for-cakephp/">here</a>. Before <a href="http://trac.phtagr.org/changeset/632">r632</a> each preview was rendered by the original image which consumed a lot of time. Now an image preview manager was introduced which reuses existing down sampled images to gain speed. While each conversion from the original image costs about 4.4s, the down sampling from an 600px to 220px requires only 0.2s Further each preview configuration (defined in the <a href="http://trac.phtagr.org/browser/trunk/controllers/components/preview_manager.php">Preview Manager Component</a>) might be depend on a greater preview image. These dependencies might trigger the generation of all previews before calculating the requested one.</p>
<p>Unfortunately, the preview cache file schema changed and all previews  have to be recalculated again. However, since <a href="http://trac.phtagr.org/changeset/639">r639</a> phTagr supports the batch generation of previews with a CakePHP shell script <em>preview</em>. You can create these previews at the command with</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ cd &lt;phtagr base&gt;
$ cake/console/cake preview
Help screen
---------------------------------------------------------------
This shell generates preview images in batch mode.
&nbsp;
generate
 Generate previews.
---------------------------------------------------------------
Options:
-max count
 Maximum generation count. Default is 10. Use 0 to generate all previews.
-start-chunk number
 Set the start chunk number. A chunk has a size of 100 media. Default is 1.
-size (mini|thumb|preview|high)
 Set the minimum preview size. Default is thumb.
-user username
 Generate only previews for given user.
-verbose
 Be verbose
---------------------------------------------------------------
$ preview generate -size mini -verbose
Page 1/180 (0.56%)
Page 2/180 (1.11%)
Page 3/180 (1.67%)
...</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/10/10/improved-preview-handling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast File Responder for CakePHP</title>
		<link>http://www.phtagr.org/2010/10/03/fast-file-responder-for-cakephp/</link>
		<comments>http://www.phtagr.org/2010/10/03/fast-file-responder-for-cakephp/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 19:22:10 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=402</guid>
		<description><![CDATA[This article is very useful for all CakePHP applications which deal with lots of photos or other files which are shown in the resulting page. I will introduce an Fast File Responder for CakePHP which immediately sends the file to the client without stepping into the CakePHP stack. It increases the performances drastically to an [...]]]></description>
			<content:encoded><![CDATA[<p>This article is very useful for all <a href="http://www.cakephp.org">CakePHP</a> applications which deal with lots of photos or other files which are shown in the resulting page. I will introduce an <strong>Fast File Responder for CakePHP</strong> which immediately sends the file to the client without stepping into the CakePHP stack. It increases the performances drastically to an minimum and got its inspiration from <a href="http://realm3.com/articles/lightning_fast_cakephp">Lightning Fast Caching for CakePHP</a>. The provided approach of the Fast File Responder is used in the open source social web gallery phTagr.</p>
<p>The web gallery <a href="http://www.phtagr.org">phTagr</a> is written on top of the great MVC framework CakePHP and deals with lots of photos. Its photo explorer displays by default 12 photos at once (see <a href="http://demo.phtagr.org/explorer">demo page</a>). Therefore the CakePHP framework is called 13 times. The first request handles the authorized and the selection of the 12 photos. Then each photo is requested by the client to fetch it and to display it into the page. These requests check again the authorization and correctness of the user for each photo and requires a lot of time since it traverses again the whole MVC stack.</p>
<p>time = 1 x explorer page + 12 x image request = 13 x CakePHP stack = 13 x ~0.40s = 3,40s</p>
<p>Since the first request already checked the authorization of the photos the following 12 requests and checks are redundant and can be omitted. The user session can be used to store these authorization information for the 12 media requests and the photos could be send immediately before the CakePHP stack is called.</p>
<p>time = 1 x explorer page + 12 x fast image request = 1 x CakePHP stack = 0.45s</p>
<p>To do so a Fast File Responder component adds the file information to the session. It adds for each photo request the filename of the preview and an expiration date for safety.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> FastFileResponderComponent extens Object <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$controller</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$components</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Session'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'FileCache'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$sessionKey</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'fastFile.items'</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$expireOffset</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// seconds</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$controller</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">controller</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$controller</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> add<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_readable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$files</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionKey</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$files</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'expires'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expireOffset</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'file'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionKey</span><span style="color: #339933;">,</span> <span style="color: #000088;">$files</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> addAll<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Than the <code>app/webroot/index.php</code> is modified to check for fast files before the MVC stack is called.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// ...</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'CORE_PATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #666666; font-style: italic;">// Check the request URI if it matches the URI for photos</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'url'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/media\/\w+\/\d+/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'url'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">require</span> ROOT <span style="color: #339933;">.</span> DS <span style="color: #339933;">.</span> APP_DIR <span style="color: #339933;">.</span> DS <span style="color: #339933;">.</span> <span style="color: #0000ff;">'fast_file_responder.php'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$fileResponder</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FastFileResponder<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fileResponder</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">exists</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$fileResponder</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$fileResponder</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fileResponder</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span>CORE_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'cake'</span> <span style="color: #339933;">.</span> DS <span style="color: #339933;">.</span> <span style="color: #0000ff;">'bootstrap.php'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p>Finally the Fast File Responder itself located in <code>app/fast_file_responder.php</code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/** This class enables a fast file response without the framework stack of
 * CakePHP. It checks the session and the URL and returns a valid file */</span>
<span style="color: #000000; font-weight: bold;">class</span> FastFileResponder <span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/** Should be same as in app/config/core.php Session.cookie */</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$sessionCookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'CAKEPHP'</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$sessionKey</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'fastFile'</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$items</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">startSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Starts the session if the session sessionCookie is set */</span>
  <span style="color: #000000; font-weight: bold;">function</span> startSession<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionCookie</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #990000;">session_id</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionCookie</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionKey</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionKey</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'items'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">deleteExpiredItems</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Deletes expired itemes from the session list */</span>
  <span style="color: #000000; font-weight: bold;">function</span> deleteExpiredItems<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$now</span> <span style="color: #339933;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'expires'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$now</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sessionKey</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Simple log function for debug purpos */</span>
  <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$h</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> DS <span style="color: #339933;">.</span> <span style="color: #0000ff;">'fast_file_responder.log'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">@</span><span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$h</span><span style="color: #339933;">,</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">%s</span> <span style="color: #009933; font-weight: bold;">%s</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Y-M-d h:i:s'</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">@</span><span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$h</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Extracts the item key from the url and returns it. Returns false if no
   * key could be found. This function must be adapted for others */</span>
  <span style="color: #000000; font-weight: bold;">function</span> getItemKey<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'url'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'url'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/media\/(\w+)\/(\d+)/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'-'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Returns the file of the media request */</span>
  <span style="color: #000000; font-weight: bold;">function</span> getFilename<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getItemKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$key</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$item</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'expires'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">is_readable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Returns an array of request headers */</span>
  <span style="color: #000000; font-weight: bold;">function</span> getRequestHeaders<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apache_request_headers'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">apache_request_headers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$headers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$h</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$h</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$v</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$h</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ereg</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTTP_(.+)'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$h</span><span style="color: #339933;">,</span> <span style="color: #000088;">$hp</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hp</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$v</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$headers</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Evaluates the client file cache and response if the client has still a
   * valid file
   * @param filename Current cache file */</span>
  <span style="color: #000000; font-weight: bold;">function</span> checkClientCache<span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$cacheTime</span> <span style="color: #339933;">=</span> <span style="color: #990000;">filemtime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequestHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'if-modified-since'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'if-modified-since'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$cacheTime</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Last-Modified: '</span> <span style="color: #339933;">.</span> <span style="color: #990000;">gmdate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'D, d M Y H:i:s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cacheTime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' GMT'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">304</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// Allow further caching for 30 days</span>
      <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Cache-Control: max-age=2592000, must-revalidate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> sendResponseHeaders<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$fileSize</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">filesize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: image/jpg'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Length: '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$fileSize</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Cache-Control: max-age=2592000, must-revalidate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Pragma: cache'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Last-Modified: '</span> <span style="color: #339933;">.</span> <span style="color: #990000;">gmdate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'D, d M Y H:i:s'</span><span style="color: #339933;">,</span> <span style="color: #990000;">filemtime</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Evaluates if a valid cache file exists */</span>
  <span style="color: #000000; font-weight: bold;">function</span> exists<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFilename</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Sends the cache file if it exists and exit. If it returns an error
    * occured */</span>
  <span style="color: #000000; font-weight: bold;">function</span> send<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFilename</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">checkClientCache</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendResponseHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$chunkSize</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1024</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$buffer</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'rb'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$buffer</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fread</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$chunkSize</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$buffer</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">//$this-&gt;log(&quot;File send: $filename&quot;);</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/** Closes the session */</span>
  <span style="color: #000000; font-weight: bold;">function</span> close<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">session_write_close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Now the requested images are shown almost simultaneously with the explorer photo page. Awesome!</p>
<p>Please leave a comment if you liked this proposal.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/10/03/fast-file-responder-for-cakephp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Improved Groups and Email Notifications</title>
		<link>http://www.phtagr.org/2010/09/04/improved-groups-and-email-notifications/</link>
		<comments>http://www.phtagr.org/2010/09/04/improved-groups-and-email-notifications/#comments</comments>
		<pubDate>Sat, 04 Sep 2010 12:21:52 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[announce]]></category>
		<category><![CDATA[Related Links]]></category>
		<category><![CDATA[user]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[group]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=364</guid>
		<description><![CDATA[Today I published two significant improvements of this great gallery which boosts the user experience and the social interaction. Until now the powerful access control of your media was just fun for you &#8211; but now it is easier than ever to share your photos in groups with your friends. A group got a new [...]]]></description>
			<content:encoded><![CDATA[<p>Today I published two significant improvements of this great gallery which boosts the user experience and the social interaction.</p>
<p>Until now the powerful access control of your media was just fun for you &#8211; but now it is easier than ever to share your photos in groups with your friends. A group got a new description text and some flag for the management. Other users can now see your groups and can subscribe the them by just a single click. It depends on you if your friends are able join the group immediately or the new subscriber needs a confirmation. Further a group can be shared, too. Other group members can assign a shared group to their media as well and all group members are able to see these photos or videos.</p>
<p><a href="http://demo.phtagr.org/images/view/235"><img class="alignnone" title="Group details" src="http://demo.phtagr.org/media/preview/235" alt="" width="400" height="306" /></a></p>
<p>The other great feature is a shell task which sends notification emails of new media for users. It should be uses in a cron job and will inform your uses of your gallery on new uploads. Since your shell has no clue about your gallery URL, you have to configure it in the <code>core.php</code> with the parameter <code>Notification.url</code>. To test is you can use one of the parameters <code>verbose</code>, <code>dryrun</code>, <code>noemail</code>, or <code>force</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">8</span> <span style="color: #000000;">15</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>phtagr<span style="color: #000000; font-weight: bold;">/</span>cake<span style="color: #000000; font-weight: bold;">/</span>console<span style="color: #000000; font-weight: bold;">/</span>cake <span style="color: #660033;">-app</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>phtagr<span style="color: #000000; font-weight: bold;">/</span>app notify run</pre></div></div>

<p>Please run the <code>setup</code> to upgrade your database (and do not forget to make a backup before &#8211; just in case).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/09/04/improved-groups-and-email-notifications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>phTagr z językiem polskim</title>
		<link>http://www.phtagr.org/2010/09/03/phtagr-z-jezykiem-polskim/</link>
		<comments>http://www.phtagr.org/2010/09/03/phtagr-z-jezykiem-polskim/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 06:10:27 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[user]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=359</guid>
		<description><![CDATA[I&#8217;m pleased to announce that phTagr has now an Polish translation &#8211; many thanks to Bartosz Fenski (aka fEnIo) for his time. The fresh baked zip file could be downloaded from SourceForge.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce that phTagr has now an Polish translation &#8211; many thanks to Bartosz Fenski (aka fEnIo) for his time. The fresh baked <a href="http://sourceforge.net/projects/phtagr/files/latest">zip</a> file could be downloaded from <a href="http://sourceforge.net/projects/phtagr/files">SourceForge</a>.</p>
<p><a href="http://demo.phtagr.org/images/view/232"><img class="alignnone" title="Polish Translation" src="http://demo.phtagr.org/media/preview/232" alt="" width="400" height="281" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/09/03/phtagr-z-jezykiem-polskim/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Love the phTagr gallery through Flattr</title>
		<link>http://www.phtagr.org/2010/08/14/love-the-phtagr-gallery-through-flattr/</link>
		<comments>http://www.phtagr.org/2010/08/14/love-the-phtagr-gallery-through-flattr/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 20:53:11 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[Nicht kategorisiert]]></category>
		<category><![CDATA[donation]]></category>
		<category><![CDATA[support]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=351</guid>
		<description><![CDATA[Recently a (German) news channel reported about the social micro payment system Flattr where you can share your love to thousand articles, songs, videos, or software by a simple click while having the opportunity to receive love from others. It&#8217;s a donation without troubles. I think this payment-love sharing is a really really great idea! [...]]]></description>
			<content:encoded><![CDATA[<p>Recently a (German) <a href="http://www.heise.de/newsticker/meldung/Belohndienst-Flattr-fuer-jeden-1059148.html">news channel</a> reported about the social micro payment system <a href="http://flattr.com">Flattr</a> where you can share your love to thousand articles, songs, videos, or software by a simple click while having the opportunity to receive love from others. It&#8217;s a donation without troubles.</p>
<p>I think this payment-love sharing is a really really great idea! You can pay back your loved content sources or loved projects easily while receiving honors of others. All you need is an account at <a href="http://flattr.com">Flattr.com</a> and some monthly donation input to give love and to receive love. If you love 10 things your monthly donation is shared to these 10 things, if you love 100, all 100 receive a little love &#8211; but at the end all you loved things receive something!</p>
<p>It&#8217;s a good idea for all the content creators, all song writers, all video editors, all software hobby writers like me. Therefore, you are able to tell your love for this great hobby project now! Just Flattr phTagr&#8230;</p>
<p><a href="http://flattr.com/thing/49109/Social-Web-Gallery-phTagr" target="_blank"><img title="Flattr this" src="http://api.flattr.com/button/button-static-50x60.png" border="0" alt="Flattr this" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/08/14/love-the-phtagr-gallery-through-flattr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phTagr räägib nüüd eesti keeles</title>
		<link>http://www.phtagr.org/2010/08/13/phtagr-raagib-nuud-eesti-keeles/</link>
		<comments>http://www.phtagr.org/2010/08/13/phtagr-raagib-nuud-eesti-keeles/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 19:36:26 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[user]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://www.phtagr.org/?p=347</guid>
		<description><![CDATA[I&#8217;m happy to announce that phTagr has now an Estonian translation. Thanks to Craig for his great work who found also lots of missing translation texts. The fresh baked zip file could be downloaded from SourceForge. For upgrade information please have a look at our wiki page. Further, phTagr supports now the media selection by [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that phTagr has now an Estonian translation. Thanks to Craig for his great work who found also lots of missing translation texts. The fresh baked <a href="http://sourceforge.net/projects/phtagr/files/latest">zip</a> file could be downloaded from <a href="http://sourceforge.net/projects/phtagr/files">SourceForge</a>. For upgrade information please have a look at our <a href="http://trac.phtagr.org/wiki/HowToMigratePhtagr">wiki page</a>.</p>
<p style="text-align: center;"><a href="http://demo.phtagr.org/media/view/231/categories:screenshot"><img class="aligncenter" title="Estonian phTagr" src="http://demo.phtagr.org/media/preview/231" alt="" width="400" height="269" /></a></p>
<p>Further, phTagr supports now the media selection by the upload folder. This feature is very useful for albums which are ordered by folder. The folder link could be found by media detail tab in the media view.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phtagr.org/2010/08/13/phtagr-raagib-nuud-eesti-keeles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

