xref: /plugin/kanban/syntax.php (revision f4b18c92ed322afef4847ac5c154503a8bb2d449)
1*f4b18c92SGill B.<?php
2*f4b18c92SGill B.if(!defined('DOKU_INC')) die();
3*f4b18c92SGill B.
4*f4b18c92SGill B.class syntax_plugin_kanban extends DokuWiki_Syntax_Plugin {
5*f4b18c92SGill B.    public function getType() { return 'substition'; }
6*f4b18c92SGill B.    public function getSort() { return 150; }
7*f4b18c92SGill B.    public function connectTo($mode) {
8*f4b18c92SGill B.        $this->Lexer->addSpecialPattern('\{\{kanban>.*?\}\}', $mode, 'plugin_kanban');
9*f4b18c92SGill B.    }
10*f4b18c92SGill B.
11*f4b18c92SGill B.    public function handle($match, $state, $pos, Doku_Handler $handler) {
12*f4b18c92SGill B.		return [substr($match, 9, -2)];
13*f4b18c92SGill B.
14*f4b18c92SGill B.    }
15*f4b18c92SGill B.
16*f4b18c92SGill B.    public function render($mode, Doku_Renderer $renderer, $data) {
17*f4b18c92SGill B.        if ($mode != 'xhtml') return false;
18*f4b18c92SGill B.        global $conf;
19*f4b18c92SGill B.		//$mydata = str_split("||",$data);
20*f4b18c92SGill B.		list($boardName) = $data;
21*f4b18c92SGill B.		//echo $boardName;//debugging line
22*f4b18c92SGill B.        //list($boardName) = $mydata[0];
23*f4b18c92SGill B.		//list($boardList) = $mydata[1];
24*f4b18c92SGill B.		list($var1, $var2) = explode("+", $boardName); //added - 5-8-2026
25*f4b18c92SGill B.		//Change the variable back to boardName
26*f4b18c92SGill B.		$boardName = $var1;//added - 5-8-2026
27*f4b18c92SGill B.        // Path to individual card files: data/kanban/[boardName]/*.json
28*f4b18c92SGill B.        // $kanbanDir = $conf['savedir'] . '/kanban/' . $boardName . '/'; //WORKS!!
29*f4b18c92SGill B.		$kanbanDir = $conf['savedir'] . '/kanban/' . $boardName . '/'; //added - 5-8-2026
30*f4b18c92SGill B.
31*f4b18c92SGill B.        // Dynamically create the directory if it doesn't exist
32*f4b18c92SGill B.        if (!is_dir($kanbanDir)) io_makeFileDir($kanbanDir . 'placeholder.txt');
33*f4b18c92SGill B.
34*f4b18c92SGill B.        $renderer->doc .= '<div class="kanban-board" data-board="' . hsc($boardName) . '">';
35*f4b18c92SGill B.        // $columns = ['Projects', 'WIP', 'On Hold', 'Done']; // WORKS!!
36*f4b18c92SGill B.		// echo $var2;
37*f4b18c92SGill B.		$headers = explode(",",$var2); //added - 5-8-2026
38*f4b18c92SGill B.		$outpea = [];//added - 5-8-2026
39*f4b18c92SGill B.		$thankee = count($headers);//added - 5-8-2026
40*f4b18c92SGill B.		for($x=0;$x<$thankee;$x++){//added - 5-8-2026
41*f4b18c92SGill B.			if($headers[$x] && $headers[$x] != "" && !is_null($headers[$x])){//added - 5-8-2026
42*f4b18c92SGill B.					$outpea[$x] = $headers[$x];//added - 5-8-2026
43*f4b18c92SGill B.			}else{//added - 5-8-2026
44*f4b18c92SGill B.				continue;//added - 5-8-2026
45*f4b18c92SGill B.			}//added - 5-8-2026
46*f4b18c92SGill B.		}//added - 5-8-2026
47*f4b18c92SGill B.		$columns = $outpea;//added - 5-8-2026
48*f4b18c92SGill B.        $colVal=0;//added - 5-8-2026
49*f4b18c92SGill B.
50*f4b18c92SGill B.        // Load all .json files in the board directory
51*f4b18c92SGill B.        $savedCards = [];
52*f4b18c92SGill B.        foreach (glob($kanbanDir . "*.json") as $file) {
53*f4b18c92SGill B.            $card = json_decode(io_readFile($file), true);
54*f4b18c92SGill B.            if ($card) $savedCards[] = $card;
55*f4b18c92SGill B.        }
56*f4b18c92SGill B.
57*f4b18c92SGill B.        foreach ($columns as $col) {
58*f4b18c92SGill B.
59*f4b18c92SGill B.            $id = strtolower(str_replace(' ', '-', $col));
60*f4b18c92SGill B.            $renderer->doc .= '<div class="kanban-col" data-id="' . $id . '">';
61*f4b18c92SGill B.            $renderer->doc .= '  <h3>' . hsc($col) . '</h3>';
62*f4b18c92SGill B.            $renderer->doc .= '  <div class="cards-container"><div class="kanban-card-locked" data-id=0"><div class="triple-lines"></div></div>';
63*f4b18c92SGill B.
64*f4b18c92SGill B.            foreach ($savedCards as $card) {
65*f4b18c92SGill B.                if ($card['column'] === $id) {
66*f4b18c92SGill B.                    $renderer->doc .= $this->_renderCardHtml($card);
67*f4b18c92SGill B.                }
68*f4b18c92SGill B.            }
69*f4b18c92SGill B.			if($colVal!==0){//added - 5-8-2026
70*f4b18c92SGill B.				$renderer->doc .= '  </div></div>';//added - 5-8-2026
71*f4b18c92SGill B.			}else{//added - 5-8-2026
72*f4b18c92SGill B.				$renderer->doc .= '  </div><button class="add-card-btn">+ Add Card</button></div>';
73*f4b18c92SGill B.				//$renderer->doc .= '  </div><button class="add-col-btn">+ Add Column</button> <button class="add-card-btn">+ Add Card</button></div>';//added - 5-8-2026
74*f4b18c92SGill B.			}//added - 5-8-2026
75*f4b18c92SGill B.			$colVal = ($colVal + 1);//added - 5-8-2026
76*f4b18c92SGill B.        }
77*f4b18c92SGill B.        $renderer->doc .= '<div>My name goes here</div></div>';
78*f4b18c92SGill B.
79*f4b18c92SGill B.        return true;
80*f4b18c92SGill B.    }
81*f4b18c92SGill B.
82*f4b18c92SGill B.    private function _renderCardHtml($card) {
83*f4b18c92SGill B.		$currNote = hsc($card['note']);
84*f4b18c92SGill B.        $imp = hsc($card['importance'] ?? 'medium');
85*f4b18c92SGill B.		if(hsc($card['checked']) !== "true"){
86*f4b18c92SGill B.			$dat = "";
87*f4b18c92SGill B.		}else{
88*f4b18c92SGill B.			$dat = "checked";
89*f4b18c92SGill B.		}
90*f4b18c92SGill B.		$fullNotes = '';
91*f4b18c92SGill B.		$notes=hsc($card['note']);
92*f4b18c92SGill B.		$notif = explode("+",$notes);
93*f4b18c92SGill B.		array_map('trim', $notif);
94*f4b18c92SGill B.		foreach($notif as $note){
95*f4b18c92SGill B.			if($note == ""){
96*f4b18c92SGill B.				continue;
97*f4b18c92SGill B.			}else{
98*f4b18c92SGill B.			$fullNotes = $fullNotes . "+ " . $note . "<br>";
99*f4b18c92SGill B.			}
100*f4b18c92SGill B.		}
101*f4b18c92SGill B.
102*f4b18c92SGill B.		//return the card data only if the card has not been checked complete
103*f4b18c92SGill B.		if($dat != "checked"){
104*f4b18c92SGill B.        return '<div class="kanban-card '.$imp.'" data-id="'.hsc($card['id']).'">'
105*f4b18c92SGill B.		     . '<input type="checkbox" ' . $dat . '>'
106*f4b18c92SGill B.             . '<strong class="card-title">'.hsc($card['name']).'</strong><div id="noteDiv" class="noteDiv">Content</div>'
107*f4b18c92SGill B.             . '<div class="card-desc">'.hsc($card['desc'] ?? '').'</div>'
108*f4b18c92SGill B.             . '<input class="btn-notes" value="+Add Note">'
109*f4b18c92SGill B.			 . '<div class="card-note">' . $fullNotes . '</div></div>';
110*f4b18c92SGill B.		}
111*f4b18c92SGill B.    }
112*f4b18c92SGill B.}
113