<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.elvishsu.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.elvishsu.com/" rel="alternate" type="text/html" /><updated>2025-01-18T22:07:42+00:00</updated><id>https://www.elvishsu.com/feed.xml</id><title type="html">Elvis is still in the building</title><subtitle>A simple yet creative software designer</subtitle><author><name>Elvis Hsu</name></author><entry><title type="html">A short update from me</title><link href="https://www.elvishsu.com/2024/05/a-short-update-from-me.html" rel="alternate" type="text/html" title="A short update from me" /><published>2024-05-06T00:00:00+00:00</published><updated>2024-05-06T00:00:00+00:00</updated><id>https://www.elvishsu.com/2024/05/a-short-update-from-me</id><content type="html" xml:base="https://www.elvishsu.com/2024/05/a-short-update-from-me.html"><![CDATA[<p>It has been a while since I post a blog page on <a href="https://elvishsu66.blogspot.com">Blogger</a> which was created back in 2013. So I took an opportunity to transform my personal site to <a href="https://pages.github.com/">GitHub Pages</a> with <a href="https://jekyllrb.com/">Jekyll framework</a>. The following is a short summary of myself in 2024.</p>

<hr />

<h2 id="introduction">Introduction</h2>

<p>I am a seasoned software development leader with a robust career spanning various high-level positions, including full stack software engineer, head of desktop development, solutions architect, chief architect, and director of engineering. My journey reflects a dedicated pursuit of excellence in technology and leadership.</p>

<h2 id="early-career">Early Career</h2>

<p>My career in software development began with hands-on roles that provided me with extensive experience in coding, system design, and problem-solving. These formative years laid the groundwork for my future endeavours in tech leadership and set the stage for a deep, practical understanding of technology development.</p>

<h2 id="transition-to-leadership">Transition to Leadership</h2>

<p>As I progressed to the role of head of desktop development, my focus shifted from individual contributions to strategic team leadership. In this pivotal role, I honed my skills in managing diverse teams, overseeing large-scale projects, and driving critical innovations, marking the beginning of my journey as a technology leader.</p>

<h2 id="advanced-leadership-roles-chief-architect--director-of-engineering">Advanced Leadership Roles: Chief Architect &amp; Director of Engineering</h2>

<p>In my subsequent roles as <a href="https://www.linkedin.com/company/numeus">Chief Architect</a> and <a href="https://www.linkedin.com/company/forteus/">Director of Engineering</a>, I embraced greater challenges and responsibilities. Steering the architectural direction of software solutions at a corporate level as Chief Architect, I integrated cutting-edge technologies, enhancing system reliability, and ensured scalability. Transitioning to Director of Engineering, I expanded my influence, overseeing multiple engineering teams, guiding complex software development cycles, and ensuring alignment with our strategic business objectives. My leadership style fostered an environment of innovation, collaboration, and excellence, encouraging my teams to push technical boundaries and deliver exceptional results.</p>

<h2 id="technical-skills-and-specialisations">Technical Skills and Specialisations</h2>

<p>My technical expertise encompasses full stack development, cloud technology, and Kubernetes. These skills have enabled me to lead projects requiring deep technical expertise and innovative solutions architecture. My approach often involves hands-on engagement with the technology itself, coupled with strategic oversight.</p>

<h2 id="leadership-philosophy">Leadership Philosophy</h2>

<p>As a leader, I believe in fostering an environment of collaboration and open communication. I am committed to developing talent and encouraging my teams to push the boundaries of what is technically possible. My leadership is characterised by a commitment to excellence and a deep understanding of how technology can be used to drive business success.</p>

<h2 id="vision-for-the-future">Vision for the Future</h2>

<p>My technical vision for the future focuses on the transformative potential of cloud architecture and distributed software solutions. I am passionate about designing systems that are not only robust and scalable but also adaptable to the rapid changes in technology that characterise our era. By leveraging emerging technologies and pushing the limits of what current platforms can do, I aim to lead the development of solutions that pave the way for next-generation software ecosystems. This vision is rooted in a belief that continuous innovation and strategic foresight are key to staying ahead in the competitive tech landscape.</p>

<h2 id="conclusion">Conclusion</h2>

<p>With a proven track record of successful leadership in various high-level technical roles, I am equipped to take on new challenges that combine my expertise in software engineering and strategic leadership. My journey is one of continual learning and adaptation, reflecting my commitment to not only keeping pace with but also shaping the future of technology. If you are interested in my experience, feel free to check it out at <a href="/about">here</a>.</p>]]></content><author><name>Elvis Hsu</name></author><category term="Thoughts" /><summary type="html"><![CDATA[The journey is the reward]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.elvishsu.com/assets/posts/bg-a-brand-new-start.jpg" /><media:content medium="image" url="https://www.elvishsu.com/assets/posts/bg-a-brand-new-start.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Showcase the blog site elements</title><link href="https://www.elvishsu.com/2024/05/showcase-the-blog-site-elements.html" rel="alternate" type="text/html" title="Showcase the blog site elements" /><published>2024-05-05T00:00:00+00:00</published><updated>2024-05-05T00:00:00+00:00</updated><id>https://www.elvishsu.com/2024/05/showcase-the-blog-site-elements</id><content type="html" xml:base="https://www.elvishsu.com/2024/05/showcase-the-blog-site-elements.html"><![CDATA[<h2 id="the-standard-paragraphs">The standard paragraphs</h2>
<p>Welcome to this demo page! Here, you’ll get an exclusive preview of our <a href="https://duckduckgo.com/?q=cutting-edge+platform" target="_blank" rel="noopener">cutting-edge platform</a> designed to revolutionise your digital experience. Our intuitive interface, powered by the latest advancements in technology, offers seamless navigation and unparalleled functionality. Explore the various features that make our platform stand out, including real-time data analytics, customisable dashboards, and robust security measures to protect your information. Whether you’re a small business looking to streamline operations or a large enterprise aiming to enhance customer engagement, our solution is tailored to meet your needs. Dive in and discover how we can transform your digital landscape.</p>

<hr />

<h2 id="headings-by-default">Headings by default:</h2>
<h1 id="h1-default-styles-for-headings">H1 Default styles for headings</h1>
<h2 id="h2-default-styles-for-headings">H2 Default styles for headings</h2>
<h3 id="h3-default-styles-for-headings">H3 Default styles for headings</h3>
<h4 id="h4-default-styles-for-headings">H4 Default styles for headings</h4>
<h5 id="h5-default-styles-for-headings">H5 Default styles for headings</h5>
<h6 id="h6-default-styles-for-headings">H6 Default styles for headings</h6>

<hr />

<h2 id="tables">Tables</h2>

<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
      <th style="text-align: center">Header 3</th>
      <th>Header 4</th>
      <th style="text-align: right">Header 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Row:1 Cell:1</td>
      <td>Row:1 Cell:2</td>
      <td style="text-align: center">Row:1 Cell:3</td>
      <td>Row:1 Cell:4</td>
      <td style="text-align: right">Row:1 Cell:5</td>
    </tr>
    <tr>
      <td>Row:2 Cell:1</td>
      <td>Row:2 Cell:2</td>
      <td style="text-align: center">Row:2 Cell:3</td>
      <td>Row:2 Cell:4</td>
      <td style="text-align: right">Row:2 Cell:5</td>
    </tr>
    <tr>
      <td>Row:3 Cell:1</td>
      <td>Row:3 Cell:2</td>
      <td style="text-align: center">Row:3 Cell:3</td>
      <td>Row:3 Cell:4</td>
      <td style="text-align: right">Row:3 Cell:5</td>
    </tr>
    <tr>
      <td>Row:4 Cell:1</td>
      <td>Row:4 Cell:2</td>
      <td style="text-align: center">Row:4 Cell:3</td>
      <td>Row:4 Cell:4</td>
      <td style="text-align: right">Row:4 Cell:5</td>
    </tr>
    <tr>
      <td>Row:5 Cell:1</td>
      <td>Row:5 Cell:2</td>
      <td style="text-align: center">Row:5 Cell:3</td>
      <td>Row:5 Cell:4</td>
      <td style="text-align: right">Row:5 Cell:5</td>
    </tr>
    <tr>
      <td>Row:6 Cell:1</td>
      <td>Row:6 Cell:2</td>
      <td style="text-align: center">Row:6 Cell:3</td>
      <td>Row:6 Cell:4</td>
      <td style="text-align: right">Row:6 Cell:5</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="quotes">Quotes</h2>
<p>A quote looks like this:</p>
<blockquote>
  <p>The longer I live, the more I realize that I am never wrong about anything, and that all the pains I have so humbly taken to verify my notions have only wasted my time!</p>

  <p>– <cite>George Bernard Shaw</cite></p>
</blockquote>

<hr />

<h2 id="lists">Lists</h2>

<h3 id="unordered-list-example">Unordered list example:</h3>
<ul>
  <li>Poutine drinking vinegar bitters.</li>
  <li>Coloring book distillery fanny pack.</li>
  <li>Venmo biodiesel gentrify enamel pin meditation.</li>
  <li>Jean shorts shaman listicle pickled portland.</li>
  <li>Salvia mumblecore brunch iPhone migas.</li>
</ul>

<hr />

<h3 id="ordered-list-example">Ordered list example:</h3>
<ol>
  <li>Bitters semiotics vice thundercats synth.</li>
  <li>Literally cred narwhal bitters wayfarers.</li>
  <li>Kale chips chartreuse paleo tbh street art marfa.</li>
  <li>Mlkshk polaroid sriracha brooklyn.</li>
  <li>Pug you probably haven’t heard of them air plant man bun.</li>
</ol>

<hr />

<h2 id="syntax-highlighter">Syntax Highlighter</h2>

<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Program</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Hello, World!"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">urllib.request</span>
<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>

<span class="n">IMG_RE</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="nb">compile</span><span class="p">(</span><span class="s">'&lt;img[^&gt;]+src="https:\/\/(?P&lt;src&gt;[^"]+)"'</span><span class="p">)</span>
<span class="n">DATE_RE</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="nb">compile</span><span class="p">(</span><span class="s">'(?P&lt;date&gt;[0-9]+\-[0-9]+\-[0-9]+)'</span><span class="p">)</span>
<span class="n">THUMB_RE</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="nb">compile</span><span class="p">(</span><span class="s">'thumbnail: (?P&lt;thumb&gt;.+)'</span><span class="p">)</span>
<span class="n">files</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">Path</span><span class="p">(</span><span class="s">"_posts"</span><span class="p">).</span><span class="n">glob</span><span class="p">(</span><span class="s">"*.html"</span><span class="p">))</span>

<span class="k">for</span> <span class="nb">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="nb">file</span><span class="p">.</span><span class="n">absolute</span><span class="p">().</span><span class="n">as_posix</span><span class="p">()</span>
    <span class="n">date_prefix</span> <span class="o">=</span> <span class="n">DATE_RE</span><span class="p">.</span><span class="n">search</span><span class="p">(</span><span class="n">filename</span><span class="p">).</span><span class="n">group</span><span class="p">(</span><span class="s">'date'</span><span class="p">)</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
        <span class="n">file_index</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">contents</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">read</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">IMG_RE</span><span class="p">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">contents</span><span class="p">):</span>
            <span class="n">sourceurl</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"https://</span><span class="si">{</span><span class="n">match</span><span class="p">.</span><span class="n">group</span><span class="p">(</span><span class="s">'src'</span><span class="p">)</span><span class="si">}</span><span class="s">"</span>
            <span class="n">thumburl</span> <span class="o">=</span> <span class="n">THUMB_RE</span><span class="p">.</span><span class="n">findall</span><span class="p">(</span><span class="n">contents</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">extstart</span> <span class="o">=</span> <span class="n">sourceurl</span><span class="p">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">'.'</span><span class="p">)</span>
            <span class="n">extension</span> <span class="o">=</span> <span class="n">sourceurl</span><span class="p">[</span><span class="n">extstart</span><span class="p">:]</span>
            <span class="n">newfile</span> <span class="o">=</span> <span class="n">date_prefix</span> <span class="o">+</span> <span class="s">'-image-{:04d}{}'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">file_index</span><span class="p">,</span> <span class="n">extension</span><span class="p">)</span>
            <span class="n">file_index</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">print</span><span class="p">(</span><span class="s">'{} =&gt; {}'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">sourceurl</span><span class="p">,</span> <span class="n">newfile</span><span class="p">))</span>
            <span class="n">urllib</span><span class="p">.</span><span class="n">request</span><span class="p">.</span><span class="n">urlretrieve</span><span class="p">(</span><span class="n">sourceurl</span><span class="p">,</span> <span class="s">'../assets/posts/blogger/'</span> <span class="o">+</span> <span class="n">newfile</span><span class="p">)</span>
            <span class="n">contents</span> <span class="o">=</span> <span class="n">contents</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="n">sourceurl</span><span class="p">,</span> <span class="s">'/assets/posts/blogger/'</span> <span class="o">+</span> <span class="n">newfile</span><span class="p">)</span>
            <span class="n">contents</span> <span class="o">=</span> <span class="n">contents</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="n">thumburl</span><span class="p">,</span> <span class="s">'/assets/posts/blogger/'</span> <span class="o">+</span> <span class="n">newfile</span><span class="p">)</span>

    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
        <span class="n">f</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">contents</span><span class="p">)</span>
</code></pre></div></div>

<hr />

<h2 id="youtube-embed">YouTube Embed</h2>
<p>
<iframe width="640" height="360" src="https://www.youtube.com/embed/B3szaVzQx0o?si=WyOlq3ZfHGYs3DWf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</p>

<h2 id="vimeo-embed">Vimeo Embed</h2>
<p>
<iframe width="640" height="360" src="https://player.vimeo.com/video/148834441?h=9dae3ab297" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen=""></iframe>
</p>
<hr />

<h2 id="images">Images</h2>
<p><img src="/assets/posts/bg-sunshine-coast.jpg" alt="bg" class="center" /></p>]]></content><author><name>Elvis Hsu</name></author><category term="Thoughts" /><category term="Tips" /><summary type="html"><![CDATA[Sometimes, you can give it a little push]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.elvishsu.com/assets/posts/bg-lisbon-skyline.jpg" /><media:content medium="image" url="https://www.elvishsu.com/assets/posts/bg-lisbon-skyline.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Issue with “Don’t track your own pageviews”</title><link href="https://www.elvishsu.com/2014/05/issue-with-dont-track-your-own-pageviews.html" rel="alternate" type="text/html" title="Issue with “Don’t track your own pageviews”" /><published>2014-05-20T11:41:00+00:00</published><updated>2014-05-20T11:41:00+00:00</updated><id>https://www.elvishsu.com/2014/05/issue-with-dont-track-your-own-pageviews</id><content type="html" xml:base="https://www.elvishsu.com/2014/05/issue-with-dont-track-your-own-pageviews.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-05-20-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="/assets/posts/blogger/2014-05-20-image-0000.png" /></a></div>
Do you use your own domain name with Blogger? Do you place "<b>Blogger's Stats Widget</b>" on your page? Or do you regularly check up the stats from your Blogger's dashboard? And most importantly have you found that "<b>Don't track your own pagesviews</b>" link no longer works?<br />
<br />
Well, it used to be working when I used the regular subdomain under&nbsp;blogspot.com. Many bloggers have reported this issue to <a href="https://productforums.google.com/forum/#!topic/blogger/PSwkuiIQrbw" target="_blank" rel="noopener noreferrer">Google</a> but yet no acceptable answers from them. However there is a way to <b>patch</b> this issue.<br />
<br />
<a name='more'></a>Let's have a look how to re-produce this error.<br />
<br />
1. Login to your <b>Blogger Dashboard</b>&nbsp;(<a href="http://www.blogger.com/" target="_blank" rel="noopener noreferrer">www.blogger.com</a>)<br />
2. Go to <b>Stats</b> --> <b>Overview</b> of your blog<br />
3. Click the "<b>Don't track your own pageviews</b>" link<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-05-20-image-0001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-05-20-image-0001.png" height="336" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
4. A blue window should appear like image below and the loading icon keeps spinning</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-05-20-image-0002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-05-20-image-0002.png" height="138" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
5. A while later, an error message "<i><span style="color: #990000;">There was an error while fetching stats. Please reload page.</span></i>" prompted.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-05-20-image-0003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-05-20-image-0003.png" height="122" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
6. If you reload the page, try again, and the above message will appear again.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b><span style="font-size: large;">So, if this is the issue, how can I make my own blogger site stop tracking my computer?&nbsp;</span></b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
1. Open a new tab on your browser while you're still logged in&nbsp;</div>
<div class="separator" style="clear: both; text-align: left;">
2. Copy the text below and paste it on the address bar of the new tab</div>
<blockquote class="tr_bq" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;">www.<b>yourdomain.com</b>/b/statsBlockingCookie?action=SET&amp;callback=__gwt_jsonp__.P2.onSuccess</span></blockquote>
<div class="separator" style="clear: both; text-align: left;">
3. Replace "<b>yourdomain.com</b>" to your domain name</div>
<div class="separator" style="clear: both; text-align: left;">
4. Press "<b>Enter</b>" and a response should be shown like below</div>
<blockquote class="tr_bq" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;">// API callback<br />__gwt_jsonp__.P2.onSuccess({"status":"yes"});</span></blockquote>
5. Go to your home page and keep reloading the page. You will find that the pageviews counter stop incrementing (the counter is either on your home page or the dashboard).<br />
<br />
<span style="font-size: large;"><b>Important Note</b></span><br />
<br />
1. This method does not fix the fundamental problem of the link<br />
2. You need to do it on every browser of your computer<br />
3. If you have other authors to access the blog, they have to do the same process<br />
<br />]]></content><author><name>Elvis Hsu</name></author><category term="Blogger" /><category term="Tips" /><summary type="html"><![CDATA[Do you use your own domain name with Blogger? Do you place "Blogger's Stats Widget" on your page? Or do you regularly check up the stats from your Blogger's dashboard? And most importantly have you found that "Don't track your own pagesviews" link no longer works? Well, it used to be working when I used the regular subdomain under&nbsp;blogspot.com. Many bloggers have reported this issue to Google but yet no acceptable answers from them. However there is a way to patch this issue. Let's have a look how to re-produce this error. 1. Login to your Blogger Dashboard&nbsp;(www.blogger.com) 2. Go to Stats --> Overview of your blog 3. Click the "Don't track your own pageviews" link 4. A blue window should appear like image below and the loading icon keeps spinning 5. A while later, an error message "There was an error while fetching stats. Please reload page." prompted. 6. If you reload the page, try again, and the above message will appear again. So, if this is the issue, how can I make my own blogger site stop tracking my computer?&nbsp; 1. Open a new tab on your browser while you're still logged in&nbsp; 2. Copy the text below and paste it on the address bar of the new tab www.yourdomain.com/b/statsBlockingCookie?action=SET&amp;callback=__gwt_jsonp__.P2.onSuccess 3. Replace "yourdomain.com" to your domain name 4. Press "Enter" and a response should be shown like below // API callback__gwt_jsonp__.P2.onSuccess({"status":"yes"}); 5. Go to your home page and keep reloading the page. You will find that the pageviews counter stop incrementing (the counter is either on your home page or the dashboard). Important Note 1. This method does not fix the fundamental problem of the link 2. You need to do it on every browser of your computer 3. If you have other authors to access the blog, they have to do the same process]]></summary></entry><entry><title type="html">Build your own Related Posts widget for Blogger</title><link href="https://www.elvishsu.com/2014/01/build-your-own-related-posts-widget-for-blogger.html" rel="alternate" type="text/html" title="Build your own Related Posts widget for Blogger" /><published>2014-01-30T13:33:00+00:00</published><updated>2014-01-30T13:33:00+00:00</updated><id>https://www.elvishsu.com/2014/01/build-your-own-related-posts-widget-for-blogger</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/build-your-own-related-posts-widget-for-blogger.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-30-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="/assets/posts/blogger/2014-01-30-image-0000.png" height="227" width="320"/></a></div>
    I have visited many blog sites and most of them have "<b>Related Posts</b>"
    or "<b>You may also like -</b> " section for visitors who like to discover
    more related articles or stories. I am one of those visitors who likes to
    find out more interesting posts which are related to the original article I
    have read. Indeed, having related posts section will increase your exposures
    of your site. That is no doubt about it.<br>
    <br>
    Unfortunately, I didn't have this feature on my site since I started to
    customise it. Of course I then started to do some research about building a
    "<span style="font-weight: bold;">Related Posts</span>" widget for Blogger.
    Obviously, there are lots of articles talking about "<b>adding</b>" related
    posts widget to your Blogger site but not many of them have detailed
    explanations. Well, fortunately some of them guided me to create this jQuery
    plugin.&nbsp;
    <a name='more'></a><br>
    <br>
    So first of all, what does related posts mean? Are they related to the title
    of the original article? Or are they related to the category of the original
    post? Or are they related to the author's posts? Well, I would answer yes to
    all of them. You may have other supportive answers too. &nbsp; <br>
    <br>
    In this plugin, I find related posts based on the current article's "<b>labels</b>"
    via the Blogger's <b>RSS feed</b>. So you need to label your article in
    order to make this plugin work. Since the RSS feed provides all information
    I needed, I just need to extract and parse the data to what I need for
    "related posts". So what do I need from the RSS feed? <br>
    <br>
    <ul>
      <li>The <b>post id</b> or <b>labels</b> of current article</li>
      <li>The labels of each article</li>
      <li>The URL link of each article</li>
      <li>The title of each article</li>
      <li>The thumbnail link of each article</li>
    </ul>
    <br>
    Luckily Google provides a comprehensive documentation for its data APIs for
    Blogger developers so if you want to dig more information out, just pay a
    visit to <a href="https://developers.google.com/gdata/docs/2.0/reference#Queries"
      target="_blank" rel="noopener noreferrer">here</a>.
    <br>
    <br>
    Anyway, the concept is to use the <b>labels</b> of current article to find
    related posts and the post id or article link as identifier to exclude
    current article from the collection of related posts. When the labels are
    retrieved, then we start to find and collect posts whose labels contain the
    original article's labels. Finally, we output these collected posts to the
    site. Here is the source code of this plugin.
    

<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">){</span>
  <span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">relatedPosts</span><span class="o">=</span><span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">){</span>
   <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span>
    <span class="nx">blogId</span><span class="p">,</span>
    <span class="nx">postId</span><span class="p">;</span>
 
   <span class="kd">var</span> <span class="nx">settings</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="kc">true</span><span class="p">,{</span>
    <span class="na">url</span><span class="p">:</span> <span class="dl">''</span><span class="p">,</span>
    <span class="na">postId</span><span class="p">:</span><span class="dl">''</span><span class="p">,</span>
    <span class="na">labels</span><span class="p">:[],</span>
    <span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">Related Posts: </span><span class="dl">'</span><span class="p">,</span>
    <span class="na">itemClass</span><span class="p">:</span> <span class="dl">'</span><span class="s1">related_item</span><span class="dl">'</span><span class="p">,</span>
       <span class="na">wrapperClass</span><span class="p">:</span> <span class="dl">'</span><span class="s1">related_items_wapper</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">titleClass</span><span class="p">:</span> <span class="dl">'</span><span class="s1">title</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">shuffle</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
    <span class="na">thumbUsePost</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
    <span class="na">thumbWidth</span><span class="p">:</span><span class="mi">100</span><span class="p">,</span>
    <span class="na">thumbHeight</span><span class="p">:</span><span class="mi">75</span><span class="p">,</span>
    <span class="na">maxPosts</span><span class="p">:</span> <span class="mi">6</span>
   <span class="p">},</span><span class="nx">config</span><span class="p">);</span>
 
   <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">$</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">labels</span><span class="p">)){</span>
    <span class="nx">settings</span><span class="p">.</span><span class="nx">labels</span> <span class="o">=</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">labels</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">split</span><span class="p">(</span><span class="dl">'</span><span class="s1">,</span><span class="dl">'</span><span class="p">);</span>
   <span class="p">}</span>
   <span class="k">return</span> <span class="nx">init</span><span class="p">();</span>
 
   <span class="kd">function</span> <span class="nx">init</span><span class="p">(){</span>
    <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
        <span class="na">url</span><span class="p">:</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">url</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">/feeds/posts/default?alt=json&amp;max-results=500</span><span class="dl">'</span><span class="p">,</span>
        <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">get</span><span class="dl">'</span><span class="p">,</span>
        <span class="na">dataType</span><span class="p">:</span> <span class="dl">"</span><span class="s2">jsonp</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">cache</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
        <span class="na">success</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">){</span>
         <span class="c1">// get the blog feed id</span>
         <span class="nx">blogId</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">feed</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">$t</span><span class="p">;</span>
         <span class="k">if</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">postId</span> <span class="o">!==</span> <span class="dl">''</span><span class="p">){</span>
          <span class="c1">// get the current post id</span>
          <span class="nx">postId</span> <span class="o">=</span> <span class="nx">blogId</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">.post-</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">postId</span><span class="p">;</span>
         <span class="p">}</span>
         <span class="c1">// get related posts</span>
         <span class="kd">var</span> <span class="nx">posts</span> <span class="o">=</span> <span class="nx">findRelatedPosts</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">feed</span><span class="p">.</span><span class="nx">entry</span><span class="p">);</span>
            <span class="c1">// add section title</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;h2/&gt;</span><span class="dl">'</span><span class="p">).</span><span class="nx">text</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">title</span><span class="p">));</span>
            <span class="kd">var</span> <span class="nx">wrapper</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;div/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">class</span><span class="dl">'</span><span class="p">:</span><span class="nx">settings</span><span class="p">.</span><span class="nx">wrapperClass</span><span class="p">});</span>
         <span class="c1">// construct the output</span>
            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">posts</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
             <span class="kd">var</span> <span class="nx">entry</span> <span class="o">=</span> <span class="nx">posts</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
             <span class="kd">var</span> <span class="nx">href</span> <span class="o">=</span> <span class="nx">getLink</span><span class="p">(</span><span class="nx">entry</span><span class="p">);</span>
             <span class="c1">// the link</span>
             <span class="kd">var</span> <span class="nx">link</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;a/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">href</span><span class="dl">'</span><span class="p">:</span><span class="nx">href</span><span class="p">});</span>
             <span class="c1">// the thumbnail</span>
             <span class="kd">var</span> <span class="nx">thumb</span> <span class="o">=</span> <span class="nx">findThumbnail</span><span class="p">(</span><span class="nx">entry</span><span class="p">,</span><span class="nx">entry</span><span class="p">.</span><span class="nx">title</span><span class="p">.</span><span class="nx">$t</span><span class="p">);</span>
             <span class="c1">// the post title</span>
             <span class="kd">var</span> <span class="nx">pTitle</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;div/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">class</span><span class="dl">'</span><span class="p">:</span><span class="nx">settings</span><span class="p">.</span><span class="nx">titleClass</span><span class="p">});</span>
             <span class="c1">// the item block</span>
             <span class="kd">var</span> <span class="nx">div</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;div/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">class</span><span class="dl">'</span><span class="p">:</span><span class="nx">settings</span><span class="p">.</span><span class="nx">itemClass</span><span class="p">});</span>
             <span class="c1">// add thumbnail</span>
             <span class="nx">div</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">thumb</span><span class="p">);</span>
                <span class="c1">// wrap the link</span>
                <span class="nx">thumb</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">link</span><span class="p">);</span>
             <span class="c1">// add post title</span>
                      <span class="nx">div</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">pTitle</span><span class="p">);</span>
                      <span class="nx">pTitle</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">link</span><span class="p">.</span><span class="nx">text</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">title</span><span class="p">.</span><span class="nx">$t</span><span class="p">));</span>
                      <span class="c1">// add the item block</span>
                <span class="nx">wrapper</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">div</span><span class="p">);</span>
                <span class="nx">div</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span> <span class="o">=</span> <span class="nx">href</span><span class="p">;</span> <span class="p">})</span>
            <span class="p">}</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">);</span>
            <span class="c1">// clear the layout</span>
           <span class="nx">me</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;div style="clear:both;"&gt;&lt;/div&gt;</span><span class="dl">'</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">});</span>   
   <span class="p">}</span>
   
   <span class="c1">// gets the entry link</span>
   <span class="kd">function</span> <span class="nx">getLink</span><span class="p">(</span><span class="nx">entry</span><span class="p">){</span>
    <span class="kd">var</span> <span class="nx">href</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">#</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">$</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">link</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">v</span><span class="p">){</span>
     <span class="k">if</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">rel</span><span class="o">==</span><span class="dl">'</span><span class="s1">alternate</span><span class="dl">'</span><span class="p">){</span>
      <span class="nx">href</span> <span class="o">=</span> <span class="nx">v</span><span class="p">.</span><span class="nx">href</span><span class="p">;</span>
      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
     <span class="p">};</span>
    <span class="p">});</span>
    <span class="k">return</span> <span class="nx">href</span><span class="p">;</span>
   <span class="p">}</span>
 
   <span class="c1">// find related entries</span>
   <span class="kd">function</span> <span class="nx">findRelatedPosts</span><span class="p">(</span><span class="nx">entries</span><span class="p">){</span>
    <span class="kd">var</span> <span class="nx">posts</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="kd">var</span> <span class="nx">cats</span> <span class="o">=</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">labels</span><span class="p">;</span>
 
    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">entries</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
     <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">matchCurrentPost</span><span class="p">(</span><span class="nx">entries</span><span class="p">[</span><span class="nx">i</span><span class="p">])){</span>    
      <span class="k">if</span><span class="p">(</span><span class="nx">matchCategory</span><span class="p">(</span><span class="nx">entries</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span><span class="nx">cats</span><span class="p">)){</span>
       <span class="nx">posts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">entries</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
      <span class="p">}</span>
     <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">// shuffle array</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">shuffle</span><span class="p">){</span>
     <span class="nx">posts</span><span class="p">.</span><span class="nx">sort</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="mf">0.5</span> <span class="o">-</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="p">});</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">posts</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="nx">settings</span><span class="p">.</span><span class="nx">maxPosts</span><span class="p">);</span>
   <span class="p">}</span>
 
   <span class="kd">function</span> <span class="nx">findThumbnail</span><span class="p">(</span><span class="nx">entry</span><span class="p">,</span> <span class="nx">title</span><span class="p">){</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">thumbUsePost</span><span class="p">){</span>
     <span class="k">if</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">content</span><span class="p">){</span>
      <span class="kd">var</span> <span class="nx">div</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;div/&gt;</span><span class="dl">'</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">content</span><span class="p">.</span><span class="nx">$t</span><span class="p">);</span>
      <span class="kd">var</span> <span class="nx">imgs</span> <span class="o">=</span> <span class="nx">div</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="dl">'</span><span class="s1">img</span><span class="dl">'</span><span class="p">);</span>
      <span class="k">if</span><span class="p">(</span><span class="nx">imgs</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>     
       <span class="k">return</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;img/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">src</span><span class="dl">'</span><span class="p">:</span><span class="nx">imgs</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">src</span><span class="p">,</span> <span class="dl">'</span><span class="s1">alt</span><span class="dl">'</span><span class="p">:</span> <span class="nx">imgs</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">alt</span><span class="p">,</span> <span class="dl">'</span><span class="s1">title</span><span class="dl">'</span><span class="p">:</span> <span class="nx">title</span><span class="p">,</span> <span class="dl">'</span><span class="s1">width</span><span class="dl">'</span><span class="p">:</span><span class="nx">settings</span><span class="p">.</span><span class="nx">thumbWidth</span><span class="p">,</span><span class="dl">'</span><span class="s1">height</span><span class="dl">'</span><span class="p">:</span><span class="nx">settings</span><span class="p">.</span><span class="nx">thumbHeight</span><span class="p">});</span>
      <span class="p">}</span>
     <span class="p">}</span>
    <span class="p">}</span><span class="k">else</span><span class="p">{</span>
     <span class="k">return</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;img/&gt;</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">src</span><span class="dl">'</span><span class="p">:</span><span class="nx">entry</span><span class="p">.</span><span class="nx">media$thumbnail</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span><span class="dl">'</span><span class="s1">title</span><span class="dl">'</span><span class="p">:</span> <span class="nx">title</span><span class="p">,</span><span class="dl">'</span><span class="s1">alt</span><span class="dl">'</span><span class="p">:</span><span class="nx">title</span><span class="p">,</span><span class="dl">'</span><span class="s1">width</span><span class="dl">'</span><span class="p">:</span><span class="nx">entry</span><span class="p">.</span><span class="nx">media$thumbnail</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span><span class="dl">'</span><span class="s1">height</span><span class="dl">'</span><span class="p">:</span><span class="nx">entry</span><span class="p">.</span><span class="nx">media$thumbnail</span><span class="p">.</span><span class="nx">height</span><span class="p">});</span>
    <span class="p">}</span>
   <span class="p">}</span>
 
   <span class="kd">function</span> <span class="nx">matchCurrentPost</span><span class="p">(</span><span class="nx">entry</span><span class="p">){</span>
    <span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">postId</span><span class="p">){</span>
     <span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">entry</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">$t</span>
     <span class="nx">match</span> <span class="o">=</span> <span class="p">(</span><span class="nx">id</span> <span class="o">==</span> <span class="nx">postId</span><span class="p">);</span>    
    <span class="p">}</span><span class="k">else</span><span class="p">{</span>
     <span class="kd">var</span> <span class="nx">href</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">location</span><span class="p">.</span><span class="nx">hash</span><span class="p">,</span><span class="dl">''</span><span class="p">);</span>
     <span class="nx">href</span> <span class="o">=</span> <span class="nx">href</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">'</span><span class="s1">?</span><span class="dl">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">();</span>
     <span class="nx">$</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">link</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="nx">v</span><span class="p">){</span>
      <span class="k">if</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">rel</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">alternate</span><span class="dl">'</span><span class="p">){</span>
       <span class="k">if</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">href</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">()</span> <span class="o">==</span> <span class="nx">href</span><span class="p">){</span>
        <span class="nx">match</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
       <span class="p">}</span>
      <span class="p">}</span>
     <span class="p">});</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">match</span><span class="p">;</span>
   <span class="p">}</span>
 
   <span class="c1">// find any matched category</span>
   <span class="kd">function</span> <span class="nx">matchCategory</span><span class="p">(</span><span class="nx">entry</span><span class="p">,</span> <span class="nx">tags</span><span class="p">){</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">entry</span><span class="p">.</span><span class="nx">category</span><span class="p">){</span>
     <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">entry</span><span class="p">.</span><span class="nx">category</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
      <span class="kd">var</span> <span class="nx">tag</span> <span class="o">=</span> <span class="nx">entry</span><span class="p">.</span><span class="nx">category</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">term</span><span class="p">;</span>
      <span class="k">if</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">inArray</span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span><span class="nx">tags</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">){</span>
       <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
      <span class="p">}</span>
     <span class="p">}</span>    
    <span class="p">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
   <span class="p">}</span>
  <span class="p">};</span>
 <span class="p">})(</span><span class="nx">jQuery</span><span class="p">);</span></code></pre></figure>You may notice that I use the url <span style="font-weight: bold;">/feeds/posts/default</span>
