Empfehlungen: Erweiterte Suche

Aufgabenverwaltung - ToDo-Listen

Anleitungen und Quellcode-Auszüge die den Start vereinfachen sollen.

Aufgabenverwaltung - ToDo-Listen

Beitragvon Dogo » Fr 9. Okt 2009, 00:36

Hallo Kollegen,

ich habe gerade in meinem aktuellen Projekt ein ToDo-Modell ohne Relationen hinzugefügt.
Ist sehr praktisch, finde ich. Kann man in jedes Projekt schnell einkopieren und auch mal Solo benutzen.
Ist nur ne quick & dirty-Lösung, aber hilfreich. Ich hab's angehangen.

Hier der Code:

SQL:
Code: Alles auswählen

CREATE TABLE IF NOT EXISTS `todos` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(48) NOT NULL,
  `link` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `parent_id` int(10) unsigned NOT NULL,
  `lft` int(10) unsigned NOT NULL,
  `rght` int(10) unsigned NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  `status` tinyint(1) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='Todo-Liste';
 

In "link" kann man den Pfad angeben, auf die die Aufgabe zutrifft (z.B. "/users/register/").
Status habe ich nur für 0 oder 1 vorgesehen.

Modell:
Code: Alles auswählen
<?
class Todo extends AppModel {
    var $name = 'Todo';
    var $actsAs = array('Tree');
}
?>


Controller:
Code: Alles auswählen
<?
class TodosController extends AppController {
var $name = 'Todos';
var $scaffold;

function index() {
    $this->set('todos', $this->Todo->find('all', array('order' => 'lft ASC')));
}

function add() {
    if (!empty($this->data)) {
        $this->data['Todo']['name'] = nl2br($this->data['Todo']['name']);
        $this->data['Todo']['description'] = nl2br($this->data['Todo']['description']);
        if ($this->Todo->save($this->data)) {
            $this->redirect(array('controller' => 'todos', 'action' => 'index'));
        }
    }
    else {
    // Ersten eintrag in Auswahl-Liste künstlich erzeugen
    $all_todos = $this->Todo->generatetreelist(null, null, null, '-');
    $all_todos[0] = 'Neuer Aufgabenzweig';
    $this->set('todos', $all_todos);
    }
}

function edit($id = NULL) {
    if (!empty($this->data)) {
        $this->data['Todo']['name'] = nl2br($this->data['Todo']['name']);
        $this->data['Todo']['description'] = nl2br($this->data['Todo']['description']);
        if ($this->Todo->save($this->data)) {
            $this->redirect(array('controller' => 'todos', 'action' => 'index'));
        }
        else {
            pr ($this->data);
        }
    }
    else {
    $this->data = $this->Todo->read();
    $all_todos = $this->Todo->generatetreelist(null, null, null, '-');
    $all_todos[0] = 'Neuer Aufgabenzweig';
    $this->set('todos', $all_todos);    }
}

function getDepth($id) {
    $depth = $this->Todo->getpath($id);
    return (sizeof($depth));
}

}
?>

Die Funktion "getDepth" geht auch bestimmt, in dem man das Array aus dem find() in der Funktion index() auswertet. Kann ja wer machen und den Code hier reinstellen :)

index.ctp:
Code: Alles auswählen
<!-- File: /app/views/todos/index.ctp -->
<?php
//pr ($todos);
?>

<h1>Aufgaben</h1>
<table>
    <tr>
        <th>Name</th>
        <th>Link</th>
        <th>Beschreibung</th>
    </tr>

    <?php
    foreach ($todos as $todo) {
    // todo: das hier eleganter machen, ohne zusätzliche Abfragen
    $depth = $this->requestAction('/todos/getDepth/'.$todo['Todo']['id']);
    // hintergrundfarbe errechnen
    $color = dechex(255/$depth);
    ?>
    <tr>
        <td style="text-align: left;padding-left: <?php echo $depth*15; ?>px; background: #00<?php echo $color; ?>00;">
        <?php echo $html->link($todo['Todo']['name'],"/todos/edit/".$todo['Todo']['id']); ?>
        </td>
        <td><?php echo $html->link($todo['Todo']['link'],$todo['Todo']['link']); ?></td>
        <td>
        <?php
        echo $todo['Todo']['description'];
        ?>
        </td>
    </tr>
    <?php
    }
    ?>

</table>
<?php echo $html->link('Aufgabe hinzufügen',array('controller' => 'todos', 'action' => 'add'))?>

Ich habe den Baum eingerückt und farbig dargestellt. Geht auch bestimmt eleganter - tut aber seinen Dienst.

