Posted by & filed under Categorized.

OpenJDK Runtime Environment (IcedTea6 1.9.10) (6b20-1.9.10-0ubuntu1~10.04.2)
OpenJDK Client VM (build 19.0-b09, mixed mode, sharing)
WARNING: You are launching IDE using OpenJDK Java runtime

THIS IS STRICTLY UNSUPPORTED DUE TO KNOWN PERFORMANCE AND GRAPHICS PROBLEMS

NOTE: If you have both Sun JDK and OpenJDK installed
please validate either WEBIDE_JDK or JDK_HOME environment variable points to valid Sun JDK installation

Ubuntu Sun (Oracle) Java Installation Guide

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo apt-get update
aptitude install sun-java6-jdk
sudo update-alternatives --config java

Posted by & filed under Programming.

While implementing a REST service, Apache started to append HTML 404 error HTML to my custom 404 application/json response.
It seems the Windows Apache version which comes with Zend Server requires a httpd.conf entry to disable the HTML to be appended to the response:

To disable it for a 404 error:
ErrorDocument 404 ” ”

So in general:
ErrorDocument ” ”

It’s weird though that the Linux version does not append this HTML error code by default.

Posted by & filed under Categorized.

I found this code snippet which shows how array based parameters should be documented with PHPDoc (in ZF projects). The topic came up because I’m always nagging about those magic functions and magic properties in ZF and how poorly they are documented. It seems we’ve been neglecting adding PHPDoc tags a bit because PHPDoc does have support to document magic methods and magic class properties:

@method Magic Properties

@property Magic Methods

/**
* $args may contain the following keys:
* - var1:
* - var2:
*
* @param array @args
* @return void
*/

Items prefixed with a ‘- ‘ will be treated as bullets by phpDocumentor.

source: zend framework community

I’m currently piloting PhpStorm because I had some issues with Zend Studio, it’s interesting to notice that a phpdoc line like:

/*
 * @return Foo[]
 */
function getList() {
   $f = array();
   $f[] = new Foo();
   ...
   return $f;
}

triggers auto-completion in PhpStorm when looping over the return value like:

$list = $this->getList();
foreach($list as $l) {
    $l->(starts auto-completion ...)
}

Posted by & filed under Categorized.

Zend Framework Command Line Console Tool v1.11.10
Usage:
zf [--global-opts] action-name [--action-opts] provider-name [--provider-opts] [provider parameters ...]
Note: You may use “?” in any place of the above usage string to ask for more specific help information.
Example: “zf ? version” will list all available actions for the version provider.Providers and their actions:

Version
zf show version mode[=mini] name-included[=1]
Note: There are specialties, use zf show version.? to get specific help on them.Config
zf create config
zf show config
zf enable config
Note: There are specialties, use zf enable config.? to get specific help on them.
zf disable config
Note: There are specialties, use zf disable config.? to get specific help on them.

Phpinfo
zf show phpinfo

Manifest
zf show manifest

Profile
zf show profile

Project
zf create project path name-of-profile file-of-profile
zf show project
Note: There are specialties, use zf show project.? to get specific help on them.

Application
zf change application.class-name-prefix class-name-prefix

Model
zf create model name module

View
zf create view controller-name action-name-or-simple-name module

Controller
zf create controller name index-action-included[=1] module

Action
zf create action name controller-name[=Index] view-included[=1] module

Module
zf create module name

Form
zf enable form module
zf create form name module

Layout
zf enable layout
zf disable layout

DbAdapter
zf configure db-adapter dsn section-name[=production]

DbTable
zf create db-table name actual-table-name module force-overwrite
Note: There are specialties, use zf create db-table.? to get specific help on them.

ProjectProvider
zf create project-provider name actions

Examples (Windows):

zf create project ./
zf create module test
zf create controller Test index-action-included=1 test

Remarks:
- The Zend Tool will maintain a xml based configuration file called ‘.zfproject.xml’, do not remove!
- Zend Tool is case sensitive, thus “zf create module blog” and “zf create module Blog” are different commands, running them both will create 2 modules (in Windows it will only result in 1 module directory though!)
- The create module command did not create a module Bootstrap file
- The bootstrap file in the tests directory has a lowercase ‘b’ which probably needs to be an uppercase like ‘Bootstrap.php’
- Note: PHPUnit is required in order to generate controller test stubs.
- For a module Bootstrap to work, the application.ini needs resources.modules = ""