instead of <span style="font-weight: bold;">/feeds/posts/summary</span>. If
I use summary, then I cannot extract the original images for thumbnails.
Also if the images of the article were not uploaded via Blogger then you
don't have the thumbnail link from the feed. Therefore the most secure way
is use the original image link from the article itself. 
<br>
<br>

<h2>So how can I use this widget? </h2>

There are 4 key factors you need to do:
<ol>
  <li> Make sure you have jQuery library loaded </li>
  <li> Make sure you have the plugin placed after the jQuery library link </li>
  <li> Place the div container to the place you want to show (usually we
    place it at the end of the article)&nbsp;</li>
  <li>Call the plugin when the document is ready</li>
</ol>

<br>
Let's get started and we only need 3 steps to make it work<br>
<br>

<h3>1. Place the code to the section you want to show the related posts</h3>
Below is the code you need to put to the place you want to show on your page<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;b:if</span> <span class="na">cond=</span><span class="s">'data:blog.pageType == &amp;quot;item&amp;quot;'</span><span class="nt">&gt;</span>
 <span class="c">&lt;!-- related posts --&gt;</span>
 <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">'related_posts'</span><span class="nt">&gt;&lt;/div&gt;</span>
 <span class="nt">&lt;script&gt;</span><span class="kd">var</span> <span class="nx">labels</span> <span class="o">=</span> <span class="o">&amp;</span><span class="err">#</span><span class="mi">39</span><span class="p">;</span><span class="o">&lt;</span><span class="nx">b</span><span class="p">:</span><span class="nx">loop</span> <span class="nx">values</span><span class="o">=</span><span class="dl">'</span><span class="s1">data:post.labels</span><span class="dl">'</span> <span class="kd">var</span><span class="o">=</span><span class="dl">'</span><span class="s1">label</span><span class="dl">'</span><span class="o">&gt;&lt;</span><span class="nx">data</span><span class="p">:</span><span class="nx">label</span><span class="p">.</span><span class="nx">name</span><span class="o">/&gt;&lt;</span><span class="nx">b</span><span class="p">:</span><span class="k">if</span> <span class="nx">cond</span><span class="o">=</span><span class="dl">'</span><span class="s1">data:label.isLast != &amp;quot;true&amp;quot;</span><span class="dl">'</span><span class="o">&gt;</span><span class="p">,</span><span class="o">&lt;</span><span class="sr">/b:if&gt;&lt;/</span><span class="nx">b</span><span class="p">:</span><span class="nx">loop</span><span class="o">&gt;&amp;</span><span class="err">#</span><span class="mi">39</span><span class="p">;;</span><span class="nt">&lt;/script&gt;</span>                  
<span class="nt">&lt;/b:if&gt;</span></code></pre></figure>First you need to open your HTML template editor and search for<br>
<br><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">'post-footer'</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></figure><br>
if you cannot find above, then we need to find below text<br>
<br><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;b:includable</span> <span class="na">id=</span><span class="s">'post'</span> <span class="na">var=</span><span class="s">'post'</span><span class="nt">&gt;</span></code></pre></figure><br>
when you found above part, you need to scroll down until you see<br>
<br><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;/b:includable&gt;</span></code></pre></figure><br>
when you see it, place the sample code above it.<br>
<br>
<hr>
<h3> 2. Place the CSS code to your skin</h3>
Search the text below in your HTML template editor<br>
<br><figure class="highlight"><pre><code class="language-html" data-lang="html">]]&gt;<span class="nt">&lt;/b:skin&gt;</span></code></pre></figure><br>
then place the code below above the <span style="font-family: Courier New,Courier,monospace;">]]&gt;&lt;b:skin&gt;</span><br><figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="nf">#related_posts</span><span class="p">{</span>
 <span class="nl">border-top</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#d0d0d0</span><span class="p">;</span>
 <span class="nl">border-bottom</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#d0d0d0</span><span class="p">;</span>         
<span class="p">}</span>

<span class="nf">#related_posts</span> <span class="nt">h2</span> <span class="p">{</span>
 <span class="nl">background</span><span class="p">:</span> <span class="m">#211f1c</span> <span class="sx">url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWn7_a5I7J7O5g_kfWL4RQed7bkH1F52l7DaNt6BB-xn1T1aSarlkfwbdA5uzlMtiTLDw7bCZLCuQKgSFKLCQ7WhadJhHwzQBY0P9-TT6pTvex8A30pmb77GMLo_09T1xdO7lQM7MsRes/s1600/texture-dark.jpg)</span> <span class="nb">fixed</span><span class="p">;</span>
 <span class="nl">display</span><span class="p">:</span><span class="nb">block</span><span class="p">;</span>
 <span class="nl">height</span><span class="p">:</span><span class="m">35px</span><span class="p">;</span>
 <span class="nl">color</span><span class="p">:</span><span class="no">white</span><span class="p">;</span>
 <span class="nl">font-weight</span><span class="p">:</span> <span class="nb">normal</span><span class="p">;</span>
 <span class="nl">letter-spacing</span><span class="p">:</span> <span class="m">-0.5px</span><span class="p">;</span>
 <span class="nl">font-size</span><span class="p">:</span> <span class="m">18px</span><span class="p">;</span>
 <span class="nl">padding-left</span><span class="p">:</span><span class="m">20px</span><span class="p">;</span>
 <span class="nl">line-height</span><span class="p">:</span> <span class="m">33px</span><span class="p">;</span>
 <span class="nl">font-family</span><span class="p">:</span><span class="s1">"Trebuchet MS"</span><span class="p">,</span> <span class="n">Helvetica</span><span class="p">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_items_wapper</span><span class="p">{</span>
 <span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
 <span class="nl">overflow</span><span class="p">:</span><span class="nb">hidden</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span><span class="p">{</span>
 <span class="nl">float</span><span class="p">:</span><span class="nb">left</span><span class="p">;</span>
 <span class="nl">overflow</span><span class="p">:</span> <span class="nb">hidden</span><span class="p">;</span>
 <span class="nl">width</span><span class="p">:</span><span class="m">100px</span><span class="p">;</span>
 <span class="nl">height</span><span class="p">:</span><span class="m">190px</span><span class="p">;</span>
 <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
 <span class="nl">border-radius</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
 <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#ececec</span><span class="p">;</span>
 <span class="nl">background</span><span class="p">:</span><span class="m">#fff</span><span class="p">;</span>
 <span class="nl">margin-right</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
 <span class="nl">-moz-box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">8px</span> <span class="m">4px</span> <span class="m">-4px</span> <span class="m">#000</span><span class="p">;</span>
 <span class="nl">-webkit-box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">8px</span> <span class="m">4px</span> <span class="m">-4px</span> <span class="m">#000</span><span class="p">;</span>
 <span class="nl">box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">8px</span> <span class="m">4px</span> <span class="m">-4px</span> <span class="m">#000</span><span class="p">;</span>
   <span class="nl">-webkit-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">.5s</span> <span class="n">ease</span><span class="p">;</span>
  <span class="nl">-moz-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">.5s</span> <span class="n">ease</span><span class="p">;</span>
    <span class="nl">-o-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">.5s</span> <span class="n">ease</span><span class="p">;</span>
   <span class="nl">-ms-transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">.5s</span> <span class="n">ease</span><span class="p">;</span>
    <span class="nl">transition</span><span class="p">:</span> <span class="n">all</span> <span class="m">.5s</span> <span class="n">ease</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span><span class="nd">:hover</span><span class="p">{</span>
 <span class="nl">-moz-box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">0</span> <span class="m">4px</span> <span class="m">4px</span> <span class="m">#ddd</span><span class="p">;</span>
 <span class="nl">-webkit-box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">0</span> <span class="m">4px</span> <span class="m">4px</span> <span class="m">#ddd</span><span class="p">;</span>
 <span class="nl">box-shadow</span><span class="p">:</span> <span class="m">0</span> <span class="m">0</span> <span class="m">4px</span> <span class="m">4px</span> <span class="m">#ddd</span><span class="p">;</span>
 <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#ddd</span><span class="p">;</span>
 <span class="nl">background</span><span class="p">:</span> <span class="m">#eee</span><span class="p">;</span>
 <span class="nl">cursor</span><span class="p">:</span> <span class="nb">pointer</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span><span class="nd">:hover</span> <span class="nt">img</span><span class="o">,</span> <span class="nc">.related_item</span><span class="nd">:hover</span> <span class="nc">.title</span><span class="p">{</span>
 <span class="nl">opacity</span><span class="p">:</span> <span class="m">.7</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span> <span class="nt">img</span><span class="p">{</span>
 <span class="nl">float</span><span class="p">:</span><span class="nb">left</span><span class="p">;</span>
 <span class="nl">border-top-left-radius</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
 <span class="nl">border-top-right-radius</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span> <span class="nc">.title</span><span class="p">{</span>
 <span class="nl">float</span><span class="p">:</span><span class="nb">left</span><span class="p">;</span>
 <span class="nl">font-size</span><span class="p">:</span> <span class="m">90%</span><span class="p">;</span>
 <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
 <span class="nl">background</span><span class="p">:</span> <span class="m">#555</span><span class="p">;</span>
 <span class="nl">padding</span><span class="p">:</span><span class="m">10px</span> <span class="m">5px</span><span class="p">;</span>
 <span class="nl">height</span><span class="p">:</span><span class="m">100%</span><span class="p">;</span>
 <span class="nl">max-width</span><span class="p">:</span> <span class="m">90px</span><span class="p">;</span>
 <span class="nl">word-wrap</span><span class="p">:</span><span class="n">break-word</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.related_item</span> <span class="nc">.title</span> <span class="nt">a</span><span class="p">{</span>
 <span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
 <span class="nl">color</span><span class="p">:</span><span class="m">#fff</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure><hr>

<h3> 3. Execute the plugin</h3>

Search the text below in your HTML template editor<br>
<br><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;/body&gt;</span></code></pre></figure><br>
then place the code below above</span><br>
<br><figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c">&lt;!--</span> <span class="nx">comment</span> <span class="nx">out</span> <span class="nx">below</span> <span class="k">if</span> <span class="nx">you</span> <span class="nx">have</span> <span class="nx">jQuery</span> <span class="nx">library</span> <span class="nx">loaded</span> <span class="nx">already</span> <span class="o">--&gt;</span>
<span class="o">&lt;</span><span class="nx">script</span> <span class="nx">src</span><span class="o">=</span><span class="dl">'</span><span class="s1">//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js</span><span class="dl">'</span> <span class="o">/&gt;</span>
<span class="o">&lt;</span><span class="nx">script</span> <span class="nx">src</span><span class="o">=</span><span class="dl">'</span><span class="s1">https://dl.dropboxusercontent.com/u/99319532/Blogger/host/related_posts.js</span><span class="dl">'</span><span class="o">/&gt;</span>
<span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
  <span class="c1">// related posts</span>
  <span class="k">if</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#related_posts</span><span class="dl">'</span><span class="p">).</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
    <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#related_posts</span><span class="dl">'</span><span class="p">).</span><span class="nx">relatedPosts</span><span class="p">({</span><span class="na">labels</span><span class="p">:</span><span class="nx">labels</span><span class="p">,</span><span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">You may also like -</span><span class="dl">'</span><span class="p">});</span>
  <span class="p">};</span>
<span class="o">&lt;</span><span class="nx">script</span><span class="o">/&gt;</span></code></pre></figure>Now, you should be able to see your related post on your page. You can tweak
the query to search articles related to the author or give it a date range.
If you don't know how to do it, just leave a comment and I will help you. If
you have other suggestions or ideas, please also leave your comment.]]></content><author><name>Elvis Hsu</name></author><category term="Blogger" /><category term="Coding" /><category term="Javascript" /><summary type="html"><![CDATA[I have visited many blog sites and most of them have "Related Posts" or "You may also like - " section for visitors who like to discover more related articles or stories. I am one of those visitors who likes to find out more interesting posts which are related to the original article I have read. Indeed, having related posts section will increase your exposures of your site. That is no doubt about it. Unfortunately, I didn't have this feature on my site since I started to customise it. Of course I then started to do some research about building a "Related Posts" widget for Blogger. Obviously, there are lots of articles talking about "adding" related posts widget to your Blogger site but not many of them have detailed explanations. Well, fortunately some of them guided me to create this jQuery plugin.&nbsp; So first of all, what does related posts mean? Are they related to the title of the original article? Or are they related to the category of the original post? Or are they related to the author's posts? Well, I would answer yes to all of them. You may have other supportive answers too. &nbsp; In this plugin, I find related posts based on the current article's "labels" via the Blogger's RSS feed. So you need to label your article in order to make this plugin work. Since the RSS feed provides all information I needed, I just need to extract and parse the data to what I need for "related posts". So what do I need from the RSS feed? The post id or labels of current article The labels of each article The URL link of each article The title of each article The thumbnail link of each article Luckily Google provides a comprehensive documentation for its data APIs for Blogger developers so if you want to dig more information out, just pay a visit to here. Anyway, the concept is to use the labels of current article to find related posts and the post id or article link as identifier to exclude current article from the collection of related posts. When the labels are retrieved, then we start to find and collect posts whose labels contain the original article's labels. Finally, we output these collected posts to the site. Here is the source code of this plugin.]]></summary></entry><entry><title type="html">Flickr Photo Gallery with Colorbox in jQuery</title><link href="https://www.elvishsu.com/2014/01/flickr-photo-gallery-with-colorbox-in.html" rel="alternate" type="text/html" title="Flickr Photo Gallery with Colorbox in jQuery" /><published>2014-01-24T00:13:00+00:00</published><updated>2014-01-24T00:13:00+00:00</updated><id>https://www.elvishsu.com/2014/01/flickr-photo-gallery-with-colorbox-in</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/flickr-photo-gallery-with-colorbox-in.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-24-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="Flickr Photo Gallery" border="0" src="/assets/posts/blogger/2014-01-24-image-0000.png" height="148" title="Flickr Photo Gallery" width="200" /></a></div>
Last week I updated my Blogger site to be responsive and optimised the <a href="https://developers.google.com/speed/pagespeed/insights/?url=www.elvishsu.com" target="_blank" title="Google PageSpeed Insights">page
load time</a>. Whilst doing those optimisation, I was looking for a simple
photo gallery to display the photos from my <a href="http://www.flickr.com/photos/elvishsu66" target="_blank" title="Elvis's Photostream">Flickr
photo stream</a>. I've tried <a href="http://www.flickrslideshow.com/" target="_blank" title="flickr sideshow">flickr
sideshow</a><span style="text-decoration: underline;"></span>, <a href="http://www.db798.com/pictobrowser/" target="_blank" title="pictobrowser">pictobrowser
</a>and <a href="http://www.slideflickr.com/" target="_blank" title="slideflickr">slideflickr</a>
however I was not satisfied with them. I then started to study the <a href="http://www.flickr.com/services/api/" target="_blank" title="Flickr API">Flickr
API</a> and tried to make a Flickr-like justified layout for my <a href="https://www.blogger.com/p/photography.html" target="_blank" title="My Phtos">photography
page</a>. While trying to code the jQuery plugin, I found two great
articles by Sam from <a href="http://www.wackylabs.net/2012/03/flickr-justified-layout-in-jquery/" target="_blank" title="wackylabs">Wackylabs.net</a>
and <a href="http://miromannino.com/projects/justified-gallery/" target="_top">Miro
Mannino</a>. Miro explained how the layout could be done with a detailed
illustrations but I decided to use Sam's algorithm to build my own jQuery
plugin.<br />
<a name='more'></a><br />
The plugin loads 5 rows when scrolling to the end of the page until photos
all are loaded. If the configuration specifies more than one page, then it
calls and loads next page until it reaches maximum pages. The current
solution is not perfect and may affect the performance when it loads more
than <span style="font-weight: bold;">800</span> photos. I will be working
on optimising the performance to allow loading more photos.<br />
<br />
This jQuery plugin also uses <a href="http://www.jacklmoore.com/colorbox/" target="_blank" title="Colorbox">Colorbox</a>
    to show larger version of photos when user clicks on the photo.<br />
<br />
Okay, let me explain the configuration and how to use the plugin. However
feel free to jump straight to the <a href="https://dl.dropboxusercontent.com/u/99319532/Blogger/host/flickrGallery.html" target="_blank" rel="noopener noreferrer">demo</a>
to view-source.<br />
<br />
<ul>
<li><span style="font-weight: bold;">rows</span>: the total/initial rows
        to show (default to 5)</li>
<li> <span style="font-weight: bold;">rowHeight</span>: the desired
        height of row (default to 150)</li>
<li><span style="font-weight: bold;">borderWidth</span>: the border width
        of each photo (default to 5)</li>
<li><span style="font-weight: bold;">shuffle</span>: shuffles the photo
        array when value is true (default to false)</li>
<li><span style="font-weight: bold;">maxPage</span>: the maximum flickr
        pages to load (default to 3)</li>
<li><span style="font-weight: bold;">loadOnScroll</span>: loads new photos
        when scrolling to page end (default to false)</li>
<li><span style="font-weight: bold;">params->method</span>: the <a href="http://www.flickr.com/services/api/" target="_blank" rel="noopener noreferrer">Flick
          API</a> method (default to '<a href="http://www.flickr.com/services/api/flickr.photos.search.html" target="_blank" rel="noopener noreferrer">flickr.photos.search</a>')</li>
<li><span style="font-weight: bold;">params->api_key</span>: the API
        key which you can get it from <a href="http://www.flickr.com/services/apps/create/apply" target="_blank" title="Apply Flickr API key">here</a></li>
<li><span style="font-weight: bold;">params->user_id</span>: your user
        id for fetching your photo stream. You can get it from <a href="http://idgettr.com/" target="_blank" title="Flickr user id">here</a><a href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" target="_blank" title="Flickr user id"><br />
        </a><span style="font-weight: bold;"></span></li>
<li><span style="font-weight: bold;">params->per_page</span>: the
        available photos per page from the results of API call (default to 100)</li>
<li><span style="font-weight: bold;">params->page</span>: the start
        page (default to 1)</li>
<li><span style="font-weight: bold;">params->tags</span>: the tag of
        photos to search (default to blank)</li>
</ul>
<br />
The following example uses "<a href="http://www.flickr.com/services/api/flickr.photos.search.html" target="_blank" title="search flickr photos">flickr.photos.search</a>"
    method to load photos with tag "<span style="font-weight: bold;">canon</span>".
    It shuffles loaded photos to randomly display photos. If you want to display
    your photo stream, you should add "<a href="http://idgettr.com/" target="_blank" title="Your Flickr id">user_id</a>"
    to <span style="font-weight: bold;">params</span> and change the method to
    "<a href="https://www.flickr.com/services/api/flickr.people.getPhotos.html" target="_blank" title="Get your photos">flickr.people.getPhotos</a>".<br /><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">'en'</span><span class="nt">&gt;</span>
 <span class="nt">&lt;head&gt;</span>
 <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">'utf-8'</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;title&gt;</span>Flickr Photo Gallery with Colorbox in jQuery<span class="nt">&lt;/title&gt;</span>
 <span class="nt">&lt;/head&gt;</span>
 <span class="nt">&lt;body&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">'container'</span><span class="nt">&gt;</span><span class="c">&lt;!-- Nothing here --&gt;</span><span class="nt">&lt;/div&gt;</span>

  <span class="c">&lt;!-- Place your script above the end of &lt;/body&gt; --&gt;</span>  
  <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">'https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'</span><span class="nt">&gt;&lt;/script&gt;</span>
  <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">'text/javascript'</span> <span class="na">src=</span><span class="s">'flickrGallery.js'</span><span class="nt">&gt;&lt;/script&gt;</span>
  <span class="nt">&lt;script&gt;</span>
   <span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">config</span><span class="o">=</span><span class="p">{</span>
     <span class="na">rows</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="c1">// total rows</span>
     <span class="na">rowHeight</span><span class="p">:</span> <span class="mi">150</span><span class="p">,</span> <span class="c1">// the height of each row</span>
     <span class="na">borderWidth</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="c1">// the width of the border</span>
     <span class="na">shuffle</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// shuffle the images</span>
     <span class="na">maxPages</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="c1">// max flickr pages to load</span>
     <span class="na">loadOnScroll</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span> <span class="c1">// load more phots when scrolling</span>
     <span class="na">cb_url</span><span class="p">:</span><span class="dl">'</span><span class="s1">url_o</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// the link for colorbox</span>
     <span class="na">params</span><span class="p">:{</span>
      <span class="na">method</span><span class="p">:</span>  <span class="dl">'</span><span class="s1">flickr.photos.search</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// flickr api method</span>
      <span class="na">api_key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ad2e1cc1d51162a8ee4ee4b022a711f4</span><span class="dl">'</span><span class="p">,</span><span class="c1">// your API key</span>
      <span class="na">per_page</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="c1">// max 500</span>
      <span class="na">page</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">// page to load</span>
      <span class="na">tags</span><span class="p">:</span> <span class="dl">'</span><span class="s1">canon</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// search tag,</span>
      <span class="na">extras</span><span class="p">:</span> <span class="dl">'</span><span class="s1">url_o</span><span class="dl">'</span> <span class="c1">// add to existing params (url_n,url_c,url_m,url_z,owner_name)</span>
     <span class="p">}</span>
    <span class="p">};</span>
    <span class="c1">// start loading the gallery</span>
    <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#container</span><span class="dl">'</span><span class="p">).</span><span class="nx">flickrGallery</span><span class="p">(</span><span class="nx">config</span><span class="p">);</span>
   <span class="p">});</span>
  <span class="nt">&lt;/script&gt;</span>
 <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span></code></pre></figure>You can see it in action at below or from <a href="http://elvishsu66.github.io/legacy/flickrGallery.html" target="_blank" title="Flickr Photo Gallery with Colorbox in jQuery">here</a>.
You can also read and study the plugin from <a href="https://raw.githubusercontent.com/elvishsu66/Blogger/master/host/flickrGallery.js" target="_blank" title="Plugin source">here</a>.<br />

<br />
<div id="images-container"></div>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript' src='/assets/js/flickrGallery.js'></script>
<script>
   var flickrConfig = {rows: 5, rowHeight: 120, borderWidth: 3};
    $(document).ready(function() {
        $('#images-container').flickrGallery(flickrConfig);
    });
</script>]]></content><author><name>Elvis Hsu</name></author><category term="Coding" /><category term="Javascript" /><summary type="html"><![CDATA[Last week I updated my Blogger site to be responsive and optimised the page load time. Whilst doing those optimisation, I was looking for a simple photo gallery to display the photos from my Flickr photo stream. I've tried flickr sideshow, pictobrowser and slideflickr however I was not satisfied with them. I then started to study the Flickr API and tried to make a Flickr-like justified layout for my photography page. While trying to code the jQuery plugin, I found two great articles by Sam from Wackylabs.net and Miro Mannino. Miro explained how the layout could be done with a detailed illustrations but I decided to use Sam's algorithm to build my own jQuery plugin. The plugin loads 5 rows when scrolling to the end of the page until photos all are loaded. If the configuration specifies more than one page, then it calls and loads next page until it reaches maximum pages. The current solution is not perfect and may affect the performance when it loads more than 800 photos. I will be working on optimising the performance to allow loading more photos. This jQuery plugin also uses Colorbox to show larger version of photos when user clicks on the photo. Okay, let me explain the configuration and how to use the plugin. However feel free to jump straight to the demo to view-source. rows: the total/initial rows to show (default to 5) rowHeight: the desired height of row (default to 150) borderWidth: the border width of each photo (default to 5) shuffle: shuffles the photo array when value is true (default to false) maxPage: the maximum flickr pages to load (default to 3) loadOnScroll: loads new photos when scrolling to page end (default to false) params->method: the Flick API method (default to 'flickr.photos.search') params->api_key: the API key which you can get it from here params->user_id: your user id for fetching your photo stream. You can get it from here params->per_page: the available photos per page from the results of API call (default to 100) params->page: the start page (default to 1) params->tags: the tag of photos to search (default to blank) The following example uses "flickr.photos.search" method to load photos with tag "canon". It shuffles loaded photos to randomly display photos. If you want to display your photo stream, you should add "user_id" to params and change the method to "flickr.people.getPhotos".]]></summary></entry><entry><title type="html">Summarising your Blogger posts</title><link href="https://www.elvishsu.com/2014/01/summarising-your-blogger-posts.html" rel="alternate" type="text/html" title="Summarising your Blogger posts" /><published>2014-01-16T18:28:00+00:00</published><updated>2014-01-16T18:28:00+00:00</updated><id>https://www.elvishsu.com/2014/01/summarising-your-blogger-posts</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/summarising-your-blogger-posts.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-16-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="Summarising your Blogger posts" border="0" src="/assets/posts/blogger/2014-01-16-image-0000.png" title="Summarising your Blogger posts" /></a></div>
I use a simple JavaScript function to summarise the posts on the home page
    of this blog. It worked quite well since the Blogger.com hasn't complained
    about it. Well, things have gotten a little bit ugly. Few days ago, I post a
    new article "<a href="http://www.elvishsu66.com/2014/01/start-your-own-mvc-framework-with-php.html" target="_blank" rel="noopener noreferrer">Start
      your own MVC Framework with PHP</a>" which is quite a long post. It
    contains code samples, descriptions and CSS code for presentation.<br />
<br />
After I published the article, I noticed that some posts on my home page
    went missing. I set the setting to display 8 posts per page for home page,
    categories, paging and search results. However the home page only displayed
    5 posts and I was not very happy about it. So I went <a href="https://productforums.google.com/forum/?hl=en#%21forum/blogger" target="_blank" rel="noopener noreferrer">Blogger
      Help Forum</a> to search for solutions. Voilà ~ The reason is that if <a href="http://www.elvishsu66.com/2014/01/start-your-own-mvc-framework-with-php.html" target="_blank" rel="noopener noreferrer">one</a>
    or more of your recent posts is/are too long/big, Blogger.com will cut down
    the number of the posts to display. The main reason is to enhance the
    loading speed. Well, fair enough but what should I do now? Divide the post
    to two or three parts? Mate, I'm not going to do it. So what then? It must
    be a way to fix it. So I started to search any possible solutions on Google
    again and found the term "<a href="https://support.google.com/blogger/answer/154172?hl=en" target="_blank" rel="noopener noreferrer">Jump
      Break</a>".<br />
<a name='more'></a><br />
What does <span style="font-weight: bold;">Jump Break</span> do? When you
    click the <i style="font-weight: bold;">Jump Break</i> icon on the
    Blogger's editor, it inserts a "<span style="color: red;"><!--more--><br /></span>"
    Html comment at the place where you want to break the content. So basically
    when the <b><a href="http://www.bloggersentral.com/2010/08/targeting-specific-pages-with.html" target="_blank" rel="noopener noreferrer">data:blog.pageType</a></b>
    is not "<b>item</b>", the server only dispatch the post content up to that
    point. If you want to know more about it, you can have a look at <a href="http://mumsmakelists.blogspot.ch/2013/06/customize-jump-break.html" target="_blank" rel="noopener noreferrer">this
      tutorial</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-16-image-0001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-01-16-image-0001.png" /></a></div>
<br />
Usually I compose the articles with <a href="http://en.wikipedia.org/wiki/WYSIWYG" target="_blank" rel="noopener noreferrer">WYSIWYG</a>
    html editors (<a href="http://bluegriffon.org/" target="_blank" rel="noopener noreferrer">BlueGriffon</a>&nbsp;or
    <a href="http://www.kompozer.net/" target="_blank" rel="noopener noreferrer">Kompozer</a>&nbsp;) on my
    computer. When the article is completed, I copy the Html code and paste it
    on the Blogger's editor and then publish it. That is probably the reason I
    didn't notice the feature of Blogger's editor.<br />
<br />
I also use a simple function with JavaScript to summarise the "<span style="font-weight: bold;">jump
      broken</span>" post content and display the first image of the post. It
    gives me power to control the summary of the post body. So how do I do it?<br />
<br />
First of all, you need to <a href="https://support.google.com/blogger/answer/46870?hl=en" target="_blank" rel="noopener noreferrer">edit
      the Html code</a> of your template. If you don't feel confident to do
    this, but you are willing to try. You should <a href="https://support.google.com/blogger/answer/97416?hl=en" target="_top">backup</a>
    your template before changing anything in your template.<br />
<h6>
Step 1:</h6>
<ol>
<li>When you are in the <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMAnJTncTXReApDQWQ8y_i6xW1GFkr4-bncF2WPnVQcIQlwphYLGXPRIE7ss2zxiIe9uehbys4D9unWhckUaVUPfZeR-Divpw-nqVnw2_Md17fOoW3Nu1yqBQSiLM25H_PJpv8AM3T10Gc/s1600/post-image-02.png" target="_blank" rel="noopener noreferrer">template
          Html editor</a>, focus your cursor in the code area. </li>
<li>Press <span style="font-weight: bold;">Ctrl + F</span> or <span style="font-weight: bold;">Command
          + F</span> if you are using OSX. This should bring up a little search
        box at <span style="font-style: italic; font-weight: bold;">right top</span>
        of the editor. </li>
<li>Type <span style="color: red;"></head></span> in the search box
        and press <span style="font-style: italic; font-weight: bold;">enter</span>,
        the editor should bring you to that part of the code and highlight it. </li>
<li>Now you <span style="font-weight: bold;">copy</span> the code below
        and <span style="font-weight: bold;">paste</span> it above the <span style="color: red;"></head></span>
        tag.</li>
</ol>
<figure class="highlight"><pre><code class="language-js" data-lang="js">    <span class="o">&lt;</span><span class="nx">script</span> <span class="nx">src</span><span class="o">=</span><span class="dl">'</span><span class="s1">//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js</span><span class="dl">'</span><span class="o">/&gt;</span>
    <span class="o">&lt;</span><span class="nx">script</span> <span class="nx">language</span><span class="o">=</span><span class="dl">'</span><span class="s1">javascript</span><span class="dl">'</span><span class="o">&gt;</span>
     <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">){</span>
        <span class="cm">/**
         * Summarise the post content
         */</span>
        <span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">summariseContent</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">url</span><span class="p">){</span>
          <span class="kd">var</span> <span class="nx">summary_noimg</span> <span class="o">=</span> <span class="mi">650</span><span class="p">;</span>
          <span class="kd">var</span> <span class="nx">summary_img</span> <span class="o">=</span> <span class="mi">450</span><span class="p">;</span>
          <span class="kd">var</span> <span class="nx">img_thumb_height</span> <span class="o">=</span> <span class="mi">150</span><span class="p">;</span>
          <span class="kd">var</span> <span class="nx">img_thumb_width</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span>
          <span class="kd">var</span> <span class="nx">block</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">#</span><span class="dl">"</span><span class="o">+</span><span class="nx">id</span><span class="p">);</span>
          <span class="kd">var</span> <span class="nx">imgtag</span> <span class="o">=</span> <span class="dl">""</span><span class="p">;</span>
          <span class="kd">var</span> <span class="nx">imgs</span> <span class="o">=</span> <span class="nx">block</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="dl">'</span><span class="s1">img</span><span class="dl">'</span><span class="p">);</span>
          <span class="kd">var</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">summary_noimg</span><span class="p">;</span>
          <span class="k">if</span><span class="p">(</span><span class="nx">imgs</span><span class="p">.</span><span class="nx">length</span><span class="o">&gt;=</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> 
            <span class="nx">imgtag</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">&lt;span style="float: left; padding: 0px 10px 5px 0px;"&gt;</span><span class="dl">'</span> <span class="o">+</span> 
                     <span class="dl">'</span><span class="s1">&lt;a href="</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">url</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">"&gt;</span><span class="dl">'</span> <span class="o">+</span>
                     <span class="dl">'</span><span class="s1">&lt;img src="</span><span class="dl">'</span><span class="o">+</span><span class="nx">imgs</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">src</span><span class="o">+</span><span class="dl">'</span><span class="s1">" style="background:#fff;padding:3px;border:1px solid #eee;width:</span><span class="dl">'</span><span class="o">+</span><span class="nx">img_thumb_width</span><span class="o">+</span><span class="dl">'</span><span class="s1">px;height:</span><span class="dl">'</span><span class="o">+</span><span class="nx">img_thumb_height</span><span class="o">+</span><span class="dl">'</span><span class="s1">px;" /&gt;</span><span class="dl">'</span><span class="o">+</span>
                     <span class="dl">'</span><span class="s1">&lt;/a&gt;</span><span class="dl">'</span> <span class="o">+</span>
                     <span class="dl">'</span><span class="s1">&lt;/span&gt;</span><span class="dl">'</span><span class="p">;</span>
            <span class="nx">len</span> <span class="o">=</span> <span class="nx">summary_img</span><span class="p">;</span>
          <span class="p">};</span>
          <span class="kd">var</span> <span class="nx">text</span> <span class="o">=</span> <span class="nx">block</span><span class="p">.</span><span class="nx">text</span><span class="p">().</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">len</span><span class="p">);</span>
          <span class="kd">var</span> <span class="nx">summary</span> <span class="o">=</span> <span class="nx">imgtag</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">&lt;div&gt;</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">$</span><span class="p">.</span><span class="nx">trim</span><span class="p">(</span><span class="nx">text</span><span class="p">)</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> [...]&lt;/div&gt;</span><span class="dl">'</span><span class="p">;</span>
          <span class="nx">block</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nx">summary</span><span class="p">);</span>    
        <span class="p">};</span>
      <span class="p">})(</span><span class="nx">jQuery</span><span class="p">);</span>
      <span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>    </code></pre></figure>