add.ctp:
Code: Alles auswählen
<!-- File: /app/views/todos/add.ctp -->

<h1>Aufgabe hinzufügen</h1>
<?php
echo $form->create('Todo');
echo $form->input('name');
echo $form->input('description');
echo $form->input('parent_id', array('options' => $todos, 'label' => 'Unteraufgabe von?'));
echo $form->input('status', array('type' => 'checkbox', 'label' => 'Erledigt?'));
echo $form->end('Aufgabe erstellen');
?>


edit.ctp:
Code: Alles auswählen
<!-- File: /app/views/todos/edit.ctp -->

<h1>Aufgabe ändern</h1>
<?php
echo $form->create('Todo');
echo $form->input('id', array('type' => 'hidden'));
echo $form->input('name');
echo $form->input('description');
echo $form->input('parent_id', array('options' => $todos, 'label' => 'Unteraufgabe von?'));
echo $form->input('status', array('type' => 'checkbox', 'label' => 'Erledigt?'));
echo $form->end('Aufgabe speichern');
?>


Viel Spaß damit,

Dogo
Dateianhänge
Todo.zip
Alles im Zip
(2.39 KiB) 66-mal heruntergeladen
Zuletzt geändert von Dogo am Fr 9. Okt 2009, 10:33, insgesamt 3-mal geändert.
Benutzeravatar
Dogo
 
Beiträge: 63
Registriert: Do 6. Aug 2009, 00:59
Wohnort: Wuppertal

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon euromark » Fr 9. Okt 2009, 01:03

n paar kleinere fehler und unschönheiten sind noch drin
aber ansonsten gelungen - sehr nett

z.b. wird bei
add() actions vor einem save IMMER create() ausgeführt normalerweise
(siehe gebackene scripts)

dein statusfeld in der db sollte klein nicht groß geschrieben sein - also "status" statt "Status" heißen

redirects sollten in array form vorliegen (controller=>, action=>) etc, um routing zu ermöglichen/vereinfachen

// Ersten eintrag in Auswahl-Liste künstlich erzeugen
könnte man evtl auch mit empty=>'' im jeweiligen view machen (zumal array-wert [0] normalerweise ja schon ein aktives element ist)

für varchar/text feld noch h(), sofern es auch für andere zugänglich sein könnte - aus sicherheitsgründen
bei textfeldern zusätzlich nl2br() wegen zeilenumbrüchen


soviel von mir^^
euromark
 
Beiträge: 643
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.x
OS: Windows

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon euromark » Fr 9. Okt 2009, 01:06

n paar kleinere fehler und unschönheiten sind noch drin
aber ansonsten gelungen - sehr nett

z.b. wird bei
add() actions vor einem save IMMER create() ausgeführt normalerweise
(siehe gebackene scripts)
kann unangenehme nebeneffekts haben sonst, je nachdem was man vorher noch macht...

dein statusfeld in der db sollte klein nicht groß geschrieben sein - also "status" statt "Status" heißen
und kann wie die anderen numeric fields ebenfalls unsigned sein

redirects sollten in array form vorliegen (controller=>, action=>) etc, um routing zu ermöglichen/vereinfachen

// Ersten eintrag in Auswahl-Liste künstlich erzeugen
könnte man evtl auch mit empty=>array('0'=>'xyz') im jeweiligen view machen (zumal array-wert [0] normalerweise ja schon ein aktives element ist)

für varchar/text feld noch h(), sofern es auch für andere zugänglich sein könnte - aus sicherheitsgründen
bei textfeldern zusätzlich nl2br() wegen zeilenumbrüchen

soviel von mir^^
euromark
 
Beiträge: 643
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.x
OS: Windows

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon Dogo » Fr 9. Okt 2009, 09:36

euromark hat geschrieben:n paar kleinere fehler und unschönheiten sind noch drin
aber ansonsten gelungen - sehr nett

Mehr als nett sollte es auch vorerst nicht werden :)

euromark hat geschrieben:z.b. wird bei
add() actions vor einem save IMMER create() ausgeführt normalerweise
(siehe gebackene scripts)

Habe noch nie was gebacken, kannste das betreffende ergänzen, so wie Du es meinst?

euromark hat geschrieben:dein statusfeld in der db sollte klein nicht groß geschrieben sein - also "status" statt "Status" heißen

Ups... merci!

euromark hat geschrieben:redirects sollten in array form vorliegen (controller=>, action=>) etc, um routing zu ermöglichen/vereinfachen