A simple module Bootstrap looks like:

<?php
class Yourmodulename_Bootstrap extends Zend_Application_Module_Bootstrap {
	protected function _initSomething () {
    }
}

Posted by & filed under Programming.

Somehow it’s always a pain to find the right configuration parameters and proper format in ZF which makes me reverse engineer them.

$this->captcha = new Zend_Form_Element_Captcha('captcha',
	array(
		'captcha'=>array ('ReCaptcha'),
		'captchaOptions'=>array (
			'pubkey'=>'...',
			'privkey'=>'...'
		)
	)
);

Posted by & filed under Programming.

Demo
jQuery plug-in source at BitBucket

Examples of how to use the plug-in.

// global configuration options
$.own3d.liveurl = 'http://ingol.nl/own3d/live.php';
$.own3d.channelurl = 'http://ingol.nl/own3d/channel.php';

// A single stream
$('#own3d-cowclan').own3d({liveid:'1213', title:'COWCLAN'});
// A single stream with HD
$('#own3d-rebootgpf').own3d({liveid:'1208', title:'REBOOTGPF', hd:true});
// A single stream without title
$('#own3d-1208').own3d({liveid:'1208', hd:true, embed:true, channelid: 'orlissenberg'});
// A single channel, live streams only
$('#channel').own3d({channelid:'clgame', hd:true, embed:true});
// A single channel, live and offline streams
$('#channel-all').own3d({channelid:'clgame', hd:true, showall:true});

The jQuery OWN3D Plug-in Code.

(function($){
  $.own3d = {
    liveurl : 'live.php',
    channelurl : 'channel.php'
  };

  $.fn.own3d = function(options) {
    return this.each(function(){
      var self = $(this);
      self.data('liveid', options.liveid);

      if (options &amp;amp;&amp;amp; options.liveid) {
        $.ajax({
            type: &amp;quot;GET&amp;quot;,
            async: true,
            data: {live_id:options.liveid},
            url: $.own3d.liveurl,
            dataType: &amp;quot;jsonp&amp;quot;,
            success: function(data){
              var title = (options.title) ? options.title : 'OWN3D CHANNEL ['+options.liveid+']';
              var liveclass = (options.hd) ? 'own3d-live-hd' : 'own3d-live';

              self.empty();
              self.addClass('own3d');

              var link = $('&amp;lt;a/&amp;gt;')
                  .attr('href','http://www.own3d.tv/live/'+options.liveid)
                  .attr('target','_blank');

              if (data.isLive &amp;amp;&amp;amp; data.isLive == 'true') {                  
                link.html(title+' - LIVE (viewers: '+data.liveViewers+' - duration: '+Math.round(parseInt(data.liveDuration) / 60)+' minutes)');
                
                if ((options.showthumbnail || options.embed) &amp;amp;&amp;amp; options.channelid) {                     
                  $.ajax({
                      type: &amp;quot;GET&amp;quot;,
                      async: true,
                      data: {channel_id : options.channelid, stream_guid : 'http://www.own3d.tv/live/'+options.liveid},
                      url: $.own3d.channelurl,
                      dataType: &amp;quot;jsonp&amp;quot;,
                      success: function(data){                          
                        if (options.showthumbnail &amp;amp;&amp;amp; data.thumbnail) {
                          var table = $('&amp;lt;table/&amp;gt;');

                          var status = $('&amp;lt;td/&amp;gt;').append($('&amp;lt;div/&amp;gt;').addClass(liveclass).append(link));
                          table.append($('&amp;lt;tr/&amp;gt;').append(status));
                          
                          var thumbnail = $('&amp;lt;td/&amp;gt;').append($('&amp;lt;img/&amp;gt;').attr('src',data.thumbnail));
                          table.append($('&amp;lt;tr/&amp;gt;').append(thumbnail));
                                                                              
                          self.append(table);
                        } else if (options.embed &amp;amp;&amp;amp; data.title) {
                            
                            var e = '&amp;lt;iframe height=&amp;quot;360&amp;quot; width=&amp;quot;640&amp;quot; frameborder=&amp;quot;0&amp;quot; src=&amp;quot;http://www.own3d.tv/liveembed/'+self.data('liveid')+'&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;';                            
                            var table = $('&amp;lt;table/&amp;gt;');

                            var status = $('&amp;lt;td/&amp;gt;').append($('&amp;lt;div/&amp;gt;').addClass(liveclass).append(link));
                            table.append($('&amp;lt;tr/&amp;gt;').append(status));
                                                        
                            var embeddedplayer = $('&amp;lt;td/&amp;gt;').html(e);                            
                            table.append($('&amp;lt;tr/&amp;gt;').append(embeddedplayer));
                                                                                
                            self.append(table);
                        };
                      },
                      error: function(XMLHttpRequest, textStatus, errorThrown){
                        // console.debug(errorThrown);
                      }
                  });
                } else {
                  self.append(link);
                  self.addClass(liveclass);
                }                
              } else {
                link.html(title+' - OFFLINE');
                self.removeClass(liveclass);
                self.append(link);
              }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown){
                // console.debug(errorThrown);
            }
        });
      } else if (options &amp;amp;&amp;amp; options.channelid) {
        var ajaxdata = {
          channel_id : options.channelid
        };
        if (options.showall) { ajaxdata.showall = 1; };

        $.ajax({
            type: &amp;quot;GET&amp;quot;,
            async: true,
            data: ajaxdata,
            url: $.own3d.channelurl,
            dataType: &amp;quot;jsonp&amp;quot;,
            success: function(data){
              self.empty();

              var embedded = true;
              for(var i=0;i&amp;lt;data.streams.length;i++) {
                var stream = data.streams[i];

                var plugindata = {
                  liveid : stream.liveid, 
                  title : stream.title, 
                  channelid : options.channelid,
                  // embed the first, thumbnail the rest
                  showthumbnail : (options.showthumbnail) || (!(options.showthumbnail) &amp;amp;&amp;amp; options.embed &amp;amp;&amp;amp; !embedded) ? true : false,
                  embed : (options.embed) ? true &amp;amp;&amp;amp; embedded : false                  
                };

                // prevent opening multiple embedded players
                embedded = false;                

                self.append($('&amp;lt;div/&amp;gt;').own3d(plugindata));
              }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown){
              // console.debug(errorThrown);
            }
        });
      }
    });
  }
})(jQuery)