<h6>
 Step 2:</h6>
This step is pretty difficult since each template places the post body at
    different places of the code. Sometimes it appears at the part for mobile
    layout. You will need to test and find out where the actual post body (<span style="font-weight: bold;"><data:post.body/></span>)
    located. Normally it should appears one or two times when you search the key
    word "<span style="color: red; font-weight: bold;">expr:id='&amp;quot;post-body-&amp;quot;
      + data:post.id</span>". Once you have found it, then place the code below
    after <span style="font-weight: bold;"></div></span> tag where "<span style="color: red; font-weight: bold;">expr:id='&amp;quot;post-body-&amp;quot;
      + data:post.id</span>" belongs to. And then replace "<span style="color: #000066; font-weight: bold;">expr:id='&amp;quot;<span style="color: red;">post-body</span>-&amp;quot;
      + data:post.id</span>" to "<span style="color: #000066; font-weight: bold;">expr:id='&amp;quot;<span style="color: red;">summary</span>-&amp;quot;
      + data:post.id</span>" to make it unique.<br />

      
<figure class="highlight"><pre><code class="language-js" data-lang="js">  
      <span class="o">&lt;</span><span class="nx">script</span> <span class="nx">type</span><span class="o">=</span><span class="dl">'</span><span class="s1">text/javascript</span><span class="dl">'</span><span class="o">&gt;</span>
        <span class="nx">$</span><span class="p">().</span><span class="nx">summariseContent</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="nx">quote</span><span class="p">;</span><span class="nx">summary</span><span class="o">-&lt;</span><span class="nx">data</span><span class="p">:</span><span class="nx">post</span><span class="p">.</span><span class="nx">id</span><span class="o">/&gt;&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="nx">quote</span><span class="p">;,</span><span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="nx">quote</span><span class="p">;</span><span class="o">&lt;</span><span class="nx">data</span><span class="p">:</span><span class="nx">post</span><span class="p">.</span><span class="nx">url</span><span class="o">/&gt;&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="nx">quote</span><span class="p">;);</span>
      <span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>    </code></pre></figure>

<br />
This is my version which may give you a idea how it should look like. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-16-image-0002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-01-16-image-0002.png" /></a></div>
<br />
When the code is placed, then save the template and reload your home page of
    your blog. Remember that you may need to test few more times until you find
    the right <span style="font-weight: bold;"><data:post.body/></span>
    you want. <br />
<br />
I uses the summarise function and jump break together. The jump break
    feature cuts down the size of post body at home, searchs and categories
    pages. The summarise function helps me to reorganise it. I just need to be
    sure that first image falls before the jump break point in order to display
    it on each summarised post. <br />
<br />
If you enjoy this article, please leave a like or a plus and let me know
    your thoughts in the comments.]]></content><author><name>Elvis Hsu</name></author><category term="Blogger" /><category term="Javascript" /><category term="Tips" /><summary type="html"><![CDATA[I use a simple JavaScript function to summarise the posts on the home page of this blog. It worked quite well since the Blogger.com hasn't complained about it. Well, things have gotten a little bit ugly. Few days ago, I post a new article "Start your own MVC Framework with PHP" which is quite a long post. It contains code samples, descriptions and CSS code for presentation. After I published the article, I noticed that some posts on my home page went missing. I set the setting to display 8 posts per page for home page, categories, paging and search results. However the home page only displayed 5 posts and I was not very happy about it. So I went Blogger Help Forum to search for solutions. Voilà ~ The reason is that if one or more of your recent posts is/are too long/big, Blogger.com will cut down the number of the posts to display. The main reason is to enhance the loading speed. Well, fair enough but what should I do now? Divide the post to two or three parts? Mate, I'm not going to do it. So what then? It must be a way to fix it. So I started to search any possible solutions on Google again and found the term "Jump Break". What does Jump Break do? When you click the Jump Break icon on the Blogger's editor, it inserts a "" Html comment at the place where you want to break the content. So basically when the data:blog.pageType is not "item", the server only dispatch the post content up to that point. If you want to know more about it, you can have a look at this tutorial. Usually I compose the articles with WYSIWYG html editors (BlueGriffon&nbsp;or Kompozer&nbsp;) on my computer. When the article is completed, I copy the Html code and paste it on the Blogger's editor and then publish it. That is probably the reason I didn't notice the feature of Blogger's editor. I also use a simple function with JavaScript to summarise the "jump broken" post content and display the first image of the post. It gives me power to control the summary of the post body. So how do I do it? First of all, you need to edit the Html code of your template. If you don't feel confident to do this, but you are willing to try. You should backup your template before changing anything in your template. Step 1: When you are in the template Html editor, focus your cursor in the code area. Press Ctrl + F or Command + F if you are using OSX. This should bring up a little search box at right top of the editor. Type in the search box and press enter, the editor should bring you to that part of the code and highlight it. Now you copy the code below and paste it above the tag. &lt;script src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'/&gt; &lt;script language='javascript'&gt; (function($){ /** * Summarise the post content */ $.fn.summariseContent = function(id, url){ var summary_noimg = 650; var summary_img = 450; var img_thumb_height = 150; var img_thumb_width = 200; var block = $("#"+id); var imgtag = ""; var imgs = block.find('img'); var len = summary_noimg; if(imgs.length&gt;=1) { imgtag = '&lt;span style="float: left; padding: 0px 10px 5px 0px;"&gt;' + '&lt;a href="' + url + '"&gt;' + '&lt;img src="'+imgs[0].src+'" style="background:#fff;padding:3px;border:1px solid #eee;width:'+img_thumb_width+'px;height:'+img_thumb_height+'px;" /&gt;'+ '&lt;/a&gt;' + '&lt;/span&gt;'; len = summary_img; }; var text = block.text().substring(0, len); var summary = imgtag + '&lt;div&gt;' + $.trim(text) + ' [...]&lt;/div&gt;'; block.html(summary); }; })(jQuery); &lt;/script&gt;]]></summary></entry><entry><title type="html">Start your own MVC Framework with PHP</title><link href="https://www.elvishsu.com/2014/01/start-your-own-mvc-framework-with-php.html" rel="alternate" type="text/html" title="Start your own MVC Framework with PHP" /><published>2014-01-14T19:51:00+00:00</published><updated>2014-01-14T19:51:00+00:00</updated><id>https://www.elvishsu.com/2014/01/start-your-own-mvc-framework-with-php</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/start-your-own-mvc-framework-with-php.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-14-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="/assets/posts/blogger/2014-01-14-image-0000.png" title="Start your own MVC Framework with PHP" alt="Start your own MVC Framework with PHP"/></a></div>
I have been using ASP .NET MVC for many years. It is a complex framework but
    not difficult to learn (at least for .NET developers). Anyway, I like the
    way it handles templates and routing. Few years ago, one of my clients asked
    me to developed a simple ERP system with PHP and MySQL. My first thought
    was: "Why not developing a simple MVC framework with PHP?". It would allow
    me to utilise the backend code and avoid mixing code in classes.<br />
<br />
I started to study many PHP MVC Frameworks such as <a href="http://framework.zend.com/" target="_blank" rel="noopener noreferrer">Zend
      Framework</a>, <a href="http://symfony.com/" target="_blank" rel="noopener noreferrer">Symfony</a>
    and <a href="http://cakephp.org/" target="_blank" rel="noopener noreferrer">CakePHP</a> but I
    realised those "<span style="font-style: italic; font-weight: bold;">ready-to-use</span>"
    frameworks are overkilled for this simple project and I would like to have
    codes that I could manipulate easily and apply them to next simple projects
    without making my brand hurts. <br />
<a name='more'></a><br />
Luckily, I found this article: <a href="http://anantgarg.com/2009/03/13/write-your-own-php-mvc-framework-part-1/" target="_blank" rel="noopener noreferrer">Write
      your own PHP MVC Framework</a>. It is a very good article and it explained
    the concept of MVC comprehensively. If you just start learning MVC, this is
    a great place start. Well, the truth is the article inspired me to create my
    own little MVC framework with PHP.<br />
<br />
Anyway, before you continue reading, I recommend you to read through the
    article I mentioned <a href="http://anantgarg.com/2009/03/13/write-your-own-php-mvc-framework-part-1/" target="_blank" rel="noopener noreferrer">above</a>.
    My version of MVC is a little bit different from Anant Garg's but I believe you will find it useful.<br />
<br />
In this article, I would like to focus on the routing and template operations. Since Anant Garg has covered most important parts of MVC, I will just point out some features of my own framework in this article.<br />
<br />
Before we start talking about the details, let's have a look at the
    directory structure. You can expand the folder below and link to sample
    codes of this article. The structure is pretty much the same as
    Anant Garg's. The only difference is that I put all public assessable files (images, style
    sheets and js scripts) into public folder.
<br />
<style>
        .filepath{
          color:red;
        }
        /* CSS Tree menu styles */
        input, select, textarea, th, td { font-size: 1em; }
        ul.tree {
          padding: 0 0 0 30px;
          width: 300px;
        }
        ul.tree li {
          position: relative;
          margin-left: -15px;
          list-style: none;
        }
        ul.tree li.file {
          margin-left: -1px !important;
          background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy4k1ZDHcMbgVgYvJAA6tBSrWqsS7PW81ohLj9m_DTO5tYTD1FiAOapjOv6wbAgns1RuMCrvWbHxtDKRCN1cBw8ndirJyUXX3L1lC-BSsA_myaznf5RnhN653GS9v35oFFDuXppicRBFo/s1600/document.png) 0 0 no-repeat;
          padding-left: 21px;
        }        
        ul.tree li input {
          position: absolute;
          left: 0;
          margin-left: 0;
          opacity: 0;
          z-index: 2;
          cursor: pointer;
          height: 1em;
          width: 1em;
          top: 0;
        }
        ul.tree li input + ul {
          background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiia-XI9AJe5Vv52MJ_bDYrx5UCo5a51Zdi0Q0ax773BcEZzI61L_dDwC21T9vZCUbXF4HoNe5DwHS8BkWPipGegtWIG48VFvu7VeYn-FglaKt6A7FSbWWNJE6kvVRj05wC4yNs_IHcT1s/s1600/toggle-small-expand.png) 40px 0 no-repeat;
          margin: -17px 0 0 -44px; /* 15px */
          height: 1em;
        }        
        ul.tree li input + ul > li { 
          display: none; 
          margin-left: -14px !important; 
          padding-left: 1px; 
        }
        ul.tree li label {
          background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqxbFCB91yAQD2SZU596Kuuact18CGvOwt4nfulTwRHjZpssiQBTjwSLjaFn2ybXNwczXBQLQ6FYHt8OEKsf6SY72awQKoKtD1PzWZY9O31uqSc8ByIrrfblvjJZjUlmmz2i2Ruwhg4N4/s1600/folder.png) 15px 1px no-repeat;
          cursor: pointer;
          display: block;
          padding-left: 37px;
          border:none;
        }        
        ul.tree li input:checked + ul {
          background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK_R4u9lNR0vgtNtGkwSM-PvTpBwqg9Md6mBL37IbaFRrZEdBGPUmzyxGjIrwPQSNQQlDVce6cLHB8sij4y_AWHMtYkuItg5fpGCmdIDLJDhDSY9nhf11eKz0TwPJOVvBhShSFtcGdQ-U/s1600/toggle-small.png) 40px 5px no-repeat;
          margin: -22px 0 0 -44px; /* 20px */
          padding: 1.563em 0 0 80px;
          height: auto;
        }
        ul.tree li input:checked + ul > li { 
          display: block; 
          margin: 0 0 0.125em; /* 2px */
        }
        ul.tree li input:checked + ul > li:last-child { 
          margin: 0 0 0.063em; /* 1px */ 
        }</style><br />
<div style="background-color: #ffffcc; border: 1px dashed rgb(0, 0, 0); padding: 10px; width: 330px;">
<ul class="tree">
<li><label for="root">htdocs</label><input checked="checked" id="root" type="checkbox" />
          <ul>
<li><label for="app">application</label><input id="app" type="checkbox" />
              <ul>
<li><label for="ctrl">controllers</label> <input id="ctrl" type="checkbox" />
                  <ul>
<li class="file"><a href="#download">blogController.php</a></li>
</ul>
</li>
<li><label for="models">models</label> <input id="models" type="checkbox" />
                  <ul>
<li class="file"><a href="#download">blogModel.php</a></li>
</ul>
</li>
<li><label for="views">views</label> <input id="views" type="checkbox" />
                  <ul>
