Hey !
Very easy, update process was a piece of cake. Just upload and upgrade, also auto update all the plugins and that’s it.
Recommended !
Hey !
Very easy, update process was a piece of cake. Just upload and upgrade, also auto update all the plugins and that’s it.
Recommended !
Hi again.
We’ve added a new feature, requested by user “Jorge González” from spain.
Now you can view all the modified tasks in a month, just click on the “Report” link added to the left column.
Those tasks could be used to build a monthly activity report, or something else…
Thanks to the user for the sugestion, we encourage you to take part in the project sending feedback and comments to the blog (now the comments will be attended).
Long live to the lich king !
Hey, you bad dog !
There were about 3k spam comments in the blog, so I decided to erase all the comments (sorry if you were waiting for a response) and activate akismet. Let’s see if this works as expected.
Hi all.
Now the projects can be ordered the way you want, using the “order” field in each project.
The default value is 1000, and all the same priority projects are alphabetically ordered, as usual.
AND the “-1″ value hides the project from the main view and the project selector (to add new tasks).
Total programming time: 2 hours, I love cake php !!
Hi All:
This is a mini-howto to add a simple “export to csv” feature, so you can control your tasks and projects inside excel, or build reports of what you’ve done for a group of projects.
All the filters apply before the CSV file is created.
Note: The link to build the CSV is located at the bottom of the Tasks table.
Step by step tutorial:
<?php/*** CSV helper for cakePHP. Compatible with version 1.1.x.x and higher.*
* PHP versions 4 and 5
*
* Licensed under The MIT License
*
* @copyright Adam Royle
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class CsvHelper extends Helper { var $delimiter = ',';
var $enclosure = '"';
var $filename = null;
var $line = array();
var $buffer;
/**
* This option preserves leading zeros on numeric data when opened in Excel.
* Use it ONLY when the csv file is going to be opened in Excel, as it uses
* non-standard syntax, and will probably break in other systems.
*/
var $preserveLeadingZerosInExcel = false;
var $_tmpFile = false;
function CsvHelper() {
$this->clear();
}
/**
* Adds a multi-dimensional array to the buffer.
*
* @param array $data Multi-dimensional array
* @param boolean $addFieldNames Add a row of field names before adding data
* @access public
*/
function addGrid($data, $addFieldNames = true, $fieldList = null) {
if (!$data) {
return false;
}
if (@is_array(reset($row = reset($data)))) {
// Array generated by cakePHP model
// eg.
// $data = array(array('Model' => array('field_name' => 'field value')), array('Model' => array('field_name' => 'field value')))
$defaultModel = key($row);
if ($this->filename === null) {
$this->setFilename(Inflector::pluralize($defaultModel));
}
if ($fieldList) {
$fields = array();
foreach ($fieldList as $fieldName) {
if (strpos($fieldName, '.')) {
list($modelName, $fieldName) = explode('.', $fieldName);
} else {
$modelName = $defaultModel;
}
$fields[] = array(Inflector::humanize($modelName), $fieldName);
}
if ($addFieldNames){
foreach ($fields as $field) {
if ($field[0] != $defaultModel) {
$this->addField($field[0].' '.Inflector::humanize($field[1]));
} else {
$this->addField(Inflector::humanize($field[1]));
}
}
$this->endRow();
}
foreach ($data as $row) {
foreach ($fields as $field) {
@$this->addField($row[$field[0]][$field[1]]);
}
$this->endRow();
}
} else {
if ($addFieldNames){
foreach (reset($row) as $key => $value) {
$this->addField(Inflector::humanize($key));
}
$this->endRow();
}
foreach ($data as $row) {
$this->addRow($row[$defaultModel]);
}
}
} else {
// Regular 2-dimensional array (with or without keys).
// eg.
// $data = array(array('field_name' => 'field_value'), array('field_name' => 'field_value'))
// or
// $data = array(array('field value'), array('field value'))
if ($fieldList) {
if ($addFieldNames){
foreach ($fieldList as $fieldName) {
$this->addField(Inflector::humanize($fieldName));
}
$this->endRow();
}
foreach ($data as $row) {
foreach ($fieldList as $fieldName) {
@$this->addField($row[$fieldName]);
}
$this->endRow();
}
} else {
if ($addFieldNames) {
foreach (reset($data) as $key => $value) {
$this->addField(Inflector::humanize($key));
}
$this->endRow();
}
foreach ($data as $row) {
$this->addRow($row);
}
}
}
}
/**
* Adds a single field value to the buffer. You must call $csv->endRow() to commit fields to the buffer.
*
* @param string $value Field value
* @access public
*/
function addField($value) {
$this->line[] = $value;
}
/**
* Commits the row of fields that were added by addField()
*
* @access public
*/
function endRow() {
$this->addRow($this->line);
$this->line = array();
}
/**
* Adds a single row to the buffer.
*
* @param array $row Data to be added
* @access public
*/
function addRow($row) {
if ($this->preserveLeadingZerosInExcel) {
// convert the number to a string formula
foreach ($row as $key => $value){
if (strlen($value) > 1 && $value[0] == '0' && is_numeric($value)) {
$row[$key] = '="'.$value.'"';
}
}
}
fputcsv($this->buffer, $row, $this->delimiter, $this->enclosure);
}
/**
* Outputs headers
*
* @param string $filename Filename to save as
* @access public
*/
function renderHeaders($filename = null) {
if (is_string($filename)) {
$this->setFilename($filename);
}
if ($this->filename === null) {
$this->filename = 'Data.csv';
}
if ($this->filename) {
header("Content-disposition:attachment;filename=".$this->filename);
}
header("Content-type:application/vnd.ms-excel");
}
/**
* Sets the output filename. Automatically appends .csv if necessary.
*
* @param string $filename Filename to save as
* @access public
*/
function setFilename($filename) {
$this->filename = $filename;
if (strtolower(substr($this->filename, -4)) != '.csv') {
$this->filename .= '.csv';
}
}
/**
* Returns CSV string and clears internal buffer. Outputs headers() if necessary.
*
* @param mixed $outputHeaders Boolean to determine if should output headers, or a string to set the filename
* @param string $to_encoding Encoding to use
* @param string $from_encoding
* @return string String CSV formatted string
* @access public
*/
function render($outputHeaders = true, $to_encoding = null, $from_encoding = "auto") {
if ($outputHeaders) {
if (is_string($outputHeaders)) {
$this->setFilename($outputHeaders);
}
$this->renderHeaders();
}
if ($this->_tmpFile) {
rewind($this->buffer);
$output = '';
while (!feof($this->buffer)) {
$output .= fread($this->buffer, 8192);
}
fclose($this->buffer);
} else {
rewind($this->buffer);
$output = stream_get_contents($this->buffer);
}
// get around excel bug (http://support.microsoft.com/kb/323626/)
if (substr($output,0,2) == 'ID') {
$pos = strpos($output, $this->delimiter);
if ($pos === false) {
$pos = strpos($output, "\n");
}
if ($pos !== false) {
$output = $this->enclosure . substr($output, 0, $pos) . $this->enclosure . substr($output, $pos);
}
}
if ($to_encoding) {
$output = mb_convert_encoding($output, $to_encoding, $from_encoding);
}
$this->clear();
return $this->output($output);
}
/**
* Clears internal buffer. This is called automatically by CsvHelper::render()
*
* @access public
*/
function clear() {
$this->line = array();
$this->buffer = @fopen('php://temp/maxmemory:'.(5*1024*1024), 'r+');
if ($this->buffer === false) {
$this->_tmpFile = true;
$this->buffer = tmpfile();
}
}
}
/**
* A PHP4 implementation of the equivalent PHP5 function
*
* See (http://www.php.net/manual/en/function.fputcsv.php) for details
*/
if (!function_exists('fputcsv')) {
function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
$str = '';
$escape_char = '\\';
foreach ($fields as $value) {
settype($value, 'string');
if (strpos($value, $delimiter) !== false ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $value.$delimiter;
}
}
$str = substr($str,0,-1);
$str .= "\n";
return fwrite($handle, $str);
}
}
?>
class XXXController extends AppController {
.....
var $helpers = array('Html', 'Form' , 'Javascript', 'Ajax', 'Csv');
.....
function exportcsv() {
$this->layout = '';
$this->set('dataToExport', $this->ZZZZ->findAll());
}
<?php
$csv->addGrid($dataToExport);
echo $csv->render(true);
?>
Notes: If you want to test the code generated, change render(false) for render(true) on the view, and the code will be shown on the browser.
Enjoy this new feature.
Hi all !
Today I’ve installed an RSS Reader Component in my cake application, so you can read the news at login time.
How ?
First, after searching cake community (bakery), I located this CakePHP RSS component
Following the instructions (very easy), you download the component into your vendors and components folder, then use it to get the feed, and display it as you like.
Tip: Cake has a funtion “truncate” inside the Text Helper to aid you if you like to get the first N characters for a headline or description of your feed.
Here is the code I’ve used
#CONTROLLER
var $helpers = array('Javascript','DAuth', 'Text');
var $components = array('DAuth','RequestHandler', 'Simplepie');
...... code ......
$items = $this->Simplepie->feed('http://blog.allmythingstodo.com/rss');
$this->set('feeds', $items);
#END OF CONTROLLER
#VIEW
<?php
foreach($feeds as $feed) {
echo $html->link($feed->get_title(), $feed->get_permalink()) . '<br/>';
echo $text->truncate($feed->get_description());
}
?>
#END OF VIEW
Hello dear allmythingstodo user or casual reader.
My name is Mauro Cabestany and I’m working now for 3 months in this little project, which aims to be a complete GTD oriented Personal Management Tool, to assist you in your workload planning.
Please feel free to login at my GTD Tools – AllMyThingsToDo page and start using it for free.
By the way, don’t worry about your email, or use a junk email to register because we are not using any validation. If we need to contact you, we’ll use this blog to keep in touch with AMTTD users.
Remember, contribute with suggestions or comments. Positive and negative feedback is welcome.
Spammers, please don’t touch my blogs.
Powered by WordPress