A simple PHP – Zend Framework script to enable a cross domain request to the OWN3D API (the full project contains two, one for the live status and one for the channel information).

&amp;lt;?php

// Define path to application directory
define('APPLICATION_PATH', realpath(dirname(__FILE__)));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../../apps/library'),
    get_include_path(),
)));

$liveid = isset($_GET['live_id']) ? intval($_GET['live_id']) : 0;

require_once 'Zend/Http/Client.php';
$client = new Zend_Http_Client('http://api.own3d.tv/liveCheck.php?live_id='.$liveid, array('adapter' =&amp;gt; 'Zend_Http_Client_Adapter_Socket'));

$xmlstr = $client-&amp;gt;request()-&amp;gt;getBody();
$xml = new SimpleXMLElement($xmlstr);

require_once 'Zend/Json/Encoder.php';
header('Content-Type: application/json');

// JSONP
if (isset($_GET['callback'])) {
        echo $_GET['callback'].'('. Zend_Json_Encoder::encode(array(
        'isLive'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;isLive,
        'liveViewers'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;liveViewers,
        'liveDuration'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;liveDuration,
    )).')';
}
// JSON
else {
    echo Zend_Json_Encoder::encode(array(
        'isLive'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;isLive,
        'liveViewers'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;liveViewers,
        'liveDuration'=&amp;gt;(string)$xml-&amp;gt;liveEvent-&amp;gt;liveDuration,
    ));
}

Posted by & filed under Categorized.

The images were eating away the low amount of bandwidth I own (see also the scary red bar on the usage summary) so I put low resolutions images on the LoL Plug-ins Demo page and centralized the image storage. If it becomes too popular I might need to re-locate though *EEK*

Thanks for visiting, come again!

p.s. High resolution images are still available in the code repository.
p.p.s. Clicking on advertisement banners will give me more bandwidth or just donate :)

*update* I put the images on the Amazon Simple Storage Service (Amazon S3) which should provide some stress relief, well at least it scales better!