<li><label for="index">index</label> <input id="index" type="checkbox" />
                      <ul>
<li class="file"><a href="#application-view-index-index.php">index.php</a></li>
</ul>
</li>
<li><label for="blog">blog</label> <input id="blog" type="checkbox" />
                      <ul>
<li class="file">index.php</li>
<li class="file">detail.php</li>
<li class="file">create.php</li>
<li class="file">update.php</li>
<li class="file">delete.php</li>
</ul>
</li>
<li><label for="about">about</label> <input id="about" type="checkbox" />
                      <ul>
<li class="file">index.php</li>
</ul>
</li>
<li><label for="shared">shared</label> <input id="shared" type="checkbox" />
                      <ul>
<li class="file"><a href="#application-view-shared-_defaultLayout.php">_defaultLayout.php.php</a></li>
</ul>
</li>
</ul>
</li>
<li class="file">.htaccess</li>
</ul>
</li>
<li><label for="config">config</label> <input id="config" type="checkbox" />
              <ul>
<li class="file">config.php</li>
<li class="file">.htaccess</li>
</ul>
</li>
<li><label for="lib">library</label> <input id="lib" type="checkbox" />
              <ul>
<li><label for="core">core</label> <input id="core" type="checkbox" />
                  <ul>
<li class="file">MyHelper.class.php</li>
<li class="file">MySqlDataAdapter.class.php</li>
</ul>
</li>
<li><label for="mvc">mvc</label> <input id="mvc" type="checkbox" />
                  <ul>
<li class="file"><a href="#library-mvc-Controller.class.php">Controller.class.php</a></li>
<li class="file"><a href="#library-mvc-Model.class.php">Model.class.php</a></li>
<li class="file"><a href="#library-mvc-Router.class.php">Router.class.php</a></li>
<li class="file"><a href="#library-mvc-Template.class.php">Template.class.php</a></li>
</ul>
</li>
<li class="file"><a href="#library-bootstrap.php">bootstrap.php</a></li>
<li class="file">.htaccess</li>
</ul>
</li>
<li><label for="public">public</label> <input id="public" type="checkbox" />
              <ul>
<li><label for="scripts">scripts</label> <input id="scripts" type="checkbox" />
                  <ul>
<li class="file">your-js-files.js</li>
</ul>
</li>
<li><label for="images">images</label> <input id="images" type="checkbox" />
                  <ul>
<li class="file">your-images.png</li>
</ul>
</li>
<li><label for="themes">themes</label> <input id="themes" type="checkbox" />
                  <ul>
<li class="file">your-css-styles.css</li>
</ul>
</li>
<li class="file"><a href="#public-index.php">index.php</a></li>
<li class="file"><a href="#public-.htaccess">.htaccess</a></li>
</ul>
</li>
<li class="file"><a href="#htdocs.htaccess">.htaccess</a></li>
</ul>
</li>
</ul>
</div>
<br />
<h3>
Apache mode_rewrite module</h3>
Routing plays an important role in MVC framework since it translate your URL
    to match your controllers and actions. When any Http request pass to your
    site, it will go to <span style="font-weight: bold;">htdocs/.htaccess</span>
    first. Then we parse the URL and redirect the request to <span style="font-weight: bold;">htdocs/public</span>
    folder. In fact, we only have a <span style="font-weight: bold;">single</span>
    entry point since every request will be going to <span style="font-weight: bold;">htdocs/public</span>
    folder and waiting for next process.<br />
<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="htdocs.htaccess">htdocs/.htaccess</a> <br />
<figure class="highlight"><pre><code class="language-js" data-lang="js">  
      <span class="nx">Options</span> <span class="o">+</span><span class="nx">FollowSymLinks</span>
      <span class="o">&lt;</span><span class="nx">ifmodule</span> <span class="nx">mod_rewrite</span><span class="p">.</span><span class="nx">c</span><span class="o">=</span><span class="dl">""</span><span class="o">&gt;</span>         
          <span class="err">#</span> <span class="nx">Tell</span> <span class="nx">PHP</span> <span class="nx">that</span> <span class="nx">the</span> <span class="nx">mod_rewrite</span> <span class="nx">module</span> <span class="nx">is</span> <span class="nx">ENABLED</span><span class="p">.</span>
          <span class="nx">SetEnv</span> <span class="nx">HTTP_MOD_REWRITE</span> <span class="nx">On</span>
          <span class="nx">RewriteEngine</span> <span class="nx">on</span>
          <span class="nx">RewriteRule</span> <span class="o">^</span><span class="nx">$</span>   <span class="kr">public</span><span class="o">/</span>    <span class="p">[</span><span class="nx">L</span><span class="p">]</span>    
          <span class="nx">RewriteRule</span> <span class="p">(.</span><span class="o">*</span><span class="p">)</span> <span class="kr">public</span><span class="o">/</span><span class="nx">$1</span>  <span class="p">[</span><span class="nx">L</span><span class="p">]</span>
      <span class="o">&lt;</span><span class="sr">/ifmodule</span><span class="err">&gt;
</span>    </code></pre></figure>

<br />
In the root of the public folder, we have another <span style="font-weight: bold;">.htaccess</span>
    waiting for us to process the requests (sample below). We put every public
    accessible files into the public folder, so it is much easier to organise
    them in the future. If the requests are <span style="font-style: italic; font-weight: bold;">images</span>,
    <span style="font-style: italic; font-weight: bold;">videos, style sheets</span>
    or <span style="font-style: italic; font-weight: bold;">script files</span>,
    then we just feed them to clients directly. If the request is the actual
    page, then we parse the URL and let the <span style="font-weight: bold;">/public/index.php</span>
    to handle the rest of actions. The actual URL and query strings are assigned
    to <span style="font-weight: bold;">_route</span> variable.<br />
<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="public-.htaccess">/public/.htaccess</a> <br />
<figure class="highlight"><pre><code class="language-js" data-lang="js">      
        <span class="nx">Options</span> <span class="o">+</span><span class="nx">FollowSymLinks</span>
        <span class="o">&lt;</span><span class="nx">ifmodule</span> <span class="nx">mod_rewrite</span><span class="p">.</span><span class="nx">c</span><span class="o">=</span><span class="dl">""</span><span class="o">&gt;</span>
          <span class="err">#</span> <span class="nx">Tell</span> <span class="nx">PHP</span> <span class="nx">that</span> <span class="nx">the</span> <span class="nx">mod_rewrite</span> <span class="nx">module</span> <span class="nx">is</span> <span class="nx">ENABLED</span><span class="p">.</span>
          <span class="nx">SetEnv</span> <span class="nx">HTTP_MOD_REWRITE</span> <span class="nx">On</span>
          <span class="nx">RewriteEngine</span> <span class="nx">On</span>
          <span class="nx">RewriteCond</span> <span class="o">%</span><span class="p">{</span><span class="nx">REQUEST_FILENAME</span><span class="p">}</span> <span class="o">!-</span><span class="nx">f</span>
          <span class="nx">RewriteCond</span> <span class="o">%</span><span class="p">{</span><span class="nx">REQUEST_FILENAME</span><span class="p">}</span> <span class="o">!-</span><span class="nx">d</span>
          <span class="nx">RewriteRule</span> <span class="o">^</span><span class="p">(.</span><span class="o">*</span><span class="p">)</span><span class="nx">$</span> <span class="nx">index</span><span class="p">.</span><span class="nx">php</span><span class="p">?</span><span class="nx">_route</span><span class="o">=</span><span class="nx">$1</span><span class="p">?</span><span class="o">%</span><span class="p">{</span><span class="nx">QUERY_STRING</span><span class="p">}</span> <span class="p">[</span><span class="nx">PT</span><span class="p">,</span><span class="nx">L</span><span class="p">]</span>
        <span class="o">&lt;</span><span class="sr">/ifmodule</span><span class="err">&gt;
</span>    </code></pre></figure>

<br />
Once we have an actual page request, then our MVC bootstrap process starts
    from here. The only difference here between Anant Garg's code is we need to
    get the original query strings since PHP parses the query string to be part
    of URL entity.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="public-index.php">/public/index.php</a> <br />
<figure class="highlight"><pre><code class="language-php" data-lang="php">  
      <span class="cp">&lt;?php</span>
        <span class="c1">// Ensure we have session</span>
        <span class="k">if</span><span class="p">(</span><span class="nb">session_id</span><span class="p">()</span> <span class="o">===</span> <span class="s2">""</span><span class="p">){</span>
            <span class="nb">session_start</span><span class="p">();</span>
        <span class="p">}</span>
        
        <span class="c1">// define the directory separator</span>
        <span class="nb">define</span><span class="p">(</span><span class="s1">'DS'</span><span class="p">,</span> <span class="no">DIRECTORY_SEPARATOR</span><span class="p">);</span>
        <span class="c1">// define the application path</span>
        <span class="nb">define</span><span class="p">(</span><span class="s1">'ROOT'</span><span class="p">,</span> <span class="nb">dirname</span><span class="p">(</span><span class="nb">dirname</span><span class="p">(</span><span class="k">__FILE__</span><span class="p">)));</span>

        <span class="c1">// the routing url, we need to use original 'QUERY_STRING' from server paramater because php has parsed the url if we use $_GET</span>
        <span class="nv">$_route</span> <span class="o">=</span> <span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'_route'</span><span class="p">])</span> <span class="o">?</span> <span class="nb">preg_replace</span><span class="p">(</span><span class="s1">'/^_route=(.*)/'</span><span class="p">,</span><span class="s1">'$1'</span><span class="p">,</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'QUERY_STRING'</span><span class="p">])</span> <span class="o">:</span> <span class="s1">''</span><span class="p">;</span>
        
        <span class="c1">// start to dispatch</span>
        <span class="k">require_once</span> <span class="p">(</span><span class="no">ROOT</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'library'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'bootstrap.php'</span><span class="p">);</span>
    </code></pre></figure>

<br />
<h3>
Bootstrap</h3>
Basically, this part does not have big differences between Anant Garg's
    concept. The differences are:<br />
<ul>
<li>I included a <span style="font-weight: bold;">config.php</span> file
        to serve configuration parameters such as site name and title</li>
<li>I use <a href="http://www.php.net/manual/en/function.spl-autoload-register.php" target="_blank" rel="noopener noreferrer">spl_autoload_register</a>
        instead of <a href="http://www.php.net/manual/en/function.autoload.php" target="_blank" rel="noopener noreferrer">__autoload</a>
        (Please refer this <a href="http://stackoverflow.com/questions/6894538/php-spl-autoload-register-vs-autoload" target="_blank" rel="noopener noreferrer">discussion</a>)</li>
<li>I wrapped the "<span style="font-weight: bold;">removeMagicQuotes</span>"
        and "<span style="font-weight: bold;">unregisterGlobals</span>"
        functions to <span style="font-weight: bold;"> MyHelpers</span> class</li>
<li> I use use the <span style="font-weight: bold;">Router</span> class
        to handle further operations and dispatch the outputs</li>
<li> I call <a href="http://php.net/manual/en/function.session-write-close.php" target="_blank" rel="noopener noreferrer">session_write_close</a>
        and the end of the operation to unlock the session data. This is useful
        when you have many concurrent connections such as using Ajax operations.</li>
</ul>
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="library-bootstrap.php">/library/bootstrap.php</a>
    <br />

<figure class="highlight"><pre><code class="language-php" data-lang="php">    <span class="cp">&lt;?php</span> 
        <span class="c1">// Ensure we have session</span>
        <span class="k">if</span><span class="p">(</span><span class="nb">session_id</span><span class="p">()</span> <span class="o">===</span> <span class="s2">""</span><span class="p">){</span>
            <span class="nb">session_start</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="c1">// the config file path</span>
        <span class="nv">$path</span> <span class="o">=</span> <span class="no">ROOT</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'config'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'config.php'</span><span class="p">;</span>
        
        <span class="c1">// include the config settings</span>
        <span class="k">require_once</span> <span class="p">(</span><span class="nv">$path</span><span class="p">);</span>
        
        <span class="c1">// Autoload any classes that are required</span>
        <span class="nb">spl_autoload_register</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$className</span><span class="p">)</span> <span class="p">{</span>
        
            <span class="c1">//$className = strtolower($className);</span>
            <span class="nv">$rootPath</span> <span class="o">=</span> <span class="no">ROOT</span> <span class="mf">.</span> <span class="no">DS</span><span class="p">;</span>
            <span class="nv">$valid</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
           
            <span class="c1">// check root directory of library</span>
            <span class="nv">$valid</span> <span class="o">=</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$classFile</span> <span class="o">=</span> <span class="nv">$rootPath</span> <span class="mf">.</span> <span class="s1">'library'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$className</span> <span class="mf">.</span> <span class="s1">'.class.php'</span><span class="p">);</span>
            
            <span class="c1">// if we cannot find any, then find library/core directory</span>
            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$valid</span><span class="p">){</span>
                <span class="nv">$valid</span> <span class="o">=</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$classFile</span> <span class="o">=</span> <span class="nv">$rootPath</span> <span class="mf">.</span> <span class="s1">'library'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'core'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$className</span> <span class="mf">.</span> <span class="s1">'.class.php'</span><span class="p">);</span>    
            <span class="p">}</span>
            <span class="c1">// if we cannot find any, then find library/mvc directory</span>
            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$valid</span><span class="p">){</span>
                <span class="nv">$valid</span> <span class="o">=</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$classFile</span> <span class="o">=</span> <span class="nv">$rootPath</span> <span class="mf">.</span> <span class="s1">'library'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'mvc'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$className</span> <span class="mf">.</span> <span class="s1">'.class.php'</span><span class="p">);</span>
            <span class="p">}</span>     
            <span class="c1">// if we cannot find any, then find application/controllers directory</span>
            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$valid</span><span class="p">){</span>
                <span class="nv">$valid</span> <span class="o">=</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$classFile</span> <span class="o">=</span> <span class="nv">$rootPath</span> <span class="mf">.</span> <span class="s1">'application'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'controllers'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$className</span> <span class="mf">.</span> <span class="s1">'.php'</span><span class="p">);</span>
            <span class="p">}</span> 
            <span class="c1">// if we cannot find any, then find application/models directory</span>
            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$valid</span><span class="p">){</span>
                <span class="nv">$valid</span> <span class="o">=</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$classFile</span> <span class="o">=</span> <span class="nv">$rootPath</span> <span class="mf">.</span> <span class="s1">'application'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="s1">'models'</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$className</span> <span class="mf">.</span> <span class="s1">'.php'</span><span class="p">);</span>
            <span class="p">}</span>  
          
            <span class="c1">// if we have valid fild, then include it</span>
            <span class="k">if</span><span class="p">(</span><span class="nv">$valid</span><span class="p">){</span>
               <span class="k">require_once</span><span class="p">(</span><span class="nv">$classFile</span><span class="p">);</span> 
            <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                <span class="cm">/* Error Generation Code Here */</span>
            <span class="p">}</span>    
        <span class="p">});</span>
        
        
        <span class="c1">// remove the magic quotes</span>
        <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">removeMagicQuotes</span><span class="p">();</span>
        
        <span class="c1">// unregister globals</span>
        <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">unregisterGlobals</span><span class="p">();</span>
        
        <span class="c1">// register route</span>
        <span class="nv">$router</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Router</span><span class="p">(</span><span class="nv">$_route</span><span class="p">);</span>
        
        <span class="c1">// finaly we dispatch the output</span>
        <span class="nv">$router</span><span class="o">-&gt;</span><span class="nf">dispatch</span><span class="p">();</span>
        
        <span class="c1">// close session to speed up the concurrent connections</span>
        <span class="c1">// http://php.net/manual/en/function.session-write-close.php</span>
        <span class="nb">session_write_close</span><span class="p">();</span>
      </code></pre></figure>

<br />
<h3>
The Router (Router.class.php)</h3>
The Router class plays an important role in our framework. It translates the
    controllers, actions for further process. When the <span style="font-weight: bold;">Router::dispatch</span>
    method is called, it starts parsing the <span style="font-weight: bold;">_route</span>
    value first. After we found what controller and action are, then we process
    the request and dispatch the results to the clients.<br />
<br />
We uses regular expression match by <a href="http://ch1.php.net/preg_match" target="_blank" rel="noopener noreferrer">preg_match</a>
    method to parse our routing patterns. If you have other patterns, you can
    simply add more test patterns to the code (<span style="font-style: italic;">Line
      25 - 29</span>).<br />
<br />
After we found out what controller and action are, we start to parse our
    query string. This step is necessary since PHP has parsed the query string
    to URL formated string (<span style="font-style: italic;">Line 54 - 68</span>).<br />
<br />
After we got our query string, then we need to determine which request
    method has client sent in order to retrieve our parameters. This part
    supports <a href="http://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank" rel="noopener noreferrer">RESTful</a>
    and standard Http requests (<span style="font-style: italic;">Line 71 - 104</span>).
    Since I use <a href="http://en.wikipedia.org/wiki/Representational_state_transfer#Concept" target="_blank" rel="noopener noreferrer">RESTful</a>
    data store from <a href="http://docs.sencha.com/extjs/4.2.2/#%21/api/Ext.data.proxy.Rest" target="_blank" rel="noopener noreferrer">ExtJs</a>
    a lot, therefore I included in the Router class.<br />
<br />
The parameters may not include the "<span style="font-weight: bold;">id</span>",
    therefore we need to put "<span style="font-weight: bold;">id</span>" value
    to our parameters array.<br />
<br />
We start to validate the existence of controller class, model class and
    action method. If all of them exist, then we try to match the action
    method's arguments with requested parameters. We then use <a href="http://ch1.php.net/call_user_func_array" target="_blank" rel="noopener noreferrer">call_user_func_array</a>
    to call the action method with filtered parameters (<span style="font-style: italic;">Line
      120 - 152</span>). <br />
<br />
The last action would be deliver the results to the clients which you can
    see at <span style="font-style: italic;">Line 155</span>. The <span style="font-weight: bold;">$this->_view</span>
    value is actually the result from the Template.class.php.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="library-mvc-Router.class.php">/library/mvc/Router.class.php</a>
    <br />

<figure class="highlight"><pre><code class="language-php" data-lang="php">    <span class="cp">&lt;?php</span>
    <span class="kd">class</span> <span class="nc">Router</span>
    <span class="p">{</span>
      <span class="k">protected</span> <span class="nv">$_controller</span><span class="p">,</span>
                <span class="nv">$_action</span><span class="p">,</span>
                <span class="nv">$_view</span><span class="p">,</span>
                <span class="nv">$_params</span><span class="p">,</span>
                <span class="nv">$_route</span><span class="p">;</span>
            
      <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$_route</span><span class="p">){</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_route</span> <span class="o">=</span> <span class="nv">$_route</span><span class="p">;</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="s1">'Controller'</span><span class="p">;</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="s1">'index'</span><span class="p">;</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> 
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_view</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> <span class="c1">// the initial view</span>
      <span class="p">}</span>
 
      <span class="k">private</span> <span class="k">function</span> <span class="n">parseRoute</span><span class="p">(){</span>
          <span class="nv">$id</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
          <span class="c1">// parse path info</span>
          <span class="k">if</span> <span class="p">(</span><span class="k">isset</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_route</span><span class="p">)){</span>
              <span class="c1">// the request path</span>
              <span class="nv">$path</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_route</span><span class="p">;</span>
              <span class="c1">// the rules to route</span>
              <span class="nv">$cai</span> <span class="o">=</span>  <span class="s1">'/^([\w]+)\/([\w]+)\/([\d]+).*$/'</span><span class="p">;</span>  <span class="c1">//  controller/action/id</span>
              <span class="nv">$ci</span> <span class="o">=</span>   <span class="s1">'/^([\w]+)\/([\d]+).*$/'</span><span class="p">;</span>           <span class="c1">//  controller/id</span>
              <span class="nv">$ca</span> <span class="o">=</span>   <span class="s1">'/^([\w]+)\/([\w]+).*$/'</span><span class="p">;</span>           <span class="c1">//  controller/action</span>
              <span class="nv">$c</span> <span class="o">=</span>    <span class="s1">'/^([\w]+).*$/'</span><span class="p">;</span>                    <span class="c1">//  action</span>
              <span class="nv">$i</span> <span class="o">=</span>    <span class="s1">'/^([\d]+).*$/'</span><span class="p">;</span>                    <span class="c1">//  id</span>
              <span class="c1">// initialize the matches</span>
              <span class="nv">$matches</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
              <span class="c1">// if this is home page route</span>
              <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$path</span><span class="p">)){</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="s1">'index'</span><span class="p">;</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="s1">'index'</span><span class="p">;</span>
              <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="nv">$cai</span><span class="p">,</span> <span class="nv">$path</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">)){</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
                  <span class="nv">$id</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
              <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="nv">$ci</span><span class="p">,</span> <span class="nv">$path</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">)){</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
                  <span class="nv">$id</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
              <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="nv">$ca</span><span class="p">,</span> <span class="nv">$path</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">)){</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
              <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="nv">$c</span><span class="p">,</span> <span class="nv">$path</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">)){</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="s1">'index'</span><span class="p">;</span>    
              <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="nv">$i</span><span class="p">,</span> <span class="nv">$path</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">)){</span>
                  <span class="nv">$id</span> <span class="o">=</span> <span class="nv">$matches</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
              <span class="p">}</span>
              
              <span class="c1">// get query string from url        </span>
              <span class="nv">$query</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
              <span class="nv">$parse</span> <span class="o">=</span> <span class="nb">parse_url</span><span class="p">(</span><span class="nv">$path</span><span class="p">);</span>
              <span class="c1">// if we have query string</span>
              <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$parse</span><span class="p">[</span><span class="s1">'query'</span><span class="p">])){</span>
                  <span class="c1">// parse query string</span>
                  <span class="nb">parse_str</span><span class="p">(</span><span class="nv">$parse</span><span class="p">[</span><span class="s1">'query'</span><span class="p">],</span> <span class="nv">$query</span><span class="p">);</span>
                  <span class="c1">// if query paramater is parsed</span>
                  <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$query</span><span class="p">)){</span>
                      <span class="c1">// merge the query parameters to $_GET variables</span>
                      <span class="nv">$_GET</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">,</span> <span class="nv">$query</span><span class="p">);</span>
                      <span class="c1">// merge the query parameters to $_REQUEST variables</span>
                      <span class="nv">$_REQUEST</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$_REQUEST</span><span class="p">,</span> <span class="nv">$query</span><span class="p">);</span>
                  <span class="p">}</span>
              <span class="p">}</span>
          <span class="p">}</span>
  
          <span class="c1">// gets the request method</span>
          <span class="nv">$method</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s2">"REQUEST_METHOD"</span><span class="p">];</span>   
       
          <span class="c1">// assign params by methods  </span>
          <span class="k">switch</span><span class="p">(</span><span class="nv">$method</span><span class="p">){</span>
              <span class="k">case</span> <span class="s2">"GET"</span><span class="o">:</span> <span class="c1">// view</span>
                  <span class="c1">// we need to remove _route in the $_GET params</span>
                  <span class="k">unset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'_route'</span><span class="p">]);</span>
                  <span class="c1">// merege the params</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">,</span> <span class="nv">$_GET</span><span class="p">);</span>               
              <span class="k">break</span><span class="p">;</span>
              <span class="k">case</span> <span class="s2">"POST"</span><span class="o">:</span> <span class="c1">// create</span>
              <span class="k">case</span> <span class="s2">"PUT"</span><span class="o">:</span>  <span class="c1">// update</span>
              <span class="k">case</span> <span class="s2">"DELETE"</span><span class="o">:</span> <span class="c1">// delete</span>
              <span class="p">{</span>
                  <span class="c1">// ignore the file upload</span>
                  <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="s1">'HTTP_X_FILE_NAME'</span><span class="p">,</span><span class="nv">$_SERVER</span><span class="p">))</span>
                  <span class="p">{</span>
                      <span class="k">if</span><span class="p">(</span><span class="nv">$method</span> <span class="o">==</span> <span class="s2">"POST"</span><span class="p">){</span>
                          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">,</span> <span class="nv">$_POST</span><span class="p">);</span> 
                      <span class="p">}</span><span class="k">else</span><span class="p">{</span>           
                          <span class="c1">// temp params </span>
                          <span class="nv">$p</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
                          <span class="c1">// the request payload</span>
                          <span class="nv">$content</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s2">"php://input"</span><span class="p">);</span>
                          <span class="c1">// parse the content string to check we have [data] field or not</span>
                          <span class="nb">parse_str</span><span class="p">(</span><span class="nv">$content</span><span class="p">,</span> <span class="nv">$p</span><span class="p">);</span>
                          <span class="c1">// if we have data field</span>
                          <span class="nv">$p</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$content</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
                          <span class="c1">// merge the data to existing params</span>
                          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">,</span> <span class="nv">$p</span><span class="p">);</span>
                      <span class="p">}</span>   
                  <span class="p">}</span>          
              <span class="p">}</span>
              <span class="k">break</span><span class="p">;</span>                
          <span class="p">}</span>
          <span class="c1">// set param id to the id we have</span>
          <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$id</span><span class="p">)){</span>   
           <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]</span><span class="o">=</span><span class="nv">$id</span><span class="p">;</span>
          <span class="p">}</span>
  
          <span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">==</span> <span class="s1">'index'</span><span class="p">){</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">);</span>
          <span class="p">}</span>       
      <span class="p">}</span>
      
      <span class="k">public</span> <span class="k">function</span> <span class="n">dispatch</span><span class="p">()</span> <span class="p">{</span>
          <span class="c1">// call to parse routes</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">parseRoute</span><span class="p">();</span>
          <span class="c1">// set controller name</span>
          <span class="nv">$controllerName</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="p">;</span>
          <span class="c1">// set model name</span>
          <span class="nv">$model</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="mf">.</span><span class="s1">'Model'</span><span class="p">;</span>
          <span class="c1">// if we have extended model</span>
          <span class="nv">$model</span> <span class="o">=</span> <span class="nb">class_exists</span><span class="p">(</span><span class="nv">$model</span><span class="p">)</span> <span class="o">?</span> <span class="nv">$model</span> <span class="o">:</span> <span class="s1">'Model'</span><span class="p">;</span>
          <span class="c1">// assign controller full name</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="mf">.</span><span class="o">=</span> <span class="s1">'Controller'</span><span class="p">;</span>
          <span class="c1">// if we have extended controller</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nb">class_exists</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="p">)</span> <span class="o">?</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">:</span> <span class="s1">'Controller'</span><span class="p">;</span>
          <span class="c1">// construct the controller class</span>
          <span class="nv">$dispatch</span> <span class="o">=</span> <span class="k">new</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">_controller</span><span class="p">(</span><span class="nv">$model</span><span class="p">,</span> <span class="nv">$controllerName</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span><span class="p">);</span>
          <span class="c1">// if we have action function in controller</span>
          <span class="nv">$hasActionFunction</span> <span class="o">=</span> <span class="p">(</span><span class="n">int</span><span class="p">)</span><span class="nb">method_exists</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span><span class="p">);</span>
          <span class="c1">// we need to reference the parameters to a correct order in order to match the arguments order </span>
          <span class="c1">// of the calling function</span>
          <span class="nv">$c</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ReflectionClass</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="p">);</span>
          <span class="nv">$m</span> <span class="o">=</span> <span class="nv">$hasActionFunction</span> <span class="o">?</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">:</span> <span class="s1">'defaultAction'</span><span class="p">;</span>
          <span class="nv">$f</span> <span class="o">=</span> <span class="nv">$c</span><span class="o">-&gt;</span><span class="nf">getMethod</span><span class="p">(</span><span class="nv">$m</span><span class="p">);</span>
          <span class="nv">$p</span> <span class="o">=</span> <span class="nv">$f</span><span class="o">-&gt;</span><span class="nf">getParameters</span><span class="p">();</span>            
          <span class="nv">$params_new</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
          <span class="nv">$params_old</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_params</span><span class="p">;</span>
          <span class="c1">// re-map the parameters</span>
          <span class="k">for</span><span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span><span class="o">&lt;</span><span class="nb">count</span><span class="p">(</span><span class="nv">$p</span><span class="p">);</span><span class="nv">$i</span><span class="o">++</span><span class="p">){</span>
              <span class="nv">$key</span> <span class="o">=</span> <span class="nv">$p</span><span class="p">[</span><span class="nv">$i</span><span class="p">]</span><span class="o">-&gt;</span><span class="nf">getName</span><span class="p">();</span>
              <span class="k">if</span><span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span><span class="nv">$params_old</span><span class="p">)){</span>
                  <span class="nv">$params_new</span><span class="p">[</span><span class="nv">$i</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$params_old</span><span class="p">[</span><span class="nv">$key</span><span class="p">];</span>
                  <span class="k">unset</span><span class="p">(</span><span class="nv">$params_old</span><span class="p">[</span><span class="nv">$key</span><span class="p">]);</span>
              <span class="p">}</span>
          <span class="p">}</span>
          <span class="c1">// after reorder, merge the leftovers</span>
          <span class="nv">$params_new</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$params_new</span><span class="p">,</span> <span class="nv">$params_old</span><span class="p">);</span>
          <span class="c1">// call the action method</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_view</span> <span class="o">=</span> <span class="nb">call_user_func_array</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nv">$dispatch</span><span class="p">,</span> <span class="nv">$m</span><span class="p">),</span> <span class="nv">$params_new</span><span class="p">);</span>  
          <span class="c1">// finally, we print it out</span>
          <span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_view</span><span class="p">){</span>
             <span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_view</span><span class="p">;</span>
          <span class="p">}</span>
      <span class="p">}</span>
  <span class="p">}</span>
  </code></pre></figure>