Ja, da hast Du recht. Ändere ich noch.

euromark hat geschrieben:// Ersten eintrag in Auswahl-Liste künstlich erzeugen
könnte man evtl auch mit empty=>'' im jeweiligen view machen (zumal array-wert [0] normalerweise ja schon ein aktives element ist)

Ha! Nee. Der erste Auto-Increment-Wert ist 1. Zumindest bei den DIngern, die ich gerade in der Pipeline habe.

euromark hat geschrieben:für varchar/text feld noch h(), sofern es auch für andere zugänglich sein könnte - aus sicherheitsgründen
bei textfeldern zusätzlich nl2br() wegen zeilenumbrüchen

nl2br - klar. So lange Beschreibungen habe ich noch nicht reingepackt. Aber was meinst Du mit dem "h()"? Hört sich nach was selbstverständlichem an, sagt mir aber gar nix.

euromark hat geschrieben:soviel von mir^^

Danke für's Feedback!
Benutzeravatar
Dogo
 
Beiträge: 63
Registriert: Do 6. Aug 2009, 00:59
Wohnort: Wuppertal

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon Dogo » Fr 9. Okt 2009, 10:34

"Status" in "status" geändert,
redirects korrigiert,
neu hochgeladen.
Benutzeravatar
Dogo
 
Beiträge: 63
Registriert: Do 6. Aug 2009, 00:59
Wohnort: Wuppertal

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon euromark » Fr 9. Okt 2009, 13:37

h() escaped - um potential schadhaften js injection code harmlos werden zu lassen

beispiele gibts hier genug:
http://ha.ckers.org/xss.html

und ja, in der tat SOLLTE dies in jedem projekt standard sein
es macht auch sinn, die backscripte dahingehend anzupassen

dadurch erspart man sich irgendwelche clean-vorgänge beim abspeichern, die
da sowieso meistens keinen sinn machen.
einfach bei der ausgabe drauf achten, dass keine js-injection möglich ist und man ist auf der sicheren seite.

hier ein beispiel:
Code: Alles auswählen
<h2><?php  __('News');?></h2>
    <dl><?php $i = 0; $class = ' class="altrow"';?>
        <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Title'); ?></dt>
        <dd<?php if ($i++ % 2 == 0) echo $class;?>>
            <?php echo h($news['News']['title']); ?>
            &amp;nbsp;
        </dd>
        <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Url'); ?></dt>
        <dd<?php if ($i++ % 2 == 0) echo $class;?>>
            <?php echo h($news['News']['url']); ?>
            &amp;nbsp;
        </dd>
        <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Details'); ?></dt>
        <dd<?php if ($i++ % 2 == 0) echo $class;?>>
            <?php echo nl2br(h($news['News']['details'])); ?>
            &amp;nbsp;
        </dd>
        <dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Prio'); ?></dt>
        <dd<?php if ($i++ % 2 == 0) echo $class;?>>
            <?php echo h($news['News']['prio']); ?>
            &amp;nbsp;
        </dd>
    </dl>
 
euromark
 
Beiträge: 643
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.x
OS: Windows

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon j-ckruse » Mi 23. Mär 2011, 15:12

Hallo,

auch wenn dieses Tutorial/Snippet schon etwas älter ist, habe ich noch eine Frage dazu:

Zum Einrücken wird die Spalte lft der Tabelle ausgewertet. Hat jemand von euch ein Beispiel, wie ich den Wert setzen kann, wenn ich eine Unteraufgabe erstellen möchte?
Entweder suche ich falsch oder ich habe noch nichts passendes gefunden.

Gruß,
Jens
j-ckruse
 
Beiträge: 17
Registriert: So 19. Sep 2010, 09:10

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon euromark » Mi 23. Mär 2011, 17:23

wenn du es richtig machst mit dem interface, musst du dich darum gar nich kümmern
cake macht das über das behavior von alleine
du musst lediglich den "parent" eintrag auswählen. ist auch besser so, das nicht anzufassen (manuell)
euromark
 
Beiträge: 643
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.x
OS: Windows

Re: Aufgabenverwaltung - ToDo-Listen

Beitragvon j-ckruse » Mi 23. Mär 2011, 18:35

Ah Ok, danke für den Hinweis.
Ich dachte, ich müsste da manuell machen und die Werte dann irgendwie berechnen. Das ist natürlich praktisch, wenn es automatisiert geht.
j-ckruse
 
Beiträge: 17
Registriert: So 19. Sep 2010, 09:10


Zurück zu Tutorials und Snippets

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste

cron