diff --git a/oss/piwik/trunk/plugins/ExampleRssWidget/ExampleRssWidget.php b/oss/piwik/trunk/plugins/ExampleRssWidget/ExampleRssWidget.php
new file mode 100644
index 00000000..ddf44e25
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleRssWidget/ExampleRssWidget.php
@@ -0,0 +1,132 @@
+ Piwik_Translate('ExampleRssWidget_PluginDescription'),
+ 'author' => 'Piwik',
+ 'author_homepage' => 'http://piwik.org/',
+ 'version' => '0.1',
+ );
+ }
+
+ public function getListHooksRegistered()
+ {
+ return array( 'template_css_import' => 'css');
+ }
+
+ function css()
+ {
+ echo "\n";
+ }
+}
+
+Piwik_AddWidget('Example Widgets', 'Piwik.org Blog', 'ExampleRssWidget', 'rssPiwik');
+Piwik_AddWidget('Example Widgets', 'Piwik Changelog', 'ExampleRssWidget', 'rssChangelog');
+
+/**
+ *
+ * @package Piwik_ExampleRssWidget
+ */
+class Piwik_ExampleRssWidget_Controller extends Piwik_Controller
+{
+ function rssPiwik()
+ {
+ $rss = new Piwik_ExampleRssWidget_Rss('http://feeds.feedburner.com/Piwik');
+ $rss->showDescription(true);
+ echo $rss->get();
+ }
+ function rssChangelog()
+ {
+ $rss = new Piwik_ExampleRssWidget_Rss('http://feeds.feedburner.com/PiwikReleases');
+ $rss->setCountPosts(1);
+ $rss->showDescription(false);
+ $rss->showContent(true);
+ echo $rss->get();
+ }
+}
+
+/**
+ *
+ * @package Piwik_ExampleRssWidget
+ */
+class Piwik_ExampleRssWidget_Rss
+{
+ protected $url = null;
+ protected $count = 3;
+ protected $showDescription = false;
+ protected $showContent = false;
+ function __construct($url)
+ {
+ $this->url = $url;
+ }
+ function showDescription($bool)
+ {
+ $this->showDescription = $bool;
+ }
+ function showContent($bool)
+ {
+ $this->showContent = $bool;
+ }
+ function setCountPosts($count)
+ {
+ $this->count = $count;
+ }
+ function get()
+ {
+ try {
+ $rss = Zend_Feed::import($this->url);
+ } catch (Zend_Feed_Exception $e) {
+ echo "Error while importing feed: {$e->getMessage()}\n";
+ exit;
+ }
+
+ $output = '
';
+ return $output;
+ }
+}
diff --git a/oss/piwik/trunk/plugins/ExampleRssWidget/templates/styles.css b/oss/piwik/trunk/plugins/ExampleRssWidget/templates/styles.css
new file mode 100644
index 00000000..43722016
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleRssWidget/templates/styles.css
@@ -0,0 +1,31 @@
+.rss ul {
+ list-style-image:none;
+ list-style-position:outside;
+ list-style-type:none;
+ padding:0pt;
+}
+.rss li {
+ line-height:140%;
+ margin-bottom:6px;
+ margin:0.5em 0pt 1em;
+}
+.rss-title, .rss-date {
+ float:left;
+ font-size:14px;
+ line-height:140%;
+}
+.rss-title{
+ color:#2583AD;
+ margin:0pt 0.5em 0.2em 0pt;
+ font-weight:bold;
+}
+.rss-date {
+ color:#999999;
+ margin:0pt;
+}
+.rss-content, .rss-description {
+ clear:both;
+ line-height:1.5em;
+ font-size:11px;
+ color:#333333;
+}
diff --git a/oss/piwik/trunk/plugins/ExampleUI/API.php b/oss/piwik/trunk/plugins/ExampleUI/API.php
new file mode 100644
index 00000000..549468f3
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleUI/API.php
@@ -0,0 +1,106 @@
+getDateStart()->toString('Y-m-d'); // eg. "2009-04-01"
+ $dateEnd = $period->getDateEnd()->toString('Y-m-d'); // eg. "2009-04-30"
+
+ // here you could select from your custom table in the database, eg.
+ $query = "SELECT AVG(temperature)
+ FROM server_temperatures
+ WHERE date > ?
+ AND date < ?
+ GROUP BY date
+ ORDER BY date ASC";
+ //$result = Piwik_FetchAll($query, array($dateStart, $dateEnd));
+ // to keep things simple, we generate the data
+ foreach($period->getSubperiods() as $subPeriod)
+ {
+ $server1 = rand(50,90);
+ $server2 = rand(40, 110);
+ $value = array('server1' => $server1, 'server2' => $server2);
+ $temperatures[$subPeriod->getLocalizedShortString()] = $value;
+ }
+
+ // convert this array to a DataTable object
+ $dataTable = new Piwik_DataTable();
+ $dataTable->addRowsFromArrayWithIndexLabel($temperatures);
+ return $dataTable;
+ }
+
+ // we generate an array of random server temperatures
+ public function getTemperatures()
+ {
+ $xAxis = array(
+ '0h', '1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h',
+ '12h', '13h', '14h', '15h', '16h', '17h', '18h', '19h', '20h', '21h', '22h', '23h',
+ );
+ $temperatureValues = array_slice(range(50,90), 0, count($xAxis));
+ shuffle($temperatureValues);
+ $temperatures = array();
+ foreach($xAxis as $i => $xAxisLabel) {
+ $temperatures[$xAxisLabel] = $temperatureValues[$i];
+ }
+
+ // convert this array to a DataTable object
+ $dataTable = new Piwik_DataTable();
+ $dataTable->addRowsFromArrayWithIndexLabel($temperatures);
+ return $dataTable;
+ }
+
+ public function getPlanetRatios()
+ {
+ $planetRatios = array(
+ 'Mercury' => 0.382,
+ 'Venus' => 0.949,
+ 'Earth' => 1.00,
+ 'Mars' => 0.532,
+ 'Jupiter' => 11.209,
+ 'Saturn' => 9.449,
+ 'Uranus' => 4.007,
+ 'Neptune' => 3.883,
+ );
+ // convert this array to a DataTable object
+ $dataTable = new Piwik_DataTable();
+ $dataTable->addRowsFromArrayWithIndexLabel($planetRatios);
+ return $dataTable;
+ }
+
+ public function getPlanetRatiosWithLogos()
+ {
+ $planetsDataTable = $this->getPlanetRatios();
+ foreach($planetsDataTable->getRows() as $row)
+ {
+ $row->addMetadata('logo', "plugins/ExampleUI/images/icons-planet/".strtolower($row->getColumn('label').".png"));
+ $row->addMetadata('url', "http://en.wikipedia.org/wiki/".$row->getColumn('label'));
+ }
+ return $planetsDataTable;
+ }
+}
diff --git a/oss/piwik/trunk/plugins/ExampleUI/Controller.php b/oss/piwik/trunk/plugins/ExampleUI/Controller.php
new file mode 100644
index 00000000..ad3d8a5c
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleUI/Controller.php
@@ -0,0 +1,141 @@
+init( $this->pluginName, __FUNCTION__, 'ExampleUI.getTemperatures' );
+ $view->setColumnTranslation('value', "Temperature in °C");
+ $view->setColumnTranslation('label', "Hour of day");
+ $view->setSortedColumn('label', 'asc');
+ $view->setGraphLimit( 24 );
+ $view->setLimit( 24 );
+ $view->disableExcludeLowPopulation();
+ $view->disableShowAllColumns();
+ $view->setAxisYUnit('°C'); // useful if the user requests the bar graph
+ return $this->renderView($view);
+ }
+
+ function evolutionGraph()
+ {
+ echo "Evolution of server temperatures over the last few days
";
+ $this->echoEvolutionGraph();
+ }
+
+ function echoEvolutionGraph()
+ {
+ $view = Piwik_ViewDataTable::factory('graphEvolution');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getTemperaturesEvolution' );
+ $view->setColumnTranslation('server1', "Temperature server piwik.org");
+ $view->setColumnTranslation('server2', "Temperature server dev.piwik.org");
+ $view->setAxisYUnit('°C'); // useful if the user requests the bar graph
+ return $this->renderView($view);
+ }
+
+ function barGraph()
+ {
+ $view = Piwik_ViewDataTable::factory('graphVerticalBar');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getTemperatures' );
+ $view->setColumnTranslation('value', "Temperature");
+ $view->setAxisYUnit('°C');
+ $view->setGraphLimit( 24 );
+ $view->disableFooter();
+ return $this->renderView($view);
+ }
+
+ function pieGraph()
+ {
+ $view = Piwik_ViewDataTable::factory('graphPie');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getPlanetRatios' );
+ $view->setColumnsToDisplay( 'value' );
+ $view->setColumnTranslation('value', "times the diameter of Earth");
+ $view->setGraphLimit( 10 );
+ $view->disableFooterIcons();
+ return $this->renderView($view);
+ }
+
+ function tagClouds()
+ {
+ echo "Simple tag cloud
";
+ $this->echoSimpleTagClouds();
+
+ echo "
Advanced tag cloud: with logos and links
+
+ - The logo size is proportional to the value returned by the API
+ - The logo is linked to a specific URL
+
";
+ $this->echoAdvancedTagClouds();
+ }
+ function echoSimpleTagClouds()
+ {
+ $view = Piwik_ViewDataTable::factory('cloud');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getPlanetRatios' );
+ $view->setColumnsToDisplay( array('label','value') );
+ $view->setColumnTranslation('value', "times the diameter of Earth");
+ $view->disableFooter();
+ $this->renderView($view);
+ }
+ function echoAdvancedTagClouds()
+ {
+ $view = Piwik_ViewDataTable::factory('cloud');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getPlanetRatiosWithLogos' );
+ $view->setDisplayLogoInTagCloud(true);
+ $view->disableFooterExceptExportIcons();
+ $view->setColumnsToDisplay( array('label','value') );
+ $view->setColumnTranslation('value', "times the diameter of Earth");
+ $this->renderView($view);
+ }
+
+ function sparklines()
+ {
+ require_once PIWIK_INCLUDE_PATH . '/core/SmartyPlugins/function.sparkline.php';
+ $srcSparkline1 = Piwik_Url::getCurrentQueryStringWithParametersModified(array('action'=>'generateSparkline', 'server' => 'server1', 'rand'=>rand()));
+ $htmlSparkline1 = smarty_function_sparkline(array('src' => $srcSparkline1));
+ echo "$htmlSparkline1 Evolution of temperature for server piwik.org
";
+
+ $srcSparkline2 = Piwik_Url::getCurrentQueryStringWithParametersModified(array('action'=>'generateSparkline', 'server' => 'server2', 'rand'=>rand()));
+ $htmlSparkline2 = smarty_function_sparkline(array('src' => $srcSparkline2));
+ echo "$htmlSparkline2 Evolution of temperature for server dev.piwik.org
";
+ }
+
+ function generateSparkline()
+ {
+ $serverRequested = Piwik_Common::getRequestVar('server');
+ $view = Piwik_ViewDataTable::factory('sparkline');
+ $view->init( $this->pluginName, __FUNCTION__, 'ExampleUI.getTemperaturesEvolution' );
+ $view->setColumnsToDisplay($serverRequested);
+ $this->renderView($view);
+ }
+
+ function misc()
+ {
+ echo "Evolution graph filtered to Google and Yahoo!
";
+ $this->echoDataTableSearchEnginesFiltered();
+ }
+
+ function echoDataTableSearchEnginesFiltered()
+ {
+ $view = $this->getLastUnitGraph($this->pluginName, __FUNCTION__, 'Referers.getSearchEngines');
+ $view->setColumnsToDisplay( 'nb_visits' );
+ $view->setSearchPattern('^(Google|Yahoo!)$', 'label');
+ return $this->renderView($view);
+ }
+}
diff --git a/oss/piwik/trunk/plugins/ExampleUI/ExampleUI.php b/oss/piwik/trunk/plugins/ExampleUI/ExampleUI.php
new file mode 100644
index 00000000..90193563
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleUI/ExampleUI.php
@@ -0,0 +1,70 @@
+ Piwik_Translate('ExampleUI_PluginDescription'),
+ 'author' => 'Piwik',
+ 'author_homepage' => 'http://piwik.org/',
+ 'version' => '0.1',
+ );
+ }
+
+ function getListHooksRegistered()
+ {
+ $hooks = array(
+ 'Menu.add' => 'addMenus',
+ );
+ return $hooks;
+ }
+
+ function addMenus()
+ {
+ $menus = array(
+ 'Data tables' => 'dataTables',
+ 'Evolution graph' => 'evolutionGraph',
+ 'Bar graph' => 'barGraph',
+ 'Pie graph' => 'pieGraph',
+ 'Tag clouds' => 'tagClouds',
+ 'Sparklines' => 'sparklines',
+ 'Misc' => 'misc',
+ );
+ foreach($menus as $subMenu => $action)
+ {
+ Piwik_AddMenu('UI Framework', $subMenu, array('module' => 'ExampleUI', 'action' => $action));
+ }
+ }
+}
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/LICENSE b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/LICENSE
new file mode 100644
index 00000000..cbaa1f23
--- /dev/null
+++ b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/LICENSE
@@ -0,0 +1,3 @@
+Author : Dan Wiersema
+License: Free for non-commercial use.
+http://www.iconspedia.com/icon/neptune-4672.html
\ No newline at end of file
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/earth.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/earth.png
new file mode 100644
index 00000000..448f8a63
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/earth.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/jupiter.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/jupiter.png
new file mode 100644
index 00000000..a3377465
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/jupiter.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mars.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mars.png
new file mode 100644
index 00000000..1335faab
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mars.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mercury.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mercury.png
new file mode 100644
index 00000000..90f72e69
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/mercury.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/neptune.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/neptune.png
new file mode 100644
index 00000000..c2acf71b
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/neptune.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/saturn.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/saturn.png
new file mode 100644
index 00000000..5cbde1b1
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/saturn.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/uranus.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/uranus.png
new file mode 100644
index 00000000..3657d3d8
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/uranus.png differ
diff --git a/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/venus.png b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/venus.png
new file mode 100644
index 00000000..41af2ae0
Binary files /dev/null and b/oss/piwik/trunk/plugins/ExampleUI/images/icons-planet/venus.png differ