<br />
<h3>
 The Controller (Controller.class.php)</h3>
Like many other MVC frameworks, our controller plays logical operations. At
    Line 18, we assign our configurations (From config.php) for internal use.
    Then we initialise the <span style="font-weight: bold;">Template.class.php</span>
    and models. <br />
<br />
Well, I am a bit lazy, so I made a defaultAction method. When there is no
    available actions but we have outputs then we use <span style="font-weight: bold;">defaultAction</span>
    to call the related files in the view folder. If we cannot find any related
    files, then we throw a <span style="font-weight: bold;">404</span> <span style="font-weight: bold;">unknownAction</span>
    for clients. <br />
<br />
I just added few methods for my own, other than that it is pretty much the
    same as Anant Garg's controller.<br />
<br />
Please note that I use <span style="font-weight: bold;">MySqlDataAdapter.class.php</span>
    as <span style="font-weight: bold;">$db</span> to perform database
    operations instead of putting it into the Model class. It is much easier for
    me to update the database wrapper class since I may use other type of
    database connections such as T-SQL or SQLite.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="library-mvc-Controller.class.php">/library/mvc/Controller.class.php</a>
    <br />
<figure class="highlight"><pre><code class="language-php" data-lang="php">    <span class="cp">&lt;?php</span>
      <span class="kd">class</span> <span class="nc">Controller</span> <span class="p">{</span>
          <span class="k">protected</span> <span class="nv">$_model</span><span class="p">,</span>
                    <span class="nv">$_controller</span><span class="p">,</span>
                    <span class="nv">$_action</span><span class="p">;</span>
          
          <span class="k">public</span>    <span class="nv">$cfg</span><span class="p">,</span>
                    <span class="nv">$view</span><span class="p">,</span>
                    <span class="nv">$table</span><span class="p">,</span>
                    <span class="nv">$id</span><span class="p">,</span>
                    <span class="nv">$db</span><span class="p">,</span>
                    <span class="nv">$userValidation</span><span class="p">;</span>
          
          <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$model</span><span class="o">=</span><span class="s2">"Model"</span><span class="p">,</span> <span class="nv">$controller</span><span class="o">=</span><span class="s2">"Controler"</span><span class="p">,</span> <span class="nv">$action</span><span class="o">=</span><span class="s2">"index"</span><span class="p">)</span> <span class="p">{</span>
              <span class="c1">// register configurations from config.php</span>
              <span class="k">global</span> <span class="nv">$cfg</span><span class="p">;</span>      
              <span class="c1">// set config</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">cfg</span> <span class="o">=</span> <span class="nv">$cfg</span><span class="p">;</span>              
              <span class="c1">// construct MVC</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$controller</span><span class="p">;</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="nv">$action</span><span class="p">;</span>
              <span class="c1">// initialise the template class</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Template</span><span class="p">(</span><span class="nv">$controller</span><span class="p">,</span> <span class="nv">$action</span><span class="p">);</span>   
              <span class="c1">// call the function for derived class      </span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">init</span><span class="p">();</span>
              <span class="c1">// start contruct models</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_model</span> <span class="o">=</span> <span class="k">new</span> <span class="nv">$model</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">db</span><span class="p">);</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_model</span><span class="o">-&gt;</span><span class="n">controller</span> <span class="o">=</span> <span class="nv">$this</span><span class="p">;</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">table</span> <span class="o">=</span> <span class="nv">$controller</span><span class="p">;</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * Initialize the required classes and variables
          */</span>
          <span class="k">protected</span> <span class="k">function</span> <span class="n">init</span><span class="p">(){</span>
           <span class="cm">/* Put your code here*/</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * Redirect to action
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">redirectToAction</span><span class="p">(</span><span class="nv">$action</span><span class="p">,</span> <span class="nv">$controller</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">()){</span>        
              <span class="k">if</span><span class="p">(</span><span class="nv">$controller</span> <span class="o">===</span> <span class="kc">false</span><span class="p">){</span>
                  <span class="nv">$controller</span> <span class="o">=</span> <span class="nb">get_called_class</span><span class="p">();</span>  
              <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nb">is_string</span><span class="p">(</span><span class="nv">$controller</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="nb">class_exists</span><span class="p">(</span><span class="nv">$controller</span><span class="mf">.</span><span class="s1">'Controller'</span><span class="p">)){</span>
                  <span class="nv">$controller</span> <span class="o">=</span> <span class="nv">$controller</span><span class="mf">.</span><span class="s1">'Controller'</span><span class="p">;</span>
                  <span class="nv">$controller</span> <span class="o">=</span> <span class="k">new</span> <span class="nv">$controller</span><span class="p">();</span>
              <span class="p">}</span>
              <span class="k">return</span> <span class="nb">call_user_func_array</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nv">$controller</span><span class="p">,</span> <span class="nv">$action</span><span class="p">),</span> <span class="nv">$params</span><span class="p">);</span>
          <span class="p">}</span>
       
          <span class="cd">/**
          * process default action view
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">defaultAction</span><span class="p">(</span><span class="nv">$params</span> <span class="o">=</span> <span class="kc">null</span><span class="p">){</span>
            <span class="c1">// make the default action path</span>
            <span class="nv">$path</span> <span class="o">=</span> <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">UrlContent</span><span class="p">(</span><span class="s2">"~/views/</span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span><span class="si">}</span><span class="s2">.php"</span><span class="p">);</span>  
            <span class="c1">// if we have action name</span>
            <span class="k">if</span><span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$path</span><span class="p">)){</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span><span class="o">-&gt;</span><span class="n">viewPath</span> <span class="o">=</span> <span class="nv">$path</span><span class="p">;</span>
            <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">unknownAction</span><span class="p">();</span>
            <span class="p">}</span>
            <span class="c1">// if we have parameters</span>
            <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$params</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="nb">is_array</span><span class="p">(</span><span class="nv">$params</span><span class="p">)){</span>
                  <span class="c1">// assign local variables</span>
                  <span class="k">foreach</span><span class="p">(</span><span class="nv">$params</span> <span class="k">as</span> <span class="nv">$key</span><span class="o">=&gt;</span><span class="nv">$value</span><span class="p">){</span>
                   <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span><span class="o">-&gt;</span><span class="nf">set</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span> <span class="nv">$value</span><span class="p">);</span>   
                  <span class="p">}</span>
            <span class="p">}</span>
            <span class="c1">// dispatch the result</span>
            <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">view</span><span class="p">();</span>
          <span class="p">}</span>

          <span class="cd">/**
          * unknownAction
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">unknownAction</span><span class="p">(</span><span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">()){</span>
            <span class="c1">// feed 404 header to the client</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"HTTP/1.0 404 Not Found"</span><span class="p">);</span>
            <span class="c1">// find custom 404 page</span>
            <span class="nv">$path</span> <span class="o">=</span> <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">UrlContent</span><span class="p">(</span><span class="s2">"~/views/shared/_404.php"</span><span class="p">);</span>
            <span class="c1">// if we have custom 404 page, then use it</span>
            <span class="k">if</span><span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$path</span><span class="p">)){</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span><span class="o">-&gt;</span><span class="n">viewPath</span> <span class="o">=</span> <span class="nv">$path</span><span class="p">;</span>
              <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">view</span><span class="p">();</span>
            <span class="p">}</span><span class="k">else</span><span class="p">{</span>
              <span class="k">exit</span><span class="p">;</span> <span class="c1">//Do not do any more work in this script. </span>
            <span class="p">}</span>
          <span class="p">}</span>        
          
          <span class="cd">/**
          * set the variables
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">set</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span><span class="nv">$value</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// set the parameters to the template class</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span><span class="o">-&gt;</span><span class="nf">set</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">);</span>
          <span class="p">}</span>      
            
          <span class="cd">/**
          * Returns the template result
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">view</span><span class="p">(){</span>
            <span class="c1">// dispatch the result of the template class</span>
            <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">view</span><span class="p">;</span>
          <span class="p">}</span>
      <span class="p">}</span>
    </code></pre></figure>

<br />
<h3>
The Model (Model.class.php)</h3>
Well, since most of database operations are handled by MySqlDataAdapter.php,
    the Model class is just a base class to assist Controller class.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="library-mvc-Model.class.php">/library/mvc/Model.class.php</a>
    <br />
<figure class="highlight"><pre><code class="language-php" data-lang="php"> <span class="cp">&lt;?php</span>
      <span class="kd">class</span> <span class="nc">Model</span><span class="p">{</span>
        <span class="k">protected</span> <span class="nv">$_model</span><span class="p">;</span>
        <span class="k">public</span> <span class="nv">$db</span><span class="p">,</span> <span class="nv">$controller</span><span class="p">;</span>
          
          <span class="cd">/**
          * Constructor for Model
          * 
          */</span>
        <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$db</span><span class="p">)</span> <span class="p">{</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">db</span> <span class="o">=</span> <span class="nv">$db</span><span class="p">;</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_model</span> <span class="o">=</span> <span class="nb">get_class</span><span class="p">(</span><span class="nv">$this</span><span class="p">);</span>
              <span class="nv">$defaultModel</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_model</span><span class="o">==</span><span class="s1">'Model'</span><span class="p">);</span>
              
              <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$defaultModel</span><span class="p">){</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">table</span> <span class="o">=</span> <span class="nb">preg_replace</span><span class="p">(</span><span class="s1">'/Model$/'</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_model</span><span class="p">);</span><span class="c1">// remove ending Model        </span>
              <span class="p">}</span>
              
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">init</span><span class="p">();</span>
        <span class="p">}</span>
      
        <span class="k">protected</span> <span class="k">function</span> <span class="n">init</span><span class="p">(){</span>
          <span class="cm">/* Put your code here*/</span>     
        <span class="p">}</span>
      <span class="p">}</span>
    </code></pre></figure>

<br />
<h3>
The Template (Template.class.php)</h3>
The Template class handles our output operations. I use <a href="http://ch2.php.net/ob_start" target="_blank" rel="noopener noreferrer">ob_start</a>,
    <a href="http://ch2.php.net/manual/en/function.ob-get-contents.php" target="_blank" rel="noopener noreferrer">ob_get_contents</a>,
    <a href="http://ch2.php.net/manual/en/function.ob-end-clean.php" target="_blank" rel="noopener noreferrer">ob_end_clean</a>
    and <a href="http://ch2.php.net/manual/en/function.ob-end-flush.php" target="_blank" rel="noopener noreferrer">ob_end_flush</a>
    to hold the output data and join them together before dispatching to
    clients.<br />
<br />
<span style="text-decoration: underline;"></span>You may also notice that I
    use <a href="https://code.google.com/p/minify/" target="_blank" rel="noopener noreferrer">PHP minify</a>
    to reduce the size of the outputs. If the operation is html output then I
    minify Html, CSS and JavaScript contents. If the operation is Ajax or just
    JavaScript contents, then I only minify it with JS minify only.<br />
<br />
At the end, we override the <a href="http://www.php.net/manual/en/language.oop5.magic.php#object.tostring" target="_blank" rel="noopener noreferrer">__toString()</a>
    method in order for <a href="https://www.blogger.com/blogger.g?blogID=1691872865366176972#library-mvc-Router.class.php">Router.class.php</a>
    to dispatch the output.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="library-mvc-Template.class.php">/library/mvc/Template.class.php</a>
    <br />
<figure class="highlight"><pre><code class="language-php" data-lang="php">      
    <span class="cp">&lt;?php</span>
      <span class="kd">class</span> <span class="nc">Template</span> <span class="p">{</span>                      
        <span class="k">protected</span> <span class="nv">$_variables</span> <span class="o">=</span> <span class="k">array</span><span class="p">(),</span>
                  <span class="nv">$_controller</span><span class="p">,</span>
                  <span class="nv">$_action</span><span class="p">,</span>
                    <span class="nv">$_bodyContent</span><span class="p">;</span>
                    
          <span class="k">public</span>    <span class="nv">$viewPath</span><span class="p">,</span> 
                    <span class="nv">$section</span> <span class="o">=</span> <span class="k">array</span><span class="p">(),</span>
                    <span class="nv">$layout</span><span class="p">;</span>
          
          <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$controller</span><span class="p">,</span> <span class="nv">$action</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="o">=</span> <span class="nv">$controller</span><span class="p">;</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="nv">$action</span><span class="p">;</span>
                <span class="c1">// we set the configuration variables to local variables for rendering</span>
                <span class="k">global</span> <span class="nv">$cfg</span><span class="p">;</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">set</span><span class="p">(</span><span class="s1">'cfg'</span><span class="p">,</span><span class="nv">$cfg</span><span class="p">);</span>
          <span class="p">}</span>
        
          <span class="cd">/** 
           * Set Variables 
           */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">set</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_variables</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * set action
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">setAction</span><span class="p">(</span><span class="nv">$action</span><span class="p">){</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="o">=</span> <span class="nv">$action</span><span class="p">;</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * RenderBody
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">renderBody</span><span class="p">(){</span>
            <span class="c1">// if we have content, then deliver it</span>
              <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_bodyContent</span><span class="p">)){</span>
                  <span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_bodyContent</span><span class="p">;</span>
              <span class="p">}</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * RenderSection
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">renderSection</span><span class="p">(</span><span class="nv">$section</span><span class="p">){</span>
              <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">section</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$section</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">section</span><span class="p">)){</span>
                  <span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">section</span><span class="p">[</span><span class="nv">$section</span><span class="p">];</span>
              <span class="p">}</span>
          <span class="p">}</span>
      
        <span class="cd">/** 
        * Display Template 
        */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">render</span><span class="p">()</span> <span class="p">{</span>  
              <span class="c1">// extract the variables for view pages</span>
              <span class="nb">extract</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_variables</span><span class="p">);</span>
              <span class="c1">// the view path</span>
              <span class="nv">$path</span> <span class="o">=</span> <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">UrlContent</span><span class="p">(</span><span class="s1">'~/views/'</span><span class="p">);</span>
              <span class="c1">// start buffering</span>
              <span class="nb">ob_start</span><span class="p">();</span>
              <span class="c1">// render page content</span>
              <span class="k">if</span><span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">viewPath</span><span class="p">)){</span> 
                  <span class="k">include</span> <span class="p">(</span><span class="nv">$path</span> <span class="mf">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_controller</span> <span class="mf">.</span> <span class="no">DS</span> <span class="mf">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_action</span> <span class="mf">.</span> <span class="s1">'.php'</span><span class="p">);</span>
              <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                  <span class="k">include</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">viewPath</span><span class="p">);</span>
              <span class="p">}</span>
              <span class="c1">// get the body contents</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_bodyContent</span> <span class="o">=</span> <span class="nb">ob_get_contents</span><span class="p">();</span>
              <span class="c1">// clean the buffer</span>
              <span class="nb">ob_end_clean</span><span class="p">();</span>
              <span class="c1">// check if we have any layout defined</span>
              <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">layout</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="p">(</span><span class="o">!</span><span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">isAjax</span><span class="p">())){</span>
                  <span class="c1">// we need to check the path contains app prefix (~)</span>
                  <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">layout</span> <span class="o">=</span> <span class="nc">MyHelpers</span><span class="o">::</span><span class="nf">UrlContent</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">layout</span><span class="p">);</span>
                  <span class="c1">// start buffer (minify pages)</span>
                  <span class="nb">ob_start</span><span class="p">(</span><span class="s1">'MyHelpers::minify_content'</span><span class="p">);</span>
                  <span class="c1">// include the template</span>
                  <span class="k">include</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">layout</span><span class="p">);</span>
              <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                  <span class="nb">ob_start</span><span class="p">(</span><span class="s1">'MyHelpers::minify_content_js'</span><span class="p">);</span>
                  <span class="c1">// just output the content</span>
                  <span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">_bodyContent</span><span class="p">;</span>
              <span class="p">}</span>
              <span class="c1">// end buffer</span>
              <span class="nb">ob_end_flush</span><span class="p">();</span>
          <span class="p">}</span>
          
          <span class="cd">/**
          * return the renderred html string
          */</span>
          <span class="k">public</span> <span class="k">function</span> <span class="n">__toString</span><span class="p">(){</span>
              <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">render</span><span class="p">();</span>
              <span class="k">return</span> <span class="s1">''</span><span class="p">;</span>
          <span class="p">}</span>
      <span class="p">}</span>   
    </code></pre></figure>

<br />
<h3>
How to use template?</h3>
The logic is similar to .NET MVC's template operations. We have shared pages
    to accommodate each view page. Simply assign the main page layout at top of
    each view page (<span style="font-weight: bold;">$this->layout="~/view/shared/_defaultLayout.php"</span>).
    If we have dynamic sections, then we place <span style="font-weight: bold;">$this->section['param']</span>
    at the view page.<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="application-view-shared-_defaultLayout.php">/application/view/shared/_defaultLayout.php</a><br />
<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="nt">&lt;html&gt;</span>
    <span class="nt">&lt;head&gt;</span>
        <span class="cp">&lt;?php</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">renderSection</span><span class="p">(</span><span class="s1">'head'</span><span class="p">);</span><span class="cp">?&gt;</span>
    <span class="nt">&lt;/head&gt;</span>
    <span class="nt">&lt;body&gt;</span>
        <span class="cp">&lt;?php</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">renderBody</span><span class="p">();</span><span class="cp">?&gt;</span>
    <span class="nt">&lt;/body&gt;</span>
    <span class="nt">&lt;/html&gt;</span></code></pre></figure>

<br />
When you put your content of the page, you can also place sections to
    defined place in the _defaultLayout.php<br />
<br />
<a class="filepath" href="https://www.blogger.com/blogger.g?blogID=1691872865366176972" name="application-view-index-index.php">/application/view/index/index.php</a><br />
<figure class="highlight"><pre><code class="language-php" data-lang="php">        <span class="cp">&lt;?php</span>
          <span class="c1">// The default layout template</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">layout</span> <span class="o">=</span> <span class="s1">'~/views/shared/_defaultLayout.php'</span><span class="p">;</span>
          <span class="c1">// The value to put on the head section</span>
          <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">section</span><span class="p">[</span><span class="s1">'head'</span><span class="p">]</span><span class="o">=</span><span class="s2">"&lt;script src='http://code.jquery.com/jquery-latest.min.js'&gt;&lt;/script&gt;"</span><span class="p">;</span>
        <span class="cp">?&gt;</span>
        <span class="nt">&lt;strong&gt;</span>This is the text I want to show in the body<span class="nt">&lt;/strong&gt;</span>
    </code></pre></figure>

<br />
<span style="font-weight: bold;">The output result </span><br />
<figure class="highlight"><pre><code class="language-html" data-lang="html">      <span class="nt">&lt;html&gt;</span>
        <span class="nt">&lt;head&gt;</span>
          <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">'http://code.jquery.com/jquery-latest.min.js'</span><span class="nt">&gt;&lt;/script&gt;</span>
        <span class="nt">&lt;/head&gt;</span>
        <span class="nt">&lt;body&gt;</span>
          <span class="nt">&lt;strong&gt;</span>This is the text I want to show in the body<span class="nt">&lt;/strong&gt;</span>
        <span class="nt">&lt;/body&gt;</span>
      <span class="nt">&lt;/html&gt;</span>
   </code></pre></figure>

<a name='download'></a>
<br />
In conclusion, the concept is not difficult and should be easy to apply on any simple project. If you understand how Anant Garg wants to achieve, you should be able to comprehend this post. You can download the sample code from <a href="https://drive.google.com/uc?export=download&amp;confirm=no_antivirus&amp;id=0BxNgktpBGY4Ya1ZiUUtlb1ZBYVE">HERE</a>
    for further reading. The sample has more implementations on this simple MVC
    framework. <br />
<br />

<table>
  <tr>
     <td style="text-align: center; vertical-align: middle; height:32px; width:32px;">
          <img align="absmiddle" src='http://icons.iconarchive.com/icons/gakuseisean/aire/32/Download-Folder-icon.png' />
     </td>
     <td style="vertical-align: middle;">
 <a style="font-size:20px;" href="https://drive.google.com/uc?export=download&amp;confirm=no_antivirus&amp;id=0BxNgktpBGY4Ya1ZiUUtlb1ZBYVE">Download Sample Project</a>
</td>
  </tr>
</table>

If you enjoy this article, please leave a like or a plus and let me know your thoughts in the comments. <br />

<p style="font-size:14px;color:red;"> 
 <b>Update</b>: I have updated the MySqlDataAdapter.class.php in the sample code which replaced <b>mysql_*</b> functions to <b>PDO (<a href="http://www.php.net/manual/en/book.pdo.php" target="_blank" rel="noopener noreferrer">PHP Data Objects</a>)</b>.
</p>]]></content><author><name>Elvis Hsu</name></author><category term="MySQL" /><category term="Coding" /><summary type="html"><![CDATA[I have been using ASP .NET MVC for many years. It is a complex framework but not difficult to learn (at least for .NET developers). Anyway, I like the way it handles templates and routing. Few years ago, one of my clients asked me to developed a simple ERP system with PHP and MySQL. My first thought was: "Why not developing a simple MVC framework with PHP?". It would allow me to utilise the backend code and avoid mixing code in classes. I started to study many PHP MVC Frameworks such as Zend Framework, Symfony and CakePHP but I realised those "ready-to-use" frameworks are overkilled for this simple project and I would like to have codes that I could manipulate easily and apply them to next simple projects without making my brand hurts. Luckily, I found this article: Write your own PHP MVC Framework. It is a very good article and it explained the concept of MVC comprehensively. If you just start learning MVC, this is a great place start. Well, the truth is the article inspired me to create my own little MVC framework with PHP. Anyway, before you continue reading, I recommend you to read through the article I mentioned above. My version of MVC is a little bit different from Anant Garg's but I believe you will find it useful. In this article, I would like to focus on the routing and template operations. Since Anant Garg has covered most important parts of MVC, I will just point out some features of my own framework in this article. Before we start talking about the details, let's have a look at the directory structure. You can expand the folder below and link to sample codes of this article. The structure is pretty much the same as Anant Garg's. The only difference is that I put all public assessable files (images, style sheets and js scripts) into public folder. htdocs application controllers blogController.php models blogModel.php views index index.php blog index.php detail.php create.php update.php delete.php about index.php shared _defaultLayout.php.php .htaccess config config.php .htaccess library core MyHelper.class.php MySqlDataAdapter.class.php mvc Controller.class.php Model.class.php Router.class.php Template.class.php bootstrap.php .htaccess public scripts your-js-files.js images your-images.png themes your-css-styles.css index.php .htaccess .htaccess Apache mode_rewrite module Routing plays an important role in MVC framework since it translate your URL to match your controllers and actions. When any Http request pass to your site, it will go to htdocs/.htaccess first. Then we parse the URL and redirect the request to htdocs/public folder. In fact, we only have a single entry point since every request will be going to htdocs/public folder and waiting for next process. htdocs/.htaccess Options +FollowSymLinks &lt;ifmodule mod_rewrite.c=""&gt; # Tell PHP that the mod_rewrite module is ENABLED. SetEnv HTTP_MOD_REWRITE On RewriteEngine on RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L] &lt;/ifmodule&gt;]]></summary></entry><entry><title type="html">Edit your CSS and JavaScript files on Google Drive</title><link href="https://www.elvishsu.com/2014/01/edit-your-css-and-javascript-files-on.html" rel="alternate" type="text/html" title="Edit your CSS and JavaScript files on Google Drive" /><published>2014-01-09T20:50:00+00:00</published><updated>2014-01-09T20:50:00+00:00</updated><id>https://www.elvishsu.com/2014/01/edit-your-css-and-javascript-files-on</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/edit-your-css-and-javascript-files-on.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-09-image-0000.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="Edit your CSS and JavaScript files on Google Drive" border="0" src="/assets/posts/blogger/2014-01-09-image-0000.png" height="150" title="Edit your CSS and JavaScript files on Google Drive" width="200" /></a></div>
Well, I like <a href="http://blogger.com/" target="_blank" rel="noopener noreferrer">blogger.com</a>. It is free and it allows me to play around the
    source code of templates. Since last year, I started to use customised
    templates and tweak some of the source codes. Believe or not, I actually
    enjoy it. Anyway, this is not what this post about. <br />
<br />
I use <a href="https://drive.google.com/" target="_blank" title="Google Drive">Google Drive</a> to host my CSS and JavaScript files for this blog site. I edit
    these files on my computer and let <a href="https://tools.google.com/dlpage/drive" target="_blank" title="Access files on your computer from anywhere.">Google
      Drive application</a> to synchronise the files to the cloud. It sounds
    normal and I believe many other people would use the same way I do. However,
    what if I want to edit these text based files over Google Drive itself, on
    the browser? "<span style="font-weight: bold;">Yes, You Can!</span>" but you
    need third party <a href="https://chrome.google.com/webstore/category/collection/drive_apps" target="_blank" title="Chrome Web Store">Google
      Drive Apps</a> to achieve the goal.<br />
<br />
I found two third party Google Drive apps, <a href="https://www.neutrondrive.com/" target="_top" title="Neutron Drive">Neutron
      Drive</a> and <a href="https://drivenotepad.appspot.com/" target="_blank" rel="noopener noreferrer">Drive
      Notepad</a>. Both are great apps and have their pros and cons. I started
    with Drive Notepad since it was the first app I found. But I use Neutron
    Drive more often because it integrates very well with Google Drive and it has
    file browser feature.<br />
<a name='more'></a><br />
<h4>
<span style="font-weight: bold;">Highlights for both apps </span></h4>
<ul>
<li>Support for a variety of file types, including *.css, *js and *.html</li>
<li>Syntax highlighting for popular program languages</li>
<li>Support common used keyboard shortcuts</li>
<li>Google Drive revision control</li>
</ul>
<br />
Personally, I like to use Neutron Drive. It has more features than Drive Notepad such as file browser, html live view, themes and <a href="https://www.neutrondrive.com/blog/ftp-client" target="_blank" rel="noopener noreferrer">FTP client</a>. However if you like clean and simple GUI, Drive Notepad would be a great fit. Well, if you're interested in letting Google Drive hosting your Blogger site's CSS or JavaScript files, check both apps out and let me know what you think in the comments!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGLP1s22J0c6w5kt-Bk7DY_gO_dEQOkuKTK5ExCoo8bbfJrCGFlwQSkRtk0P-nM7w2eGpaGO_u6G9CKfIqxFvcprdyI2MCyIc12WcWL1Z_9bNeo9FlgxLKjH4xhdCcgabXFZ8NRuMP43s/s1600/Screen+Shot+-+Google+Drive.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="/assets/posts/blogger/2014-01-09-image-0001.png" height="212" width="400" /></a></div>
<br />
<span style="font-style: italic;">PS. If you want to know how to host these
      files on Google Drive, you can have a look at articles from <a href="http://www.komku.org/2013/08/how-to-host-javascript-or-css-files-on-google-drive.html" target="_blank" title="How to Host JavaScript or CSS Files on Google Drive">Nelda
        Yuntantri</a>,&nbsp; <a href="http://www.techsperia.com/2013/07/how-to-host-javascript-and-css-scripts.html" target="_blank" title="How To Host JavaScript And CSS Scripts On Google Drive">Raj
        Mehta</a> or <a href="http://www.mybloggerlab.com/2013/04/how-to-host-css-or-javascript-files-in-blogger-using-google-drive.html" target="_blank" title="How to Host CSS or JavaScript Files in Blogger using Google Drive">Syed
        Faizan Ali</a>. </span>]]></content><author><name>Elvis Hsu</name></author><category term="Blogger" /><category term="Tips" /><summary type="html"><![CDATA[Well, I like blogger.com. It is free and it allows me to play around the source code of templates. Since last year, I started to use customised templates and tweak some of the source codes. Believe or not, I actually enjoy it. Anyway, this is not what this post about. I use Google Drive to host my CSS and JavaScript files for this blog site. I edit these files on my computer and let Google Drive application to synchronise the files to the cloud. It sounds normal and I believe many other people would use the same way I do. However, what if I want to edit these text based files over Google Drive itself, on the browser? "Yes, You Can!" but you need third party Google Drive Apps to achieve the goal. I found two third party Google Drive apps, Neutron Drive and Drive Notepad. Both are great apps and have their pros and cons. I started with Drive Notepad since it was the first app I found. But I use Neutron Drive more often because it integrates very well with Google Drive and it has file browser feature. Highlights for both apps Support for a variety of file types, including *.css, *js and *.html Syntax highlighting for popular program languages Support common used keyboard shortcuts Google Drive revision control Personally, I like to use Neutron Drive. It has more features than Drive Notepad such as file browser, html live view, themes and FTP client. However if you like clean and simple GUI, Drive Notepad would be a great fit. Well, if you're interested in letting Google Drive hosting your Blogger site's CSS or JavaScript files, check both apps out and let me know what you think in the comments! PS. If you want to know how to host these files on Google Drive, you can have a look at articles from Nelda Yuntantri,&nbsp; Raj Mehta or Syed Faizan Ali.]]></summary></entry><entry><title type="html">Generate MetaData for ExtJs Data Reader</title><link href="https://www.elvishsu.com/2014/01/generate-metadata-for-extjs-data-reader.html" rel="alternate" type="text/html" title="Generate MetaData for ExtJs Data Reader" /><published>2014-01-02T21:22:00+00:00</published><updated>2014-01-02T21:22:00+00:00</updated><id>https://www.elvishsu.com/2014/01/generate-metadata-for-extjs-data-reader</id><content type="html" xml:base="https://www.elvishsu.com/2014/01/generate-metadata-for-extjs-data-reader.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="/assets/posts/blogger/2014-01-02-image-0000.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="Generate MetaData for ExtJs Data Reader" border="0" src="/assets/posts/blogger/2014-01-02-image-0000.png" title="Generate MetaData for ExtJs Data Reader" /></a></div>
<a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.reader.Reader-property-metaData" target="_blank" rel="noopener noreferrer">Metadata</a> is one of my most used properties in&nbsp;<a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.reader.Reader" target="_blank" rel="noopener noreferrer">Ext.data.reader.Reader</a>. It allows me to pass custom data/configuration to <a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.Panel" target="_blank" rel="noopener noreferrer">Grid Panel</a>, <a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.Panel" target="_blank" rel="noopener noreferrer">Form</a>, <a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.field.ComboBox" target="_blank" rel="noopener noreferrer">ComboBox</a> and other components without needing extra efforts to change the code. At the following example, I just want to put my column layout configuration to the grid without configuring the data fields in the <a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.JsonStore" target="_blank" rel="noopener noreferrer">data store</a>. If the settings of data fields is bound with data columns' information on the database, then we could save a lot of time to match the data field types when updating/retrieving data to/from server.<br />
<br />
In this article, we are going to retrieve field types, defaultValues, and allowBlank settings via the meta data which is generated based on the data columns information of the MySQL database.<br />
<a name='more'></a><br />
For example, we want to display a data grid with <a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.toolbar.Paging" target="_blank" rel="noopener noreferrer">paging toolbar</a> which shows a list of values of 'items'.<br />
<br />
We now just need to create a simple <b><a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.JsonStore" target="_blank" rel="noopener noreferrer">JsonStore</a></b> and let the <b><a href="http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.proxy.Ajax" target="_blank" rel="noopener noreferrer">proxy</a></b> retrieves the information by '<b>MetaDataExample.php</b>'.<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// File Name: index.php</span>
<span class="c1">// Start loading the page        </span>
<span class="nx">Ext</span><span class="p">.</span><span class="nx">onReady</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
 <span class="nx">Ext</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.data.JsonStore</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
  <span class="na">storeId</span><span class="p">:</span><span class="dl">'</span><span class="s1">itemsStore</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">autoLoad</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
  <span class="na">proxy</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ajax</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">url</span><span class="p">:</span> <span class="dl">'</span><span class="s1">MetaDataExample.php</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// our data link</span>
    <span class="na">reader</span><span class="p">:</span> <span class="p">{</span>
     <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">json</span><span class="dl">'</span>
    <span class="p">}</span>
   <span class="p">}</span>
 <span class="p">});</span>
 
 <span class="nx">Ext</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.grid.Panel</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
  <span class="na">title</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Items</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">store</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">StoreManager</span><span class="p">.</span><span class="nx">lookup</span><span class="p">(</span><span class="dl">'</span><span class="s1">itemsStore</span><span class="dl">'</span><span class="p">),</span>
  <span class="na">columns</span><span class="p">:</span> <span class="p">[</span>
   <span class="p">{</span> <span class="na">text</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ID</span><span class="dl">'</span><span class="p">,</span>  <span class="na">dataIndex</span><span class="p">:</span> <span class="dl">'</span><span class="s1">id</span><span class="dl">'</span> <span class="p">},</span>
   <span class="p">{</span> <span class="na">text</span><span class="p">:</span> <span class="dl">'</span><span class="s1">SKU</span><span class="dl">'</span><span class="p">,</span> <span class="na">dataIndex</span><span class="p">:</span> <span class="dl">'</span><span class="s1">sku</span><span class="dl">'</span><span class="p">,</span> <span class="na">flex</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>
   <span class="p">{</span> <span class="na">text</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Name</span><span class="dl">'</span><span class="p">,</span> <span class="na">dataIndex</span><span class="p">:</span> <span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span> <span class="na">flex</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>
   <span class="p">{</span> <span class="na">text</span><span class="p">:</span> <span class="dl">'</span><span class="s1">QTY</span><span class="dl">'</span><span class="p">,</span> <span class="na">dataIndex</span><span class="p">:</span> <span class="dl">'</span><span class="s1">qty</span><span class="dl">'</span><span class="p">}</span>
  <span class="p">],</span>
  <span class="na">dockedItems</span><span class="p">:</span> <span class="p">[{</span>
   <span class="na">xtype</span><span class="p">:</span> <span class="dl">'</span><span class="s1">pagingtoolbar</span><span class="dl">'</span><span class="p">,</span>
   <span class="na">store</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">StoreManager</span><span class="p">.</span><span class="nx">lookup</span><span class="p">(</span><span class="dl">'</span><span class="s1">itemsStore</span><span class="dl">'</span><span class="p">),</span>   <span class="c1">// same store GridPanel is using</span>
   <span class="na">dock</span><span class="p">:</span> <span class="dl">'</span><span class="s1">bottom</span><span class="dl">'</span><span class="p">,</span>
   <span class="na">displayInfo</span><span class="p">:</span> <span class="kc">true</span>
  <span class="p">}],</span>
  <span class="na">height</span><span class="p">:</span> <span class="mi">600</span><span class="p">,</span>
  <span class="na">width</span><span class="p">:</span> <span class="mi">800</span><span class="p">,</span>
  <span class="na">renderTo</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">getBody</span><span class="p">()</span>
 <span class="p">});</span> 
<span class="p">});</span>  </code></pre></figure>

<br />
<br />
<br />
The following function feeds the meta data to the client and it indicates that we want to show all records from all fields of&nbsp;<strong>items</strong> table. The '<b>db</b>' variable is a custom class to handle the database operation and I will explain the functions <a href="http://www.blogger.com/blogger.g?blogID=1691872865366176972#MySqlDataAdapter">later</a>. The '<b>ret</b>' variable contains output data to feed the JSON reader.<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MetaDataExample.php</span>
<span class="k">public</span> <span class="k">function</span> <span class="n">getItems</span><span class="p">(){</span>
 <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tableName</span> <span class="o">=</span>  <span class="s2">"items"</span><span class="p">;</span>
 <span class="nv">$start</span> <span class="o">=</span> <span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'start'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'start'</span><span class="p">]</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
 <span class="nv">$limit</span> <span class="o">=</span> <span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'limit'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'limit'</span><span class="p">]</span> <span class="o">:</span> <span class="mi">10</span><span class="p">;</span>
 
 <span class="nv">$query</span> <span class="o">=</span> <span class="s2">"SELECT * FROM `</span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tableName</span><span class="si">}</span><span class="s2">` LIMIT </span><span class="si">{</span><span class="nv">$start</span><span class="si">}</span><span class="s2">,</span><span class="si">{</span><span class="nv">$limit</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span>
 
 <span class="nv">$stmt</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">db</span><span class="o">-&gt;</span><span class="nf">query</span><span class="p">(</span><span class="nv">$query</span><span class="p">);</span>
 <span class="c1">// get the number of records</span>
 <span class="nv">$r</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">db</span><span class="o">-&gt;</span><span class="nf">query</span><span class="p">(</span><span class="s2">"SELECT COUNT(*) FROM `</span><span class="si">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tableName</span><span class="si">}</span><span class="s2">`"</span><span class="p">,</span> <span class="no">PDO</span><span class="o">::</span><span class="no">FETCH_NUM</span><span class="p">);</span>
 <span class="c1">// gets the first column as value</span>
 <span class="nv">$nbrows</span> <span class="o">=</span> <span class="nv">$r</span><span class="o">-&gt;</span><span class="nf">fetchColumn</span><span class="p">();</span>

 <span class="c1">// initialize the default output array</span>
 <span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
 <span class="c1">// if we have rows</span>
 <span class="k">if</span><span class="p">(</span><span class="nv">$nbrows</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">){</span>
   <span class="k">while</span><span class="p">(</span><span class="nv">$row</span> <span class="o">=</span> <span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">FETCH_ASSOC</span><span class="p">))</span> <span class="p">{</span>
    <span class="nv">$data</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$row</span><span class="p">;</span>
   <span class="p">}</span>
 <span class="p">}</span>  
 
 <span class="c1">// prepare the metadata</span>
 <span class="nv">$ret</span><span class="p">[</span><span class="s1">'metaData'</span><span class="p">]</span> <span class="o">=</span>   <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">makeMetaData</span><span class="p">(</span><span class="nv">$stmt</span><span class="p">);</span>
 <span class="nv">$ret</span><span class="p">[</span><span class="s1">'total'</span><span class="p">]</span>    <span class="o">=</span>   <span class="nv">$nbrows</span><span class="p">;</span>
 <span class="nv">$ret</span><span class="p">[</span><span class="s1">'data'</span><span class="p">]</span>     <span class="o">=</span>   <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">Char2Utf8</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span>
 <span class="nv">$ret</span><span class="p">[</span><span class="s1">'success'</span><span class="p">]</span>  <span class="o">=</span>   <span class="kc">true</span><span class="p">;</span>
 <span class="nv">$ret</span><span class="p">[</span><span class="s1">'message'</span><span class="p">]</span>  <span class="o">=</span>   <span class="kc">true</span><span class="p">;</span>
 
 <span class="k">echo</span> <span class="nb">json_encode</span><span class="p">(</span><span class="nv">$ret</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<br />
<br />
We want to avoid some unwanted characters to appear on the data, we need to convert some characters to <a href="http://ch1.php.net/utf8_encode" target="_blank" rel="noopener noreferrer">UTF8</a> format characters.<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MetaDataExample.php</span>
<span class="k">protected</span> <span class="k">function</span> <span class="n">Char2Utf8</span><span class="p">(</span><span class="nv">$var</span><span class="p">){</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">is_array</span><span class="p">(</span><span class="nv">$var</span><span class="p">))</span> <span class="p">{</span>
            <span class="nv">$out</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
            <span class="k">foreach</span> <span class="p">(</span><span class="nv">$var</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=&gt;</span> <span class="nv">$v</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$out</span><span class="p">[</span><span class="nv">$key</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">Char2Utf8</span><span class="p">(</span><span class="nv">$v</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">if</span><span class="p">(</span><span class="nb">gettype</span><span class="p">(</span><span class="nv">$var</span><span class="p">)</span><span class="o">==</span><span class="s1">'string'</span><span class="p">){</span>
                <span class="nv">$out</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="nb">chr</span><span class="p">(</span><span class="mi">194</span><span class="p">),</span> <span class="s2">""</span><span class="p">,</span> <span class="nv">$var</span><span class="p">);</span>
                <span class="nv">$out</span> <span class="o">=</span> <span class="nb">utf8_encode</span><span class="p">(</span><span class="nv">$out</span><span class="p">);</span>
            <span class="p">}</span>
            <span class="k">else</span>
              <span class="nv">$out</span> <span class="o">=</span> <span class="nv">$var</span><span class="p">;</span>  
        <span class="p">}</span>       
        <span class="k">return</span> <span class="nv">$out</span><span class="p">;</span>                   
    <span class="p">}</span></code></pre></figure>

<br />
<br />
At the following function, we start to generate the metadata for output. The key part is the value of <strong>'fields'</strong>, since we want to output the field types and default values based by the database's table structure.
<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MetaDataExample.php</span>
<span class="k">protected</span> <span class="k">function</span> <span class="n">makeMetaData</span><span class="p">(</span><span class="nv">$result</span><span class="p">,</span> <span class="nv">$overrides</span> <span class="o">=</span> <span class="kc">false</span><span class="p">){</span>
        <span class="cm">/*
        metaData: {
            idProperty: 'id',
            root: 'data',
            totalProperty: 'total',
            successProperty: 'success',
            messageProperty: 'message',
            fields: [
                {name: 'name', allowBlank: false},
                {name: 'job', mapping: 'occupation'}
            ],
            sortInfo: {field: 'name', direction:'ASC'}, // used by store to set its sortInfo
            foo: 'bar' // custom property
        }*/</span>
 
        <span class="nv">$metaData</span><span class="p">[</span><span class="s1">'idProperty'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'id'</span><span class="p">;</span>
        <span class="nv">$metaData</span><span class="p">[</span><span class="s1">'totalProperty'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'total'</span><span class="p">;</span>
        <span class="nv">$metaData</span><span class="p">[</span><span class="s1">'successProperty'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'success'</span><span class="p">;</span>
        <span class="nv">$metaData</span><span class="p">[</span><span class="s1">'root'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'data'</span><span class="p">;</span>        
        <span class="nv">$metaData</span><span class="p">[</span><span class="s1">'fields'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">parseMetaDataFields</span><span class="p">(</span><span class="nv">$result</span><span class="p">,</span> <span class="nv">$overrides</span><span class="p">);</span>        
        
        <span class="k">return</span> <span class="nv">$metaData</span><span class="p">;</span>
    <span class="p">}</span></code></pre></figure>

<br />
<br />
We start to parse the meta data output fields from the data columns of the data table. First of all, we find out the name of the data table from the query result object and gather the columns' information by calling '<b>getFullColumnsInfo</b>' function which is in the database class. Then we begin to collect the list of database output fields from the query result and match the names to the columns' information we have collected. The columns' information has pretty much enough properties we need in order to generate the settings of <b>field name, field type, default value</b> and <b>allowBlank</b> for meta data fields.<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MetaDataExample.php</span>
<span class="k">protected</span> <span class="k">function</span> <span class="n">parseMetaDataFields</span><span class="p">(</span><span class="nv">$stmt</span><span class="p">,</span> <span class="nv">$overrides</span> <span class="o">=</span> <span class="kc">false</span><span class="p">){</span>
        <span class="c1">// gets the table of the $result</span>
        <span class="nv">$table</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tableName</span><span class="p">;</span>
        <span class="c1">// gets the table descriptions for future use</span>
        <span class="nv">$columnsInfo</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">db</span><span class="o">-&gt;</span><span class="nf">getFullColumnsInfo</span><span class="p">(</span><span class="nv">$table</span><span class="p">);</span>
        <span class="c1">// gets the number of fields</span>
        <span class="nv">$nbFields</span> <span class="o">=</span> <span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">columnCount</span><span class="p">();</span>
        <span class="c1">// starts a empty array</span>
        <span class="nv">$fields</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
        <span class="c1">// loop through the fields</span>
        <span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nv">$nbFields</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">){</span>
          <span class="nv">$meta</span> <span class="o">=</span> <span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">getColumnMeta</span><span class="p">(</span><span class="nv">$i</span><span class="p">);</span>
          <span class="nv">$name</span>  <span class="o">=</span> <span class="nv">$meta</span><span class="p">[</span><span class="s1">'name'</span><span class="p">];</span>
          <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'name'</span><span class="p">]</span>  <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span> 
            
          <span class="k">if</span><span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$columnsInfo</span><span class="p">)){</span>
            <span class="nv">$type</span>  <span class="o">=</span> <span class="nv">$columnsInfo</span><span class="p">[</span><span class="nv">$name</span><span class="p">][</span><span class="s1">'Type'</span><span class="p">];</span>
                  
            <span class="k">if</span><span class="p">(</span><span class="nv">$type</span> <span class="o">==</span> <span class="s1">'date'</span><span class="p">)</span>
               <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'dateFormat'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'Y-m-d'</span><span class="p">;</span>
            <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nv">$type</span> <span class="o">==</span> <span class="s1">'datetime'</span><span class="p">)</span>
               <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'dateFormat'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'c'</span><span class="p">;</span>   
               
            <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'type'</span><span class="p">]</span>  <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">convertType</span><span class="p">(</span><span class="nv">$type</span><span class="p">);</span>
            
            <span class="k">if</span><span class="p">(</span><span class="nv">$name</span> <span class="o">!=</span> <span class="s1">'id'</span><span class="p">){</span>
                <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'allowBlank'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$columnsInfo</span><span class="p">[</span><span class="nv">$name</span><span class="p">][</span><span class="s1">'Null'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'YES'</span><span class="p">)</span> <span class="o">?</span> <span class="kc">true</span> <span class="o">:</span> <span class="kc">false</span><span class="p">;</span>
                <span class="c1">// if we have default value in table column</span>
                <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nb">is_null</span><span class="p">(</span><span class="nv">$columnsInfo</span><span class="p">[</span><span class="nv">$name</span><span class="p">][</span><span class="s1">'Default'</span><span class="p">])){</span>
                 <span class="k">if</span><span class="p">(</span><span class="nv">$columnsInfo</span><span class="p">[</span><span class="nv">$name</span><span class="p">][</span><span class="s1">'Default'</span><span class="p">]</span><span class="o">==</span><span class="s1">'CURRENT_TIMESTAMP'</span><span class="p">){</span>
                  <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'defaultValue'</span><span class="p">]</span> <span class="o">=</span><span class="s1">'new Date()'</span><span class="p">;</span>
                 <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                  <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'defaultValue'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$columnsInfo</span><span class="p">[</span><span class="nv">$name</span><span class="p">][</span><span class="s1">'Default'</span><span class="p">];</span>
                 <span class="p">}</span>                   
                <span class="p">}</span>
            <span class="p">}</span>
          <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
              <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'type'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'auto'</span><span class="p">;</span>
          <span class="p">}</span>
          
          <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$overrides</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="nb">is_array</span><span class="p">(</span><span class="nv">$overrides</span><span class="p">)){</span>
            <span class="k">if</span><span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$overrides</span><span class="p">)){</span>
                <span class="k">foreach</span><span class="p">(</span><span class="nv">$overrides</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$key</span><span class="o">=&gt;</span><span class="nv">$value</span><span class="p">){</span>
                    <span class="nv">$fields</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="nv">$key</span><span class="p">]</span><span class="o">=</span><span class="nv">$value</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>
          <span class="p">}</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="nv">$fields</span><span class="p">;</span>
    <span class="p">}</span></code></pre></figure>

<br />
<br />
The <b>convertType</b> function plays an important role. We want to convert MySQL's data type to ExtJs data type. This function contains my most used types. The rest of less used types, I leave them to be 'auto'. If you have further types need to be converted, feel free to add them in.<br />
<br />
Please note that MySQL does <b>not</b> have '<b><a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html" target="_blank" rel="noopener noreferrer">Boolean</a></b>' type, but it uses '<b><a href="http://dev.mysql.com/doc/refman/5.0/en/integer-types.html" target="_blank" rel="noopener noreferrer">tinyint</a></b>' instead.<br />
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MetaDataExample.php</span>
<span class="k">public</span> <span class="k">function</span> <span class="n">convertType</span><span class="p">(</span><span class="nv">$type</span><span class="p">){</span>
        <span class="k">if</span><span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$type</span><span class="p">,</span><span class="s1">'('</span><span class="p">)</span> <span class="o">!==</span> <span class="kc">false</span><span class="p">){</span>
            <span class="nv">$type</span> <span class="o">=</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$type</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">strpos</span><span class="p">(</span><span class="nv">$type</span><span class="p">,</span><span class="s1">'('</span><span class="p">));</span>
        <span class="p">}</span>

        <span class="k">switch</span><span class="p">(</span><span class="nv">$type</span><span class="p">){</span>
            <span class="k">case</span> <span class="s1">'varchar'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'char'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'text'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'tinytext'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'mediumtext'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'longtext'</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'string'</span><span class="p">;</span>
            <span class="k">case</span> <span class="s1">'int'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'smallint'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'mediumint'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'bigint'</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'int'</span><span class="p">;</span>
            <span class="k">case</span> <span class="s1">'tinyint'</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'boolean'</span><span class="p">;</span>
            <span class="k">case</span> <span class="s1">'real'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'float'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'double'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'decimal'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'numeric'</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'float'</span><span class="p">;</span>
            <span class="k">case</span> <span class="s1">'date'</span><span class="o">:</span>
            <span class="k">case</span> <span class="s1">'datetime'</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'date'</span><span class="p">;</span>
            <span class="k">default</span><span class="o">:</span>
                <span class="k">return</span> <span class="s1">'auto'</span><span class="p">;</span>        
        <span class="p">}</span>
    <span class="p">}</span></code></pre></figure>

<br />
<br />
The following simple database class wraps functions we need together. In this example, we use&nbsp;&nbsp;<b><a href="http://www.php.net/manual/en/ref.pdo-mysql.php" target="_blank" rel="noopener noreferrer">PDO</a></b>&nbsp;class to connect to our MySQL database. You might want to use&nbsp;<b><a href="http://www.php.net/manual/en/book.mysqli.php" target="_blank" rel="noopener noreferrer">mysqli</a></b> extension for MySQL functions instead. However I don't recommend using&nbsp;<b><a href="http://www.php.net/manual/en/ref.mysql.php" target="_blank" rel="noopener noreferrer">mysql</a></b>&nbsp;extension since <b>mysql</b> extension is <a href="http://www.php.net/manual/en/mysqlinfo.api.choosing.php" target="_blank" rel="noopener noreferrer">deprecated</a> since PHP version 5.5.0.<br />
<br />
<a href="http://www.blogger.com/blogger.g?blogID=1691872865366176972#" name="MySqlDataAdapter"></a>

<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="c1">// File Name: MySqlDataAdapter.php</span>
<span class="kd">class</span> <span class="nc">MySqlDataAdapter</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$server</span><span class="p">,</span> <span class="nv">$user</span><span class="p">,</span> <span class="nv">$password</span><span class="p">;</span>    
    <span class="cd">/**
    * Db name
    */</span>
    <span class="k">public</span> <span class="nv">$dbName</span><span class="p">;</span>
    
    <span class="cd">/**
    * MySQL pdo object
    */</span>
    <span class="k">public</span> <span class="nv">$pdo</span><span class="p">;</span>
    
    <span class="cd">/**
    * Result of statement
    */</span>
    <span class="k">protected</span> <span class="nv">$stmt</span><span class="p">;</span>
    
    <span class="cd">/**
     * Constructor
     */</span>              
    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$server</span><span class="p">,</span> <span class="nv">$user</span><span class="p">,</span> <span class="nv">$password</span><span class="p">,</span> <span class="nv">$dbName</span><span class="p">){</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">server</span>   <span class="o">=</span> <span class="nv">$server</span><span class="p">;</span>      <span class="c1">// Host address</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user</span>     <span class="o">=</span> <span class="nv">$user</span><span class="p">;</span>        <span class="c1">// User</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>    <span class="c1">// Password</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">dbName</span>   <span class="o">=</span> <span class="nv">$dbName</span><span class="p">;</span>      <span class="c1">// Database         </span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">connect</span><span class="p">();</span>
    <span class="p">}</span>
 
    <span class="cd">/**
     * Destructor
     *
     * @return void
     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">__destruct</span><span class="p">(){</span>
     <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">stmt</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
    <span class="p">}</span>
 
    <span class="cd">/**
     * Connect to the database
     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">connect</span><span class="p">(){</span>
       <span class="c1">// create the pdo object     </span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PDO</span><span class="p">(</span><span class="s1">'mysql:host='</span><span class="mf">.</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">server</span><span class="mf">.</span><span class="s1">';dbname='</span><span class="mf">.</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">dbName</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span><span class="p">);</span>       
       <span class="c1">// if connection is failed, then trigger user error</span>
       <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span> <span class="o">===</span> <span class="kc">false</span><span class="p">){</span>
            <span class="nb">trigger_error</span><span class="p">(</span><span class="s1">'Could not connect to the database.'</span><span class="p">,</span> <span class="kc">E_USER_ERROR</span><span class="p">);</span>
    <span class="p">}</span><span class="k">else</span><span class="p">{</span>
      <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="o">-&gt;</span><span class="nb">exec</span><span class="p">(</span><span class="s2">"set names utf8"</span><span class="p">);</span>
    <span class="p">}</span>
       <span class="c1">// return the connection object</span>
       <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="p">;</span>
    <span class="p">}</span>    
    
    <span class="cd">/**
     * Query the database
     *
     * @param string $queryStr SQL query string
     * @return resource MySQL result set
     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">query</span><span class="p">(</span><span class="nv">$queryStr</span><span class="p">){</span>
     <span class="k">try</span><span class="p">{</span>
      <span class="c1">//calling beginTransaction() turns off auto commit automatically</span>
      <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="o">-&gt;</span><span class="nf">beginTransaction</span><span class="p">();</span>
   <span class="c1">// prepare the statement</span>
   <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">stmt</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="o">-&gt;</span><span class="nf">prepare</span><span class="p">(</span><span class="nv">$queryStr</span><span class="p">);</span>
   <span class="c1">// execute the statement</span>
   <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">stmt</span><span class="o">-&gt;</span><span class="nf">execute</span><span class="p">();</span>
   <span class="c1">// commit the statement if everything is alright</span>
   <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="o">-&gt;</span><span class="nf">commit</span><span class="p">();</span>
  <span class="p">}</span>
  <span class="k">catch</span><span class="p">(</span><span class="nc">PDOException</span> <span class="nv">$ex</span><span class="p">){</span>
   <span class="c1">//Something went wrong rollback!</span>
      <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">pdo</span><span class="o">-&gt;</span><span class="nf">rollBack</span><span class="p">();</span>
   <span class="c1">// trigger an sql error</span>
   <span class="nb">trigger_error</span><span class="p">(</span><span class="nv">$ex</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">(),</span> <span class="kc">E_USER_ERROR</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="c1">// return the statement object</span>
  <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">stmt</span><span class="p">;</span>
    <span class="p">}</span> 

 <span class="cd">/**
  * Get column info from table name
  */</span>
    <span class="k">function</span> <span class="n">getFullColumnsInfo</span><span class="p">(</span><span class="nv">$table</span><span class="p">){</span>
        <span class="nv">$stmt</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">query</span><span class="p">(</span><span class="s2">"SHOW FULL COLUMNS FROM `</span><span class="si">{</span><span class="nv">$table</span><span class="si">}</span><span class="s2">`"</span><span class="p">);</span>
        <span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
        <span class="c1">// gets the information</span>
        <span class="k">while</span><span class="p">(</span><span class="nv">$row</span> <span class="o">=</span> <span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">(</span><span class="no">PDO</span><span class="o">::</span><span class="no">FETCH_ASSOC</span><span class="p">)){</span>
            <span class="nv">$data</span><span class="p">[</span><span class="nv">$row</span><span class="p">[</span><span class="s1">'Field'</span><span class="p">]]</span> <span class="o">=</span> <span class="nv">$row</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="c1">// return the data array</span>
        <span class="k">return</span> <span class="nv">$data</span><span class="p">;</span>        
    <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<br />
<br />
You can also use the same concept to configure the Grid Panel column settings via the meta data. Have a look at '<a href="http://www.elvishsu66.com/2011/05/dynamic-gridpanel-for-extjs-4.html" target="_blank" rel="noopener noreferrer">Dynamic GridPanel for ExtJs 4</a>' and it may give you some ideas to apply column settings via meta data to the Grid Panel.<br />
<br />
You can download the source code via <a href="https://drive.google.com/uc?export=download&amp;confirm=no_antivirus&amp;id=0BxNgktpBGY4YcmxpdlZlRmY1RGM">here</a>.<br />
<br />]]></content><author><name>Elvis Hsu</name></author><category term="ExtJs" /><category term="Coding" /><summary type="html"><![CDATA[Metadata is one of my most used properties in&nbsp;Ext.data.reader.Reader. It allows me to pass custom data/configuration to Grid Panel, Form, ComboBox and other components without needing extra efforts to change the code. At the following example, I just want to put my column layout configuration to the grid without configuring the data fields in the data store. If the settings of data fields is bound with data columns' information on the database, then we could save a lot of time to match the data field types when updating/retrieving data to/from server. In this article, we are going to retrieve field types, defaultValues, and allowBlank settings via the meta data which is generated based on the data columns information of the MySQL database. For example, we want to display a data grid with paging toolbar which shows a list of values of 'items'. We now just need to create a simple JsonStore and let the proxy retrieves the information by 'MetaDataExample.php'.]]></summary></entry><entry><title type="html">ExtJs file upload panel</title><link href="https://www.elvishsu.com/2013/12/extjs-file-upload-panel.html" rel="alternate" type="text/html" title="ExtJs file upload panel" /><published>2013-12-20T16:50:00+00:00</published><updated>2013-12-20T16:50:00+00:00</updated><id>https://www.elvishsu.com/2013/12/extjs-file-upload-panel</id><content type="html" xml:base="https://www.elvishsu.com/2013/12/extjs-file-upload-panel.html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCup4czzVcMxBJg04eKqMSpKpH2sNB7xxeu5V-YGGjSF9uy-fWE27i_K8DR0_pdoenGokf9LLnVmfB9Qo-nMmU_GS95ONL5uOUbikTEt2_mG5WXm7NaBXoCMsyQ2-COyVfBv0VS7QbniE/s1600/file_upload.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="ExtJs file upload panel" border="0" src="/assets/posts/blogger/2013-12-20-image-0000.png" height="165" title="ExtJs file upload panel" width="200" /></a></div>
A while ago, I tried to create a reusable file upload management panel for the internal intranet system. So I ended up making an extension from a grid panel with DnD and multiple files upload field. This solution allows user to select multiple files to upload as long as the browser supports HTML5. It also indicates the upload progress on each file.<br />
<br />
This widget validates file names and sizes on the client side instead of server side. The file does not need to be uploaded to server to validate its properties. Since the file is streamed to server, you may need to work out how you handle the code on the server side. I have provided a simple php code at the end of this article for anyone to start with.
<br />
<br />
Anyway in order to make this widget to work, you may need the following three extensions.<br />
<a name='more'></a><br />
<div>
<b><u>1.&nbsp;MultipleFileField</u></b></div>
<div>
<div>
<br />
The default file field from ExtJs only allows you to upload single file at a time. To enable uploading multiple file, you need to tweak the DOM settings.<br />
<br />
<b>Multiple file field (inspired from <a href="http://www.sencha.com/forum/showthread.php?143951-Multiple-select-in-a-FileField" target="_blank" rel="noopener noreferrer">here</a>)</b><br />
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">Ext</span><span class="p">.</span><span class="nx">define</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.ux.form.field.MultipleFileField</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">extend</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ext.form.field.File</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">alias</span><span class="p">:[</span><span class="dl">'</span><span class="s1">widget.multifilefield</span><span class="dl">'</span><span class="p">,</span>
           <span class="dl">'</span><span class="s1">widget.multiplefilefield</span><span class="dl">'</span><span class="p">,</span>
           <span class="dl">'</span><span class="s1">widget.multifile</span><span class="dl">'</span><span class="p">],</span>
    <span class="cm">/**
     * Override to add a "multiple" attribute.
     */</span>
    <span class="na">onRender</span><span class="p">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">callParent</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
        
        <span class="k">this</span><span class="p">.</span><span class="nx">fileInputEl</span><span class="p">.</span><span class="kd">set</span><span class="p">({</span>
            <span class="na">multiple</span><span class="p">:</span> <span class="dl">'</span><span class="s1">multiple</span><span class="dl">'</span>
        <span class="p">});</span>
    <span class="p">}</span>
<span class="p">});</span></code></pre></figure>

</div>
<div>
<br /></div>
<div>
<b><u>2. FileDrop</u></b></div>
<div>
<br />
The FileDrop plugin allows user to drop their files via their desktop.&nbsp;<a href="http://www.sencha.com/forum/showthread.php?126891-Ext.plugin.extjs.FIleDrop" target="_blank" rel="noopener noreferrer">FileDrop</a> plugin is created by&nbsp;<a href="https://github.com/mitchellsimoens">Mitchell Simoens</a>&nbsp;and you can download it from&nbsp;<a href="https://github.com/mitchellsimoens/Ext.plugin.extjs.FileDrop">here</a>. 
<br />
<br />
Please note: you may need to change the class name from "<b>Ext.plugin.extjs.FileDrop</b>" to "<b>Ext.ux.form.FileDrop</b>"</div>
<div>
<div>
<br /></div>
<div>
<b><u>3. IFrame</u></b></div>
<div>
<br />
The purpose of using IFrame widget is to show the file without downloading it. Those files might be *.html, *.txt, *.xml or *.pdf. Some users may just want to view it instead of downloading it.<br />
<br />
You can download the widget from <a href="http://www.sencha.com/forum/showthread.php?71961" target="_blank" rel="noopener noreferrer">here </a>and change the class name to '<b>Ext.ux.IFrame</b>'</div>
</div>
<div>
<br /></div>
<div>
<br />
<b>File upload grid panel</b><br />
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">Ext</span><span class="p">.</span><span class="nx">define</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.ux.form.FileUploadPanel</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">extend</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ext.panel.Panel</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">alias</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">widget.filepanel</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">fileuploadpanel</span><span class="dl">'</span><span class="p">],</span>
    <span class="na">requires</span><span class="p">:[</span>
        <span class="dl">'</span><span class="s1">Ext.ux.form.field.MultipleFileField</span><span class="dl">'</span><span class="p">,</span>
        <span class="dl">'</span><span class="s1">Ext.ux.form.FileDrop</span><span class="dl">'</span><span class="p">,</span>
        <span class="dl">'</span><span class="s1">Ext.ux.IFrame</span><span class="dl">'</span>
    <span class="p">],</span>
    <span class="na">layout</span><span class="p">:</span><span class="dl">'</span><span class="s1">card</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">autoLoadStore</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="na">maxFileSize</span><span class="p">:</span><span class="mi">10485760</span><span class="p">,</span> <span class="c1">// 10Mb</span>
    <span class="na">listUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/file/getFileList</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// your MVC path to get file list</span>
    <span class="na">listParams</span><span class="p">:{},</span>
    <span class="na">uploadUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/file/upload</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// your MVC path upload files</span>
    <span class="na">uploadParams</span><span class="p">:{},</span>
    <span class="na">downloadUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/file/download</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// your MVC path to download the file</span>
    <span class="na">downloadParams</span><span class="p">:{},</span>
    <span class="na">deleteUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/file/delete</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// your MVC path to delete the file</span>
    <span class="na">deleteParams</span><span class="p">:{},</span>
    <span class="cm">/**
    * initialising the components
    */</span>
    <span class="na">initComponent</span><span class="p">:</span> <span class="kd">function</span><span class="p">(){</span>
        <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
        <span class="c1">// Create the datastore if available</span>
        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">Ext</span><span class="p">.</span><span class="nx">isDefined</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">)){</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">store</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.data.Store</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
               <span class="na">autoLoad</span><span class="p">:</span><span class="nx">me</span><span class="p">.</span><span class="nx">autoLoadStore</span><span class="p">,</span>
               <span class="na">fields</span><span class="p">:[</span>
                <span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span>
                <span class="dl">'</span><span class="s1">size</span><span class="dl">'</span><span class="p">,</span>
                <span class="dl">'</span><span class="s1">type</span><span class="dl">'</span><span class="p">,</span> 
                <span class="p">{</span><span class="na">name</span><span class="p">:</span><span class="dl">'</span><span class="s1">lastModifiedDate</span><span class="dl">'</span><span class="p">,</span> <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">date</span><span class="dl">'</span><span class="p">,</span> <span class="na">dateFormat</span><span class="p">:</span><span class="dl">'</span><span class="s1">Y-m-d H:i:s</span><span class="dl">'</span><span class="p">},</span>
                <span class="dl">'</span><span class="s1">iconCls</span><span class="dl">'</span><span class="p">,</span>
                <span class="p">{</span><span class="na">name</span><span class="p">:</span><span class="dl">'</span><span class="s1">new_window</span><span class="dl">'</span><span class="p">,</span> <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">bool</span><span class="dl">'</span><span class="p">}</span>
               <span class="p">],</span>
               <span class="na">proxy</span><span class="p">:{</span>
                 <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">ajax</span><span class="dl">'</span><span class="p">,</span>
                 <span class="na">url</span><span class="p">:</span><span class="nx">me</span><span class="p">.</span><span class="nx">listUrl</span><span class="p">,</span>
                 <span class="na">extraParams</span><span class="p">:</span> <span class="nx">me</span><span class="p">.</span><span class="nx">listParams</span> <span class="o">||</span> <span class="kc">undefined</span><span class="p">,</span>
                 <span class="na">reader</span><span class="p">:{</span>
                     <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">json</span><span class="dl">'</span><span class="p">,</span>
                     <span class="na">root</span><span class="p">:</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span>
                 <span class="p">},</span>
                 <span class="na">listeners</span><span class="p">:{</span><span class="na">exception</span><span class="p">:</span><span class="nx">Ext</span><span class="p">.</span><span class="nx">onException</span> <span class="p">}</span>
               <span class="p">}</span>
           <span class="p">});</span>
        <span class="p">};</span>
        <span class="c1">// the temporary store to handle file uploading </span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.data.Store</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
            <span class="na">fields</span><span class="p">:[</span>
             <span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span>
             <span class="dl">'</span><span class="s1">size</span><span class="dl">'</span><span class="p">,</span>
             <span class="dl">'</span><span class="s1">type</span><span class="dl">'</span><span class="p">,</span> 
             <span class="p">{</span><span class="na">name</span><span class="p">:</span><span class="dl">'</span><span class="s1">lastModifiedDate</span><span class="dl">'</span><span class="p">,</span> <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">date</span><span class="dl">'</span><span class="p">,</span> <span class="na">dateFormat</span><span class="p">:</span><span class="dl">'</span><span class="s1">Y-m-d H:i:s</span><span class="dl">'</span><span class="p">},</span> 
             <span class="p">{</span><span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">progress</span><span class="dl">'</span><span class="p">,</span> <span class="na">type</span><span class="p">:</span><span class="dl">'</span><span class="s1">int</span><span class="dl">'</span><span class="p">}</span>
            <span class="p">],</span>
        <span class="p">});</span>        
        <span class="c1">// create a tool bar</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">bbar</span> <span class="o">!==</span> <span class="kc">false</span><span class="p">){</span>
           <span class="nx">me</span><span class="p">.</span><span class="nx">bbar</span> <span class="o">=</span> <span class="p">[{</span>
               <span class="na">xtype</span><span class="p">:</span><span class="dl">'</span><span class="s1">tbtext</span><span class="dl">'</span><span class="p">,</span>
               <span class="na">text</span><span class="p">:</span><span class="dl">'</span><span class="s1">Drap and drop your files to the grid</span><span class="dl">'</span>
           <span class="p">},</span><span class="dl">'</span><span class="s1">-&gt;</span><span class="dl">'</span><span class="p">,{</span>
               <span class="na">xtype</span><span class="p">:</span><span class="dl">'</span><span class="s1">multifile</span><span class="dl">'</span><span class="p">,</span>
               <span class="na">buttonOnly</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
               <span class="na">allowBlank</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
               <span class="na">submitValue</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span>
               <span class="na">buttonConfig</span><span class="p">:{</span>
                   <span class="na">text</span><span class="p">:</span><span class="dl">'</span><span class="s1">Add attachments</span><span class="dl">'</span><span class="p">,</span>
                   <span class="na">iconCls</span><span class="p">:</span><span class="dl">'</span><span class="s1">icon-add</span><span class="dl">'</span>
               <span class="p">},</span>
               <span class="na">listeners</span><span class="p">:{</span>
                   <span class="na">render</span><span class="p">:</span><span class="kd">function</span><span class="p">(){</span>
                       <span class="kd">var</span> <span class="nx">el</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getEl</span><span class="p">(),</span>
                           <span class="nx">field</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
                       <span class="nx">el</span><span class="p">.</span><span class="nx">dom</span><span class="p">.</span><span class="nx">onchange</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
                           <span class="nx">me</span><span class="p">.</span><span class="nx">checkFileUpload</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">files</span><span class="p">);</span>
                       <span class="p">};</span>
                   <span class="p">}</span>
               <span class="p">}</span>
           <span class="p">}];</span>  
        <span class="p">};</span>
        <span class="c1">// default config            </span>
        <span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
            <span class="na">defaults</span><span class="p">:{</span>
                <span class="na">xtype</span><span class="p">:</span><span class="dl">'</span><span class="s1">grid</span><span class="dl">'</span><span class="p">,</span>
                <span class="na">enableColumnHide</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span>
                <span class="na">enableColumnMove</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span>
                <span class="na">plugins</span><span class="p">:[{</span>
                    <span class="na">ptype</span><span class="p">:</span> <span class="dl">'</span><span class="s1">filedrop</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">readType</span><span class="p">:</span><span class="dl">'</span><span class="s1">DataURL</span><span class="dl">'</span>
                <span class="p">}]</span>
            <span class="p">},</span>
            <span class="na">tools</span><span class="p">:</span> <span class="p">[{</span>
                <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">refresh</span><span class="dl">'</span><span class="p">,</span>
                <span class="na">handler</span><span class="p">:</span> <span class="kd">function</span><span class="p">(){</span>
                    <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>
                <span class="p">}</span>
            <span class="p">}],</span>
            <span class="na">items</span><span class="p">:[{</span>
                <span class="na">store</span><span class="p">:</span><span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">,</span>
                <span class="na">columns</span><span class="p">:[{</span>
                    <span class="na">header</span><span class="p">:</span><span class="dl">'</span><span class="s1">Files</span><span class="dl">'</span><span class="p">,</span> 
                    <span class="na">flex</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> 
                    <span class="na">dataIndex</span><span class="p">:</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">renderer</span><span class="p">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">metaData</span><span class="p">,</span> <span class="nx">record</span><span class="p">){</span>
                        <span class="kd">var</span> <span class="nx">exportMode</span><span class="o">=</span><span class="kc">false</span><span class="p">;</span>                
                        <span class="k">if</span><span class="p">(</span><span class="nx">Ext</span><span class="p">.</span><span class="nx">isDefined</span><span class="p">(</span><span class="nx">metaData</span><span class="p">)</span> 
                            <span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">isDefined</span><span class="p">(</span><span class="nx">metaData</span><span class="p">.</span><span class="nx">exportMode</span><span class="p">)){</span>
                            <span class="nx">exportMode</span><span class="o">=</span><span class="nx">metaData</span><span class="p">.</span><span class="nx">exportMode</span>
                        <span class="p">};</span>
                        <span class="k">if</span><span class="p">(</span><span class="nx">exportMode</span><span class="p">){</span>
                            <span class="k">return</span> <span class="nx">value</span><span class="p">;</span>
                        <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                            <span class="kd">var</span> <span class="nx">lastModifiedDate</span> <span class="o">=</span> <span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">lastModifiedDate</span><span class="dl">'</span><span class="p">);</span>
                            <span class="kd">var</span> <span class="nx">date</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">util</span><span class="p">.</span><span class="nx">Format</span><span class="p">.</span><span class="nx">date</span><span class="p">(</span><span class="nx">lastModifiedDate</span><span class="p">,</span> <span class="dl">"</span><span class="s2">d/m/Y g:i a</span><span class="dl">"</span><span class="p">);</span>
                            <span class="k">return</span> <span class="dl">'</span><span class="s1">&lt;div class="</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">iconCls</span><span class="dl">'</span><span class="p">)</span> <span class="o">+</span><span class="dl">'</span><span class="s1">" style="background-position: center left!important; padding: 0 15px 0 25px;"&gt;</span><span class="dl">'</span><span class="o">+</span>
                            <span class="dl">'</span><span class="s1">&lt;b style="display: block;" title="</span><span class="dl">'</span><span class="o">+</span><span class="nx">value</span><span class="o">+</span><span class="dl">'</span><span class="s1">"&gt;</span><span class="dl">'</span><span class="o">+</span><span class="nx">value</span><span class="o">+</span><span class="dl">'</span><span class="s1">&lt;/b&gt;</span><span class="dl">'</span><span class="o">+</span>
                            <span class="dl">'</span><span class="s1">&lt;span style="font-size: 80%;"&gt;Size: </span><span class="dl">'</span><span class="o">+</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">size</span><span class="dl">'</span><span class="p">)</span><span class="o">+</span><span class="dl">'</span><span class="s1">, Last Modified: </span><span class="dl">'</span><span class="o">+</span> <span class="nx">date</span> <span class="o">+</span><span class="dl">'</span><span class="s1">&lt;/span&gt;&lt;/div&gt;</span><span class="dl">'</span><span class="p">;</span> 
                        <span class="p">};</span>
                    <span class="p">}</span>            
                <span class="p">},{</span>
                    <span class="na">xtype</span><span class="p">:</span> <span class="dl">'</span><span class="s1">actioncolumn</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">cls</span><span class="p">:</span> <span class="dl">'</span><span class="s1">x-icon-column-header x-action-disk-column-header</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// define your css icon here</span>
                    <span class="na">width</span><span class="p">:</span> <span class="mi">24</span><span class="p">,</span>
                    <span class="na">icon</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/public/images/ext/silk/arrow_down.png</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// change your icon path here</span>
                    <span class="na">iconCls</span><span class="p">:</span> <span class="dl">'</span><span class="s1">x-hidden</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">tooltip</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Download selected file</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">menuDisabled</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
                    <span class="na">sortable</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
                    <span class="na">handler</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">gridView</span><span class="p">,</span> <span class="nx">rowIndex</span><span class="p">,</span> <span class="nx">colIndex</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
                       <span class="nx">gridView</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="nx">record</span><span class="p">);</span>
                       <span class="kd">var</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">applyIf</span><span class="p">({</span><span class="na">fileName</span><span class="p">:</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">)},</span><span class="nx">me</span><span class="p">.</span><span class="nx">downloadParams</span><span class="p">),</span>
                           <span class="nx">queryStr</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">toQueryString</span><span class="p">(</span><span class="nx">params</span><span class="p">),</span>
                           <span class="nx">url</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">downloadUrl</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">/?</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">queryStr</span><span class="p">;</span>
                        <span class="k">if</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">new_window</span><span class="dl">'</span><span class="p">)</span> <span class="o">===</span> <span class="kc">true</span><span class="p">){</span>
                            <span class="nx">me</span><span class="p">.</span><span class="nx">showDownloadWindow</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span><span class="nx">record</span><span class="p">);</span>
                        <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                            <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="o">=</span><span class="nx">url</span><span class="p">;</span>
                        <span class="p">};</span>
                    <span class="p">}</span>
                <span class="p">},{</span>
                    <span class="na">xtype</span><span class="p">:</span> <span class="dl">'</span><span class="s1">actioncolumn</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">cls</span><span class="p">:</span> <span class="dl">'</span><span class="s1">x-icon-column-header x-action-delete-column-header</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// define your css icon here</span>
                    <span class="na">width</span><span class="p">:</span> <span class="mi">24</span><span class="p">,</span>
                    <span class="na">icon</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/public/images/ext/silk/delete.png</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">iconCls</span><span class="p">:</span> <span class="dl">'</span><span class="s1">x-hidden</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">tooltip</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Delete selected file</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">menuDisabled</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
                    <span class="na">sortable</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
                    <span class="na">handler</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">gridView</span><span class="p">,</span> <span class="nx">rowIndex</span><span class="p">,</span> <span class="nx">colIndex</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
                       <span class="nx">gridView</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="nx">record</span><span class="p">);</span>
                       <span class="kd">var</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">applyIf</span><span class="p">({</span><span class="na">fileName</span><span class="p">:</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">)},</span><span class="nx">me</span><span class="p">.</span><span class="nx">deleteParams</span><span class="p">);</span>                        
                           <span class="nx">Ext</span><span class="p">.</span><span class="nx">Ajax</span><span class="p">.</span><span class="nx">request</span><span class="p">({</span>
                             <span class="na">url</span><span class="p">:</span> <span class="nx">me</span><span class="p">.</span><span class="nx">deleteUrl</span><span class="p">,</span>
                             <span class="na">params</span><span class="p">:</span> <span class="nx">params</span><span class="p">,</span>
                             <span class="na">success</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">){</span>
                                 <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>
                             <span class="p">}</span>
                          <span class="p">});</span>
                    <span class="p">}</span>                       
                <span class="p">}],</span>                  
                <span class="na">listeners</span><span class="p">:{</span>
                   <span class="na">itemmouseenter</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">view</span><span class="p">,</span> <span class="nx">list</span><span class="p">,</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">rowIndex</span><span class="p">,</span> <span class="nx">e</span><span class="p">){</span>
                        <span class="kd">var</span> <span class="nx">icons</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">DomQuery</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="dl">'</span><span class="s1">.x-action-col-icon</span><span class="dl">'</span><span class="p">,</span> <span class="nx">node</span><span class="p">);</span>
                            <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">icons</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">icon</span><span class="p">){</span>
                                <span class="nx">Ext</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">icon</span><span class="p">).</span><span class="nx">removeCls</span><span class="p">(</span><span class="dl">'</span><span class="s1">x-hidden</span><span class="dl">'</span><span class="p">);</span>
                            <span class="p">});</span>
                   <span class="p">},</span>
                   <span class="na">itemmouseleave</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">view</span><span class="p">,</span> <span class="nx">list</span><span class="p">,</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">rowIndex</span><span class="p">,</span> <span class="nx">e</span><span class="p">){</span>
                        <span class="kd">var</span> <span class="nx">icons</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">DomQuery</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="dl">'</span><span class="s1">.x-action-col-icon</span><span class="dl">'</span><span class="p">,</span> <span class="nx">node</span><span class="p">);</span>
                        <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">icons</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">icon</span><span class="p">){</span>
                            <span class="nx">Ext</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">icon</span><span class="p">).</span><span class="nx">addCls</span><span class="p">(</span><span class="dl">'</span><span class="s1">x-hidden</span><span class="dl">'</span><span class="p">);</span>
                        <span class="p">});</span>
                   <span class="p">},</span>
                   <span class="na">loadstart</span> <span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">cmp</span><span class="p">,</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">file</span><span class="p">)</span> <span class="p">{</span>
                       <span class="nx">me</span><span class="p">.</span><span class="nx">checkFileUpload</span><span class="p">([</span><span class="nx">file</span><span class="p">]);</span>
                   <span class="p">}</span>                                
                <span class="p">}</span>            
            <span class="p">},{</span>
                <span class="na">store</span><span class="p">:</span> <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">,</span>
                <span class="na">viewConfig</span><span class="p">:{</span>
                    <span class="na">markDirty</span><span class="p">:</span><span class="kc">false</span>
                <span class="p">},</span>
                <span class="na">columns</span><span class="p">:[{</span>
                    <span class="na">header</span><span class="p">:</span><span class="dl">'</span><span class="s1">Files</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">dataIndex</span><span class="p">:</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">flex</span><span class="p">:</span><span class="mi">1</span>
                <span class="p">},{</span>
                    <span class="na">header</span><span class="p">:</span><span class="dl">'</span><span class="s1">Progress</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">dataIndex</span><span class="p">:</span><span class="dl">'</span><span class="s1">progress</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">align</span><span class="p">:</span><span class="dl">'</span><span class="s1">center</span><span class="dl">'</span><span class="p">,</span>
                    <span class="na">width</span><span class="p">:</span><span class="mi">90</span><span class="p">,</span>
                    <span class="na">renderer</span><span class="p">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">meta</span><span class="p">,</span> <span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
                        <span class="kd">var</span> <span class="nx">color</span> <span class="o">=</span> <span class="p">(</span><span class="nx">value</span> <span class="o">&lt;</span> <span class="mi">100</span><span class="p">)</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">red</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">green</span><span class="dl">'</span><span class="p">;</span>
                        <span class="k">return</span> <span class="nx">Ext</span><span class="p">.</span><span class="nb">String</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="dl">'</span><span class="s1">&lt;b style="color: {0};"&gt;{1}%&lt;/b&gt;</span><span class="dl">'</span><span class="p">,</span> <span class="nx">color</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
                    <span class="p">}</span>                    
                <span class="p">}],</span>
                <span class="na">listeners</span><span class="p">:{</span>
                   <span class="na">loadstart</span> <span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">cmp</span><span class="p">,</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">file</span><span class="p">)</span> <span class="p">{</span>
                      <span class="nx">me</span><span class="p">.</span><span class="nx">checkFileUpload</span><span class="p">([</span><span class="nx">file</span><span class="p">]);</span>
                   <span class="p">}</span>                                
                <span class="p">}</span>                
            <span class="p">}]</span>
        <span class="p">};</span>
        <span class="c1">// appy to this config</span>
        <span class="nx">Ext</span><span class="p">.</span><span class="nx">applyIf</span><span class="p">(</span><span class="nx">me</span><span class="p">,</span> <span class="nx">config</span><span class="p">);</span>
        <span class="c1">// apply to the initialConfig</span>
        <span class="nx">Ext</span><span class="p">.</span><span class="nx">applyIf</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">initialConfig</span><span class="p">,</span> <span class="nx">config</span><span class="p">);</span>
        <span class="c1">// call the arguments</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">callParent</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
        <span class="c1">// init the settings</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">render</span><span class="dl">'</span><span class="p">,</span><span class="nx">me</span><span class="p">.</span><span class="nx">onPanelRender</span><span class="p">,</span><span class="nx">me</span><span class="p">);</span>
        <span class="c1">// assign title prefix</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">titlePrefix</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">title</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">Attachments</span><span class="dl">'</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// init store events when render</span>
    <span class="na">onPanelRender</span><span class="p">:</span><span class="kd">function</span><span class="p">(){</span>
        <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">){</span>
            <span class="c1">// create grid value to the store for future use</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">grid</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">items</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> 
            <span class="c1">// change title when load</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">load</span><span class="dl">'</span><span class="p">,</span><span class="kd">function</span><span class="p">(){</span>
               <span class="kd">var</span> <span class="nx">count</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">count</span><span class="p">();</span>
               <span class="k">if</span><span class="p">(</span><span class="nx">count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
                <span class="nx">me</span><span class="p">.</span><span class="nx">setTitle</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">titlePrefix</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> (</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">count</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">)</span><span class="dl">'</span><span class="p">);</span>
               <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                <span class="nx">me</span><span class="p">.</span><span class="nx">setTitle</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">titlePrefix</span><span class="p">);</span>
               <span class="p">};</span>                
            <span class="p">});</span>    
        <span class="p">};</span>
        
        <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">){</span>
          <span class="c1">// if new file is uploading, then show progress panel</span>
          <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">add</span><span class="dl">'</span><span class="p">,</span><span class="kd">function</span><span class="p">(){</span>
             <span class="nx">me</span><span class="p">.</span><span class="nx">getLayout</span><span class="p">().</span><span class="nx">setActiveItem</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> 
          <span class="p">});</span> 
          
          <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">remove</span><span class="dl">'</span><span class="p">,</span><span class="kd">function</span><span class="p">(){</span>
              <span class="kd">var</span> <span class="nx">count</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">count</span><span class="p">();</span>
              <span class="k">if</span><span class="p">(</span><span class="nx">count</span> <span class="o">==</span> <span class="mi">0</span><span class="p">){</span>
                  <span class="nx">me</span><span class="p">.</span><span class="nx">getLayout</span><span class="p">().</span><span class="nx">setActiveItem</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> 
              <span class="p">};</span>
          <span class="p">});</span> 
        <span class="p">};</span>
    <span class="p">},</span>
    <span class="c1">// when user uses filefield</span>
    <span class="na">checkFileUpload</span><span class="p">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">files</span><span class="p">){</span>
        <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span>
            <span class="nx">invalidList</span> <span class="o">=</span> <span class="p">[];</span>
            
        <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">files</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
           <span class="k">if</span><span class="p">(</span><span class="nx">file</span><span class="p">.</span><span class="nx">size</span> <span class="o">&gt;</span> <span class="nx">me</span><span class="p">.</span><span class="nx">maxFileSize</span><span class="p">){</span>
             <span class="nx">invalidList</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span>  
           <span class="p">};</span> 
        <span class="p">});</span>
        
        <span class="k">if</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
            <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">&lt;ul&gt;</span><span class="dl">'</span><span class="p">;</span>
            <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
                <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;li&gt;</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">&lt;/li&gt;</span><span class="dl">'</span><span class="p">;</span>
            <span class="p">});</span>
            
            <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;/ul&gt;</span><span class="dl">'</span><span class="p">;</span>
            <span class="kd">var</span> <span class="nx">pl</span> <span class="o">=</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">;</span>
            <span class="nx">msg</span> <span class="o">+=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nb">String</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="dl">'</span><span class="s1">{0} file{1} exceed{2} file upload limit. Please try again!!</span><span class="dl">'</span><span class="p">,</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">:</span> <span class="dl">''</span><span class="p">),</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">''</span><span class="p">:</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">));</span>
            
            <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">show</span><span class="p">({</span>
                 <span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">Exceed file upload limit</span><span class="dl">'</span><span class="p">,</span>
                 <span class="na">msg</span><span class="p">:</span> <span class="nx">msg</span><span class="p">,</span>
                 <span class="na">buttons</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">OK</span><span class="p">,</span>
                 <span class="na">icon</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">WARNING</span>
            <span class="p">});</span>
            
            <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
        <span class="p">};</span>
        
        <span class="c1">// check the current file list</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
            <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">files</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
               <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">findExact</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span><span class="nx">file</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">){</span>
                 <span class="nx">invalidList</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span>  
               <span class="p">};</span> 
            <span class="p">});</span>        
            
            
            <span class="k">if</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
                <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">&lt;ul&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
                    <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;li&gt;</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">&lt;/li&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="p">});</span>
                
                <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;/ul&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="kd">var</span> <span class="nx">pl</span> <span class="o">=</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nx">msg</span> <span class="o">+=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nb">String</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="dl">'</span><span class="s1">{0} file{1} already exist{2}.Please try again!!</span><span class="dl">'</span><span class="p">,</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">:</span> <span class="dl">''</span><span class="p">),</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">''</span><span class="p">:</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">));</span>
                
                <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">show</span><span class="p">({</span>
                     <span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">File exists</span><span class="dl">'</span><span class="p">,</span>
                     <span class="na">msg</span><span class="p">:</span> <span class="nx">msg</span><span class="p">,</span>
                     <span class="na">buttons</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">OK</span><span class="p">,</span>
                     <span class="na">icon</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">WARNING</span>
                <span class="p">});</span>
                
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="p">};</span>
        <span class="p">};</span>
        
        <span class="c1">// check the current uploading list</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
            <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">files</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
               <span class="k">if</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">findExact</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">,</span><span class="nx">file</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">){</span>
                 <span class="nx">invalidList</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span>  
               <span class="p">};</span> 
            <span class="p">});</span>            
            
            <span class="k">if</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
                <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">&lt;ul&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">invalidList</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
                    <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;li&gt;</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">&lt;/li&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="p">});</span>
                
                <span class="nx">msg</span> <span class="o">+=</span> <span class="dl">'</span><span class="s1">&lt;/ul&gt;</span><span class="dl">'</span><span class="p">;</span>
                <span class="kd">var</span> <span class="nx">pl</span> <span class="o">=</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nx">msg</span> <span class="o">+=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nb">String</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="dl">'</span><span class="s1">{0} file{1} exist{2} in uploading list. Please try again!!</span><span class="dl">'</span><span class="p">,</span> <span class="nx">invalidList</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">:</span> <span class="dl">''</span><span class="p">),</span> <span class="p">(</span><span class="nx">pl</span> <span class="p">?</span> <span class="dl">''</span><span class="p">:</span> <span class="dl">'</span><span class="s1">s</span><span class="dl">'</span><span class="p">));</span>
                
                <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">show</span><span class="p">({</span>
                     <span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">File exists</span><span class="dl">'</span><span class="p">,</span>
                     <span class="na">msg</span><span class="p">:</span> <span class="nx">msg</span><span class="p">,</span>
                     <span class="na">buttons</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">OK</span><span class="p">,</span>
                     <span class="na">icon</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">WARNING</span>
                <span class="p">});</span>
                
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="p">};</span>
        <span class="p">};</span>     
        
        <span class="k">return</span> <span class="nx">me</span><span class="p">.</span><span class="nx">prepareFileUpload</span><span class="p">(</span><span class="nx">files</span><span class="p">);</span>
    <span class="p">},</span>
    <span class="c1">// prepare file upload</span>
    <span class="na">prepareFileUpload</span><span class="p">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">files</span><span class="p">){</span>
        <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
        <span class="nx">Ext</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">files</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">){</span>
           <span class="c1">// create a file model </span>
           <span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">applyIf</span><span class="p">({</span><span class="na">progress</span><span class="p">:</span><span class="dl">'</span><span class="s1">0%</span><span class="dl">'</span><span class="p">},</span><span class="nx">file</span><span class="p">);</span>
           <span class="c1">// add to upload store </span>
           <span class="kd">var</span> <span class="nx">records</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">f</span><span class="p">);</span>
           <span class="c1">// start uploading file</span>
           <span class="nx">me</span><span class="p">.</span><span class="nx">uploadFile</span><span class="p">(</span><span class="nx">file</span><span class="p">,</span> <span class="nx">records</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
        <span class="p">});</span>
        <span class="c1">// show the progress grid</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">getLayout</span><span class="p">().</span><span class="nx">setActiveItem</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
        
        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
    <span class="p">},</span>
    <span class="c1">// set global params</span>
    <span class="na">setGlobalParams</span><span class="p">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">params</span><span class="p">,</span> <span class="nx">load</span><span class="p">){</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">listParams</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">uploadParams</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">downloadParams</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">deleteParams</span> <span class="o">=</span> <span class="nx">params</span><span class="p">;</span>
        <span class="c1">// assign params to store proxy</span>
        <span class="kd">var</span> <span class="nx">proxy</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">getProxy</span><span class="p">();</span>
        <span class="nx">proxy</span><span class="p">.</span><span class="nx">extraParams</span> <span class="o">=</span> <span class="nx">params</span><span class="p">;</span>
        <span class="c1">// load the store to display files</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">load</span> <span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span> <span class="nx">load</span> <span class="o">==</span> <span class="kc">true</span><span class="p">){</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>
        <span class="p">};</span>
    <span class="p">},</span>
    <span class="c1">// upload the files</span>
    <span class="na">uploadFile</span><span class="p">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">,</span> <span class="nx">record</span><span class="p">){</span>
       <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">Ext</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">(</span><span class="nx">file</span><span class="p">)){</span>
            <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
            <span class="c1">// create http request object</span>
            <span class="kd">var</span> <span class="nx">xhr</span> <span class="o">=</span> <span class="nx">XMLHttpRequest</span> <span class="p">?</span> <span class="k">new</span> <span class="nx">XMLHttpRequest</span><span class="p">()</span> <span class="p">:</span> <span class="k">new</span> <span class="nx">ActiveXObject</span><span class="p">(</span><span class="dl">'</span><span class="s1">Microsoft.XMLHttp</span><span class="dl">'</span><span class="p">);</span>
            <span class="c1">// hook progress </span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">upload</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">progress</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">lengthComputable</span><span class="p">)</span> <span class="p">{</span>
                    <span class="kd">var</span> <span class="nx">current</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">position</span> <span class="o">||</span> <span class="nx">e</span><span class="p">.</span><span class="nx">loaded</span><span class="p">,</span> 
                        <span class="nx">total</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">totalSize</span> <span class="o">||</span> <span class="nx">e</span><span class="p">.</span><span class="nx">total</span><span class="p">;</span>
                    <span class="kd">var</span> <span class="nx">percent</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">((</span><span class="nx">current</span> <span class="o">/</span> <span class="nx">total</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">);</span>
                    <span class="c1">// if we have record</span>
                    <span class="k">if</span><span class="p">(</span><span class="nx">record</span><span class="p">){</span>
                        <span class="nx">record</span><span class="p">.</span><span class="kd">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">progress</span><span class="dl">'</span><span class="p">,</span> <span class="nx">percent</span><span class="p">);</span>
                    <span class="p">};</span>
                <span class="p">};</span>
            <span class="p">},</span> <span class="kc">false</span><span class="p">);</span>
            
            <span class="c1">// when upload is completed</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">upload</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">loadend</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
                <span class="c1">// if we have record</span>
                <span class="k">if</span><span class="p">(</span><span class="nx">record</span><span class="p">){</span>
                  <span class="nx">Ext</span><span class="p">.</span><span class="nx">defer</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
                      <span class="nx">me</span><span class="p">.</span><span class="nx">progressStore</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">record</span><span class="p">);</span>
                  <span class="p">},</span><span class="mi">1500</span><span class="p">);</span>
                <span class="p">};</span>
            <span class="p">},</span> <span class="kc">false</span><span class="p">);</span>
                        
            <span class="c1">// check return event</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">onreadystatechange</span><span class="o">=</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
              <span class="k">if</span><span class="p">(</span><span class="nx">xhr</span><span class="p">.</span><span class="nx">readyState</span><span class="o">==</span><span class="mi">4</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">if</span><span class="p">(</span><span class="nx">xhr</span><span class="p">.</span><span class="nx">status</span><span class="o">==</span><span class="mi">200</span><span class="p">){</span>
                  <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">xhr</span><span class="p">.</span><span class="nx">responseText</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
                  <span class="k">if</span> <span class="p">(</span><span class="nx">result</span> <span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="nx">amp</span><span class="p">;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="p">{</span>                                             
                    <span class="nx">me</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>  
                  <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                    <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">show</span><span class="p">({</span>
                      <span class="na">title</span><span class="p">:</span><span class="dl">'</span><span class="s1">Error</span><span class="dl">'</span><span class="p">,</span>
                      <span class="na">msg</span><span class="p">:</span> <span class="nx">result</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">Unknown Error</span><span class="dl">'</span><span class="p">,</span>
                      <span class="na">buttons</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">OK</span><span class="p">,</span>
                      <span class="na">icon</span><span class="p">:</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">Msg</span><span class="p">.</span><span class="nx">ERROR</span>
                    <span class="p">});</span>                                                
                  <span class="p">};</span>                                           
                <span class="p">};</span>            
              <span class="p">};</span>
             <span class="p">};</span>                                    
             
            <span class="c1">// void open(DOMString method, DOMString url, boolean async);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="dl">'</span><span class="s1">put</span><span class="dl">'</span><span class="p">,</span> <span class="nx">me</span><span class="p">.</span><span class="nx">uploadUrl</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">application/octet-stream</span><span class="dl">"</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">X-File-Name</span><span class="dl">"</span><span class="p">,</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span> <span class="o">||</span> <span class="nx">file</span><span class="p">.</span><span class="nx">fileName</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">X-File-Size</span><span class="dl">"</span><span class="p">,</span> <span class="nx">file</span><span class="p">.</span><span class="nx">size</span> <span class="o">||</span> <span class="nx">file</span><span class="p">.</span><span class="nx">fileSize</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">X-File-Type</span><span class="dl">"</span><span class="p">,</span> <span class="nx">file</span><span class="p">.</span><span class="nx">type</span><span class="p">);</span>
            <span class="kd">var</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">encode</span><span class="p">(</span><span class="nx">me</span><span class="p">.</span><span class="nx">uploadParams</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">X-File-Params</span><span class="dl">"</span><span class="p">,</span> <span class="nx">params</span><span class="p">);</span>
            <span class="nx">xhr</span><span class="p">.</span><span class="nx">setRequestHeader</span><span class="p">(</span><span class="dl">"</span><span class="s2">X-Requested-With</span><span class="dl">"</span><span class="p">,</span> <span class="dl">'</span><span class="s1">XMLHttpRequest</span><span class="dl">'</span><span class="p">);</span>
            
            <span class="k">if</span> <span class="p">(</span><span class="dl">'</span><span class="s1">getAsBinary</span><span class="dl">'</span> <span class="k">in</span> <span class="nx">file</span><span class="p">){</span>
                <span class="nx">xhr</span><span class="p">.</span><span class="nx">sendAsBinary</span><span class="p">(</span><span class="nx">file</span><span class="p">.</span><span class="nx">getAsBinary</span><span class="p">());</span>
            <span class="p">}</span><span class="k">else</span><span class="p">{</span>
                <span class="nx">xhr</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span> 
            <span class="p">};</span>
       <span class="p">};</span>        
    <span class="p">},</span>  
    <span class="c1">// show download window</span>
    <span class="na">showDownloadWindow</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">record</span><span class="p">){</span>
        <span class="kd">var</span> <span class="nx">me</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">me</span><span class="p">.</span><span class="nx">win</span><span class="p">){</span>
          <span class="nx">me</span><span class="p">.</span><span class="nx">win</span> <span class="o">=</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="dl">'</span><span class="s1">Ext.Window</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
            <span class="na">layout</span><span class="p">:</span> <span class="dl">'</span><span class="s1">fit</span><span class="dl">'</span><span class="p">,</span>
            <span class="na">iconCls</span><span class="p">:</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">iconCls</span><span class="dl">'</span><span class="p">),</span>
            <span class="na">title</span><span class="p">:</span> <span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">),</span>
            <span class="na">modal</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
            <span class="na">width</span><span class="p">:</span><span class="mi">800</span><span class="p">,</span>
            <span class="na">height</span><span class="p">:</span><span class="mi">600</span><span class="p">,</span>
            <span class="na">border</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
            <span class="na">maximizable</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
            <span class="na">closeAction</span><span class="p">:</span><span class="dl">'</span><span class="s1">hide</span><span class="dl">'</span><span class="p">,</span>
            <span class="na">items</span><span class="p">:</span> <span class="p">{</span>
              <span class="na">xtype</span><span class="p">:</span><span class="dl">'</span><span class="s1">uxiframe</span><span class="dl">'</span>
            <span class="p">},</span>
            <span class="na">listeners</span><span class="p">:{</span>
                <span class="na">beforeshow</span><span class="p">:</span><span class="kd">function</span><span class="p">(){</span>
                    <span class="nx">Ext</span><span class="p">.</span><span class="nx">suspendLayouts</span><span class="p">();</span>
                    <span class="k">this</span><span class="p">.</span><span class="nx">setSize</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">clientWidth</span><span class="o">*</span><span class="mf">0.5</span><span class="p">,</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">clientHeight</span><span class="o">*</span><span class="mf">0.8</span><span class="p">);</span>
                    <span class="nx">Ext</span><span class="p">.</span><span class="nx">resumeLayouts</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
                <span class="p">}</span>                                     
            <span class="p">}</span>
         <span class="p">});</span>
        <span class="p">};</span>
        
        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">me</span><span class="p">.</span><span class="nx">iframe</span><span class="p">){</span>
            <span class="nx">me</span><span class="p">.</span><span class="nx">iframe</span> <span class="o">=</span> <span class="nx">me</span><span class="p">.</span><span class="nx">win</span><span class="p">.</span><span class="nx">down</span><span class="p">(</span><span class="dl">'</span><span class="s1">uxiframe</span><span class="dl">'</span><span class="p">);</span>
        <span class="p">};</span>
        <span class="c1">// set icon on the window</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">win</span><span class="p">.</span><span class="nx">setIconCls</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">iconCls</span><span class="dl">'</span><span class="p">))</span>
        <span class="c1">// set title of the window</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">win</span><span class="p">.</span><span class="nx">setTitle</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">));</span>
        <span class="c1">// show the window</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">win</span><span class="p">.</span><span class="nx">show</span><span class="p">();</span>
        <span class="c1">// load the content</span>
        <span class="nx">me</span><span class="p">.</span><span class="nx">iframe</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">});</span></code></pre></figure>

</div>
<br />
<b>Server Side (PHP Code)</b>
<br />
<br />

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="k">private</span> <span class="k">function</span> <span class="n">upload</span><span class="p">(</span><span class="nv">$dstPath</span><span class="p">){</span>
        <span class="nv">$fileName</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'HTTP_X_FILE_NAME'</span><span class="p">];</span> 
        <span class="nv">$fileSize</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'HTTP_X_FILE_SIZE'</span><span class="p">];</span>
        <span class="nv">$fileType</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'HTTP_X_FILE_TYPE'</span><span class="p">];</span>

        <span class="c1">// open input stream</span>
        <span class="nv">$input</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="s1">'php://input'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">);</span>
        <span class="c1">// open output stream</span>
        <span class="nv">$output</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="nv">$dstPath</span> <span class="mf">.</span> <span class="nv">$fileName</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">);</span> 
        <span class="c1">// start to write data</span>
        <span class="k">while</span> <span class="p">(</span><span class="nv">$data</span> <span class="o">=</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$input</span><span class="p">,</span> <span class="mi">1024</span><span class="p">)){</span>
             <span class="nb">fwrite</span><span class="p">(</span><span class="nv">$output</span><span class="p">,</span><span class="nv">$data</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="c1">// close input stream</span>
        <span class="nb">fclose</span><span class="p">(</span><span class="nv">$input</span><span class="p">);</span>
        <span class="c1">// close output stream</span>
        <span class="nb">fclose</span><span class="p">(</span><span class="nv">$output</span><span class="p">);</span>
            
        <span class="nv">$result</span><span class="o">=</span> <span class="k">array</span><span class="p">(</span>
            <span class="s1">'success'</span>    <span class="o">=&gt;</span> <span class="kc">true</span><span class="p">,</span>
            <span class="s1">'data'</span>       <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">'src'</span><span class="o">=&gt;</span><span class="nv">$dstPath</span> <span class="mf">.</span> <span class="nv">$fileName</span><span class="p">,</span> <span class="s1">'file'</span><span class="o">=&gt;</span><span class="nv">$fileName</span><span class="p">,</span> <span class="s1">'size'</span><span class="o">=&gt;</span><span class="nv">$fileSize</span><span class="p">,</span> <span class="s1">'type'</span><span class="o">=&gt;</span><span class="nv">$fileType</span><span class="p">),</span>
            <span class="s1">'total'</span>      <span class="o">=&gt;</span> <span class="s1">'1'</span><span class="p">,</span>
            <span class="s1">'message'</span>    <span class="o">=&gt;</span> <span class="s1">'File uploaded successfully'</span>
        <span class="p">);</span>
        
        <span class="k">return</span> <span class="nv">$result</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">private</span> <span class="k">function</span> <span class="n">delete</span><span class="p">(</span><span class="nv">$filePath</span><span class="p">){</span>
        <span class="nv">$result</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="k">if</span><span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$filePath</span><span class="p">)){</span>
           <span class="nv">$result</span> <span class="o">=</span> <span class="nb">unlink</span><span class="p">(</span><span class="nv">$filePath</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="nv">$result</span><span class="o">=</span> <span class="k">array</span><span class="p">(</span>
         <span class="s1">'success'</span><span class="o">=&gt;</span> <span class="nv">$result</span><span class="p">,</span>
         <span class="s1">'message'</span><span class="o">=&gt;</span> <span class="s1">'Success'</span><span class="p">,</span>
         <span class="s1">'file'</span><span class="o">=&gt;</span><span class="nv">$filePath</span>
 <span class="p">);</span>
 <span class="k">return</span> <span class="nv">$result</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

</div>]]></content><author><name>Elvis Hsu</name></author><category term="ExtJs" /><category term="Coding" /><category term="Javascript" /><summary type="html"><![CDATA[A while ago, I tried to create a reusable file upload management panel for the internal intranet system. So I ended up making an extension from a grid panel with DnD and multiple files upload field. This solution allows user to select multiple files to upload as long as the browser supports HTML5. It also indicates the upload progress on each file. This widget validates file names and sizes on the client side instead of server side. The file does not need to be uploaded to server to validate its properties. Since the file is streamed to server, you may need to work out how you handle the code on the server side. I have provided a simple php code at the end of this article for anyone to start with. Anyway in order to make this widget to work, you may need the following three extensions. 1.&nbsp;MultipleFileField The default file field from ExtJs only allows you to upload single file at a time. To enable uploading multiple file, you need to tweak the DOM settings. Multiple file field (inspired from here) Ext.define('Ext.ux.form.field.MultipleFileField', { extend: 'Ext.form.field.File', alias:['widget.multifilefield', 'widget.multiplefilefield', 'widget.multifile'], /** * Override to add a "multiple" attribute. */ onRender: function() { this.callParent(arguments); this.fileInputEl.set({ multiple: 'multiple' }); } });]]></summary></entry></feed>